@kennycorrea/ui 1.8.4 → 1.8.5

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.8.5 — 2026-11-04
4
+
5
+ Icons on `Select` options.
6
+
7
+ - **`icon` on `SelectOption`**: an optional `ReactNode` drawn before the label, in the list item and on the trigger once that option is chosen. It is `aria-hidden`, so the option is named by `label` alone, which stays a required `string`. An option without an icon renders exactly as before.
8
+ - **Themes' `Select` is re-exported from primitives as `RadixSelect`**, the same way `DropdownMenu` is. It is aliased, like `RadixSegmentedControl`, because the `Select` atom already uses the name.
9
+ - Tests in `test/Select-icon.test.tsx`. A combobox is never named from its content, so the trigger keeps its field label's name whatever the icon is (a titled SVG included). The tests also check that the icon is hidden and comes before the label text.
10
+
3
11
  ## 1.8.4 — 2026-10-30
4
12
 
5
13
  A `MentionTextarea` molecule.
@@ -1,6 +1,13 @@
1
+ import { type ReactNode } from 'react';
1
2
  export interface SelectOption {
2
3
  value: string;
4
+ /** The option's text, and its accessible name — in the list and on the trigger. */
3
5
  label: string;
6
+ /**
7
+ * Drawn before the label, in the item and on the trigger once chosen. Decorative: it is
8
+ * hidden from assistive tech, so `label` alone names the option.
9
+ */
10
+ icon?: ReactNode;
4
11
  }
5
12
  export interface SelectProps {
6
13
  value?: string;
@@ -12,5 +12,5 @@ import { cn } from '../../utils/cn.js';
12
12
  */
13
13
  export const Select = forwardRef(function Select({ value, onValueChange, options, placeholder, invalid = false, disabled, required, id, name, className, ...props }, ref) {
14
14
  const strings = useUiStrings();
15
- return (_jsxs(ThemedSelect.Root, { value: value, onValueChange: onValueChange, disabled: disabled, required: required, name: name, children: [_jsx(ThemedSelect.Trigger, { ref: ref, id: id, placeholder: placeholder ?? strings.select, color: invalid ? 'red' : undefined, "aria-invalid": invalid || undefined, className: cn('ui-select-trigger w-full', className), ...props }), _jsx(ThemedSelect.Content, { position: "popper", children: options.map((option) => (_jsx(ThemedSelect.Item, { value: option.value, children: option.label }, option.value))) })] }));
15
+ return (_jsxs(ThemedSelect.Root, { value: value, onValueChange: onValueChange, disabled: disabled, required: required, name: name, children: [_jsx(ThemedSelect.Trigger, { ref: ref, id: id, placeholder: placeholder ?? strings.select, color: invalid ? 'red' : undefined, "aria-invalid": invalid || undefined, className: cn('ui-select-trigger w-full', className), ...props }), _jsx(ThemedSelect.Content, { position: "popper", children: options.map((option) => (_jsx(ThemedSelect.Item, { value: option.value, children: option.icon == null ? (option.label) : (_jsxs("span", { className: "ui-select-option inline-flex items-center gap-2", children: [_jsx("span", { "aria-hidden": "true", className: "inline-flex shrink-0", children: option.icon }), _jsx("span", { children: option.label })] })) }, option.value))) })] }));
16
16
  });
@@ -6,4 +6,4 @@
6
6
  * reaches for a `Table` or `Tabs` through this package rather than importing Themes beside it
7
7
  * and drifting from the version the atoms were built against.
8
8
  */
9
- export { AccessibleIcon, AlertDialog, AspectRatio, Blockquote, Box, Callout, CheckboxCards, CheckboxGroup, Code, Container, DataList, DropdownMenu, Em, Flex, Grid, Heading, HoverCard, IconButton, Inset, Kbd, Link, Portal, Quote, Radio, RadioCards, RadioGroup, Reset, ScrollArea, Section, SegmentedControl as RadixSegmentedControl, Slot, Slottable, Strong, Table, TabNav, Tabs, Text, TextField, Theme as ThemeRoot, ThemePanel, VisuallyHidden, } from '@radix-ui/themes';
9
+ export { AccessibleIcon, AlertDialog, AspectRatio, Blockquote, Box, Callout, CheckboxCards, CheckboxGroup, Code, Container, DataList, DropdownMenu, Em, Flex, Grid, Heading, HoverCard, IconButton, Inset, Kbd, Link, Portal, Quote, Radio, RadioCards, RadioGroup, Reset, ScrollArea, Section, SegmentedControl as RadixSegmentedControl, Select as RadixSelect, Slot, Slottable, Strong, Table, TabNav, Tabs, Text, TextField, Theme as ThemeRoot, ThemePanel, VisuallyHidden, } from '@radix-ui/themes';
@@ -6,4 +6,4 @@
6
6
  * reaches for a `Table` or `Tabs` through this package rather than importing Themes beside it
7
7
  * and drifting from the version the atoms were built against.
8
8
  */
9
- export { AccessibleIcon, AlertDialog, AspectRatio, Blockquote, Box, Callout, CheckboxCards, CheckboxGroup, Code, Container, DataList, DropdownMenu, Em, Flex, Grid, Heading, HoverCard, IconButton, Inset, Kbd, Link, Portal, Quote, Radio, RadioCards, RadioGroup, Reset, ScrollArea, Section, SegmentedControl as RadixSegmentedControl, Slot, Slottable, Strong, Table, TabNav, Tabs, Text, TextField, Theme as ThemeRoot, ThemePanel, VisuallyHidden, } from '@radix-ui/themes';
9
+ export { AccessibleIcon, AlertDialog, AspectRatio, Blockquote, Box, Callout, CheckboxCards, CheckboxGroup, Code, Container, DataList, DropdownMenu, Em, Flex, Grid, Heading, HoverCard, IconButton, Inset, Kbd, Link, Portal, Quote, Radio, RadioCards, RadioGroup, Reset, ScrollArea, Section, SegmentedControl as RadixSegmentedControl, Select as RadixSelect, Slot, Slottable, Strong, Table, TabNav, Tabs, Text, TextField, Theme as ThemeRoot, ThemePanel, VisuallyHidden, } from '@radix-ui/themes';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kennycorrea/ui",
3
- "version": "1.8.4",
3
+ "version": "1.8.5",
4
4
  "description": "A React + TypeScript component library built on Radix Themes: atoms, a Tailwind token bridge and theming.",
5
5
  "private": false,
6
6
  "type": "module",