@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.
- package/_internal/Combobox2.js +69 -1
- package/_internal/Combobox2.js.map +1 -1
- package/_internal/MenuButton.js +66 -1
- package/_internal/MenuButton.js.map +1 -1
- package/_internal/Select2.js +68 -1
- package/_internal/Select2.js.map +1 -1
- package/_internal/types.js.map +1 -1
- package/index.d.ts +217 -11
- package/package.json +15 -15
package/_internal/Combobox2.js
CHANGED
|
@@ -10,7 +10,75 @@ const COMPONENT_NAME = 'Combobox';
|
|
|
10
10
|
const CLASSNAME = 'redsift-combobox';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
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":";;;;;;;;AAsBA,MAAMA,cAAc,GAAG,UAAU,CAAA;AACjC,MAAMC,SAAS,GAAG,kBAAkB,CAAA;;AAEpC;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;AACA;AACA;AACA;AACaC,MAAAA,YAGZ,GAAIC,KAAK,IAAK;EACb,MAAM;IACJC,YAAY;IACZC,WAAW;IACXC,gBAAgB;AAChBC,IAAAA,MAAM,GAAG;AACPC,MAAAA,IAAI,EAAE,YAAY;AAClBC,MAAAA,aAAa,EAAE,KAAA;KAChB;IACDC,OAAO;IACPC,SAAS;AACTC,IAAAA,UAAU,EAAEC,eAAe;IAC3BC,UAAU;IACVC,SAAS;IACTC,gBAAgB;AAChBC,IAAAA,QAAQ,GAAG,eAAe;IAC1BC,QAAQ;IACRC,aAAa;IACbC,aAAa,GAAGC,qBAAqB,CAACC,MAAM;AAC5CC,IAAAA,KAAK,EAAEC,UAAU;IACjBC,gBAAgB;IAChBC,KAAK;IACLC,OAAO,GAAGC,eAAe,CAACC,OAAO;AACjCC,IAAAA,YAAAA;AACF,GAAC,GAAG3B,KAAK,CAAA;AAET,EAAA,MAAMoB,KAAK,GAAGQ,QAAQ,CAACP,UAAU,CAAC,CAAA;EAElC,MAAM,CAACQ,aAAa,EAAEC,QAAQ,CAAC,GAAGC,QAAQ,CACxCR,KAAK,IAAItB,YAAY,KAAKgB,aAAa,KAAK,UAAU,GAAG,EAAE,GAAG,EAAE,CAClE,CAAC,CAAA;EACD,MAAM,CAACR,UAAU,EAAEuB,aAAa,CAAC,GAAGD,QAAQ,CAASrB,eAAe,IAAI,EAAE,CAAC,CAAA;AAC3EuB,EAAAA,SAAS,CAAC,MAAM;AACd,IAAA,IAAIV,KAAK,EAAE;AACTW,MAAAA,KAAK,CAACJ,QAAQ,CAACP,KAAK,CAAC,CAAA;AACvB,KAAA;AACF,GAAC,EAAE,CAACA,KAAK,CAAC,CAAC,CAAA;AACXU,EAAAA,SAAS,CAAC,MAAM;AACd,IAAA,IAAIvB,eAAe,EAAE;AACnBwB,MAAAA,KAAK,CAACF,aAAa,CAACtB,eAAe,CAAC,CAAA;AACtC,KAAA;AACF,GAAC,EAAE,CAACA,eAAe,CAAC,CAAC,CAAA;;AAErB;EACA,MAAM,CAACyB,YAAY,EAAEC,eAAe,CAAC,GAAGC,UAAU,CAACC,cAAc,EAAE;IACjE3B,UAAU;IACV4B,cAAc,EAAEtB,aAAa,KAAKC,qBAAqB,CAACsB,QAAQ,GAAGX,aAAa,GAAG,CAACA,aAAa,CAAC;AAClGZ,IAAAA,aAAAA;AACF,GAAiB,CAAC,CAAA;AAClB,EAAA,MAAMwB,cAAc,GAAGC,OAAO,CAC5B,OAAO;AACLR,IAAAA,KAAK,EAAEC,YAAY;AACnBQ,IAAAA,QAAQ,EAAEP,eAAAA;AACZ,GAAC,CAAC,EACF,CAACD,YAAY,CACf,CAAC,CAAA;AACDF,EAAAA,SAAS,CAAC,MAAM;AACdG,IAAAA,eAAe,CAAC;MACd/B,IAAI,EAAEuC,iBAAiB,CAACC,cAAc;AACtCC,MAAAA,OAAO,EAAE;QACPnC,UAAU,EAAEA,UAAU,IAAI,KAAA;AAC5B,OAAA;AACF,KAAC,CAAC,CAAA;AACJ,GAAC,EAAE,CAACA,UAAU,CAAC,CAAC,CAAA;AAEhB,EAAA,MAAMoC,eAAe,GAAGC,MAAM,EAAkB,CAAA;AAChD,EAAA,MAAM,CAACC,cAAc,CAAC,GAAGC,KAAK,EAAE,CAAA;;AAEhC;AACA,EAAA,MAAMhB,KAAK,GAAG;IACZ9B,MAAM;IACNG,OAAO;IACPC,SAAS;AACTe,IAAAA,KAAK,EAAEM,aAAa;IACpBpB,UAAU;IACVE,UAAU,EAAEA,UAAU,IAAI,KAAK;IAC/BC,SAAS,EAAEA,SAAS,IAAI,KAAK;IAC7BK,aAAa;IACbO,OAAO;AACPuB,IAAAA,eAAe,EAAEA,eAA4C;IAC7DE,cAAc;IACd3B,gBAAgB;IAChBQ,QAAQA,CAACP,KAAoB,EAAE;AAC7B,MAAA,IAAIZ,UAAU,EAAE;AACd,QAAA,OAAA;AACF,OAAA;MAEA,MAAMwC,aAAa,GAAGtB,aAAa,CAAA;MACnCC,QAAQ,CAACP,KAAK,CAAC,CAAA;AACf,MAAA,IAAIA,KAAK,KAAK4B,aAAa,IAAIpC,QAAQ,EAAE;QACvCA,QAAQ,CAACQ,KAAK,CAAC,CAAA;AACjB,OAAA;KACD;IACDS,aAAaA,CAACT,KAAa,EAAE;AAC3B,MAAA,IAAIZ,UAAU,EAAE;AACd,QAAA,OAAA;AACF,OAAA;MAEA,MAAMwC,aAAa,GAAG1C,UAAU,CAAA;MAChCuB,aAAa,CAACT,KAAK,CAAC,CAAA;AACpB,MAAA,IAAIA,KAAK,KAAK4B,aAAa,IAAInC,aAAa,EAAE;QAC5CA,aAAa,CAACO,KAAK,CAAC,CAAA;AACtB,OAAA;AACF,KAAA;GACD,CAAA;AAED,EAAA,oBACE6B,KAAA,CAAAC,aAAA,CAACC,aAAa,EAAA;AAAC/B,IAAAA,KAAK,EAAE;AAAEH,MAAAA,KAAAA;AAAM,KAAA;AAAE,GAAA,eAC9BgC,KAAA,CAAAC,aAAA,CAACE,gBAAgB,EAAA;AAACC,IAAAA,SAAS,EAAC,eAAe;AAACC,IAAAA,WAAW,EAAE,KAAM;AAAC5C,IAAAA,gBAAgB,EAAEA,gBAAAA;AAAiB,GAAA,eACjGuC,KAAA,CAAAC,aAAA,CAACK,eAAe,CAACC,QAAQ,EAAA;AAACpC,IAAAA,KAAK,EAAEW,KAAAA;AAAM,GAAA,eACrCkB,KAAA,CAAAC,aAAA,CAACO,cAAc,CAACD,QAAQ,EAAA;AAACpC,IAAAA,KAAK,EAAEkB,cAAAA;AAAe,GAAA,eAC7CW,KAAA,CAAAC,aAAA,CAACQ,OAAO,EAAAC,QAAA,CAAA;AAACC,IAAAA,aAAa,EAAC,QAAQ;AAACC,IAAAA,UAAU,EAAC,YAAY;AAACC,IAAAA,GAAG,EAAC,KAAA;GAAUtC,EAAAA,YAAY,gBAChFyB,KAAA,CAAAC,aAAA,CAACa,OAAO,EAAAJ,QAAA,CAAA;AACN1C,IAAAA,KAAK,EAAEA,KAAM;AACb+C,IAAAA,mBAAmB,EAAE;AAAEC,MAAAA,OAAO,EAAE,iBAAiB;AAAEC,MAAAA,OAAO,EAAE,iBAAA;KAAoB;AAChFC,IAAAA,SAAS,EAAC,cAAc;AACxBC,IAAAA,IAAI,EAAC,SAAS;AACdzD,IAAAA,QAAQ,EAAEA,QAAAA;AAAS,GAAA,EACfd,KAAK,CACV,CAAC,EACDE,WAAW,IAAI,OAAOA,WAAW,KAAK,QAAQ,gBAC7CkD,KAAA,CAAAC,aAAA,CAACmB,IAAI,EAAAV,QAAA,CAAA;AACH1C,IAAAA,KAAK,EAAEA,KAAM;AACbqD,IAAAA,SAAS,EAAC,KAAK;AACfjD,IAAAA,OAAO,EAAC,SAAS;AACjBkD,IAAAA,KAAK,EAAE9D,SAAS,GAAG,OAAO,GAAGQ,KAAK,KAAKuD,KAAK,CAACC,KAAK,GAAG,WAAW,GAAG,OAAA;GAC/DzE,EAAAA,gBAAgB,GAEnBD,WACG,CAAC,gBACLkD,KAAK,CAACyB,cAAc,CAAC3E,WAAW,CAAC,GACnCA,WAAW,GACT,IACG,CACc,CACD,CACV,CACL,CAAC,CAAA;AAEpB,EAAC;AACDH,YAAY,CAAC+E,SAAS,GAAGhF,SAAS,CAAA;AAClCC,YAAY,CAACgF,WAAW,GAAGlF,cAAc,CAAA;AAElC,MAAMmF,QAAQ,GAAGC,MAAM,CAACC,MAAM,CAACnF,YAAY,EAAE;AAClDoF,EAAAA,OAAO,EAAEC,eAAe;AACxBC,EAAAA,OAAO,EAAEC,eAAAA;AACX,CAAC;;;;"}
|
package/_internal/MenuButton.js
CHANGED
|
@@ -9,7 +9,72 @@ const COMPONENT_NAME = 'MenuButton';
|
|
|
9
9
|
const CLASSNAME = 'redsift-menu-button';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
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 *
|
|
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":"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"}
|
package/_internal/Select2.js
CHANGED
|
@@ -9,7 +9,74 @@ const COMPONENT_NAME = 'Select';
|
|
|
9
9
|
const CLASSNAME = 'redsift-select';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
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 {
|
package/_internal/Select2.js.map
CHANGED
|
@@ -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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"}
|
package/_internal/types.js.map
CHANGED
|
@@ -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
|
|
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
|
-
/**
|
|
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
|
-
*
|
|
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
|
|
200
|
-
className?: string
|
|
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
|
-
*
|
|
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
|
|
333
|
-
className?: string
|
|
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
|
-
/**
|
|
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
|
-
*
|
|
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
|
|
437
|
-
className?: string
|
|
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
|
|
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.
|
|
33
|
+
"version": "12.3.0-muiv6",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@redsift/design-system": "^12.
|
|
36
|
-
"@redsift/icons": "^12.
|
|
37
|
-
"@redsift/popovers": "^12.
|
|
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": "^
|
|
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": "^
|
|
67
|
-
"@typescript-eslint/parser": "^
|
|
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": "^
|
|
74
|
-
"jest-environment-jsdom": "^29.
|
|
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": "^
|
|
87
|
+
"ts-jest": "^29.2.0"
|
|
88
88
|
},
|
|
89
89
|
"peerDependencies": {
|
|
90
|
-
"@redsift/design-system": "^12.
|
|
91
|
-
"@redsift/icons": "^12.
|
|
92
|
-
"@redsift/popovers": "^12.
|
|
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": "
|
|
97
|
+
"gitHead": "11c8c3624cc156d23913a5954fd881219b7e290e"
|
|
98
98
|
}
|