@redsift/pickers 12.2.11-muiv6 → 12.3.0-muiv6

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.
@@ -10,7 +10,75 @@ const COMPONENT_NAME = 'Combobox';
10
10
  const CLASSNAME = 'redsift-combobox';
11
11
 
12
12
  /**
13
- * The Combobox component.
13
+ * Combobox combines a text input with a filterable dropdown list.
14
+ * Supports single or multiple selection with type-ahead filtering.
15
+ *
16
+ * Variants:
17
+ * - `options`: Shows predefined options only (default)
18
+ * - `freeform`: Allows custom values not in the list
19
+ *
20
+ * Selection modes: `single`, `multiple`
21
+ *
22
+ * @example
23
+ * // Basic single-select combobox
24
+ * <Combobox label="Country" onChange={(value) => setCountry(value)}>
25
+ * <Combobox.Trigger placeholder="Search countries..." />
26
+ * <Combobox.Content>
27
+ * <Item value="us">United States</Item>
28
+ * <Item value="uk">United Kingdom</Item>
29
+ * <Item value="ca">Canada</Item>
30
+ * </Combobox.Content>
31
+ * </Combobox>
32
+ *
33
+ * @example
34
+ * // Multi-select combobox
35
+ * <Combobox
36
+ * label="Tags"
37
+ * selectionMode="multiple"
38
+ * value={selectedTags}
39
+ * onChange={setSelectedTags}
40
+ * >
41
+ * <Combobox.Trigger placeholder="Add tags..." />
42
+ * <Combobox.Content>
43
+ * <Item value="urgent">Urgent</Item>
44
+ * <Item value="bug">Bug</Item>
45
+ * <Item value="feature">Feature</Item>
46
+ * </Combobox.Content>
47
+ * </Combobox>
48
+ *
49
+ * @example
50
+ * // Open dropdown on focus (for autocomplete fields)
51
+ * <Combobox label="Assignee">
52
+ * <Combobox.Trigger openOnFocus placeholder="Search users..." />
53
+ * <Combobox.Content>...</Combobox.Content>
54
+ * </Combobox>
55
+ *
56
+ * @example
57
+ * // With Header and Footer
58
+ * <Combobox label="Recipients">
59
+ * <Combobox.Trigger />
60
+ * <Combobox.Content>
61
+ * <Combobox.Content.Header>
62
+ * <Text variant="small">Recent contacts</Text>
63
+ * </Combobox.Content.Header>
64
+ * <Combobox.Content.Listbox>
65
+ * <Item value="alice">Alice</Item>
66
+ * <Item value="bob">Bob</Item>
67
+ * </Combobox.Content.Listbox>
68
+ * <Combobox.Content.Footer>
69
+ * <Button variant="text">Add new contact</Button>
70
+ * </Combobox.Content.Footer>
71
+ * </Combobox.Content>
72
+ * </Combobox>
73
+ *
74
+ * @example
75
+ * // Freeform variant (allows custom entries)
76
+ * <Combobox label="Email" variant="freeform">
77
+ * <Combobox.Trigger placeholder="Enter or select email" />
78
+ * <Combobox.Content>
79
+ * {suggestions.map(email => <Item key={email} value={email}>{email}</Item>)}
80
+ * </Combobox.Content>
81
+ * </Combobox>
14
82
  */
15
83
  const BaseCombobox = props => {
16
84
  const {
@@ -1 +1 @@
1
- {"version":3,"file":"Combobox2.js","sources":["../../src/components/combobox/Combobox.tsx"],"sourcesContent":["import React, { RefObject, useEffect, useMemo, useReducer, useRef, useState } from 'react';\nimport { ComboboxContent } from '../combobox-content';\nimport { ComboboxTrigger } from '../combobox-trigger';\n\nimport { ComboboxProps, ComboboxSelectionMode, ComboboxValue, ComboboxVariant } from './types';\nimport { Popover } from '@redsift/popovers';\nimport { ComboboxContext } from './context';\nimport {\n ListboxReducer,\n ListboxState,\n ListboxContextProps,\n FocusWithinGroup,\n ListboxContext,\n Flexbox,\n Text,\n ListboxActionType,\n Theme,\n useTheme,\n ThemeProvider,\n useId,\n} from '@redsift/design-system';\n\nconst COMPONENT_NAME = 'Combobox';\nconst CLASSNAME = 'redsift-combobox';\n\n/**\n * The Combobox component.\n */\nexport const BaseCombobox: React.FC<ComboboxProps> & {\n displayName?: string;\n className?: string;\n} = (props) => {\n const {\n defaultValue,\n description,\n descriptionProps,\n filter = {\n type: 'startsWith',\n caseSensitive: false,\n },\n formRef,\n submitRef,\n inputValue: propsInputValue,\n isDisabled,\n isInvalid,\n maxOptionsLength,\n minWidth = 'trigger-width',\n onChange,\n onInputChange,\n selectionMode = ComboboxSelectionMode.single,\n theme: propsTheme,\n triggerClassName,\n value,\n variant = ComboboxVariant.options,\n wrapperProps,\n } = props;\n\n const theme = useTheme(propsTheme);\n\n const [selectedValue, setValue] = useState<ComboboxValue>(\n value || defaultValue || (selectionMode === 'multiple' ? [] : '')\n );\n const [inputValue, setInputValue] = useState<string>(propsInputValue || '');\n useEffect(() => {\n if (value) {\n state.setValue(value);\n }\n }, [value]);\n useEffect(() => {\n if (propsInputValue) {\n state.setInputValue(propsInputValue);\n }\n }, [propsInputValue]);\n\n /** Listbox context */\n const [listboxState, listboxDispatch] = useReducer(ListboxReducer, {\n isDisabled,\n selectedValues: selectionMode === ComboboxSelectionMode.multiple ? selectedValue : [selectedValue],\n selectionMode,\n } as ListboxState);\n const listboxContext = useMemo<ListboxContextProps>(\n () => ({\n state: listboxState,\n dispatch: listboxDispatch,\n }),\n [listboxState]\n );\n useEffect(() => {\n listboxDispatch({\n type: ListboxActionType.UPDATE_OPTIONS,\n payload: {\n isDisabled: isDisabled || false,\n },\n });\n }, [isDisabled]);\n\n const freeTextItemRef = useRef<HTMLDivElement>();\n const [freeTextItemId] = useId();\n\n /** Combobox context. */\n const state = {\n filter,\n formRef,\n submitRef,\n value: selectedValue,\n inputValue,\n isDisabled: isDisabled || false,\n isInvalid: isInvalid || false,\n selectionMode,\n variant,\n freeTextItemRef: freeTextItemRef as RefObject<HTMLDivElement>,\n freeTextItemId,\n triggerClassName,\n setValue(value: ComboboxValue) {\n if (isDisabled) {\n return;\n }\n\n const previousValue = selectedValue;\n setValue(value);\n if (value !== previousValue && onChange) {\n onChange(value);\n }\n },\n setInputValue(value: string) {\n if (isDisabled) {\n return;\n }\n\n const previousValue = inputValue;\n setInputValue(value);\n if (value !== previousValue && onInputChange) {\n onInputChange(value);\n }\n },\n };\n\n return (\n <ThemeProvider value={{ theme }}>\n <FocusWithinGroup focusType=\"virtual-focus\" focusOnInit={false} maxOptionsLength={maxOptionsLength}>\n <ComboboxContext.Provider value={state}>\n <ListboxContext.Provider value={listboxContext}>\n <Flexbox flexDirection=\"column\" alignItems=\"flex-start\" gap=\"0px\" {...wrapperProps}>\n <Popover\n theme={theme}\n overrideDisplayName={{ content: 'ComboboxContent', trigger: 'ComboboxTrigger' }}\n placement=\"bottom-start\"\n role=\"listbox\"\n minWidth={minWidth}\n {...props}\n />\n {description && typeof description === 'string' ? (\n <Text\n theme={theme}\n marginTop=\"8px\"\n variant=\"caption\"\n color={isInvalid ? 'error' : theme === Theme.light ? 'dark-grey' : 'white'}\n {...descriptionProps}\n >\n {description}\n </Text>\n ) : React.isValidElement(description) ? (\n description\n ) : null}\n </Flexbox>\n </ListboxContext.Provider>\n </ComboboxContext.Provider>\n </FocusWithinGroup>\n </ThemeProvider>\n );\n};\nBaseCombobox.className = CLASSNAME;\nBaseCombobox.displayName = COMPONENT_NAME;\n\nexport const Combobox = Object.assign(BaseCombobox, {\n Trigger: ComboboxTrigger,\n Content: ComboboxContent,\n});\n"],"names":["COMPONENT_NAME","CLASSNAME","BaseCombobox","props","defaultValue","description","descriptionProps","filter","type","caseSensitive","formRef","submitRef","inputValue","propsInputValue","isDisabled","isInvalid","maxOptionsLength","minWidth","onChange","onInputChange","selectionMode","ComboboxSelectionMode","single","theme","propsTheme","triggerClassName","value","variant","ComboboxVariant","options","wrapperProps","useTheme","selectedValue","setValue","useState","setInputValue","useEffect","state","listboxState","listboxDispatch","useReducer","ListboxReducer","selectedValues","multiple","listboxContext","useMemo","dispatch","ListboxActionType","UPDATE_OPTIONS","payload","freeTextItemRef","useRef","freeTextItemId","useId","previousValue","React","createElement","ThemeProvider","FocusWithinGroup","focusType","focusOnInit","ComboboxContext","Provider","ListboxContext","Flexbox","_extends","flexDirection","alignItems","gap","Popover","overrideDisplayName","content","trigger","placement","role","Text","marginTop","color","Theme","light","isValidElement","className","displayName","Combobox","Object","assign","Trigger","ComboboxTrigger","Content","ComboboxContent"],"mappings":"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"}
1
+ {"version":3,"file":"Combobox2.js","sources":["../../src/components/combobox/Combobox.tsx"],"sourcesContent":["import React, { RefObject, useEffect, useMemo, useReducer, useRef, useState } from 'react';\nimport { ComboboxContent } from '../combobox-content';\nimport { ComboboxTrigger } from '../combobox-trigger';\n\nimport { ComboboxProps, ComboboxSelectionMode, ComboboxValue, ComboboxVariant } from './types';\nimport { Popover } from '@redsift/popovers';\nimport { ComboboxContext } from './context';\nimport {\n ListboxReducer,\n ListboxState,\n ListboxContextProps,\n FocusWithinGroup,\n ListboxContext,\n Flexbox,\n Text,\n ListboxActionType,\n Theme,\n useTheme,\n ThemeProvider,\n useId,\n} from '@redsift/design-system';\n\nconst COMPONENT_NAME = 'Combobox';\nconst CLASSNAME = 'redsift-combobox';\n\n/**\n * Combobox combines a text input with a filterable dropdown list.\n * Supports single or multiple selection with type-ahead filtering.\n *\n * Variants:\n * - `options`: Shows predefined options only (default)\n * - `freeform`: Allows custom values not in the list\n *\n * Selection modes: `single`, `multiple`\n *\n * @example\n * // Basic single-select combobox\n * <Combobox label=\"Country\" onChange={(value) => setCountry(value)}>\n * <Combobox.Trigger placeholder=\"Search countries...\" />\n * <Combobox.Content>\n * <Item value=\"us\">United States</Item>\n * <Item value=\"uk\">United Kingdom</Item>\n * <Item value=\"ca\">Canada</Item>\n * </Combobox.Content>\n * </Combobox>\n *\n * @example\n * // Multi-select combobox\n * <Combobox\n * label=\"Tags\"\n * selectionMode=\"multiple\"\n * value={selectedTags}\n * onChange={setSelectedTags}\n * >\n * <Combobox.Trigger placeholder=\"Add tags...\" />\n * <Combobox.Content>\n * <Item value=\"urgent\">Urgent</Item>\n * <Item value=\"bug\">Bug</Item>\n * <Item value=\"feature\">Feature</Item>\n * </Combobox.Content>\n * </Combobox>\n *\n * @example\n * // Open dropdown on focus (for autocomplete fields)\n * <Combobox label=\"Assignee\">\n * <Combobox.Trigger openOnFocus placeholder=\"Search users...\" />\n * <Combobox.Content>...</Combobox.Content>\n * </Combobox>\n *\n * @example\n * // With Header and Footer\n * <Combobox label=\"Recipients\">\n * <Combobox.Trigger />\n * <Combobox.Content>\n * <Combobox.Content.Header>\n * <Text variant=\"small\">Recent contacts</Text>\n * </Combobox.Content.Header>\n * <Combobox.Content.Listbox>\n * <Item value=\"alice\">Alice</Item>\n * <Item value=\"bob\">Bob</Item>\n * </Combobox.Content.Listbox>\n * <Combobox.Content.Footer>\n * <Button variant=\"text\">Add new contact</Button>\n * </Combobox.Content.Footer>\n * </Combobox.Content>\n * </Combobox>\n *\n * @example\n * // Freeform variant (allows custom entries)\n * <Combobox label=\"Email\" variant=\"freeform\">\n * <Combobox.Trigger placeholder=\"Enter or select email\" />\n * <Combobox.Content>\n * {suggestions.map(email => <Item key={email} value={email}>{email}</Item>)}\n * </Combobox.Content>\n * </Combobox>\n */\nexport const BaseCombobox: React.FC<ComboboxProps> & {\n displayName?: string;\n className?: string;\n} = (props) => {\n const {\n defaultValue,\n description,\n descriptionProps,\n filter = {\n type: 'startsWith',\n caseSensitive: false,\n },\n formRef,\n submitRef,\n inputValue: propsInputValue,\n isDisabled,\n isInvalid,\n maxOptionsLength,\n minWidth = 'trigger-width',\n onChange,\n onInputChange,\n selectionMode = ComboboxSelectionMode.single,\n theme: propsTheme,\n triggerClassName,\n value,\n variant = ComboboxVariant.options,\n wrapperProps,\n } = props;\n\n const theme = useTheme(propsTheme);\n\n const [selectedValue, setValue] = useState<ComboboxValue>(\n value || defaultValue || (selectionMode === 'multiple' ? [] : '')\n );\n const [inputValue, setInputValue] = useState<string>(propsInputValue || '');\n useEffect(() => {\n if (value) {\n state.setValue(value);\n }\n }, [value]);\n useEffect(() => {\n if (propsInputValue) {\n state.setInputValue(propsInputValue);\n }\n }, [propsInputValue]);\n\n /** Listbox context */\n const [listboxState, listboxDispatch] = useReducer(ListboxReducer, {\n isDisabled,\n selectedValues: selectionMode === ComboboxSelectionMode.multiple ? selectedValue : [selectedValue],\n selectionMode,\n } as ListboxState);\n const listboxContext = useMemo<ListboxContextProps>(\n () => ({\n state: listboxState,\n dispatch: listboxDispatch,\n }),\n [listboxState]\n );\n useEffect(() => {\n listboxDispatch({\n type: ListboxActionType.UPDATE_OPTIONS,\n payload: {\n isDisabled: isDisabled || false,\n },\n });\n }, [isDisabled]);\n\n const freeTextItemRef = useRef<HTMLDivElement>();\n const [freeTextItemId] = useId();\n\n /** Combobox context. */\n const state = {\n filter,\n formRef,\n submitRef,\n value: selectedValue,\n inputValue,\n isDisabled: isDisabled || false,\n isInvalid: isInvalid || false,\n selectionMode,\n variant,\n freeTextItemRef: freeTextItemRef as RefObject<HTMLDivElement>,\n freeTextItemId,\n triggerClassName,\n setValue(value: ComboboxValue) {\n if (isDisabled) {\n return;\n }\n\n const previousValue = selectedValue;\n setValue(value);\n if (value !== previousValue && onChange) {\n onChange(value);\n }\n },\n setInputValue(value: string) {\n if (isDisabled) {\n return;\n }\n\n const previousValue = inputValue;\n setInputValue(value);\n if (value !== previousValue && onInputChange) {\n onInputChange(value);\n }\n },\n };\n\n return (\n <ThemeProvider value={{ theme }}>\n <FocusWithinGroup focusType=\"virtual-focus\" focusOnInit={false} maxOptionsLength={maxOptionsLength}>\n <ComboboxContext.Provider value={state}>\n <ListboxContext.Provider value={listboxContext}>\n <Flexbox flexDirection=\"column\" alignItems=\"flex-start\" gap=\"0px\" {...wrapperProps}>\n <Popover\n theme={theme}\n overrideDisplayName={{ content: 'ComboboxContent', trigger: 'ComboboxTrigger' }}\n placement=\"bottom-start\"\n role=\"listbox\"\n minWidth={minWidth}\n {...props}\n />\n {description && typeof description === 'string' ? (\n <Text\n theme={theme}\n marginTop=\"8px\"\n variant=\"caption\"\n color={isInvalid ? 'error' : theme === Theme.light ? 'dark-grey' : 'white'}\n {...descriptionProps}\n >\n {description}\n </Text>\n ) : React.isValidElement(description) ? (\n description\n ) : null}\n </Flexbox>\n </ListboxContext.Provider>\n </ComboboxContext.Provider>\n </FocusWithinGroup>\n </ThemeProvider>\n );\n};\nBaseCombobox.className = CLASSNAME;\nBaseCombobox.displayName = COMPONENT_NAME;\n\nexport const Combobox = Object.assign(BaseCombobox, {\n Trigger: ComboboxTrigger,\n Content: ComboboxContent,\n});\n"],"names":["COMPONENT_NAME","CLASSNAME","BaseCombobox","props","defaultValue","description","descriptionProps","filter","type","caseSensitive","formRef","submitRef","inputValue","propsInputValue","isDisabled","isInvalid","maxOptionsLength","minWidth","onChange","onInputChange","selectionMode","ComboboxSelectionMode","single","theme","propsTheme","triggerClassName","value","variant","ComboboxVariant","options","wrapperProps","useTheme","selectedValue","setValue","useState","setInputValue","useEffect","state","listboxState","listboxDispatch","useReducer","ListboxReducer","selectedValues","multiple","listboxContext","useMemo","dispatch","ListboxActionType","UPDATE_OPTIONS","payload","freeTextItemRef","useRef","freeTextItemId","useId","previousValue","React","createElement","ThemeProvider","FocusWithinGroup","focusType","focusOnInit","ComboboxContext","Provider","ListboxContext","Flexbox","_extends","flexDirection","alignItems","gap","Popover","overrideDisplayName","content","trigger","placement","role","Text","marginTop","color","Theme","light","isValidElement","className","displayName","Combobox","Object","assign","Trigger","ComboboxTrigger","Content","ComboboxContent"],"mappings":"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"}
@@ -9,7 +9,72 @@ const COMPONENT_NAME = 'MenuButton';
9
9
  const CLASSNAME = 'redsift-menu-button';
10
10
 
11
11
  /**
12
- * The MenuButton component.
12
+ * MenuButton displays a button that opens a menu of actions.
13
+ * Unlike Select (for choosing values), MenuButton triggers actions.
14
+ *
15
+ * Built on Popover with keyboard navigation and proper ARIA roles.
16
+ *
17
+ * @example
18
+ * // Basic menu button
19
+ * <MenuButton label="Actions">
20
+ * <MenuButton.Trigger>Options</MenuButton.Trigger>
21
+ * <MenuButton.Content>
22
+ * <Item onAction={() => handleEdit()}>Edit</Item>
23
+ * <Item onAction={() => handleDuplicate()}>Duplicate</Item>
24
+ * <Item onAction={() => handleDelete()}>Delete</Item>
25
+ * </MenuButton.Content>
26
+ * </MenuButton>
27
+ *
28
+ * @example
29
+ * // Three-dot icon menu (common pattern)
30
+ * <MenuButton>
31
+ * <MenuButton.Trigger>
32
+ * <IconButton icon={mdiDotsVertical} aria-label="More options" />
33
+ * </MenuButton.Trigger>
34
+ * <MenuButton.Content>
35
+ * <Item onAction={handleShare}>Share</Item>
36
+ * <Item onAction={handleExport}>Export</Item>
37
+ * </MenuButton.Content>
38
+ * </MenuButton>
39
+ *
40
+ * @example
41
+ * // Button with dynamic chevron indicator
42
+ * <MenuButton>
43
+ * <MenuButton.Trigger>
44
+ * {({ isOpen }) => (
45
+ * <Button rightIcon={isOpen ? mdiChevronUp : mdiChevronDown}>
46
+ * Sort by
47
+ * </Button>
48
+ * )}
49
+ * </MenuButton.Trigger>
50
+ * <MenuButton.Content>...</MenuButton.Content>
51
+ * </MenuButton>
52
+ *
53
+ * @example
54
+ * // Items with icons
55
+ * <MenuButton>
56
+ * <MenuButton.Trigger>Actions</MenuButton.Trigger>
57
+ * <MenuButton.Content>
58
+ * <Item onAction={handleEdit}>
59
+ * <Icon icon={mdiPencil} />
60
+ * Edit
61
+ * </Item>
62
+ * <Item onAction={handleDelete}>
63
+ * <Icon icon={mdiDelete} color="danger" />
64
+ * Delete
65
+ * </Item>
66
+ * </MenuButton.Content>
67
+ * </MenuButton>
68
+ *
69
+ * @example
70
+ * // With links instead of actions
71
+ * <MenuButton>
72
+ * <MenuButton.Trigger>Navigate</MenuButton.Trigger>
73
+ * <MenuButton.Content>
74
+ * <Item><Link href="/dashboard">Dashboard</Link></Item>
75
+ * <Item><Link href="/settings">Settings</Link></Item>
76
+ * </MenuButton.Content>
77
+ * </MenuButton>
13
78
  */
14
79
  const BaseMenuButton = props => {
15
80
  const {
@@ -1 +1 @@
1
- {"version":3,"file":"MenuButton.js","sources":["../../src/components/menu-button/MenuButton.tsx"],"sourcesContent":["import React from 'react';\nimport { MenuButtonContent } from '../menu-button-content';\nimport { MenuButtonTrigger } from '../menu-button-trigger';\n\nimport { MenuButtonProps } from './types';\nimport { Popover } from '@redsift/popovers';\nimport { MenuButtonContext } from './context';\nimport { FocusWithinGroup, Flexbox, Text, Theme, useTheme, ThemeProvider } from '@redsift/design-system';\n\nconst COMPONENT_NAME = 'MenuButton';\nconst CLASSNAME = 'redsift-menu-button';\n\n/**\n * The MenuButton component.\n */\nexport const BaseMenuButton: React.FC<MenuButtonProps> & {\n displayName?: string;\n className?: string;\n} = (props) => {\n const {\n color,\n description,\n descriptionProps,\n isDisabled,\n label,\n labelProps,\n minWidth = 'trigger-width',\n theme: propsTheme,\n triggerClassName,\n variant,\n wrapperProps,\n } = props;\n\n const theme = useTheme(propsTheme);\n\n /** MenuButton context. */\n const state = {\n color,\n isDisabled: isDisabled || false,\n theme,\n triggerClassName,\n variant,\n };\n\n return (\n <ThemeProvider value={{ theme }}>\n <FocusWithinGroup focusType=\"virtual-focus\" listRole=\"menu\" focusOnInit={false}>\n <MenuButtonContext.Provider value={state}>\n <Flexbox flexDirection=\"column\" alignItems=\"flex-start\" gap=\"0px\" {...wrapperProps}>\n {label && typeof label === 'string' ? <Text {...labelProps}>{label}</Text> : label ? label : null}\n <Popover\n theme={theme}\n overrideDisplayName={{ content: 'MenuButtonContent', trigger: 'MenuButtonTrigger' }}\n placement=\"bottom-end\"\n minWidth={minWidth}\n {...props}\n />\n {description && typeof description === 'string' ? (\n <Text\n theme={theme}\n marginTop=\"8px\"\n variant=\"caption\"\n color={theme === Theme.light ? 'dark-grey' : 'white'}\n {...descriptionProps}\n >\n {description}\n </Text>\n ) : description ? (\n description\n ) : null}\n </Flexbox>\n </MenuButtonContext.Provider>\n </FocusWithinGroup>\n </ThemeProvider>\n );\n};\nBaseMenuButton.className = CLASSNAME;\nBaseMenuButton.displayName = COMPONENT_NAME;\n\nexport const MenuButton = Object.assign(BaseMenuButton, {\n Trigger: MenuButtonTrigger,\n Content: MenuButtonContent,\n});\n"],"names":["COMPONENT_NAME","CLASSNAME","BaseMenuButton","props","color","description","descriptionProps","isDisabled","label","labelProps","minWidth","theme","propsTheme","triggerClassName","variant","wrapperProps","useTheme","state","React","createElement","ThemeProvider","value","FocusWithinGroup","focusType","listRole","focusOnInit","MenuButtonContext","Provider","Flexbox","_extends","flexDirection","alignItems","gap","Text","Popover","overrideDisplayName","content","trigger","placement","marginTop","Theme","light","className","displayName","MenuButton","Object","assign","Trigger","MenuButtonTrigger","Content","MenuButtonContent"],"mappings":";;;;;;;AASA,MAAMA,cAAc,GAAG,YAAY,CAAA;AACnC,MAAMC,SAAS,GAAG,qBAAqB,CAAA;;AAEvC;AACA;AACA;AACaC,MAAAA,cAGZ,GAAIC,KAAK,IAAK;EACb,MAAM;IACJC,KAAK;IACLC,WAAW;IACXC,gBAAgB;IAChBC,UAAU;IACVC,KAAK;IACLC,UAAU;AACVC,IAAAA,QAAQ,GAAG,eAAe;AAC1BC,IAAAA,KAAK,EAAEC,UAAU;IACjBC,gBAAgB;IAChBC,OAAO;AACPC,IAAAA,YAAAA;AACF,GAAC,GAAGZ,KAAK,CAAA;AAET,EAAA,MAAMQ,KAAK,GAAGK,QAAQ,CAACJ,UAAU,CAAC,CAAA;;AAElC;AACA,EAAA,MAAMK,KAAK,GAAG;IACZb,KAAK;IACLG,UAAU,EAAEA,UAAU,IAAI,KAAK;IAC/BI,KAAK;IACLE,gBAAgB;AAChBC,IAAAA,OAAAA;GACD,CAAA;AAED,EAAA,oBACEI,KAAA,CAAAC,aAAA,CAACC,aAAa,EAAA;AAACC,IAAAA,KAAK,EAAE;AAAEV,MAAAA,KAAAA;AAAM,KAAA;AAAE,GAAA,eAC9BO,KAAA,CAAAC,aAAA,CAACG,gBAAgB,EAAA;AAACC,IAAAA,SAAS,EAAC,eAAe;AAACC,IAAAA,QAAQ,EAAC,MAAM;AAACC,IAAAA,WAAW,EAAE,KAAA;AAAM,GAAA,eAC7EP,KAAA,CAAAC,aAAA,CAACO,iBAAiB,CAACC,QAAQ,EAAA;AAACN,IAAAA,KAAK,EAAEJ,KAAAA;AAAM,GAAA,eACvCC,KAAA,CAAAC,aAAA,CAACS,OAAO,EAAAC,QAAA,CAAA;AAACC,IAAAA,aAAa,EAAC,QAAQ;AAACC,IAAAA,UAAU,EAAC,YAAY;AAACC,IAAAA,GAAG,EAAC,KAAA;AAAK,GAAA,EAAKjB,YAAY,CAAA,EAC/EP,KAAK,IAAI,OAAOA,KAAK,KAAK,QAAQ,gBAAGU,KAAA,CAAAC,aAAA,CAACc,IAAI,EAAKxB,UAAU,EAAGD,KAAY,CAAC,GAAGA,KAAK,GAAGA,KAAK,GAAG,IAAI,eACjGU,KAAA,CAAAC,aAAA,CAACe,OAAO,EAAAL,QAAA,CAAA;AACNlB,IAAAA,KAAK,EAAEA,KAAM;AACbwB,IAAAA,mBAAmB,EAAE;AAAEC,MAAAA,OAAO,EAAE,mBAAmB;AAAEC,MAAAA,OAAO,EAAE,mBAAA;KAAsB;AACpFC,IAAAA,SAAS,EAAC,YAAY;AACtB5B,IAAAA,QAAQ,EAAEA,QAAAA;AAAS,GAAA,EACfP,KAAK,CACV,CAAC,EACDE,WAAW,IAAI,OAAOA,WAAW,KAAK,QAAQ,gBAC7Ca,KAAA,CAAAC,aAAA,CAACc,IAAI,EAAAJ,QAAA,CAAA;AACHlB,IAAAA,KAAK,EAAEA,KAAM;AACb4B,IAAAA,SAAS,EAAC,KAAK;AACfzB,IAAAA,OAAO,EAAC,SAAS;IACjBV,KAAK,EAAEO,KAAK,KAAK6B,KAAK,CAACC,KAAK,GAAG,WAAW,GAAG,OAAA;AAAQ,GAAA,EACjDnC,gBAAgB,CAAA,EAEnBD,WACG,CAAC,GACLA,WAAW,GACbA,WAAW,GACT,IACG,CACiB,CACZ,CACL,CAAC,CAAA;AAEpB,EAAC;AACDH,cAAc,CAACwC,SAAS,GAAGzC,SAAS,CAAA;AACpCC,cAAc,CAACyC,WAAW,GAAG3C,cAAc,CAAA;AAEpC,MAAM4C,UAAU,GAAGC,MAAM,CAACC,MAAM,CAAC5C,cAAc,EAAE;AACtD6C,EAAAA,OAAO,EAAEC,iBAAiB;AAC1BC,EAAAA,OAAO,EAAEC,iBAAAA;AACX,CAAC;;;;"}
1
+ {"version":3,"file":"MenuButton.js","sources":["../../src/components/menu-button/MenuButton.tsx"],"sourcesContent":["import React from 'react';\nimport { MenuButtonContent } from '../menu-button-content';\nimport { MenuButtonTrigger } from '../menu-button-trigger';\n\nimport { MenuButtonProps } from './types';\nimport { Popover } from '@redsift/popovers';\nimport { MenuButtonContext } from './context';\nimport { FocusWithinGroup, Flexbox, Text, Theme, useTheme, ThemeProvider } from '@redsift/design-system';\n\nconst COMPONENT_NAME = 'MenuButton';\nconst CLASSNAME = 'redsift-menu-button';\n\n/**\n * MenuButton displays a button that opens a menu of actions.\n * Unlike Select (for choosing values), MenuButton triggers actions.\n *\n * Built on Popover with keyboard navigation and proper ARIA roles.\n *\n * @example\n * // Basic menu button\n * <MenuButton label=\"Actions\">\n * <MenuButton.Trigger>Options</MenuButton.Trigger>\n * <MenuButton.Content>\n * <Item onAction={() => handleEdit()}>Edit</Item>\n * <Item onAction={() => handleDuplicate()}>Duplicate</Item>\n * <Item onAction={() => handleDelete()}>Delete</Item>\n * </MenuButton.Content>\n * </MenuButton>\n *\n * @example\n * // Three-dot icon menu (common pattern)\n * <MenuButton>\n * <MenuButton.Trigger>\n * <IconButton icon={mdiDotsVertical} aria-label=\"More options\" />\n * </MenuButton.Trigger>\n * <MenuButton.Content>\n * <Item onAction={handleShare}>Share</Item>\n * <Item onAction={handleExport}>Export</Item>\n * </MenuButton.Content>\n * </MenuButton>\n *\n * @example\n * // Button with dynamic chevron indicator\n * <MenuButton>\n * <MenuButton.Trigger>\n * {({ isOpen }) => (\n * <Button rightIcon={isOpen ? mdiChevronUp : mdiChevronDown}>\n * Sort by\n * </Button>\n * )}\n * </MenuButton.Trigger>\n * <MenuButton.Content>...</MenuButton.Content>\n * </MenuButton>\n *\n * @example\n * // Items with icons\n * <MenuButton>\n * <MenuButton.Trigger>Actions</MenuButton.Trigger>\n * <MenuButton.Content>\n * <Item onAction={handleEdit}>\n * <Icon icon={mdiPencil} />\n * Edit\n * </Item>\n * <Item onAction={handleDelete}>\n * <Icon icon={mdiDelete} color=\"danger\" />\n * Delete\n * </Item>\n * </MenuButton.Content>\n * </MenuButton>\n *\n * @example\n * // With links instead of actions\n * <MenuButton>\n * <MenuButton.Trigger>Navigate</MenuButton.Trigger>\n * <MenuButton.Content>\n * <Item><Link href=\"/dashboard\">Dashboard</Link></Item>\n * <Item><Link href=\"/settings\">Settings</Link></Item>\n * </MenuButton.Content>\n * </MenuButton>\n */\nexport const BaseMenuButton: React.FC<MenuButtonProps> & {\n displayName?: string;\n className?: string;\n} = (props) => {\n const {\n color,\n description,\n descriptionProps,\n isDisabled,\n label,\n labelProps,\n minWidth = 'trigger-width',\n theme: propsTheme,\n triggerClassName,\n variant,\n wrapperProps,\n } = props;\n\n const theme = useTheme(propsTheme);\n\n /** MenuButton context. */\n const state = {\n color,\n isDisabled: isDisabled || false,\n theme,\n triggerClassName,\n variant,\n };\n\n return (\n <ThemeProvider value={{ theme }}>\n <FocusWithinGroup focusType=\"virtual-focus\" listRole=\"menu\" focusOnInit={false}>\n <MenuButtonContext.Provider value={state}>\n <Flexbox flexDirection=\"column\" alignItems=\"flex-start\" gap=\"0px\" {...wrapperProps}>\n {label && typeof label === 'string' ? <Text {...labelProps}>{label}</Text> : label ? label : null}\n <Popover\n theme={theme}\n overrideDisplayName={{ content: 'MenuButtonContent', trigger: 'MenuButtonTrigger' }}\n placement=\"bottom-end\"\n minWidth={minWidth}\n {...props}\n />\n {description && typeof description === 'string' ? (\n <Text\n theme={theme}\n marginTop=\"8px\"\n variant=\"caption\"\n color={theme === Theme.light ? 'dark-grey' : 'white'}\n {...descriptionProps}\n >\n {description}\n </Text>\n ) : description ? (\n description\n ) : null}\n </Flexbox>\n </MenuButtonContext.Provider>\n </FocusWithinGroup>\n </ThemeProvider>\n );\n};\nBaseMenuButton.className = CLASSNAME;\nBaseMenuButton.displayName = COMPONENT_NAME;\n\nexport const MenuButton = Object.assign(BaseMenuButton, {\n Trigger: MenuButtonTrigger,\n Content: MenuButtonContent,\n});\n"],"names":["COMPONENT_NAME","CLASSNAME","BaseMenuButton","props","color","description","descriptionProps","isDisabled","label","labelProps","minWidth","theme","propsTheme","triggerClassName","variant","wrapperProps","useTheme","state","React","createElement","ThemeProvider","value","FocusWithinGroup","focusType","listRole","focusOnInit","MenuButtonContext","Provider","Flexbox","_extends","flexDirection","alignItems","gap","Text","Popover","overrideDisplayName","content","trigger","placement","marginTop","Theme","light","className","displayName","MenuButton","Object","assign","Trigger","MenuButtonTrigger","Content","MenuButtonContent"],"mappings":";;;;;;;AASA,MAAMA,cAAc,GAAG,YAAY,CAAA;AACnC,MAAMC,SAAS,GAAG,qBAAqB,CAAA;;AAEvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACaC,MAAAA,cAGZ,GAAIC,KAAK,IAAK;EACb,MAAM;IACJC,KAAK;IACLC,WAAW;IACXC,gBAAgB;IAChBC,UAAU;IACVC,KAAK;IACLC,UAAU;AACVC,IAAAA,QAAQ,GAAG,eAAe;AAC1BC,IAAAA,KAAK,EAAEC,UAAU;IACjBC,gBAAgB;IAChBC,OAAO;AACPC,IAAAA,YAAAA;AACF,GAAC,GAAGZ,KAAK,CAAA;AAET,EAAA,MAAMQ,KAAK,GAAGK,QAAQ,CAACJ,UAAU,CAAC,CAAA;;AAElC;AACA,EAAA,MAAMK,KAAK,GAAG;IACZb,KAAK;IACLG,UAAU,EAAEA,UAAU,IAAI,KAAK;IAC/BI,KAAK;IACLE,gBAAgB;AAChBC,IAAAA,OAAAA;GACD,CAAA;AAED,EAAA,oBACEI,KAAA,CAAAC,aAAA,CAACC,aAAa,EAAA;AAACC,IAAAA,KAAK,EAAE;AAAEV,MAAAA,KAAAA;AAAM,KAAA;AAAE,GAAA,eAC9BO,KAAA,CAAAC,aAAA,CAACG,gBAAgB,EAAA;AAACC,IAAAA,SAAS,EAAC,eAAe;AAACC,IAAAA,QAAQ,EAAC,MAAM;AAACC,IAAAA,WAAW,EAAE,KAAA;AAAM,GAAA,eAC7EP,KAAA,CAAAC,aAAA,CAACO,iBAAiB,CAACC,QAAQ,EAAA;AAACN,IAAAA,KAAK,EAAEJ,KAAAA;AAAM,GAAA,eACvCC,KAAA,CAAAC,aAAA,CAACS,OAAO,EAAAC,QAAA,CAAA;AAACC,IAAAA,aAAa,EAAC,QAAQ;AAACC,IAAAA,UAAU,EAAC,YAAY;AAACC,IAAAA,GAAG,EAAC,KAAA;AAAK,GAAA,EAAKjB,YAAY,CAAA,EAC/EP,KAAK,IAAI,OAAOA,KAAK,KAAK,QAAQ,gBAAGU,KAAA,CAAAC,aAAA,CAACc,IAAI,EAAKxB,UAAU,EAAGD,KAAY,CAAC,GAAGA,KAAK,GAAGA,KAAK,GAAG,IAAI,eACjGU,KAAA,CAAAC,aAAA,CAACe,OAAO,EAAAL,QAAA,CAAA;AACNlB,IAAAA,KAAK,EAAEA,KAAM;AACbwB,IAAAA,mBAAmB,EAAE;AAAEC,MAAAA,OAAO,EAAE,mBAAmB;AAAEC,MAAAA,OAAO,EAAE,mBAAA;KAAsB;AACpFC,IAAAA,SAAS,EAAC,YAAY;AACtB5B,IAAAA,QAAQ,EAAEA,QAAAA;AAAS,GAAA,EACfP,KAAK,CACV,CAAC,EACDE,WAAW,IAAI,OAAOA,WAAW,KAAK,QAAQ,gBAC7Ca,KAAA,CAAAC,aAAA,CAACc,IAAI,EAAAJ,QAAA,CAAA;AACHlB,IAAAA,KAAK,EAAEA,KAAM;AACb4B,IAAAA,SAAS,EAAC,KAAK;AACfzB,IAAAA,OAAO,EAAC,SAAS;IACjBV,KAAK,EAAEO,KAAK,KAAK6B,KAAK,CAACC,KAAK,GAAG,WAAW,GAAG,OAAA;AAAQ,GAAA,EACjDnC,gBAAgB,CAAA,EAEnBD,WACG,CAAC,GACLA,WAAW,GACbA,WAAW,GACT,IACG,CACiB,CACZ,CACL,CAAC,CAAA;AAEpB,EAAC;AACDH,cAAc,CAACwC,SAAS,GAAGzC,SAAS,CAAA;AACpCC,cAAc,CAACyC,WAAW,GAAG3C,cAAc,CAAA;AAEpC,MAAM4C,UAAU,GAAGC,MAAM,CAACC,MAAM,CAAC5C,cAAc,EAAE;AACtD6C,EAAAA,OAAO,EAAEC,iBAAiB;AAC1BC,EAAAA,OAAO,EAAEC,iBAAAA;AACX,CAAC;;;;"}
@@ -9,7 +9,74 @@ const COMPONENT_NAME = 'Select';
9
9
  const CLASSNAME = 'redsift-select';
10
10
 
11
11
  /**
12
- * The Select component.
12
+ * Select allows users to choose a single option from a dropdown list.
13
+ * Built on Floating UI with keyboard navigation and screen reader support.
14
+ *
15
+ * Composed of `Select.Trigger` and `Select.Content` sub-components.
16
+ * Use the `Item` component for options.
17
+ *
18
+ * For searchable/filterable lists, use Combobox instead.
19
+ *
20
+ * @example
21
+ * // Basic select with TextField trigger (default)
22
+ * <Select label="Country" onChange={(value) => setCountry(value)}>
23
+ * <Select.Trigger placeholder="Select a country" />
24
+ * <Select.Content>
25
+ * <Item value="us">United States</Item>
26
+ * <Item value="uk">United Kingdom</Item>
27
+ * <Item value="ca">Canada</Item>
28
+ * </Select.Content>
29
+ * </Select>
30
+ *
31
+ * @example
32
+ * // Button trigger variant
33
+ * <Select label="Actions">
34
+ * <Select.Trigger variant="button">Choose action</Select.Trigger>
35
+ * <Select.Content>
36
+ * <Item value="edit">Edit</Item>
37
+ * <Item value="delete">Delete</Item>
38
+ * </Select.Content>
39
+ * </Select>
40
+ *
41
+ * @example
42
+ * // Controlled select with default value
43
+ * <Select
44
+ * label="Status"
45
+ * value={status}
46
+ * defaultValue="active"
47
+ * onChange={setStatus}
48
+ * >
49
+ * <Select.Trigger />
50
+ * <Select.Content>
51
+ * <Item value="active">Active</Item>
52
+ * <Item value="inactive">Inactive</Item>
53
+ * <Item value="pending">Pending</Item>
54
+ * </Select.Content>
55
+ * </Select>
56
+ *
57
+ * @example
58
+ * // Render function for custom trigger content
59
+ * <Select label="Sort by">
60
+ * <Select.Trigger>
61
+ * {({ selected }) => (
62
+ * <Button rightIcon={mdiChevronDown}>
63
+ * {selected?.label || 'Select'}
64
+ * </Button>
65
+ * )}
66
+ * </Select.Trigger>
67
+ * <Select.Content>...</Select.Content>
68
+ * </Select>
69
+ *
70
+ * @example
71
+ * // With validation
72
+ * <Select label="Priority" isRequired isInvalid={!priority}>
73
+ * <Select.Trigger placeholder="Choose priority" />
74
+ * <Select.Content>
75
+ * <Item value="low">Low</Item>
76
+ * <Item value="medium">Medium</Item>
77
+ * <Item value="high">High</Item>
78
+ * </Select.Content>
79
+ * </Select>
13
80
  */
14
81
  const BaseSelect = props => {
15
82
  const {
@@ -1 +1 @@
1
- {"version":3,"file":"Select2.js","sources":["../../src/components/select/Select.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useReducer, useState } from 'react';\nimport { SelectContent } from '../select-content';\nimport { SelectTrigger } from '../select-trigger';\n\nimport { SelectProps } from './types';\nimport { Popover } from '@redsift/popovers';\nimport { SelectContext } from './context';\nimport {\n ListboxReducer,\n ListboxState,\n ListboxContextProps,\n FocusWithinGroup,\n ListboxContext,\n Flexbox,\n Text,\n ListboxActionType,\n Theme,\n useTheme,\n ThemeProvider,\n} from '@redsift/design-system';\n\nconst COMPONENT_NAME = 'Select';\nconst CLASSNAME = 'redsift-select';\n\n/**\n * The Select component.\n */\nexport const BaseSelect: React.FC<SelectProps> & {\n displayName?: string;\n className?: string;\n} = (props) => {\n const {\n color,\n defaultValue,\n description,\n descriptionProps,\n isDisabled,\n isInvalid,\n minWidth = 'trigger-width',\n onChange,\n theme: propsTheme,\n triggerClassName,\n value,\n variant,\n wrapperProps,\n } = props;\n\n const theme = useTheme(propsTheme);\n\n const [selectedValue, setValue] = useState<string>(value || defaultValue || '');\n useEffect(() => {\n if (value) {\n state.setValue(value);\n }\n }, [value]);\n\n /** Listbox context */\n const [listboxState, listboxDispatch] = useReducer(ListboxReducer, {\n isDisabled,\n selectedValues: [selectedValue],\n } as ListboxState);\n const listboxContext = useMemo<ListboxContextProps>(\n () => ({\n state: listboxState,\n dispatch: listboxDispatch,\n }),\n [listboxState]\n );\n useEffect(() => {\n listboxDispatch({\n type: ListboxActionType.UPDATE_OPTIONS,\n payload: {\n isDisabled: isDisabled || false,\n },\n });\n }, [isDisabled, theme]);\n\n /** Select context. */\n const state = {\n color,\n isDisabled: isDisabled || false,\n isInvalid: isInvalid || false,\n setValue(value: string) {\n if (isDisabled) {\n return;\n }\n\n const previousValue = selectedValue;\n setValue(value);\n if (value !== previousValue && onChange) {\n onChange(value);\n }\n },\n theme,\n triggerClassName,\n value: selectedValue,\n variant,\n };\n\n return (\n <ThemeProvider value={{ theme }}>\n <FocusWithinGroup focusType=\"virtual-focus\" focusOnInit={false}>\n <SelectContext.Provider value={state}>\n <ListboxContext.Provider value={listboxContext}>\n <Flexbox flexDirection=\"column\" alignItems=\"flex-start\" gap=\"0px\" {...wrapperProps}>\n <Popover\n theme={theme}\n overrideDisplayName={{ content: 'SelectContent', trigger: 'SelectTrigger' }}\n placement=\"bottom-start\"\n role=\"listbox\"\n minWidth={minWidth}\n {...props}\n />\n {description && typeof description === 'string' ? (\n <Text\n theme={theme}\n marginTop=\"8px\"\n variant=\"caption\"\n color={isInvalid ? 'error' : theme === Theme.light ? 'dark-grey' : 'white'}\n {...descriptionProps}\n >\n {description}\n </Text>\n ) : description ? (\n description\n ) : null}\n </Flexbox>\n </ListboxContext.Provider>\n </SelectContext.Provider>\n </FocusWithinGroup>\n </ThemeProvider>\n );\n};\nBaseSelect.className = CLASSNAME;\nBaseSelect.displayName = COMPONENT_NAME;\n\nexport const Select = Object.assign(BaseSelect, {\n Trigger: SelectTrigger,\n Content: SelectContent,\n});\n"],"names":["COMPONENT_NAME","CLASSNAME","BaseSelect","props","color","defaultValue","description","descriptionProps","isDisabled","isInvalid","minWidth","onChange","theme","propsTheme","triggerClassName","value","variant","wrapperProps","useTheme","selectedValue","setValue","useState","useEffect","state","listboxState","listboxDispatch","useReducer","ListboxReducer","selectedValues","listboxContext","useMemo","dispatch","type","ListboxActionType","UPDATE_OPTIONS","payload","previousValue","React","createElement","ThemeProvider","FocusWithinGroup","focusType","focusOnInit","SelectContext","Provider","ListboxContext","Flexbox","_extends","flexDirection","alignItems","gap","Popover","overrideDisplayName","content","trigger","placement","role","Text","marginTop","Theme","light","className","displayName","Select","Object","assign","Trigger","SelectTrigger","Content","SelectContent"],"mappings":"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"}
1
+ {"version":3,"file":"Select2.js","sources":["../../src/components/select/Select.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useReducer, useState } from 'react';\nimport { SelectContent } from '../select-content';\nimport { SelectTrigger } from '../select-trigger';\n\nimport { SelectProps } from './types';\nimport { Popover } from '@redsift/popovers';\nimport { SelectContext } from './context';\nimport {\n ListboxReducer,\n ListboxState,\n ListboxContextProps,\n FocusWithinGroup,\n ListboxContext,\n Flexbox,\n Text,\n ListboxActionType,\n Theme,\n useTheme,\n ThemeProvider,\n} from '@redsift/design-system';\n\nconst COMPONENT_NAME = 'Select';\nconst CLASSNAME = 'redsift-select';\n\n/**\n * Select allows users to choose a single option from a dropdown list.\n * Built on Floating UI with keyboard navigation and screen reader support.\n *\n * Composed of `Select.Trigger` and `Select.Content` sub-components.\n * Use the `Item` component for options.\n *\n * For searchable/filterable lists, use Combobox instead.\n *\n * @example\n * // Basic select with TextField trigger (default)\n * <Select label=\"Country\" onChange={(value) => setCountry(value)}>\n * <Select.Trigger placeholder=\"Select a country\" />\n * <Select.Content>\n * <Item value=\"us\">United States</Item>\n * <Item value=\"uk\">United Kingdom</Item>\n * <Item value=\"ca\">Canada</Item>\n * </Select.Content>\n * </Select>\n *\n * @example\n * // Button trigger variant\n * <Select label=\"Actions\">\n * <Select.Trigger variant=\"button\">Choose action</Select.Trigger>\n * <Select.Content>\n * <Item value=\"edit\">Edit</Item>\n * <Item value=\"delete\">Delete</Item>\n * </Select.Content>\n * </Select>\n *\n * @example\n * // Controlled select with default value\n * <Select\n * label=\"Status\"\n * value={status}\n * defaultValue=\"active\"\n * onChange={setStatus}\n * >\n * <Select.Trigger />\n * <Select.Content>\n * <Item value=\"active\">Active</Item>\n * <Item value=\"inactive\">Inactive</Item>\n * <Item value=\"pending\">Pending</Item>\n * </Select.Content>\n * </Select>\n *\n * @example\n * // Render function for custom trigger content\n * <Select label=\"Sort by\">\n * <Select.Trigger>\n * {({ selected }) => (\n * <Button rightIcon={mdiChevronDown}>\n * {selected?.label || 'Select'}\n * </Button>\n * )}\n * </Select.Trigger>\n * <Select.Content>...</Select.Content>\n * </Select>\n *\n * @example\n * // With validation\n * <Select label=\"Priority\" isRequired isInvalid={!priority}>\n * <Select.Trigger placeholder=\"Choose priority\" />\n * <Select.Content>\n * <Item value=\"low\">Low</Item>\n * <Item value=\"medium\">Medium</Item>\n * <Item value=\"high\">High</Item>\n * </Select.Content>\n * </Select>\n */\nexport const BaseSelect: React.FC<SelectProps> & {\n displayName?: string;\n className?: string;\n} = (props) => {\n const {\n color,\n defaultValue,\n description,\n descriptionProps,\n isDisabled,\n isInvalid,\n minWidth = 'trigger-width',\n onChange,\n theme: propsTheme,\n triggerClassName,\n value,\n variant,\n wrapperProps,\n } = props;\n\n const theme = useTheme(propsTheme);\n\n const [selectedValue, setValue] = useState<string>(value || defaultValue || '');\n useEffect(() => {\n if (value) {\n state.setValue(value);\n }\n }, [value]);\n\n /** Listbox context */\n const [listboxState, listboxDispatch] = useReducer(ListboxReducer, {\n isDisabled,\n selectedValues: [selectedValue],\n } as ListboxState);\n const listboxContext = useMemo<ListboxContextProps>(\n () => ({\n state: listboxState,\n dispatch: listboxDispatch,\n }),\n [listboxState]\n );\n useEffect(() => {\n listboxDispatch({\n type: ListboxActionType.UPDATE_OPTIONS,\n payload: {\n isDisabled: isDisabled || false,\n },\n });\n }, [isDisabled, theme]);\n\n /** Select context. */\n const state = {\n color,\n isDisabled: isDisabled || false,\n isInvalid: isInvalid || false,\n setValue(value: string) {\n if (isDisabled) {\n return;\n }\n\n const previousValue = selectedValue;\n setValue(value);\n if (value !== previousValue && onChange) {\n onChange(value);\n }\n },\n theme,\n triggerClassName,\n value: selectedValue,\n variant,\n };\n\n return (\n <ThemeProvider value={{ theme }}>\n <FocusWithinGroup focusType=\"virtual-focus\" focusOnInit={false}>\n <SelectContext.Provider value={state}>\n <ListboxContext.Provider value={listboxContext}>\n <Flexbox flexDirection=\"column\" alignItems=\"flex-start\" gap=\"0px\" {...wrapperProps}>\n <Popover\n theme={theme}\n overrideDisplayName={{ content: 'SelectContent', trigger: 'SelectTrigger' }}\n placement=\"bottom-start\"\n role=\"listbox\"\n minWidth={minWidth}\n {...props}\n />\n {description && typeof description === 'string' ? (\n <Text\n theme={theme}\n marginTop=\"8px\"\n variant=\"caption\"\n color={isInvalid ? 'error' : theme === Theme.light ? 'dark-grey' : 'white'}\n {...descriptionProps}\n >\n {description}\n </Text>\n ) : description ? (\n description\n ) : null}\n </Flexbox>\n </ListboxContext.Provider>\n </SelectContext.Provider>\n </FocusWithinGroup>\n </ThemeProvider>\n );\n};\nBaseSelect.className = CLASSNAME;\nBaseSelect.displayName = COMPONENT_NAME;\n\nexport const Select = Object.assign(BaseSelect, {\n Trigger: SelectTrigger,\n Content: SelectContent,\n});\n"],"names":["COMPONENT_NAME","CLASSNAME","BaseSelect","props","color","defaultValue","description","descriptionProps","isDisabled","isInvalid","minWidth","onChange","theme","propsTheme","triggerClassName","value","variant","wrapperProps","useTheme","selectedValue","setValue","useState","useEffect","state","listboxState","listboxDispatch","useReducer","ListboxReducer","selectedValues","listboxContext","useMemo","dispatch","type","ListboxActionType","UPDATE_OPTIONS","payload","previousValue","React","createElement","ThemeProvider","FocusWithinGroup","focusType","focusOnInit","SelectContext","Provider","ListboxContext","Flexbox","_extends","flexDirection","alignItems","gap","Popover","overrideDisplayName","content","trigger","placement","role","Text","marginTop","Theme","light","className","displayName","Select","Object","assign","Trigger","SelectTrigger","Content","SelectContent"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sources":["../../src/components/combobox/context.ts","../../src/components/combobox/types.ts"],"sourcesContent":["import React from 'react';\nimport { ComboboxState } from './types';\n\nexport const ComboboxContext = React.createContext<ComboboxState | null>(null);\n","import { FlexboxProps, TextProps, Theme, ValueOf } from '@redsift/design-system';\nimport { PopoverProps } from '@redsift/popovers';\nimport { ReactElement, RefObject } from 'react';\n\n/**\n * Component variant.\n */\nexport const ComboboxSelectionMode = {\n single: 'single',\n multiple: 'multiple',\n} as const;\nexport type ComboboxSelectionMode = ValueOf<typeof ComboboxSelectionMode>;\n\nexport const ComboboxVariant = {\n options: 'options',\n suggestions: 'suggestions',\n} as const;\nexport type ComboboxVariant = ValueOf<typeof ComboboxVariant>;\n\nexport type ComboboxValue = string | string[];\n\n/**\n * Context props.\n */\nexport type ComboboxState = {\n /** Filtering parameters. */\n readonly filter?: {\n type: 'startsWith' | 'contains' | 'endsWith';\n caseSensitive?: boolean;\n };\n /** Whether the combobox is disabled or not. */\n readonly isDisabled: boolean;\n /** Whether the combobox is invalid or not. */\n readonly isInvalid: boolean;\n /** Sets the selected value. */\n setValue(value: ComboboxValue): void;\n /** Current selected value. */\n readonly value: ComboboxValue;\n /** Sets the input value. */\n setInputValue(inputValue: string): void;\n /** Current input value. */\n readonly inputValue: string;\n /** Whether the Combobox allow multiple selection or not. */\n selectionMode?: ComboboxSelectionMode;\n /** If 'options', the input field cannot have free text, the selection has to be made within the options. If 'suggestions', then choosing from the list isn't mandatory and the user can write free text within the input. */\n variant?: ComboboxVariant;\n /** Ref to the first item used to create values. */\n freeTextItemRef?: RefObject<HTMLDivElement>;\n /** Id of the first item used to create values. */\n freeTextItemId?: string;\n /** Class name to append to the trigger. */\n readonly triggerClassName?: string;\n /** Ref to the form, if any. */\n formRef?: RefObject<HTMLFormElement>;\n /** Ref to the submit button, if any. */\n submitRef?: RefObject<HTMLButtonElement>;\n};\n\n/**\n * Component props.\n */\nexport interface ComboboxProps extends PopoverProps {\n /** If 'options', the input field cannot have free text, the selection has to be made within the options. If 'suggestions', then choosing from the list isn't mandatory and the user can write free text within the input. */\n variant?: ComboboxVariant;\n /**\n * Default selected value.\n * Used for uncontrolled version.\n */\n defaultValue?: ComboboxValue;\n /** Description of the combobox. */\n description?: string | ReactElement;\n /** Additional description properties. */\n descriptionProps?: Omit<TextProps, 'ref'>;\n /** Filtering parameters. */\n filter?: {\n type: 'startsWith' | 'contains' | 'endsWith';\n caseSensitive?: boolean;\n };\n /** Ref to the form, if any. */\n formRef?: RefObject<HTMLFormElement>;\n /** Ref to the submit button, if any. */\n submitRef?: RefObject<HTMLButtonElement>;\n /** Whether the component is disabled or not. */\n isDisabled?: boolean;\n /** Whether the component is invalid or not. */\n isInvalid?: boolean;\n /** Maximum number of options displayed. Useful when too many options are displayed. */\n maxOptionsLength?: number;\n /** Method to handle selection change. */\n onChange?(value: ComboboxValue): void;\n /** Method to handle input change. */\n onInputChange?(value: string): void;\n /**\n * Currently selected value.\n * Used for controlled version.\n */\n value?: ComboboxValue;\n /** Input value. */\n inputValue?: string;\n /** Whether the Combobox allow multiple selection or not. */\n selectionMode?: ComboboxSelectionMode;\n /** Theme. */\n theme?: Theme;\n /** Class name to append to the trigger. */\n triggerClassName?: string;\n /** Props to forward to the wrapper. */\n wrapperProps?: Omit<FlexboxProps, 'ref'>;\n}\n\nexport type StyledComboboxProps = ComboboxProps;\n"],"names":["ComboboxContext","React","createContext","ComboboxSelectionMode","single","multiple","ComboboxVariant","options","suggestions"],"mappings":";;AAGO,MAAMA,eAAe,gBAAGC,KAAK,CAACC,aAAa,CAAuB,IAAI;;ACC7E;AACA;AACA;AACO,MAAMC,qBAAqB,GAAG;AACnCC,EAAAA,MAAM,EAAE,QAAQ;AAChBC,EAAAA,QAAQ,EAAE,UAAA;AACZ,EAAU;AAGH,MAAMC,eAAe,GAAG;AAC7BC,EAAAA,OAAO,EAAE,SAAS;AAClBC,EAAAA,WAAW,EAAE,aAAA;AACf,EAAU;;AAKV;AACA;AACA;;AAmCA;AACA;AACA;;;;"}
1
+ {"version":3,"file":"types.js","sources":["../../src/components/combobox/context.ts","../../src/components/combobox/types.ts"],"sourcesContent":["import React from 'react';\nimport { ComboboxState } from './types';\n\nexport const ComboboxContext = React.createContext<ComboboxState | null>(null);\n","import { FlexboxProps, TextProps, Theme, ValueOf } from '@redsift/design-system';\nimport { PopoverProps } from '@redsift/popovers';\nimport { ReactElement, RefObject } from 'react';\n\n/**\n * Component variant.\n */\nexport const ComboboxSelectionMode = {\n single: 'single',\n multiple: 'multiple',\n} as const;\nexport type ComboboxSelectionMode = ValueOf<typeof ComboboxSelectionMode>;\n\nexport const ComboboxVariant = {\n options: 'options',\n suggestions: 'suggestions',\n} as const;\nexport type ComboboxVariant = ValueOf<typeof ComboboxVariant>;\n\nexport type ComboboxValue = string | string[];\n\n/**\n * Context props.\n */\nexport type ComboboxState = {\n /** Filtering parameters. */\n readonly filter?: {\n type: 'startsWith' | 'contains' | 'endsWith';\n caseSensitive?: boolean;\n };\n /** Whether the combobox is disabled or not. */\n readonly isDisabled: boolean;\n /** Whether the combobox is invalid or not. */\n readonly isInvalid: boolean;\n /** Sets the selected value. */\n setValue(value: ComboboxValue): void;\n /** Current selected value. */\n readonly value: ComboboxValue;\n /** Sets the input value. */\n setInputValue(inputValue: string): void;\n /** Current input value. */\n readonly inputValue: string;\n /** Whether the Combobox allow multiple selection or not. */\n selectionMode?: ComboboxSelectionMode;\n /** If 'options', the input field cannot have free text, the selection has to be made within the options. If 'suggestions', then choosing from the list isn't mandatory and the user can write free text within the input. */\n variant?: ComboboxVariant;\n /** Ref to the first item used to create values. */\n freeTextItemRef?: RefObject<HTMLDivElement>;\n /** Id of the first item used to create values. */\n freeTextItemId?: string;\n /** Class name to append to the trigger. */\n readonly triggerClassName?: string;\n /** Ref to the form, if any. */\n formRef?: RefObject<HTMLFormElement>;\n /** Ref to the submit button, if any. */\n submitRef?: RefObject<HTMLButtonElement>;\n};\n\n/**\n * Component props.\n */\nexport interface ComboboxProps extends PopoverProps {\n /**\n * If 'options', the input field cannot have free text, the selection has to be made within the options. If 'suggestions', then choosing from the list isn't mandatory and the user can write free text within the input.\n * @default 'options'\n */\n variant?: ComboboxVariant;\n /**\n * Default selected value.\n * Used for uncontrolled version.\n */\n defaultValue?: ComboboxValue;\n /** Description of the combobox. */\n description?: string | ReactElement;\n /** Additional description properties. */\n descriptionProps?: Omit<TextProps, 'ref'>;\n /** Filtering parameters. */\n filter?: {\n type: 'startsWith' | 'contains' | 'endsWith';\n caseSensitive?: boolean;\n };\n /** Ref to the form, if any. */\n formRef?: RefObject<HTMLFormElement>;\n /** Ref to the submit button, if any. */\n submitRef?: RefObject<HTMLButtonElement>;\n /** Whether the component is disabled or not. */\n isDisabled?: boolean;\n /** Whether the component is invalid or not. */\n isInvalid?: boolean;\n /** Maximum number of options displayed. Useful when too many options are displayed. */\n maxOptionsLength?: number;\n /** Method to handle selection change. */\n onChange?(value: ComboboxValue): void;\n /** Method to handle input change. */\n onInputChange?(value: string): void;\n /**\n * Currently selected value.\n * Used for controlled version.\n */\n value?: ComboboxValue;\n /** Input value. */\n inputValue?: string;\n /** Whether the Combobox allow multiple selection or not. */\n selectionMode?: ComboboxSelectionMode;\n /** Theme. */\n theme?: Theme;\n /** Class name to append to the trigger. */\n triggerClassName?: string;\n /** Props to forward to the wrapper. */\n wrapperProps?: Omit<FlexboxProps, 'ref'>;\n}\n\nexport type StyledComboboxProps = ComboboxProps;\n"],"names":["ComboboxContext","React","createContext","ComboboxSelectionMode","single","multiple","ComboboxVariant","options","suggestions"],"mappings":";;AAGO,MAAMA,eAAe,gBAAGC,KAAK,CAACC,aAAa,CAAuB,IAAI;;ACC7E;AACA;AACA;AACO,MAAMC,qBAAqB,GAAG;AACnCC,EAAAA,MAAM,EAAE,QAAQ;AAChBC,EAAAA,QAAQ,EAAE,UAAA;AACZ,EAAU;AAGH,MAAMC,eAAe,GAAG;AAC7BC,EAAAA,OAAO,EAAE,SAAS;AAClBC,EAAAA,WAAW,EAAE,aAAA;AACf,EAAU;;AAKV;AACA;AACA;;AAmCA;AACA;AACA;;;;"}
package/index.d.ts CHANGED
@@ -84,7 +84,10 @@ type ComboboxState = {
84
84
  * Component props.
85
85
  */
86
86
  interface ComboboxProps extends PopoverProps {
87
- /** If 'options', the input field cannot have free text, the selection has to be made within the options. If 'suggestions', then choosing from the list isn't mandatory and the user can write free text within the input. */
87
+ /**
88
+ * If 'options', the input field cannot have free text, the selection has to be made within the options. If 'suggestions', then choosing from the list isn't mandatory and the user can write free text within the input.
89
+ * @default 'options'
90
+ */
88
91
  variant?: ComboboxVariant;
89
92
  /**
90
93
  * Default selected value.
@@ -189,15 +192,83 @@ interface ComboboxTriggerProps extends Omit<PopoverTriggerProps, 'children'> {
189
192
  declare const ComboboxTrigger: Comp<ComboboxTriggerProps, HTMLButtonElement>;
190
193
 
191
194
  /**
192
- * The Combobox component.
195
+ * Combobox combines a text input with a filterable dropdown list.
196
+ * Supports single or multiple selection with type-ahead filtering.
197
+ *
198
+ * Variants:
199
+ * - `options`: Shows predefined options only (default)
200
+ * - `freeform`: Allows custom values not in the list
201
+ *
202
+ * Selection modes: `single`, `multiple`
203
+ *
204
+ * @example
205
+ * // Basic single-select combobox
206
+ * <Combobox label="Country" onChange={(value) => setCountry(value)}>
207
+ * <Combobox.Trigger placeholder="Search countries..." />
208
+ * <Combobox.Content>
209
+ * <Item value="us">United States</Item>
210
+ * <Item value="uk">United Kingdom</Item>
211
+ * <Item value="ca">Canada</Item>
212
+ * </Combobox.Content>
213
+ * </Combobox>
214
+ *
215
+ * @example
216
+ * // Multi-select combobox
217
+ * <Combobox
218
+ * label="Tags"
219
+ * selectionMode="multiple"
220
+ * value={selectedTags}
221
+ * onChange={setSelectedTags}
222
+ * >
223
+ * <Combobox.Trigger placeholder="Add tags..." />
224
+ * <Combobox.Content>
225
+ * <Item value="urgent">Urgent</Item>
226
+ * <Item value="bug">Bug</Item>
227
+ * <Item value="feature">Feature</Item>
228
+ * </Combobox.Content>
229
+ * </Combobox>
230
+ *
231
+ * @example
232
+ * // Open dropdown on focus (for autocomplete fields)
233
+ * <Combobox label="Assignee">
234
+ * <Combobox.Trigger openOnFocus placeholder="Search users..." />
235
+ * <Combobox.Content>...</Combobox.Content>
236
+ * </Combobox>
237
+ *
238
+ * @example
239
+ * // With Header and Footer
240
+ * <Combobox label="Recipients">
241
+ * <Combobox.Trigger />
242
+ * <Combobox.Content>
243
+ * <Combobox.Content.Header>
244
+ * <Text variant="small">Recent contacts</Text>
245
+ * </Combobox.Content.Header>
246
+ * <Combobox.Content.Listbox>
247
+ * <Item value="alice">Alice</Item>
248
+ * <Item value="bob">Bob</Item>
249
+ * </Combobox.Content.Listbox>
250
+ * <Combobox.Content.Footer>
251
+ * <Button variant="text">Add new contact</Button>
252
+ * </Combobox.Content.Footer>
253
+ * </Combobox.Content>
254
+ * </Combobox>
255
+ *
256
+ * @example
257
+ * // Freeform variant (allows custom entries)
258
+ * <Combobox label="Email" variant="freeform">
259
+ * <Combobox.Trigger placeholder="Enter or select email" />
260
+ * <Combobox.Content>
261
+ * {suggestions.map(email => <Item key={email} value={email}>{email}</Item>)}
262
+ * </Combobox.Content>
263
+ * </Combobox>
193
264
  */
194
265
  declare const BaseCombobox: React.FC<ComboboxProps> & {
195
266
  displayName?: string;
196
267
  className?: string;
197
268
  };
198
269
  declare const Combobox: React.FC<ComboboxProps> & {
199
- displayName?: string | undefined;
200
- className?: string | undefined;
270
+ displayName?: string;
271
+ className?: string;
201
272
  } & {
202
273
  Trigger: _redsift_design_system.Comp<ComboboxTriggerProps, HTMLButtonElement>;
203
274
  Content: _redsift_design_system.Comp<ComboboxContentProps, HTMLDivElement> & {
@@ -322,15 +393,80 @@ interface MenuButtonProps extends PopoverProps {
322
393
  type StyledMenuButtonProps = MenuButtonProps;
323
394
 
324
395
  /**
325
- * The MenuButton component.
396
+ * MenuButton displays a button that opens a menu of actions.
397
+ * Unlike Select (for choosing values), MenuButton triggers actions.
398
+ *
399
+ * Built on Popover with keyboard navigation and proper ARIA roles.
400
+ *
401
+ * @example
402
+ * // Basic menu button
403
+ * <MenuButton label="Actions">
404
+ * <MenuButton.Trigger>Options</MenuButton.Trigger>
405
+ * <MenuButton.Content>
406
+ * <Item onAction={() => handleEdit()}>Edit</Item>
407
+ * <Item onAction={() => handleDuplicate()}>Duplicate</Item>
408
+ * <Item onAction={() => handleDelete()}>Delete</Item>
409
+ * </MenuButton.Content>
410
+ * </MenuButton>
411
+ *
412
+ * @example
413
+ * // Three-dot icon menu (common pattern)
414
+ * <MenuButton>
415
+ * <MenuButton.Trigger>
416
+ * <IconButton icon={mdiDotsVertical} aria-label="More options" />
417
+ * </MenuButton.Trigger>
418
+ * <MenuButton.Content>
419
+ * <Item onAction={handleShare}>Share</Item>
420
+ * <Item onAction={handleExport}>Export</Item>
421
+ * </MenuButton.Content>
422
+ * </MenuButton>
423
+ *
424
+ * @example
425
+ * // Button with dynamic chevron indicator
426
+ * <MenuButton>
427
+ * <MenuButton.Trigger>
428
+ * {({ isOpen }) => (
429
+ * <Button rightIcon={isOpen ? mdiChevronUp : mdiChevronDown}>
430
+ * Sort by
431
+ * </Button>
432
+ * )}
433
+ * </MenuButton.Trigger>
434
+ * <MenuButton.Content>...</MenuButton.Content>
435
+ * </MenuButton>
436
+ *
437
+ * @example
438
+ * // Items with icons
439
+ * <MenuButton>
440
+ * <MenuButton.Trigger>Actions</MenuButton.Trigger>
441
+ * <MenuButton.Content>
442
+ * <Item onAction={handleEdit}>
443
+ * <Icon icon={mdiPencil} />
444
+ * Edit
445
+ * </Item>
446
+ * <Item onAction={handleDelete}>
447
+ * <Icon icon={mdiDelete} color="danger" />
448
+ * Delete
449
+ * </Item>
450
+ * </MenuButton.Content>
451
+ * </MenuButton>
452
+ *
453
+ * @example
454
+ * // With links instead of actions
455
+ * <MenuButton>
456
+ * <MenuButton.Trigger>Navigate</MenuButton.Trigger>
457
+ * <MenuButton.Content>
458
+ * <Item><Link href="/dashboard">Dashboard</Link></Item>
459
+ * <Item><Link href="/settings">Settings</Link></Item>
460
+ * </MenuButton.Content>
461
+ * </MenuButton>
326
462
  */
327
463
  declare const BaseMenuButton: React.FC<MenuButtonProps> & {
328
464
  displayName?: string;
329
465
  className?: string;
330
466
  };
331
467
  declare const MenuButton: React.FC<MenuButtonProps> & {
332
- displayName?: string | undefined;
333
- className?: string | undefined;
468
+ displayName?: string;
469
+ className?: string;
334
470
  } & {
335
471
  Trigger: _redsift_design_system.Comp<MenuButtonTriggerProps, HTMLButtonElement>;
336
472
  Content: _redsift_design_system.Comp<MenuButtonContentProps, HTMLDivElement> & {
@@ -414,7 +550,10 @@ interface SelectProps extends PopoverProps {
414
550
  * Used for controlled version.
415
551
  */
416
552
  value?: string;
417
- /** Button variant that will be forward to the trigger. */
553
+ /**
554
+ * Button variant that will be forward to the trigger.
555
+ * @default 'secondary'
556
+ */
418
557
  variant?: ButtonVariant | TextFieldVariant;
419
558
  /** Theme. */
420
559
  theme?: Theme;
@@ -426,15 +565,82 @@ interface SelectProps extends PopoverProps {
426
565
  type StyledSelectProps = SelectProps;
427
566
 
428
567
  /**
429
- * The Select component.
568
+ * Select allows users to choose a single option from a dropdown list.
569
+ * Built on Floating UI with keyboard navigation and screen reader support.
570
+ *
571
+ * Composed of `Select.Trigger` and `Select.Content` sub-components.
572
+ * Use the `Item` component for options.
573
+ *
574
+ * For searchable/filterable lists, use Combobox instead.
575
+ *
576
+ * @example
577
+ * // Basic select with TextField trigger (default)
578
+ * <Select label="Country" onChange={(value) => setCountry(value)}>
579
+ * <Select.Trigger placeholder="Select a country" />
580
+ * <Select.Content>
581
+ * <Item value="us">United States</Item>
582
+ * <Item value="uk">United Kingdom</Item>
583
+ * <Item value="ca">Canada</Item>
584
+ * </Select.Content>
585
+ * </Select>
586
+ *
587
+ * @example
588
+ * // Button trigger variant
589
+ * <Select label="Actions">
590
+ * <Select.Trigger variant="button">Choose action</Select.Trigger>
591
+ * <Select.Content>
592
+ * <Item value="edit">Edit</Item>
593
+ * <Item value="delete">Delete</Item>
594
+ * </Select.Content>
595
+ * </Select>
596
+ *
597
+ * @example
598
+ * // Controlled select with default value
599
+ * <Select
600
+ * label="Status"
601
+ * value={status}
602
+ * defaultValue="active"
603
+ * onChange={setStatus}
604
+ * >
605
+ * <Select.Trigger />
606
+ * <Select.Content>
607
+ * <Item value="active">Active</Item>
608
+ * <Item value="inactive">Inactive</Item>
609
+ * <Item value="pending">Pending</Item>
610
+ * </Select.Content>
611
+ * </Select>
612
+ *
613
+ * @example
614
+ * // Render function for custom trigger content
615
+ * <Select label="Sort by">
616
+ * <Select.Trigger>
617
+ * {({ selected }) => (
618
+ * <Button rightIcon={mdiChevronDown}>
619
+ * {selected?.label || 'Select'}
620
+ * </Button>
621
+ * )}
622
+ * </Select.Trigger>
623
+ * <Select.Content>...</Select.Content>
624
+ * </Select>
625
+ *
626
+ * @example
627
+ * // With validation
628
+ * <Select label="Priority" isRequired isInvalid={!priority}>
629
+ * <Select.Trigger placeholder="Choose priority" />
630
+ * <Select.Content>
631
+ * <Item value="low">Low</Item>
632
+ * <Item value="medium">Medium</Item>
633
+ * <Item value="high">High</Item>
634
+ * </Select.Content>
635
+ * </Select>
430
636
  */
431
637
  declare const BaseSelect: React.FC<SelectProps> & {
432
638
  displayName?: string;
433
639
  className?: string;
434
640
  };
435
641
  declare const Select: React.FC<SelectProps> & {
436
- displayName?: string | undefined;
437
- className?: string | undefined;
642
+ displayName?: string;
643
+ className?: string;
438
644
  } & {
439
645
  Trigger: _redsift_design_system.Comp<SelectTriggerProps, HTMLButtonElement>;
440
646
  Content: _redsift_design_system.Comp<SelectContentProps, HTMLDivElement>;
package/package.json CHANGED
@@ -21,7 +21,7 @@
21
21
  "sideEffects": false,
22
22
  "scripts": {
23
23
  "build": "rollup -c",
24
- "check-types": "tsc && tsc-strict",
24
+ "check-types": "tsc --diagnostics",
25
25
  "lint": "eslint --ext .js,.jsx,.ts,.tsx src/",
26
26
  "prepare": "install-peers || exit 0",
27
27
  "prepublishOnly": "yarn build",
@@ -30,11 +30,11 @@
30
30
  "test": "yarn test:unit && yarn test:storybook"
31
31
  },
32
32
  "types": "index.d.ts",
33
- "version": "12.2.11-muiv6",
33
+ "version": "12.3.0-muiv6",
34
34
  "dependencies": {
35
- "@redsift/design-system": "^12.2.11-muiv6",
36
- "@redsift/icons": "^12.2.11-muiv6",
37
- "@redsift/popovers": "^12.2.11-muiv6",
35
+ "@redsift/design-system": "^12.3.0-muiv6",
36
+ "@redsift/icons": "^12.3.0-muiv6",
37
+ "@redsift/popovers": "^12.3.0-muiv6",
38
38
  "classnames": "^2.3.1",
39
39
  "styled-components": "6.1.19"
40
40
  },
@@ -59,19 +59,19 @@
59
59
  "@testing-library/jest-dom": "^5.16.4",
60
60
  "@testing-library/react": "^13.4.0",
61
61
  "@testing-library/user-event": "14.2.1",
62
- "@types/jest": "^27.5.1",
62
+ "@types/jest": "^29.5.0",
63
63
  "@types/react": "18.0.12",
64
64
  "@types/react-dom": "18.0.5",
65
65
  "@types/react-transition-group": "^4.4.5",
66
- "@typescript-eslint/eslint-plugin": "^5.48.0",
67
- "@typescript-eslint/parser": "^5.26.0",
66
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
67
+ "@typescript-eslint/parser": "^8.0.0",
68
68
  "autoprefixer": "^9.7.4",
69
69
  "babel-plugin-require-context-hook": "^1.0.0",
70
70
  "changelog-verify": "^1.1.2",
71
71
  "identity-obj-proxy": "^3.0.0",
72
72
  "install-peers-cli": "^2.2.0",
73
- "jest": "^28.1.0",
74
- "jest-environment-jsdom": "^29.3.0",
73
+ "jest": "^29.7.0",
74
+ "jest-environment-jsdom": "^29.7.0",
75
75
  "react": "18.2.0",
76
76
  "react-dom": "18.2.0",
77
77
  "rollup": "^2.72.1",
@@ -84,15 +84,15 @@
84
84
  "rollup-plugin-svg": "^2.0.0",
85
85
  "rollup-plugin-ts-paths-resolve": "^1.7.1",
86
86
  "rollup-plugin-typescript-paths": "^1.3.1",
87
- "ts-jest": "^28.0.3"
87
+ "ts-jest": "^29.2.0"
88
88
  },
89
89
  "peerDependencies": {
90
- "@redsift/design-system": "^12.2.4-0",
91
- "@redsift/icons": "^12.2.4-0",
92
- "@redsift/popovers": "^12.2.4-0",
90
+ "@redsift/design-system": "^12.3.0-0",
91
+ "@redsift/icons": "^12.3.0-0",
92
+ "@redsift/popovers": "^12.3.0-0",
93
93
  "react": ">=17",
94
94
  "react-dom": ">=17",
95
95
  "styled-components": "6.1.19"
96
96
  },
97
- "gitHead": "58ea466b2eb9530706f89c58bf402a955c5f8b40"
97
+ "gitHead": "11c8c3624cc156d23913a5954fd881219b7e290e"
98
98
  }