diff --git a/docs/STYLING.md b/docs/STYLING.md index 063accaa..156c7a97 100644 --- a/docs/STYLING.md +++ b/docs/STYLING.md @@ -42,9 +42,9 @@ with no class and no JS required. Neither step injects styles at runtime. own `invalidIndicator` slot rather than a mask: `InputGroup` (`primitives/input-group/`) reads React Aria's `Group` `isInvalid` render prop and renders the icon itself, so an invalid control cannot be composed without a non-colour cue. The recipe owns only the icon's colour and margins — - `Icon` owns its box, and `IconSizeProvider` (`INPUT_GROUP_ICON_SIZE`) owns its per-size step — and - gives the `suffix` slot the same `order: 1` for the same Spectrum ordering. Combobox's control is - not a plain `Group` with that state to hand, so it stays CSS-driven. + `Icon` owns its box, and `IconSizeProvider` (`FIELD_CONTROL_ICON_SIZE`) owns its per-size step — + and gives the `suffix` slot the same `order: 1` for the same Spectrum ordering. Combobox's control + is not a plain `Group` with that state to hand, so it stays CSS-driven. - `overlays/mobile-overlay.css.ts`: the scrim, tray, and dialog styles `MobileOverlay` renders for the mobile combobox tray, based on Apache-2.0 React Spectrum's `Tray.tsx` and `tray/index.css`. - `overlays/`: the private mobile tray plumbing. `mobile-overlay.tsx` wraps React Aria's diff --git a/packages/@luke-ui/react/src/combobox-field/combobox-field.tsx b/packages/@luke-ui/react/src/combobox-field/combobox-field.tsx index 9b5011d1..0a5a2695 100644 --- a/packages/@luke-ui/react/src/combobox-field/combobox-field.tsx +++ b/packages/@luke-ui/react/src/combobox-field/combobox-field.tsx @@ -31,7 +31,7 @@ import { ComboboxRoot } from '../primitives/combobox/root.js'; import { comboboxRecipe } from '../primitives/combobox/styles.css.js'; import { ComboboxTrigger } from '../primitives/combobox/trigger.js'; import { Field } from '../primitives/field/field.js'; -import { COMBOBOX_ICON_SIZE } from '../sizing/combobox-sizing.js'; +import { FIELD_CONTROL_ICON_SIZE } from '../sizing/control-size.js'; import type { DistributiveOmit } from '../types/distributive-omit.js'; import type { Prettify } from '../types/prettify.js'; import { cx } from '../utils/utils.js'; @@ -249,7 +249,7 @@ function MobileComboboxContent({ return ( <> - + + + { diff --git a/packages/@luke-ui/react/src/primitives/combobox/item.tsx b/packages/@luke-ui/react/src/primitives/combobox/item.tsx index 6eb0e73a..2fd08dc0 100644 --- a/packages/@luke-ui/react/src/primitives/combobox/item.tsx +++ b/packages/@luke-ui/react/src/primitives/combobox/item.tsx @@ -10,7 +10,8 @@ import { import { composeRenderProps } from 'react-aria-components/composeRenderProps'; import { IconSizeProvider } from '../../icon/icon-size-context.js'; import { Icon } from '../../icon/icon.js'; -import { COMBOBOX_CHECK_ICON_SIZE, COMBOBOX_ICON_SIZE } from '../../sizing/combobox-sizing.js'; +import { COMBOBOX_CHECK_ICON_SIZE } from '../../sizing/combobox-sizing.js'; +import { FIELD_CONTROL_ICON_SIZE } from '../../sizing/control-size.js'; import type { DistributiveOmit } from '../../types/distributive-omit.js'; import type { Prettify } from '../../types/prettify.js'; import type { ComboboxSize } from './root.js'; @@ -45,7 +46,7 @@ export function ComboboxItem(props: ComboboxItemProps): JSX // RAC renders item content outside this component's original tree. // Put the provider inside the item render function so the content receives the context. return ( - + {children} {isSelected ? ( + { diff --git a/packages/@luke-ui/react/src/primitives/input-group/input-group.tsx b/packages/@luke-ui/react/src/primitives/input-group/input-group.tsx index 4bc48117..862bb64d 100644 --- a/packages/@luke-ui/react/src/primitives/input-group/input-group.tsx +++ b/packages/@luke-ui/react/src/primitives/input-group/input-group.tsx @@ -7,7 +7,7 @@ import { Input as RacInput } from 'react-aria-components/Input'; import { composeRenderProps } from 'react-aria-components/composeRenderProps'; import { IconSizeProvider } from '../../icon/icon-size-context.js'; import { Icon } from '../../icon/icon.js'; -import { INPUT_GROUP_ICON_SIZE } from '../../sizing/input-group-sizing.js'; +import { FIELD_CONTROL_ICON_SIZE } from '../../sizing/control-size.js'; import type { DistributiveOmit } from '../../types/distributive-omit.js'; import type { Prettify } from '../../types/prettify.js'; import type { InputGroupSize } from './recipe.css.js'; @@ -112,9 +112,9 @@ export function InputGroup(props: InputGroupProps): JSX.Element { * The provider covers the whole group, not only the indicator below: it sizes * the group's own error icon *and* any icon a caller puts in a prefix or * suffix, so both stay proportioned to the control. Same precedent as - * `Button` (`BUTTON_ICON_SIZE`) and `ComboboxTrigger` (`COMBOBOX_ICON_SIZE`). + * `Button` (`BUTTON_ICON_SIZE`) and the field controls (`FIELD_CONTROL_ICON_SIZE`). */} - + { diff --git a/packages/@luke-ui/react/src/primitives/input-group/recipe.css.ts b/packages/@luke-ui/react/src/primitives/input-group/recipe.css.ts index c897cd37..7342c1db 100644 --- a/packages/@luke-ui/react/src/primitives/input-group/recipe.css.ts +++ b/packages/@luke-ui/react/src/primitives/input-group/recipe.css.ts @@ -171,7 +171,7 @@ const inputGroupConfig = { // The invalid icon `InputGroup` renders itself. Only colour and spacing here: // the element is a real `Icon`, so `icon.css.ts` already owns its box dimensions // and `flexShrink`, and its per-size step comes from the `IconSizeProvider` - // `InputGroup` wraps the group in (`INPUT_GROUP_ICON_SIZE`) rather than from a + // `InputGroup` wraps the group in (`FIELD_CONTROL_ICON_SIZE`) rather than from a // variant here. `color`, not `background-color`, because an `Icon` fills with // `currentColor`. `CanvasText` (not the gated danger token) keeps it a solid, // high-contrast shape when author colours are ignored. diff --git a/packages/@luke-ui/react/src/sizing/combobox-sizing.ts b/packages/@luke-ui/react/src/sizing/combobox-sizing.ts index 3d67a168..74aa1462 100644 --- a/packages/@luke-ui/react/src/sizing/combobox-sizing.ts +++ b/packages/@luke-ui/react/src/sizing/combobox-sizing.ts @@ -1,15 +1,8 @@ import type { IconSize } from '../types/icon-size.js'; -import type { FieldControlSize } from './control-size.js'; - -/** Maps combobox control size to the appropriate icon size. */ -export const COMBOBOX_ICON_SIZE: Record = { - medium: 'small', - small: 'xsmall', -}; /** * Size of the selected-item check icon. The check sits beside option text * rather than scaling with the control, so it stays fixed at both combobox - * sizes instead of following `COMBOBOX_ICON_SIZE`. + * sizes instead of following `FIELD_CONTROL_ICON_SIZE`. */ export const COMBOBOX_CHECK_ICON_SIZE: IconSize = 'xsmall'; diff --git a/packages/@luke-ui/react/src/sizing/control-size.ts b/packages/@luke-ui/react/src/sizing/control-size.ts index b0806364..9e8391f8 100644 --- a/packages/@luke-ui/react/src/sizing/control-size.ts +++ b/packages/@luke-ui/react/src/sizing/control-size.ts @@ -1,6 +1,7 @@ +import type { IconSize } from '../types/icon-size.js'; + /** - * Size union shared by the field controls (`Combobox`, `InputGroup`) whose icon-size - * maps (`COMBOBOX_ICON_SIZE`, `INPUT_GROUP_ICON_SIZE`) are keyed by it. + * Size union shared by the field controls (`Combobox`, `InputGroup`). * * Named apart from the `vars.controlSize` theme token — that's the physical block-size * value shared by every sized control (buttons included); this is a type, scoped to the @@ -12,3 +13,9 @@ * exactly this union so the two can never drift apart. */ export type FieldControlSize = 'medium' | 'small'; + +/** Maps field control size to the icon size those controls provide. */ +export const FIELD_CONTROL_ICON_SIZE: Record = { + medium: 'small', + small: 'xsmall', +}; diff --git a/packages/@luke-ui/react/src/sizing/input-group-sizing.ts b/packages/@luke-ui/react/src/sizing/input-group-sizing.ts deleted file mode 100644 index 8835ae68..00000000 --- a/packages/@luke-ui/react/src/sizing/input-group-sizing.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { IconSize } from '../types/icon-size.js'; -import type { FieldControlSize } from './control-size.js'; - -/** - * Maps `InputGroup` control size to the icon size it provides through - * `IconSizeProvider` — its own invalid indicator and any icon a caller puts in a - * prefix or suffix. Mirrors `COMBOBOX_ICON_SIZE` (`sizing/combobox-sizing.ts`) so the - * two field controls scale their icons the same way. - */ -export const INPUT_GROUP_ICON_SIZE: Record = { - medium: 'small', - small: 'xsmall', -};