From fa9b11f853c8b450e7f1f166ed7d66af6a2a9611 Mon Sep 17 00:00:00 2001 From: Gabriel Dugny Date: Wed, 31 Dec 2025 16:57:12 +0100 Subject: [PATCH] refactor: try to fit in useStyle Signed-off-by: Gabriel Dugny --- .../ToggleButtonGroup/ToggleButtonGroup.tsx | 14 +++++++++----- packages/ui/src/hooks/useStyles.ts | 18 +++++++++++++++--- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/packages/ui/src/components/ToggleButtonGroup/ToggleButtonGroup.tsx b/packages/ui/src/components/ToggleButtonGroup/ToggleButtonGroup.tsx index cec9bd90db..8e536f4406 100644 --- a/packages/ui/src/components/ToggleButtonGroup/ToggleButtonGroup.tsx +++ b/packages/ui/src/components/ToggleButtonGroup/ToggleButtonGroup.tsx @@ -18,15 +18,13 @@ import clsx from 'clsx'; import { forwardRef, Ref } from 'react'; import { ToggleButtonGroup as AriaToggleButtonGroup } from 'react-aria-components'; import type { ToggleButtonGroupProps } from './types'; -import { resolveResponsiveValue, useStyles } from '../../hooks/useStyles'; +import { useStyles } from '../../hooks/useStyles'; import { ToggleButtonGroupDefinition } from './definition'; import styles from './ToggleButtonGroup.module.css'; -import { useBreakpoint } from '../../hooks/useBreakpoint'; /** @public */ export const ToggleButtonGroup = forwardRef( (props: ToggleButtonGroupProps, ref: Ref) => { - const { breakpoint } = useBreakpoint(); const { classNames, dataAttributes, cleanedProps } = useStyles( ToggleButtonGroupDefinition, { @@ -35,13 +33,19 @@ export const ToggleButtonGroup = forwardRef( }, ); - const { className, children, orientation, ...rest } = cleanedProps; + const { + className, + children, + orientation: _orientation, + ...rest + } = cleanedProps; + const resolvedOrientation = dataAttributes['data-orientation']; return ( diff --git a/packages/ui/src/hooks/useStyles.ts b/packages/ui/src/hooks/useStyles.ts index 384b25d913..c00623e579 100644 --- a/packages/ui/src/hooks/useStyles.ts +++ b/packages/ui/src/hooks/useStyles.ts @@ -17,13 +17,23 @@ import { useBreakpoint, breakpoints } from './useBreakpoint'; import type { ComponentDefinition } from '../types'; import { utilityClassMap } from '../utils/utilityClassMap'; +type DataAttributeValue = V extends string ? V : string; + +type DataAttributesOf = T extends { + dataAttributes: infer D extends Record; +} + ? { + [K in keyof D as `data-${K & string}`]?: DataAttributeValue; + } + : Record; + /** * Resolve a responsive value based on the current breakpoint * @param value - The responsive value (string or object with breakpoint keys) * @param breakpoint - The current breakpoint * @returns The resolved value for the current breakpoint */ -export function resolveResponsiveValue( +function resolveResponsiveValue( value: T | Partial> | undefined, breakpoint: string, ): T | undefined { @@ -69,7 +79,7 @@ export function useStyles< props: P = {} as P, ): { classNames: T['classNames']; - dataAttributes: Record; + dataAttributes: DataAttributesOf & Record; utilityClasses: string; style: React.CSSProperties; cleanedProps: P; @@ -91,6 +101,7 @@ export function useStyles< const incomingStyle = props.style || {}; // Generate data attributes from component definition + // Keep this writable without running into TS2862 ("generic and can only be indexed for reading") const dataAttributes: Record = {}; for (const key of dataAttributeNames) { const value = props[key]; @@ -197,7 +208,8 @@ export function useStyles< return { classNames, - dataAttributes, + dataAttributes: dataAttributes as DataAttributesOf & + Record, utilityClasses: utilityClassList.join(' '), style: mergedStyle, cleanedProps,