@adea-ai/ui 0.72.0 → 0.72.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/components/ui/checkbox/checkbox.d.ts +2 -0
  2. package/dist/components/ui/checkbox/checkbox.d.ts.map +1 -1
  3. package/dist/components/ui/checkbox/checkbox.js +52 -13
  4. package/dist/components/ui/checkbox/checkbox.js.map +1 -1
  5. package/dist/components/ui/combobox/combobox.d.ts.map +1 -1
  6. package/dist/components/ui/combobox/combobox.js +10 -6
  7. package/dist/components/ui/combobox/combobox.js.map +1 -1
  8. package/dist/components/ui/radio-group/radio-group.d.ts +2 -1
  9. package/dist/components/ui/radio-group/radio-group.d.ts.map +1 -1
  10. package/dist/components/ui/radio-group/radio-group.js +46 -13
  11. package/dist/components/ui/radio-group/radio-group.js.map +1 -1
  12. package/dist/components/ui/slider/slider.d.ts +5 -1
  13. package/dist/components/ui/slider/slider.d.ts.map +1 -1
  14. package/dist/components/ui/slider/slider.js +36 -20
  15. package/dist/components/ui/slider/slider.js.map +1 -1
  16. package/dist/components/ui/switch/switch.d.ts +2 -0
  17. package/dist/components/ui/switch/switch.d.ts.map +1 -1
  18. package/dist/components/ui/switch/switch.js +51 -12
  19. package/dist/components/ui/switch/switch.js.map +1 -1
  20. package/dist/r/src/components/ui/checkbox/checkbox.tsx +34 -9
  21. package/dist/r/src/components/ui/combobox/combobox.tsx +1 -0
  22. package/dist/r/src/components/ui/radio-group/radio-group.tsx +22 -5
  23. package/dist/r/src/components/ui/slider/slider.tsx +43 -15
  24. package/dist/r/src/components/ui/switch/switch.tsx +34 -9
  25. package/package.json +1 -1
  26. package/src/components/ui/checkbox/checkbox.tsx +34 -9
  27. package/src/components/ui/combobox/combobox.tsx +1 -0
  28. package/src/components/ui/radio-group/radio-group.tsx +22 -5
  29. package/src/components/ui/slider/slider.tsx +43 -15
  30. package/src/components/ui/switch/switch.tsx +34 -9
@@ -1 +1 @@
1
- {"version":3,"file":"switch.js","names":["Switch","KobalteSwitch","ComponentProps","JSX","splitProps","cn","SwitchProps","Omit","controlClass","thumbClass","labelClass","descriptionClass","children","Element","props","local","rest","_$createComponent","_$mergeProps","class","Input","aria-label","aria-labelledby","Control","Thumb","_$memo","_el$","_tmpl$","_$insert","Label","Description","SwitchLabel","SwitchDescription","Switch","_$createComponent","KobalteSwitch","_$mergeProps","_$memo"],"sources":["../../../../src/components/ui/switch/switch.tsx"],"sourcesContent":["import { Switch as KobalteSwitch } from '@kobalte/core/switch'\nimport type { ComponentProps, JSX } from 'solid-js'\nimport { splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\n\n/**\n * Switch.\n *\n * For a setting that takes effect the moment it is flipped. The distinction\n * from Checkbox is behaviour, not looks: a switch applies immediately and\n * belongs in a settings row, while a checkbox is a value the user is still\n * composing and is applied when a form is submitted. A switch inside an unsaved\n * form is the mistake this split exists to prevent.\n *\n * `Switch.Input` renders a real hidden checkbox, so the control is\n * form-native, keyboard-operable, and its `aria-checked` follows the state the\n * user sees.\n */\nexport type SwitchProps = Omit<ComponentProps<typeof KobalteSwitch>, 'children'> & {\n controlClass?: string\n thumbClass?: string\n labelClass?: string\n descriptionClass?: string\n /**\n * Replaces the control and label. Omit it to get the default control beside\n * `label` and `description`; supply it to compose the parts yourself.\n */\n children?: JSX.Element\n}\n\nexport function Switch(props: SwitchProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'controlClass',\n 'thumbClass',\n 'labelClass',\n 'descriptionClass',\n 'children',\n 'aria-label',\n 'aria-labelledby',\n ])\n\n return (\n <KobalteSwitch class={cn('group/switch flex items-center gap-2.5', local.class)} {...rest}>\n {/* The name belongs on the input; see Checkbox for why. */}\n <KobalteSwitch.Input\n aria-label={local['aria-label']}\n aria-labelledby={local['aria-labelledby']}\n />\n <KobalteSwitch.Control\n class={cn(\n 'bg-input inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-transparent',\n 'transition-colors ease-out outline-none',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'data-[checked]:bg-primary',\n 'data-[invalid]:border-destructive',\n 'data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',\n local.controlClass\n )}\n >\n <KobalteSwitch.Thumb\n class={cn(\n 'bg-background pointer-events-none block size-4 rounded-full shadow-xs',\n 'transition-transform ease-out',\n 'data-[checked]:translate-x-4',\n local.thumbClass\n )}\n />\n </KobalteSwitch.Control>\n {local.children ?? (\n <div class=\"grid gap-0.5\">\n <KobalteSwitch.Label class={cn('text-sm leading-none font-medium', local.labelClass)} />\n <KobalteSwitch.Description\n class={cn('text-muted-foreground text-sm', local.descriptionClass)}\n />\n </div>\n )}\n </KobalteSwitch>\n )\n}\n\n/**\n * The switch's own label. Valid only inside a `<Switch>`: it is Kobalte's label\n * for that root's control, and outside one there is nothing to associate with.\n * A label drawn *beside* a switch — a settings row with the control trailing —\n * is plain text, and the switch takes an `aria-label` instead.\n */\nexport function SwitchLabel(props: ComponentProps<typeof KobalteSwitch.Label>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteSwitch.Label class={cn('text-sm leading-none font-medium', local.class)} {...rest} />\n )\n}\n\nexport function SwitchDescription(props: ComponentProps<typeof KobalteSwitch.Description>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteSwitch.Description class={cn('text-muted-foreground text-sm', local.class)} {...rest} />\n )\n}\n"],"mappings":";;;;;;AA8BA,SAAgBA,SAAOc,OAAoB;CACzC,MAAM,CAACC,OAAOC,QAAQZ,WAAWU,OAAO;EACtC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CAAiB,CAClB;CAED,OAAAG,gBACGhB,QAAaiB,WAAA,EAAA,KAAA,WAAA;EAAA,OAAQb,GAAG,0CAA0CU,MAAMI,KAAK;CAAC,EAAA,GAAMH,MAAI,EAAA,IAAAJ,WAAA;EAAA,OAAA;GAAAK,gBAEtFhB,OAAcmB,OAAK;IAAA,KAAA,gBAAA;KAAA,OACNL,MAAM;IAAa;IAAA,KAAA,qBAAA;KAAA,OACdA,MAAM;IAAkB;GAAA,CAAA;GAAAE,gBAE1ChB,OAAcsB,SAAO;IAAA,KAAA,WAAA;KAAA,OACblB,GACL,6FACA,2CACA,oFACA,6BACA,qCACA,iEACAU,MAAMP,YACR;IAAC;IAAA,IAAAI,WAAA;KAAA,OAAAK,gBAEAhB,OAAcuB,OAAK,EAAA,KAAA,WAAA;MAAA,OACXnB,GACL,yEACA,iCACA,gCACAU,MAAMN,UACR;KAAC,EAAA,CAAA;IAAA;GAAA,CAAA;GAAAgB,WAGJV,MAAMH,mBAAQ;IAAA,IAAAc,OAAAC,OAAA;IAAAC,OAAAF,MAAAT,gBAEVhB,OAAc4B,OAAK,EAAA,KAAA,WAAA;KAAA,OAAQxB,GAAG,oCAAoCU,MAAML,UAAU;IAAC,EAAA,CAAA,GAAA,IAAA;IAAAkB,OAAAF,MAAAT,gBACnFhB,OAAc6B,aAAW,EAAA,KAAA,WAAA;KAAA,OACjBzB,GAAG,iCAAiCU,MAAMJ,gBAAgB;IAAC,EAAA,CAAA,GAAA,IAAA;IAAA,OAAAe;GAAA,EAAA,CAAA,CAGvE;EAAA;CAAA,EAAA,CAAA,CAAA;AAGP;;;;;;;AAQA,SAAgBK,YAAYjB,OAAmD;CAC7E,MAAM,CAACC,OAAOC,QAAQZ,WAAWU,OAAO,CAAC,OAAO,CAAC;CACjD,OAAAG,gBACGhB,OAAc4B,OAAKX,WAAA,EAAA,KAAA,WAAA;EAAA,OAAQb,GAAG,oCAAoCU,MAAMI,KAAK;CAAC,EAAA,GAAMH,IAAI,CAAA;AAE7F;AAEA,SAAgBgB,kBAAkBlB,OAAyD;CACzF,MAAM,CAACC,OAAOC,QAAQZ,WAAWU,OAAO,CAAC,OAAO,CAAC;CACjD,OAAAG,gBACGhB,OAAc6B,aAAWZ,WAAA,EAAA,KAAA,WAAA;EAAA,OAAQb,GAAG,iCAAiCU,MAAMI,KAAK;CAAC,EAAA,GAAMH,IAAI,CAAA;AAEhG"}
1
+ {"version":3,"file":"switch.js","names":["Switch","KobalteSwitch","ComponentProps","JSX","splitProps","cn","SwitchProps","Omit","controlClass","thumbClass","labelClass","descriptionClass","label","Element","description","children","props","local","rest","_$createComponent","_$mergeProps","title","class","Input","aria-label","aria-labelledby","aria-describedby","aria-invalid","aria-busy","Control","Thumb","_$memo","_el$","_tmpl$","_$insert","_c$","Label","_c$2","Description","SwitchLabel","SwitchDescription","Switch","_$createComponent","KobalteSwitch","_$mergeProps","_$memo"],"sources":["../../../../src/components/ui/switch/switch.tsx"],"sourcesContent":["import { Switch as KobalteSwitch } from '@kobalte/core/switch'\nimport type { ComponentProps, JSX } from 'solid-js'\nimport { splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\n\n/**\n * Switch.\n *\n * For a setting that takes effect the moment it is flipped. The distinction\n * from Checkbox is behaviour, not looks: a switch applies immediately and\n * belongs in a settings row, while a checkbox is a value the user is still\n * composing and is applied when a form is submitted. A switch inside an unsaved\n * form is the mistake this split exists to prevent.\n *\n * `Switch.Input` renders a real hidden checkbox, so the control is\n * form-native, keyboard-operable, and its `aria-checked` follows the state the\n * user sees.\n */\nexport type SwitchProps = Omit<ComponentProps<typeof KobalteSwitch>, 'children'> & {\n controlClass?: string\n thumbClass?: string\n labelClass?: string\n descriptionClass?: string\n label?: JSX.Element\n description?: JSX.Element\n /**\n * Replaces the control and label. Omit it to get the default control beside\n * `label` and `description`; supply it to compose the parts yourself.\n */\n children?: JSX.Element\n}\n\nexport function Switch(props: SwitchProps) {\n const [local, rest] = splitProps(props, [\n 'class',\n 'controlClass',\n 'thumbClass',\n 'labelClass',\n 'descriptionClass',\n 'children',\n 'label',\n 'description',\n 'aria-label',\n 'aria-labelledby',\n 'aria-describedby',\n 'aria-invalid',\n 'aria-busy',\n 'title',\n ])\n\n return (\n <KobalteSwitch\n title={local.title}\n class={cn('group/switch flex items-center gap-2.5', local.class)}\n {...rest}\n >\n {/* The name belongs on the input; see Checkbox for why. */}\n <KobalteSwitch.Input\n aria-label={local['aria-label']}\n aria-labelledby={local['aria-labelledby']}\n aria-describedby={local['aria-describedby']}\n aria-invalid={local['aria-invalid']}\n aria-busy={local['aria-busy']}\n title={local.title}\n />\n <KobalteSwitch.Control\n class={cn(\n 'bg-input inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-transparent',\n 'transition-colors ease-out outline-none',\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'data-[checked]:bg-primary',\n 'data-[invalid]:border-destructive',\n 'data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',\n local.controlClass\n )}\n >\n <KobalteSwitch.Thumb\n class={cn(\n 'bg-background pointer-events-none block size-4 rounded-full shadow-xs',\n 'transition-transform ease-out',\n 'data-[checked]:translate-x-4',\n local.thumbClass\n )}\n />\n </KobalteSwitch.Control>\n {local.children ??\n (local.label || local.description ? (\n <div class=\"grid gap-0.5\">\n {local.label ? (\n <KobalteSwitch.Label class={cn('text-sm leading-none font-medium', local.labelClass)}>\n {local.label}\n </KobalteSwitch.Label>\n ) : null}\n {local.description ? (\n <KobalteSwitch.Description\n class={cn('text-muted-foreground text-sm', local.descriptionClass)}\n >\n {local.description}\n </KobalteSwitch.Description>\n ) : null}\n </div>\n ) : null)}\n </KobalteSwitch>\n )\n}\n\n/**\n * The switch's own label. Valid only inside a `<Switch>`: it is Kobalte's label\n * for that root's control, and outside one there is nothing to associate with.\n * A label drawn *beside* a switch — a settings row with the control trailing —\n * is plain text, and the switch takes an `aria-label` instead.\n */\nexport function SwitchLabel(props: ComponentProps<typeof KobalteSwitch.Label>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteSwitch.Label class={cn('text-sm leading-none font-medium', local.class)} {...rest} />\n )\n}\n\nexport function SwitchDescription(props: ComponentProps<typeof KobalteSwitch.Description>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <KobalteSwitch.Description class={cn('text-muted-foreground text-sm', local.class)} {...rest} />\n )\n}\n"],"mappings":";;;;;;AAgCA,SAAgBA,SAAOgB,OAAoB;CACzC,MAAM,CAACC,OAAOC,QAAQd,WAAWY,OAAO;EACtC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CAAO,CACR;CAED,OAAAG,gBACGlB,QAAamB,WAAA;EAAA,IACZC,QAAK;GAAA,OAAEJ,MAAMI;EAAK;EAAA,KAAA,WAAA;GAAA,OACXhB,GAAG,0CAA0CY,MAAMK,KAAK;EAAC;CAAA,GAC5DJ,MAAI,EAAA,IAAAH,WAAA;EAAA,OAAA;GAAAI,gBAGPlB,OAAcsB,OAAK;IAAA,KAAA,gBAAA;KAAA,OACNN,MAAM;IAAa;IAAA,KAAA,qBAAA;KAAA,OACdA,MAAM;IAAkB;IAAA,KAAA,sBAAA;KAAA,OACvBA,MAAM;IAAmB;IAAA,KAAA,kBAAA;KAAA,OAC7BA,MAAM;IAAe;IAAA,KAAA,eAAA;KAAA,OACxBA,MAAM;IAAY;IAAA,IAC7BI,QAAK;KAAA,OAAEJ,MAAMI;IAAK;GAAA,CAAA;GAAAF,gBAEnBlB,OAAc4B,SAAO;IAAA,KAAA,WAAA;KAAA,OACbxB,GACL,6FACA,2CACA,oFACA,6BACA,qCACA,iEACAY,MAAMT,YACR;IAAC;IAAA,IAAAO,WAAA;KAAA,OAAAI,gBAEAlB,OAAc6B,OAAK,EAAA,KAAA,WAAA;MAAA,OACXzB,GACL,yEACA,iCACA,gCACAY,MAAMR,UACR;KAAC,EAAA,CAAA;IAAA;GAAA,CAAA;GAAAsB,WAGJd,MAAMF,aACJE,MAAML,SAASK,MAAMH,qBAAW;IAAA,IAAAkB,OAAAC,OAAA;IAAAC,OAAAF,aAAA;KAAA,IAAAG,MAAAJ,WAAA,CAAA,CAE5Bd,MAAML,KAAK;KAAA,aAAXuB,IAAA,IAAAhB,gBACElB,OAAcmC,OAAK;MAAA,KAAA,WAAA;OAAA,OAAQ/B,GAAG,oCAAoCY,MAAMP,UAAU;MAAC;MAAA,IAAAK,WAAA;OAAA,OACjFE,MAAML;MAAK;KAAA,CAAA,IAEZ;IAAI,EAAA,CAAA,GAAA,IAAA;IAAAsB,OAAAF,aAAA;KAAA,IAAAK,OAAAN,WAAA,CAAA,CACPd,MAAMH,WAAW;KAAA,aAAjBuB,KAAA,IAAAlB,gBACElB,OAAcqC,aAAW;MAAA,KAAA,WAAA;OAAA,OACjBjC,GAAG,iCAAiCY,MAAMN,gBAAgB;MAAC;MAAA,IAAAI,WAAA;OAAA,OAEjEE,MAAMH;MAAW;KAAA,CAAA,IAElB;IAAI,EAAA,CAAA,GAAA,IAAA;IAAA,OAAAkB;GAAA,EAAA,CAAA,IAER,KAAK;EAAA;CAAA,EAAA,CAAA,CAAA;AAGjB;;;;;;;AAQA,SAAgBO,YAAYvB,OAAmD;CAC7E,MAAM,CAACC,OAAOC,QAAQd,WAAWY,OAAO,CAAC,OAAO,CAAC;CACjD,OAAAG,gBACGlB,OAAcmC,OAAKhB,WAAA,EAAA,KAAA,WAAA;EAAA,OAAQf,GAAG,oCAAoCY,MAAMK,KAAK;CAAC,EAAA,GAAMJ,IAAI,CAAA;AAE7F;AAEA,SAAgBsB,kBAAkBxB,OAAyD;CACzF,MAAM,CAACC,OAAOC,QAAQd,WAAWY,OAAO,CAAC,OAAO,CAAC;CACjD,OAAAG,gBACGlB,OAAcqC,aAAWlB,WAAA,EAAA,KAAA,WAAA;EAAA,OAAQf,GAAG,iCAAiCY,MAAMK,KAAK;CAAC,EAAA,GAAMJ,IAAI,CAAA;AAEhG"}
@@ -21,6 +21,8 @@ export type CheckboxProps = Omit<ComponentProps<typeof KobalteCheckbox>, 'childr
21
21
  controlClass?: string
22
22
  labelClass?: string
23
23
  descriptionClass?: string
24
+ label?: JSX.Element
25
+ description?: JSX.Element
24
26
  /**
25
27
  * Replaces the control and label. Omit it to get the default control beside
26
28
  * `label` and `description`; supply it to compose the parts yourself.
@@ -35,13 +37,23 @@ export function Checkbox(props: CheckboxProps) {
35
37
  'labelClass',
36
38
  'descriptionClass',
37
39
  'children',
40
+ 'label',
41
+ 'description',
38
42
  'indeterminate',
39
43
  'aria-label',
40
44
  'aria-labelledby',
45
+ 'aria-describedby',
46
+ 'aria-invalid',
47
+ 'aria-busy',
48
+ 'title',
41
49
  ])
42
50
 
43
51
  return (
44
- <KobalteCheckbox class={cn('group/checkbox flex items-start gap-2.5', local.class)} {...rest}>
52
+ <KobalteCheckbox
53
+ title={local.title}
54
+ class={cn('group/checkbox flex items-start gap-2.5', local.class)}
55
+ {...rest}
56
+ >
45
57
  {/*
46
58
  * The name goes on the input, which is what carries the value and takes
47
59
  * focus. On the Root it would land on a plain div and name nothing — the
@@ -50,6 +62,10 @@ export function Checkbox(props: CheckboxProps) {
50
62
  <KobalteCheckbox.Input
51
63
  aria-label={local['aria-label']}
52
64
  aria-labelledby={local['aria-labelledby']}
65
+ aria-describedby={local['aria-describedby']}
66
+ aria-invalid={local['aria-invalid']}
67
+ aria-busy={local['aria-busy']}
68
+ title={local.title}
53
69
  />
54
70
  <KobalteCheckbox.Control
55
71
  class={cn(
@@ -67,14 +83,23 @@ export function Checkbox(props: CheckboxProps) {
67
83
  {local.indeterminate ? <Minus class="size-3" /> : <Check class="size-3" />}
68
84
  </KobalteCheckbox.Indicator>
69
85
  </KobalteCheckbox.Control>
70
- {local.children ?? (
71
- <div class="grid gap-0.5 leading-none">
72
- <KobalteCheckbox.Label class={cn('text-sm font-medium', local.labelClass)} />
73
- <KobalteCheckbox.Description
74
- class={cn('text-muted-foreground text-sm', local.descriptionClass)}
75
- />
76
- </div>
77
- )}
86
+ {local.children ??
87
+ (local.label || local.description ? (
88
+ <div class="grid gap-0.5">
89
+ {local.label ? (
90
+ <KobalteCheckbox.Label class={cn('text-sm font-medium', local.labelClass)}>
91
+ {local.label}
92
+ </KobalteCheckbox.Label>
93
+ ) : null}
94
+ {local.description ? (
95
+ <KobalteCheckbox.Description
96
+ class={cn('text-muted-foreground text-sm', local.descriptionClass)}
97
+ >
98
+ {local.description}
99
+ </KobalteCheckbox.Description>
100
+ ) : null}
101
+ </div>
102
+ ) : null)}
78
103
  </KobalteCheckbox>
79
104
  )
80
105
  }
@@ -96,6 +96,7 @@ export function ComboboxContent(props: ComponentProps<typeof KobalteCombobox.Con
96
96
  {...rest}
97
97
  >
98
98
  <KobalteCombobox.Listbox class={cn('max-h-72 overflow-y-auto', menuContentPadding)} />
99
+ {local.children}
99
100
  <KobalteCombobox.Arrow aria-hidden="true" class={popoverArrow} />
100
101
  </KobalteCombobox.Content>
101
102
  </KobalteCombobox.Portal>
@@ -25,7 +25,8 @@ export type RadioGroupItemProps = ComponentProps<typeof KobalteRadioGroup.Item>
25
25
  controlClass?: string
26
26
  /**
27
27
  * The option's visible label. A radio with no accessible name is unreachable
28
- * by a screen reader and by voice control, so supply this or a child.
28
+ * by a screen reader and by voice control, so supply this, a labelled child,
29
+ * `aria-label`, or `aria-labelledby`.
29
30
  */
30
31
  label?: string
31
32
  description?: string
@@ -38,14 +39,28 @@ export function RadioGroupItem(props: RadioGroupItemProps) {
38
39
  'label',
39
40
  'description',
40
41
  'children',
42
+ 'aria-label',
43
+ 'aria-labelledby',
44
+ 'aria-describedby',
45
+ 'aria-invalid',
46
+ 'aria-busy',
47
+ 'title',
41
48
  ])
42
49
 
43
50
  return (
44
51
  <KobalteRadioGroup.Item
52
+ title={local.title}
45
53
  class={cn('group/radio flex items-start gap-2.5', local.class)}
46
54
  {...rest}
47
55
  >
48
- <KobalteRadioGroup.ItemInput />
56
+ <KobalteRadioGroup.ItemInput
57
+ aria-label={local['aria-label']}
58
+ aria-labelledby={local['aria-labelledby']}
59
+ aria-describedby={local['aria-describedby']}
60
+ aria-invalid={local['aria-invalid']}
61
+ aria-busy={local['aria-busy']}
62
+ title={local.title}
63
+ />
49
64
  <KobalteRadioGroup.ItemControl
50
65
  class={cn(
51
66
  'border-input bg-transparent flex size-4 shrink-0 items-center justify-center rounded-full border',
@@ -63,9 +78,11 @@ export function RadioGroupItem(props: RadioGroupItemProps) {
63
78
  </KobalteRadioGroup.ItemControl>
64
79
  {local.children ?? (
65
80
  <div class="grid gap-0.5 leading-none">
66
- <KobalteRadioGroup.ItemLabel class="text-sm font-medium">
67
- {local.label}
68
- </KobalteRadioGroup.ItemLabel>
81
+ {local.label ? (
82
+ <KobalteRadioGroup.ItemLabel class="text-sm font-medium">
83
+ {local.label}
84
+ </KobalteRadioGroup.ItemLabel>
85
+ ) : null}
69
86
  {local.description ? (
70
87
  <KobalteRadioGroup.ItemDescription class="text-muted-foreground text-sm">
71
88
  {local.description}
@@ -1,6 +1,6 @@
1
1
  import { Slider as KobalteSlider } from '@kobalte/core/slider'
2
2
  import type { ComponentProps } from 'solid-js'
3
- import { Show, splitProps } from 'solid-js'
3
+ import { For, Show, createUniqueId, createRenderEffect, splitProps } from 'solid-js'
4
4
  import { cn } from '../../../lib/utils'
5
5
 
6
6
  /**
@@ -12,9 +12,13 @@ import { cn } from '../../../lib/utils'
12
12
  * nobody can set exactly.
13
13
  *
14
14
  * Kobalte handles pointer capture, keyboard stepping and the ARIA value
15
- * wiring; this paints the track, fill and thumb.
15
+ * wiring; this paints the track, fill and one thumb per value. Each thumb
16
+ * contains a form-native input, hidden from accessibility because the visible
17
+ * thumb already exposes the slider role.
16
18
  */
17
19
  export type SliderProps = ComponentProps<typeof KobalteSlider> & {
20
+ /** Accessible names for individual thumbs, in value order (for example minimum and maximum). */
21
+ thumbLabels?: readonly string[]
18
22
  trackClass?: string
19
23
  rangeClass?: string
20
24
  thumbClass?: string
@@ -23,11 +27,13 @@ export type SliderProps = ComponentProps<typeof KobalteSlider> & {
23
27
  }
24
28
 
25
29
  export function Slider(props: SliderProps) {
30
+ const inputId = createUniqueId()
26
31
  const [local, rest] = splitProps(props, [
27
32
  'class',
28
33
  'trackClass',
29
34
  'rangeClass',
30
35
  'thumbClass',
36
+ 'thumbLabels',
31
37
  'valueLabel',
32
38
  'children',
33
39
  'aria-label',
@@ -61,21 +67,43 @@ export function Slider(props: SliderProps) {
61
67
  />
62
68
  </KobalteSlider.Track>
63
69
  {local.children}
64
- <KobalteSlider.Thumb
65
- aria-label={local['aria-label']}
66
- aria-labelledby={local['aria-labelledby']}
67
- class={cn(
68
- 'border-primary bg-background block size-4 shrink-0 rounded-full border-2 shadow-xs',
69
- 'transition-[color,box-shadow] ease-out outline-none',
70
- 'hover:ring-4 hover:ring-primary-subtle',
71
- 'focus-visible:ring-4 focus-visible:ring-primary-subtle',
72
- local.thumbClass
70
+ <For
71
+ each={Array.from(
72
+ { length: (props.value ?? props.defaultValue ?? [0]).length },
73
+ (_, index) => index
73
74
  )}
74
75
  >
75
- <Show when={local.valueLabel}>
76
- <KobalteSlider.ValueLabel class="bg-popover text-popover-foreground absolute -top-6 left-1/2 -translate-x-1/2 rounded-sm border border-border px-1 text-2xs tabular-nums" />
77
- </Show>
78
- </KobalteSlider.Thumb>
76
+ {(index) => (
77
+ <KobalteSlider.Thumb
78
+ aria-label={local.thumbLabels?.[index] ?? local['aria-label']}
79
+ aria-labelledby={local.thumbLabels?.[index] ? undefined : local['aria-labelledby']}
80
+ class={cn(
81
+ 'border-primary bg-background block size-4 shrink-0 rounded-full border-2 shadow-xs',
82
+ 'transition-[color,box-shadow] ease-out outline-none',
83
+ 'hover:ring-4 hover:ring-primary-subtle',
84
+ 'focus-visible:ring-4 focus-visible:ring-primary-subtle',
85
+ local.thumbClass
86
+ )}
87
+ >
88
+ {/* Native reset uses the value property’s default, not an HTML defaultValue attribute. */}
89
+ <KobalteSlider.Input
90
+ id={`slider-${inputId}-${index}`}
91
+ ref={(input) => {
92
+ createRenderEffect(() => {
93
+ input.defaultValue = String(
94
+ props.defaultValue?.[index] ?? props.value?.[index] ?? props.minValue ?? 0
95
+ )
96
+ })
97
+ }}
98
+ hidden
99
+ aria-hidden="true"
100
+ />
101
+ <Show when={local.valueLabel}>
102
+ <KobalteSlider.ValueLabel class="bg-popover text-popover-foreground absolute -top-6 left-1/2 -translate-x-1/2 rounded-sm border border-border px-1 text-2xs tabular-nums" />
103
+ </Show>
104
+ </KobalteSlider.Thumb>
105
+ )}
106
+ </For>
79
107
  </KobalteSlider>
80
108
  )
81
109
  }
@@ -21,6 +21,8 @@ export type SwitchProps = Omit<ComponentProps<typeof KobalteSwitch>, 'children'>
21
21
  thumbClass?: string
22
22
  labelClass?: string
23
23
  descriptionClass?: string
24
+ label?: JSX.Element
25
+ description?: JSX.Element
24
26
  /**
25
27
  * Replaces the control and label. Omit it to get the default control beside
26
28
  * `label` and `description`; supply it to compose the parts yourself.
@@ -36,16 +38,30 @@ export function Switch(props: SwitchProps) {
36
38
  'labelClass',
37
39
  'descriptionClass',
38
40
  'children',
41
+ 'label',
42
+ 'description',
39
43
  'aria-label',
40
44
  'aria-labelledby',
45
+ 'aria-describedby',
46
+ 'aria-invalid',
47
+ 'aria-busy',
48
+ 'title',
41
49
  ])
42
50
 
43
51
  return (
44
- <KobalteSwitch class={cn('group/switch flex items-center gap-2.5', local.class)} {...rest}>
52
+ <KobalteSwitch
53
+ title={local.title}
54
+ class={cn('group/switch flex items-center gap-2.5', local.class)}
55
+ {...rest}
56
+ >
45
57
  {/* The name belongs on the input; see Checkbox for why. */}
46
58
  <KobalteSwitch.Input
47
59
  aria-label={local['aria-label']}
48
60
  aria-labelledby={local['aria-labelledby']}
61
+ aria-describedby={local['aria-describedby']}
62
+ aria-invalid={local['aria-invalid']}
63
+ aria-busy={local['aria-busy']}
64
+ title={local.title}
49
65
  />
50
66
  <KobalteSwitch.Control
51
67
  class={cn(
@@ -67,14 +83,23 @@ export function Switch(props: SwitchProps) {
67
83
  )}
68
84
  />
69
85
  </KobalteSwitch.Control>
70
- {local.children ?? (
71
- <div class="grid gap-0.5">
72
- <KobalteSwitch.Label class={cn('text-sm leading-none font-medium', local.labelClass)} />
73
- <KobalteSwitch.Description
74
- class={cn('text-muted-foreground text-sm', local.descriptionClass)}
75
- />
76
- </div>
77
- )}
86
+ {local.children ??
87
+ (local.label || local.description ? (
88
+ <div class="grid gap-0.5">
89
+ {local.label ? (
90
+ <KobalteSwitch.Label class={cn('text-sm leading-none font-medium', local.labelClass)}>
91
+ {local.label}
92
+ </KobalteSwitch.Label>
93
+ ) : null}
94
+ {local.description ? (
95
+ <KobalteSwitch.Description
96
+ class={cn('text-muted-foreground text-sm', local.descriptionClass)}
97
+ >
98
+ {local.description}
99
+ </KobalteSwitch.Description>
100
+ ) : null}
101
+ </div>
102
+ ) : null)}
78
103
  </KobalteSwitch>
79
104
  )
80
105
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adea-ai/ui",
3
- "version": "0.72.0",
3
+ "version": "0.72.2",
4
4
  "description": "The Adea design system: Kobalte-backed Solid components, semantic OKLCH tokens, and the app-shell layout primitives shared by Adea and Cortana.",
5
5
  "keywords": [
6
6
  "adea",
@@ -21,6 +21,8 @@ export type CheckboxProps = Omit<ComponentProps<typeof KobalteCheckbox>, 'childr
21
21
  controlClass?: string
22
22
  labelClass?: string
23
23
  descriptionClass?: string
24
+ label?: JSX.Element
25
+ description?: JSX.Element
24
26
  /**
25
27
  * Replaces the control and label. Omit it to get the default control beside
26
28
  * `label` and `description`; supply it to compose the parts yourself.
@@ -35,13 +37,23 @@ export function Checkbox(props: CheckboxProps) {
35
37
  'labelClass',
36
38
  'descriptionClass',
37
39
  'children',
40
+ 'label',
41
+ 'description',
38
42
  'indeterminate',
39
43
  'aria-label',
40
44
  'aria-labelledby',
45
+ 'aria-describedby',
46
+ 'aria-invalid',
47
+ 'aria-busy',
48
+ 'title',
41
49
  ])
42
50
 
43
51
  return (
44
- <KobalteCheckbox class={cn('group/checkbox flex items-start gap-2.5', local.class)} {...rest}>
52
+ <KobalteCheckbox
53
+ title={local.title}
54
+ class={cn('group/checkbox flex items-start gap-2.5', local.class)}
55
+ {...rest}
56
+ >
45
57
  {/*
46
58
  * The name goes on the input, which is what carries the value and takes
47
59
  * focus. On the Root it would land on a plain div and name nothing — the
@@ -50,6 +62,10 @@ export function Checkbox(props: CheckboxProps) {
50
62
  <KobalteCheckbox.Input
51
63
  aria-label={local['aria-label']}
52
64
  aria-labelledby={local['aria-labelledby']}
65
+ aria-describedby={local['aria-describedby']}
66
+ aria-invalid={local['aria-invalid']}
67
+ aria-busy={local['aria-busy']}
68
+ title={local.title}
53
69
  />
54
70
  <KobalteCheckbox.Control
55
71
  class={cn(
@@ -67,14 +83,23 @@ export function Checkbox(props: CheckboxProps) {
67
83
  {local.indeterminate ? <Minus class="size-3" /> : <Check class="size-3" />}
68
84
  </KobalteCheckbox.Indicator>
69
85
  </KobalteCheckbox.Control>
70
- {local.children ?? (
71
- <div class="grid gap-0.5 leading-none">
72
- <KobalteCheckbox.Label class={cn('text-sm font-medium', local.labelClass)} />
73
- <KobalteCheckbox.Description
74
- class={cn('text-muted-foreground text-sm', local.descriptionClass)}
75
- />
76
- </div>
77
- )}
86
+ {local.children ??
87
+ (local.label || local.description ? (
88
+ <div class="grid gap-0.5">
89
+ {local.label ? (
90
+ <KobalteCheckbox.Label class={cn('text-sm font-medium', local.labelClass)}>
91
+ {local.label}
92
+ </KobalteCheckbox.Label>
93
+ ) : null}
94
+ {local.description ? (
95
+ <KobalteCheckbox.Description
96
+ class={cn('text-muted-foreground text-sm', local.descriptionClass)}
97
+ >
98
+ {local.description}
99
+ </KobalteCheckbox.Description>
100
+ ) : null}
101
+ </div>
102
+ ) : null)}
78
103
  </KobalteCheckbox>
79
104
  )
80
105
  }
@@ -96,6 +96,7 @@ export function ComboboxContent(props: ComponentProps<typeof KobalteCombobox.Con
96
96
  {...rest}
97
97
  >
98
98
  <KobalteCombobox.Listbox class={cn('max-h-72 overflow-y-auto', menuContentPadding)} />
99
+ {local.children}
99
100
  <KobalteCombobox.Arrow aria-hidden="true" class={popoverArrow} />
100
101
  </KobalteCombobox.Content>
101
102
  </KobalteCombobox.Portal>
@@ -25,7 +25,8 @@ export type RadioGroupItemProps = ComponentProps<typeof KobalteRadioGroup.Item>
25
25
  controlClass?: string
26
26
  /**
27
27
  * The option's visible label. A radio with no accessible name is unreachable
28
- * by a screen reader and by voice control, so supply this or a child.
28
+ * by a screen reader and by voice control, so supply this, a labelled child,
29
+ * `aria-label`, or `aria-labelledby`.
29
30
  */
30
31
  label?: string
31
32
  description?: string
@@ -38,14 +39,28 @@ export function RadioGroupItem(props: RadioGroupItemProps) {
38
39
  'label',
39
40
  'description',
40
41
  'children',
42
+ 'aria-label',
43
+ 'aria-labelledby',
44
+ 'aria-describedby',
45
+ 'aria-invalid',
46
+ 'aria-busy',
47
+ 'title',
41
48
  ])
42
49
 
43
50
  return (
44
51
  <KobalteRadioGroup.Item
52
+ title={local.title}
45
53
  class={cn('group/radio flex items-start gap-2.5', local.class)}
46
54
  {...rest}
47
55
  >
48
- <KobalteRadioGroup.ItemInput />
56
+ <KobalteRadioGroup.ItemInput
57
+ aria-label={local['aria-label']}
58
+ aria-labelledby={local['aria-labelledby']}
59
+ aria-describedby={local['aria-describedby']}
60
+ aria-invalid={local['aria-invalid']}
61
+ aria-busy={local['aria-busy']}
62
+ title={local.title}
63
+ />
49
64
  <KobalteRadioGroup.ItemControl
50
65
  class={cn(
51
66
  'border-input bg-transparent flex size-4 shrink-0 items-center justify-center rounded-full border',
@@ -63,9 +78,11 @@ export function RadioGroupItem(props: RadioGroupItemProps) {
63
78
  </KobalteRadioGroup.ItemControl>
64
79
  {local.children ?? (
65
80
  <div class="grid gap-0.5 leading-none">
66
- <KobalteRadioGroup.ItemLabel class="text-sm font-medium">
67
- {local.label}
68
- </KobalteRadioGroup.ItemLabel>
81
+ {local.label ? (
82
+ <KobalteRadioGroup.ItemLabel class="text-sm font-medium">
83
+ {local.label}
84
+ </KobalteRadioGroup.ItemLabel>
85
+ ) : null}
69
86
  {local.description ? (
70
87
  <KobalteRadioGroup.ItemDescription class="text-muted-foreground text-sm">
71
88
  {local.description}
@@ -1,6 +1,6 @@
1
1
  import { Slider as KobalteSlider } from '@kobalte/core/slider'
2
2
  import type { ComponentProps } from 'solid-js'
3
- import { Show, splitProps } from 'solid-js'
3
+ import { For, Show, createUniqueId, createRenderEffect, splitProps } from 'solid-js'
4
4
  import { cn } from '#lib/utils'
5
5
 
6
6
  /**
@@ -12,9 +12,13 @@ import { cn } from '#lib/utils'
12
12
  * nobody can set exactly.
13
13
  *
14
14
  * Kobalte handles pointer capture, keyboard stepping and the ARIA value
15
- * wiring; this paints the track, fill and thumb.
15
+ * wiring; this paints the track, fill and one thumb per value. Each thumb
16
+ * contains a form-native input, hidden from accessibility because the visible
17
+ * thumb already exposes the slider role.
16
18
  */
17
19
  export type SliderProps = ComponentProps<typeof KobalteSlider> & {
20
+ /** Accessible names for individual thumbs, in value order (for example minimum and maximum). */
21
+ thumbLabels?: readonly string[]
18
22
  trackClass?: string
19
23
  rangeClass?: string
20
24
  thumbClass?: string
@@ -23,11 +27,13 @@ export type SliderProps = ComponentProps<typeof KobalteSlider> & {
23
27
  }
24
28
 
25
29
  export function Slider(props: SliderProps) {
30
+ const inputId = createUniqueId()
26
31
  const [local, rest] = splitProps(props, [
27
32
  'class',
28
33
  'trackClass',
29
34
  'rangeClass',
30
35
  'thumbClass',
36
+ 'thumbLabels',
31
37
  'valueLabel',
32
38
  'children',
33
39
  'aria-label',
@@ -61,21 +67,43 @@ export function Slider(props: SliderProps) {
61
67
  />
62
68
  </KobalteSlider.Track>
63
69
  {local.children}
64
- <KobalteSlider.Thumb
65
- aria-label={local['aria-label']}
66
- aria-labelledby={local['aria-labelledby']}
67
- class={cn(
68
- 'border-primary bg-background block size-4 shrink-0 rounded-full border-2 shadow-xs',
69
- 'transition-[color,box-shadow] ease-out outline-none',
70
- 'hover:ring-4 hover:ring-primary-subtle',
71
- 'focus-visible:ring-4 focus-visible:ring-primary-subtle',
72
- local.thumbClass
70
+ <For
71
+ each={Array.from(
72
+ { length: (props.value ?? props.defaultValue ?? [0]).length },
73
+ (_, index) => index
73
74
  )}
74
75
  >
75
- <Show when={local.valueLabel}>
76
- <KobalteSlider.ValueLabel class="bg-popover text-popover-foreground absolute -top-6 left-1/2 -translate-x-1/2 rounded-sm border border-border px-1 text-2xs tabular-nums" />
77
- </Show>
78
- </KobalteSlider.Thumb>
76
+ {(index) => (
77
+ <KobalteSlider.Thumb
78
+ aria-label={local.thumbLabels?.[index] ?? local['aria-label']}
79
+ aria-labelledby={local.thumbLabels?.[index] ? undefined : local['aria-labelledby']}
80
+ class={cn(
81
+ 'border-primary bg-background block size-4 shrink-0 rounded-full border-2 shadow-xs',
82
+ 'transition-[color,box-shadow] ease-out outline-none',
83
+ 'hover:ring-4 hover:ring-primary-subtle',
84
+ 'focus-visible:ring-4 focus-visible:ring-primary-subtle',
85
+ local.thumbClass
86
+ )}
87
+ >
88
+ {/* Native reset uses the value property’s default, not an HTML defaultValue attribute. */}
89
+ <KobalteSlider.Input
90
+ id={`slider-${inputId}-${index}`}
91
+ ref={(input) => {
92
+ createRenderEffect(() => {
93
+ input.defaultValue = String(
94
+ props.defaultValue?.[index] ?? props.value?.[index] ?? props.minValue ?? 0
95
+ )
96
+ })
97
+ }}
98
+ hidden
99
+ aria-hidden="true"
100
+ />
101
+ <Show when={local.valueLabel}>
102
+ <KobalteSlider.ValueLabel class="bg-popover text-popover-foreground absolute -top-6 left-1/2 -translate-x-1/2 rounded-sm border border-border px-1 text-2xs tabular-nums" />
103
+ </Show>
104
+ </KobalteSlider.Thumb>
105
+ )}
106
+ </For>
79
107
  </KobalteSlider>
80
108
  )
81
109
  }