@intlayer/design-system 6.1.5 → 6.1.6
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/dist/.vite/manifest.json +13 -9
- package/dist/Form-CriPBaZk.js.map +1 -1
- package/dist/Form-DJrUK3mm.cjs.map +1 -1
- package/dist/components/Accordion/Accordion.cjs +51 -15
- package/dist/components/Accordion/Accordion.cjs.map +1 -1
- package/dist/components/Accordion/Accordion.d.ts +44 -5
- package/dist/components/Accordion/Accordion.d.ts.map +1 -1
- package/dist/components/Accordion/Accordion.mjs +52 -16
- package/dist/components/Accordion/Accordion.mjs.map +1 -1
- package/dist/components/Avatar/index.cjs +114 -31
- package/dist/components/Avatar/index.cjs.map +1 -1
- package/dist/components/Avatar/index.d.ts +46 -2
- package/dist/components/Avatar/index.d.ts.map +1 -1
- package/dist/components/Avatar/index.mjs +115 -32
- package/dist/components/Avatar/index.mjs.map +1 -1
- package/dist/components/Badge/index.cjs +88 -9
- package/dist/components/Badge/index.cjs.map +1 -1
- package/dist/components/Badge/index.d.ts +80 -2
- package/dist/components/Badge/index.d.ts.map +1 -1
- package/dist/components/Badge/index.mjs +89 -10
- package/dist/components/Badge/index.mjs.map +1 -1
- package/dist/components/Breadcrumb/index.cjs +124 -59
- package/dist/components/Breadcrumb/index.cjs.map +1 -1
- package/dist/components/Breadcrumb/index.d.ts +89 -5
- package/dist/components/Breadcrumb/index.d.ts.map +1 -1
- package/dist/components/Breadcrumb/index.mjs +124 -59
- package/dist/components/Breadcrumb/index.mjs.map +1 -1
- package/dist/components/Button/Button.cjs +44 -25
- package/dist/components/Button/Button.cjs.map +1 -1
- package/dist/components/Button/Button.d.ts +95 -1
- package/dist/components/Button/Button.d.ts.map +1 -1
- package/dist/components/Button/Button.mjs +44 -25
- package/dist/components/Button/Button.mjs.map +1 -1
- package/dist/components/ClickOutsideDiv/index.cjs +38 -7
- package/dist/components/ClickOutsideDiv/index.cjs.map +1 -1
- package/dist/components/ClickOutsideDiv/index.d.ts +13 -0
- package/dist/components/ClickOutsideDiv/index.d.ts.map +1 -1
- package/dist/components/ClickOutsideDiv/index.mjs +39 -8
- package/dist/components/ClickOutsideDiv/index.mjs.map +1 -1
- package/dist/components/Container/index.cjs +2 -0
- package/dist/components/Container/index.cjs.map +1 -1
- package/dist/components/Container/index.d.ts +42 -0
- package/dist/components/Container/index.d.ts.map +1 -1
- package/dist/components/Container/index.mjs +2 -0
- package/dist/components/Container/index.mjs.map +1 -1
- package/dist/components/ContentEditor/ContentEditor.cjs +80 -33
- package/dist/components/ContentEditor/ContentEditor.cjs.map +1 -1
- package/dist/components/ContentEditor/ContentEditor.d.ts +29 -0
- package/dist/components/ContentEditor/ContentEditor.d.ts.map +1 -1
- package/dist/components/ContentEditor/ContentEditor.mjs +80 -33
- package/dist/components/ContentEditor/ContentEditor.mjs.map +1 -1
- package/dist/components/ContentEditor/ContentEditorInput.cjs +58 -31
- package/dist/components/ContentEditor/ContentEditorInput.cjs.map +1 -1
- package/dist/components/ContentEditor/ContentEditorInput.d.ts +33 -0
- package/dist/components/ContentEditor/ContentEditorInput.d.ts.map +1 -1
- package/dist/components/ContentEditor/ContentEditorInput.mjs +58 -31
- package/dist/components/ContentEditor/ContentEditorInput.mjs.map +1 -1
- package/dist/components/ContentEditor/ContentEditorTextArea.cjs +58 -30
- package/dist/components/ContentEditor/ContentEditorTextArea.cjs.map +1 -1
- package/dist/components/ContentEditor/ContentEditorTextArea.d.ts +35 -0
- package/dist/components/ContentEditor/ContentEditorTextArea.d.ts.map +1 -1
- package/dist/components/ContentEditor/ContentEditorTextArea.mjs +59 -31
- package/dist/components/ContentEditor/ContentEditorTextArea.mjs.map +1 -1
- package/dist/components/ContentEditor/index.cjs +4 -0
- package/dist/components/ContentEditor/index.cjs.map +1 -1
- package/dist/components/ContentEditor/index.d.ts +2 -0
- package/dist/components/ContentEditor/index.d.ts.map +1 -1
- package/dist/components/ContentEditor/index.mjs +5 -1
- package/dist/components/ContentEditor/index.mjs.map +1 -1
- package/dist/components/ContentSelector/ContentSelector.cjs +9 -1
- package/dist/components/ContentSelector/ContentSelector.cjs.map +1 -1
- package/dist/components/ContentSelector/ContentSelector.d.ts +167 -0
- package/dist/components/ContentSelector/ContentSelector.d.ts.map +1 -1
- package/dist/components/ContentSelector/ContentSelector.mjs +9 -1
- package/dist/components/ContentSelector/ContentSelector.mjs.map +1 -1
- package/dist/components/CopyButton/index.cjs +23 -8
- package/dist/components/CopyButton/index.cjs.map +1 -1
- package/dist/components/CopyButton/index.d.ts +78 -0
- package/dist/components/CopyButton/index.d.ts.map +1 -1
- package/dist/components/CopyButton/index.mjs +23 -8
- package/dist/components/CopyButton/index.mjs.map +1 -1
- package/dist/components/CopyToClipboard/index.cjs +58 -22
- package/dist/components/CopyToClipboard/index.cjs.map +1 -1
- package/dist/components/CopyToClipboard/index.d.ts +68 -2
- package/dist/components/CopyToClipboard/index.d.ts.map +1 -1
- package/dist/components/CopyToClipboard/index.mjs +59 -23
- package/dist/components/CopyToClipboard/index.mjs.map +1 -1
- package/dist/components/DictionaryFieldEditor/DictionaryFieldEditor.cjs +4 -2
- package/dist/components/DictionaryFieldEditor/DictionaryFieldEditor.cjs.map +1 -1
- package/dist/components/DictionaryFieldEditor/DictionaryFieldEditor.d.ts +1 -0
- package/dist/components/DictionaryFieldEditor/DictionaryFieldEditor.d.ts.map +1 -1
- package/dist/components/DictionaryFieldEditor/DictionaryFieldEditor.mjs +4 -2
- package/dist/components/DictionaryFieldEditor/DictionaryFieldEditor.mjs.map +1 -1
- package/dist/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.cjs +2 -2
- package/dist/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.cjs.map +1 -1
- package/dist/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.mjs +2 -2
- package/dist/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.mjs.map +1 -1
- package/dist/components/DictionaryFieldEditor/SaveForm/SaveForm.cjs +3 -0
- package/dist/components/DictionaryFieldEditor/SaveForm/SaveForm.cjs.map +1 -1
- package/dist/components/DictionaryFieldEditor/SaveForm/SaveForm.d.ts +1 -0
- package/dist/components/DictionaryFieldEditor/SaveForm/SaveForm.d.ts.map +1 -1
- package/dist/components/DictionaryFieldEditor/SaveForm/SaveForm.mjs +3 -0
- package/dist/components/DictionaryFieldEditor/SaveForm/SaveForm.mjs.map +1 -1
- package/dist/components/DropDown/index.cjs +6 -4
- package/dist/components/DropDown/index.cjs.map +1 -1
- package/dist/components/DropDown/index.d.ts +92 -15
- package/dist/components/DropDown/index.d.ts.map +1 -1
- package/dist/components/DropDown/index.mjs +6 -4
- package/dist/components/DropDown/index.mjs.map +1 -1
- package/dist/components/EditableField/EditableFieldInput.cjs.map +1 -1
- package/dist/components/EditableField/EditableFieldInput.d.ts +38 -0
- package/dist/components/EditableField/EditableFieldInput.d.ts.map +1 -1
- package/dist/components/EditableField/EditableFieldInput.mjs.map +1 -1
- package/dist/components/EditableField/EditableFieldLayout.cjs +10 -2
- package/dist/components/EditableField/EditableFieldLayout.cjs.map +1 -1
- package/dist/components/EditableField/EditableFieldLayout.d.ts.map +1 -1
- package/dist/components/EditableField/EditableFieldLayout.mjs +10 -2
- package/dist/components/EditableField/EditableFieldLayout.mjs.map +1 -1
- package/dist/components/EditableField/EditableFieldTextArea.cjs.map +1 -1
- package/dist/components/EditableField/EditableFieldTextArea.d.ts +42 -0
- package/dist/components/EditableField/EditableFieldTextArea.d.ts.map +1 -1
- package/dist/components/EditableField/EditableFieldTextArea.mjs.map +1 -1
- package/dist/components/ExpandCollapse/ExpandCollapse.cjs.map +1 -1
- package/dist/components/ExpandCollapse/ExpandCollapse.d.ts +58 -0
- package/dist/components/ExpandCollapse/ExpandCollapse.d.ts.map +1 -1
- package/dist/components/ExpandCollapse/ExpandCollapse.mjs.map +1 -1
- package/dist/components/Footer/index.cjs.map +1 -1
- package/dist/components/Footer/index.d.ts +101 -0
- package/dist/components/Footer/index.d.ts.map +1 -1
- package/dist/components/Footer/index.mjs.map +1 -1
- package/dist/components/Form/elements/MultiselectElement.d.ts.map +1 -1
- package/dist/components/Form/elements/SelectElement.d.ts.map +1 -1
- package/dist/components/Form/elements/SwitchSelectorElement.d.ts.map +1 -1
- package/dist/components/Headers/index.cjs.map +1 -1
- package/dist/components/Headers/index.d.ts +69 -2
- package/dist/components/Headers/index.d.ts.map +1 -1
- package/dist/components/Headers/index.mjs.map +1 -1
- package/dist/components/HeightResizer/index.cjs +10 -7
- package/dist/components/HeightResizer/index.cjs.map +1 -1
- package/dist/components/HeightResizer/index.d.ts +89 -0
- package/dist/components/HeightResizer/index.d.ts.map +1 -1
- package/dist/components/HeightResizer/index.mjs +10 -7
- package/dist/components/HeightResizer/index.mjs.map +1 -1
- package/dist/components/InformationTag/index.cjs.map +1 -1
- package/dist/components/InformationTag/index.d.ts +72 -0
- package/dist/components/InformationTag/index.d.ts.map +1 -1
- package/dist/components/InformationTag/index.mjs.map +1 -1
- package/dist/components/KeyboardScreenAdapter/index.cjs.map +1 -1
- package/dist/components/KeyboardScreenAdapter/index.d.ts +100 -0
- package/dist/components/KeyboardScreenAdapter/index.d.ts.map +1 -1
- package/dist/components/KeyboardScreenAdapter/index.mjs.map +1 -1
- package/dist/components/Label/index.cjs +25 -3
- package/dist/components/Label/index.cjs.map +1 -1
- package/dist/components/Label/index.d.ts +65 -1
- package/dist/components/Label/index.d.ts.map +1 -1
- package/dist/components/Label/index.mjs +26 -4
- package/dist/components/Label/index.mjs.map +1 -1
- package/dist/components/Link/Link.cjs +0 -4
- package/dist/components/Link/Link.cjs.map +1 -1
- package/dist/components/Link/Link.d.ts +169 -0
- package/dist/components/Link/Link.d.ts.map +1 -1
- package/dist/components/Link/Link.mjs +0 -4
- package/dist/components/Link/Link.mjs.map +1 -1
- package/dist/components/Loader/index.cjs.map +1 -1
- package/dist/components/Loader/index.d.ts +82 -11
- package/dist/components/Loader/index.d.ts.map +1 -1
- package/dist/components/Loader/index.mjs.map +1 -1
- package/dist/components/Loader/spinner.cjs.map +1 -1
- package/dist/components/Loader/spinner.d.ts +56 -0
- package/dist/components/Loader/spinner.d.ts.map +1 -1
- package/dist/components/Loader/spinner.mjs.map +1 -1
- package/dist/components/MarkDownRender/MarkDownRender.cjs +0 -1
- package/dist/components/MarkDownRender/MarkDownRender.cjs.map +1 -1
- package/dist/components/MarkDownRender/MarkDownRender.d.ts +147 -0
- package/dist/components/MarkDownRender/MarkDownRender.d.ts.map +1 -1
- package/dist/components/MarkDownRender/MarkDownRender.mjs +0 -1
- package/dist/components/MarkDownRender/MarkDownRender.mjs.map +1 -1
- package/dist/components/MarkDownRender/processor.cjs +12 -9
- package/dist/components/MarkDownRender/processor.cjs.map +1 -1
- package/dist/components/MarkDownRender/processor.d.ts.map +1 -1
- package/dist/components/MarkDownRender/processor.mjs +12 -9
- package/dist/components/MarkDownRender/processor.mjs.map +1 -1
- package/dist/components/MaxHeightSmoother/index.cjs.map +1 -1
- package/dist/components/MaxHeightSmoother/index.d.ts +152 -0
- package/dist/components/MaxHeightSmoother/index.d.ts.map +1 -1
- package/dist/components/MaxHeightSmoother/index.mjs.map +1 -1
- package/dist/components/Modal/Modal.cjs +5 -0
- package/dist/components/Modal/Modal.cjs.map +1 -1
- package/dist/components/Modal/Modal.d.ts +81 -3
- package/dist/components/Modal/Modal.d.ts.map +1 -1
- package/dist/components/Modal/Modal.mjs +5 -0
- package/dist/components/Modal/Modal.mjs.map +1 -1
- package/dist/components/Navbar/Burger.cjs.map +1 -1
- package/dist/components/Navbar/Burger.d.ts +54 -0
- package/dist/components/Navbar/Burger.d.ts.map +1 -1
- package/dist/components/Navbar/Burger.mjs.map +1 -1
- package/dist/components/Navbar/DesktopNavbar.cjs.map +1 -1
- package/dist/components/Navbar/DesktopNavbar.d.ts +78 -0
- package/dist/components/Navbar/DesktopNavbar.d.ts.map +1 -1
- package/dist/components/Navbar/DesktopNavbar.mjs.map +1 -1
- package/dist/components/Navbar/MobileNavbar.cjs.map +1 -1
- package/dist/components/Navbar/MobileNavbar.d.ts +88 -0
- package/dist/components/Navbar/MobileNavbar.d.ts.map +1 -1
- package/dist/components/Navbar/MobileNavbar.mjs.map +1 -1
- package/dist/components/Navbar/index.cjs.map +1 -1
- package/dist/components/Navbar/index.d.ts +69 -0
- package/dist/components/Navbar/index.d.ts.map +1 -1
- package/dist/components/Navbar/index.mjs.map +1 -1
- package/dist/components/Navbar/useNavigation.cjs +8 -1
- package/dist/components/Navbar/useNavigation.cjs.map +1 -1
- package/dist/components/Navbar/useNavigation.d.ts +83 -0
- package/dist/components/Navbar/useNavigation.d.ts.map +1 -1
- package/dist/components/Navbar/useNavigation.mjs +8 -1
- package/dist/components/Navbar/useNavigation.mjs.map +1 -1
- package/dist/components/Pattern/DotPattern.cjs.map +1 -1
- package/dist/components/Pattern/DotPattern.d.ts +101 -0
- package/dist/components/Pattern/DotPattern.d.ts.map +1 -1
- package/dist/components/Pattern/DotPattern.mjs.map +1 -1
- package/dist/components/Pattern/GridPattern.cjs.map +1 -1
- package/dist/components/Pattern/GridPattern.d.ts +114 -0
- package/dist/components/Pattern/GridPattern.d.ts.map +1 -1
- package/dist/components/Pattern/GridPattern.mjs.map +1 -1
- package/dist/components/Pattern/SpotLight.cjs.map +1 -1
- package/dist/components/Pattern/SpotLight.d.ts +125 -0
- package/dist/components/Pattern/SpotLight.d.ts.map +1 -1
- package/dist/components/Pattern/SpotLight.mjs.map +1 -1
- package/dist/components/Popover/index.cjs +10 -10
- package/dist/components/Popover/index.cjs.map +1 -1
- package/dist/components/Popover/index.d.ts +110 -15
- package/dist/components/Popover/index.d.ts.map +1 -1
- package/dist/components/Popover/index.mjs +10 -10
- package/dist/components/Popover/index.mjs.map +1 -1
- package/dist/components/PressableSpan/PressableSpan.cjs +22 -5
- package/dist/components/PressableSpan/PressableSpan.cjs.map +1 -1
- package/dist/components/PressableSpan/PressableSpan.d.ts +105 -3
- package/dist/components/PressableSpan/PressableSpan.d.ts.map +1 -1
- package/dist/components/PressableSpan/PressableSpan.mjs +22 -5
- package/dist/components/PressableSpan/PressableSpan.mjs.map +1 -1
- package/dist/components/RightDrawer/RightDrawer.cjs.map +1 -1
- package/dist/components/RightDrawer/RightDrawer.d.ts +182 -0
- package/dist/components/RightDrawer/RightDrawer.d.ts.map +1 -1
- package/dist/components/RightDrawer/RightDrawer.mjs.map +1 -1
- package/dist/components/RightDrawer/isElementAtTopAndNotCovered.cjs.map +1 -1
- package/dist/components/RightDrawer/isElementAtTopAndNotCovered.d.ts +44 -0
- package/dist/components/RightDrawer/isElementAtTopAndNotCovered.d.ts.map +1 -1
- package/dist/components/RightDrawer/isElementAtTopAndNotCovered.mjs.map +1 -1
- package/dist/components/RightDrawer/useRightDrawerStore.cjs.map +1 -1
- package/dist/components/RightDrawer/useRightDrawerStore.d.ts +102 -0
- package/dist/components/RightDrawer/useRightDrawerStore.d.ts.map +1 -1
- package/dist/components/RightDrawer/useRightDrawerStore.mjs.map +1 -1
- package/dist/components/Select/Multiselect.cjs.map +1 -1
- package/dist/components/Select/Multiselect.d.ts +125 -18
- package/dist/components/Select/Multiselect.d.ts.map +1 -1
- package/dist/components/Select/Multiselect.mjs.map +1 -1
- package/dist/components/Select/Select.cjs.map +1 -1
- package/dist/components/Select/Select.d.ts +214 -7
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/components/Select/Select.mjs.map +1 -1
- package/dist/components/SwitchSelector/index.cjs.map +1 -1
- package/dist/components/SwitchSelector/index.d.ts +157 -8
- package/dist/components/SwitchSelector/index.d.ts.map +1 -1
- package/dist/components/SwitchSelector/index.mjs.map +1 -1
- package/dist/components/Table/Table.cjs.map +1 -1
- package/dist/components/Table/Table.d.ts +184 -0
- package/dist/components/Table/Table.d.ts.map +1 -1
- package/dist/components/Table/Table.mjs.map +1 -1
- package/dist/components/Tag/index.cjs.map +1 -1
- package/dist/components/Tag/index.d.ts +223 -0
- package/dist/components/Tag/index.d.ts.map +1 -1
- package/dist/components/Tag/index.mjs.map +1 -1
- package/dist/components/TextArea/AutoSizeTextArea.cjs.map +1 -1
- package/dist/components/TextArea/AutoSizeTextArea.d.ts +91 -0
- package/dist/components/TextArea/AutoSizeTextArea.d.ts.map +1 -1
- package/dist/components/TextArea/AutoSizeTextArea.mjs.map +1 -1
- package/dist/components/TextArea/AutocompleteTextArea.cjs.map +1 -1
- package/dist/components/TextArea/AutocompleteTextArea.d.ts +145 -0
- package/dist/components/TextArea/AutocompleteTextArea.d.ts.map +1 -1
- package/dist/components/TextArea/AutocompleteTextArea.mjs.map +1 -1
- package/dist/components/TextArea/TextArea.cjs.map +1 -1
- package/dist/components/TextArea/TextArea.d.ts +74 -0
- package/dist/components/TextArea/TextArea.d.ts.map +1 -1
- package/dist/components/TextArea/TextArea.mjs.map +1 -1
- package/dist/components/Toaster/Toast.cjs +4 -0
- package/dist/components/Toaster/Toast.cjs.map +1 -1
- package/dist/components/Toaster/Toast.d.ts +148 -2
- package/dist/components/Toaster/Toast.d.ts.map +1 -1
- package/dist/components/Toaster/Toast.mjs +4 -0
- package/dist/components/Toaster/Toast.mjs.map +1 -1
- package/dist/components/Toaster/Toaster.cjs.map +1 -1
- package/dist/components/Toaster/Toaster.d.ts +42 -0
- package/dist/components/Toaster/Toaster.d.ts.map +1 -1
- package/dist/components/Toaster/Toaster.mjs.map +1 -1
- package/dist/components/Toaster/useToast.cjs.map +1 -1
- package/dist/components/Toaster/useToast.d.ts +199 -2
- package/dist/components/Toaster/useToast.d.ts.map +1 -1
- package/dist/components/Toaster/useToast.mjs.map +1 -1
- package/dist/components/WithResizer/index.cjs.map +1 -1
- package/dist/components/WithResizer/index.d.ts +143 -0
- package/dist/components/WithResizer/index.d.ts.map +1 -1
- package/dist/components/WithResizer/index.mjs.map +1 -1
- package/dist/components/index.cjs +2 -2
- package/dist/components/index.d.ts +0 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.mjs +4 -4
- package/dist/components/index.mjs.map +1 -1
- package/dist/hooks/auth.cjs +2 -2
- package/dist/hooks/auth.cjs.map +1 -1
- package/dist/hooks/auth.mjs +2 -2
- package/dist/hooks/auth.mjs.map +1 -1
- package/dist/hooks/reactQuery.cjs +2 -1
- package/dist/hooks/reactQuery.cjs.map +1 -1
- package/dist/hooks/reactQuery.d.ts +1 -1
- package/dist/hooks/reactQuery.d.ts.map +1 -1
- package/dist/hooks/reactQuery.mjs +2 -1
- package/dist/hooks/reactQuery.mjs.map +1 -1
- package/dist/hooks/useAuth/useOAuth2.cjs +3 -3
- package/dist/hooks/useAuth/useOAuth2.cjs.map +1 -1
- package/dist/hooks/useAuth/useOAuth2.mjs +3 -3
- package/dist/hooks/useAuth/useOAuth2.mjs.map +1 -1
- package/dist/hooks/useAuth/useSession.cjs +3 -3
- package/dist/hooks/useAuth/useSession.cjs.map +1 -1
- package/dist/hooks/useAuth/useSession.mjs +3 -3
- package/dist/hooks/useAuth/useSession.mjs.map +1 -1
- package/dist/utils/image.cjs +30 -0
- package/dist/utils/image.cjs.map +1 -0
- package/dist/utils/image.d.ts +37 -0
- package/dist/utils/image.d.ts.map +1 -0
- package/dist/utils/image.mjs +30 -0
- package/dist/utils/image.mjs.map +1 -0
- package/package.json +20 -18
- package/dist/utils/capitalize.cjs +0 -10
- package/dist/utils/capitalize.cjs.map +0 -1
- package/dist/utils/capitalize.d.ts +0 -2
- package/dist/utils/capitalize.d.ts.map +0 -1
- package/dist/utils/capitalize.mjs +0 -10
- package/dist/utils/capitalize.mjs.map +0 -1
|
@@ -1,18 +1,200 @@
|
|
|
1
1
|
import { FC, ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for the back button functionality in the RightDrawer
|
|
4
|
+
*
|
|
5
|
+
* @interface BackButtonProps
|
|
6
|
+
*/
|
|
2
7
|
type BackButtonProps = {
|
|
8
|
+
/** Callback function triggered when the back button is clicked */
|
|
3
9
|
onBack: () => void;
|
|
10
|
+
/** Optional custom text for the back button. Defaults to "Go back" if not provided */
|
|
4
11
|
text?: string;
|
|
5
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* Props configuration for the RightDrawer component
|
|
15
|
+
*
|
|
16
|
+
* @interface RightDrawerProps
|
|
17
|
+
*/
|
|
6
18
|
type RightDrawerProps = {
|
|
19
|
+
/**
|
|
20
|
+
* Title displayed in the drawer header
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* <RightDrawer title="User Settings" identifier="settings">
|
|
24
|
+
* Content here
|
|
25
|
+
* </RightDrawer>
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
7
28
|
title?: ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* Unique identifier for the drawer instance. Required for store management
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* <RightDrawer identifier="user-profile" title="Profile">
|
|
34
|
+
* Profile content
|
|
35
|
+
* </RightDrawer>
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
8
38
|
identifier: string;
|
|
39
|
+
/** The content to be displayed inside the drawer */
|
|
9
40
|
children?: ReactNode;
|
|
41
|
+
/**
|
|
42
|
+
* Optional header content displayed below the title
|
|
43
|
+
* @example
|
|
44
|
+
* ```tsx
|
|
45
|
+
* <RightDrawer
|
|
46
|
+
* title="Settings"
|
|
47
|
+
* header={<div className="text-sm opacity-80">Configure your preferences</div>}
|
|
48
|
+
* identifier="settings"
|
|
49
|
+
* >
|
|
50
|
+
* Settings content
|
|
51
|
+
* </RightDrawer>
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
10
54
|
header?: ReactNode;
|
|
55
|
+
/**
|
|
56
|
+
* Whether the drawer should close when clicking outside of it
|
|
57
|
+
* @default true
|
|
58
|
+
* @example
|
|
59
|
+
* ```tsx
|
|
60
|
+
* <RightDrawer closeOnOutsideClick={false} identifier="persistent">
|
|
61
|
+
* This drawer requires explicit close action
|
|
62
|
+
* </RightDrawer>
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
11
65
|
closeOnOutsideClick?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Configuration for an optional back button in the drawer header
|
|
68
|
+
* @example
|
|
69
|
+
* ```tsx
|
|
70
|
+
* <RightDrawer
|
|
71
|
+
* backButton={{
|
|
72
|
+
* text: "Back to List",
|
|
73
|
+
* onBack: () => navigate('/list')
|
|
74
|
+
* }}
|
|
75
|
+
* identifier="detail-view"
|
|
76
|
+
* >
|
|
77
|
+
* Detail content
|
|
78
|
+
* </RightDrawer>
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
12
81
|
backButton?: BackButtonProps;
|
|
82
|
+
/**
|
|
83
|
+
* External control for the open state. When provided, overrides internal store state
|
|
84
|
+
* @example
|
|
85
|
+
* ```tsx
|
|
86
|
+
* const [isOpen, setIsOpen] = useState(false);
|
|
87
|
+
*
|
|
88
|
+
* <RightDrawer
|
|
89
|
+
* isOpen={isOpen}
|
|
90
|
+
* onClose={() => setIsOpen(false)}
|
|
91
|
+
* identifier="controlled"
|
|
92
|
+
* >
|
|
93
|
+
* Controlled drawer content
|
|
94
|
+
* </RightDrawer>
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
13
97
|
isOpen?: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Callback function triggered when the drawer is closed
|
|
100
|
+
* @example
|
|
101
|
+
* ```tsx
|
|
102
|
+
* <RightDrawer
|
|
103
|
+
* onClose={() => console.log('Drawer closed')}
|
|
104
|
+
* identifier="tracked"
|
|
105
|
+
* >
|
|
106
|
+
* Content with close tracking
|
|
107
|
+
* </RightDrawer>
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
14
110
|
onClose?: () => void;
|
|
15
111
|
};
|
|
112
|
+
/**
|
|
113
|
+
* RightDrawer - A slide-out drawer panel that appears from the right side of the screen
|
|
114
|
+
*
|
|
115
|
+
* A versatile drawer component that provides an overlay panel for displaying secondary content,
|
|
116
|
+
* forms, details, or navigation. Features responsive design that adapts to mobile devices,
|
|
117
|
+
* configurable close behavior, and integrated state management through Zustand store.
|
|
118
|
+
*
|
|
119
|
+
* ## Key Features
|
|
120
|
+
* - **Responsive Design**: Full-width on mobile, fixed 400px width on desktop
|
|
121
|
+
* - **State Management**: Built-in Zustand store for managing multiple drawer instances
|
|
122
|
+
* - **Accessibility**: Proper ARIA attributes, keyboard navigation, and focus management
|
|
123
|
+
* - **Flexible Layout**: Customizable header, title, and content areas
|
|
124
|
+
* - **Click Outside**: Configurable outside click detection for auto-closing
|
|
125
|
+
* - **Scroll Management**: Automatic body scroll blocking when open
|
|
126
|
+
*
|
|
127
|
+
* ## Use Cases
|
|
128
|
+
* - Navigation menus and sidebars
|
|
129
|
+
* - Detail panels and forms
|
|
130
|
+
* - Settings and configuration interfaces
|
|
131
|
+
* - Shopping carts and checkout processes
|
|
132
|
+
* - User profiles and account management
|
|
133
|
+
* - Multi-step workflows and wizards
|
|
134
|
+
*
|
|
135
|
+
* ## Accessibility
|
|
136
|
+
* - **Focus Management**: Traps focus within the drawer when open
|
|
137
|
+
* - **Keyboard Navigation**: Escape key closes the drawer
|
|
138
|
+
* - **Screen Reader Support**: Proper ARIA labels and announcements
|
|
139
|
+
* - **Touch Support**: Mobile-optimized touch interactions
|
|
140
|
+
*
|
|
141
|
+
* ## State Management
|
|
142
|
+
* The component uses a Zustand store (`useRightDrawerStore`) to manage drawer state:
|
|
143
|
+
* - Multiple drawers can be managed simultaneously using unique identifiers
|
|
144
|
+
* - External components can open/close drawers using the store
|
|
145
|
+
* - Supports both controlled (via props) and uncontrolled (via store) patterns
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* Basic usage with store management:
|
|
149
|
+
* ```tsx
|
|
150
|
+
* // Opening the drawer from another component
|
|
151
|
+
* const { open } = useRightDrawerStore();
|
|
152
|
+
*
|
|
153
|
+
* <button onClick={() => open('user-menu')}>
|
|
154
|
+
* Open Menu
|
|
155
|
+
* </button>
|
|
156
|
+
*
|
|
157
|
+
* <RightDrawer identifier="user-menu" title="User Menu">
|
|
158
|
+
* <nav>Navigation items here</nav>
|
|
159
|
+
* </RightDrawer>
|
|
160
|
+
* ```
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* Controlled drawer with external state:
|
|
164
|
+
* ```tsx
|
|
165
|
+
* const [showDrawer, setShowDrawer] = useState(false);
|
|
166
|
+
*
|
|
167
|
+
* <RightDrawer
|
|
168
|
+
* identifier="controlled-drawer"
|
|
169
|
+
* title="Settings"
|
|
170
|
+
* isOpen={showDrawer}
|
|
171
|
+
* onClose={() => setShowDrawer(false)}
|
|
172
|
+
* closeOnOutsideClick={false}
|
|
173
|
+
* >
|
|
174
|
+
* <SettingsForm onSave={() => setShowDrawer(false)} />
|
|
175
|
+
* </RightDrawer>
|
|
176
|
+
* ```
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* Complex drawer with back button and header:
|
|
180
|
+
* ```tsx
|
|
181
|
+
* <RightDrawer
|
|
182
|
+
* identifier="product-detail"
|
|
183
|
+
* title="Product Details"
|
|
184
|
+
* header={
|
|
185
|
+
* <div className="text-sm text-gray-600">
|
|
186
|
+
* SKU: {product.sku} | Stock: {product.stock}
|
|
187
|
+
* </div>
|
|
188
|
+
* }
|
|
189
|
+
* backButton={{
|
|
190
|
+
* text: "Back to Catalog",
|
|
191
|
+
* onBack: () => navigate('/catalog')
|
|
192
|
+
* }}
|
|
193
|
+
* >
|
|
194
|
+
* <ProductDetailView product={product} />
|
|
195
|
+
* </RightDrawer>
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
16
198
|
export declare const RightDrawer: FC<RightDrawerProps>;
|
|
17
199
|
export {};
|
|
18
200
|
//# sourceMappingURL=RightDrawer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RightDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/RightDrawer/RightDrawer.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,EAAE,EAEP,KAAK,SAAS,EAGf,MAAM,OAAO,CAAC;AAUf,KAAK,eAAe,GAAG;IACrB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"RightDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/RightDrawer/RightDrawer.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,EAAE,EAEP,KAAK,SAAS,EAGf,MAAM,OAAO,CAAC;AAUf;;;;GAIG;AACH,KAAK,eAAe,GAAG;IACrB,kEAAkE;IAClE,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,sFAAsF;IACtF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;GAIG;AACH,KAAK,gBAAgB,GAAG;IACtB;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;;;;;;;OAQG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;;;;;;;;OASG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAE7B;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqFG;AACH,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAyI5C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RightDrawer.mjs","sources":["../../../src/components/RightDrawer/RightDrawer.tsx"],"sourcesContent":["'use client';\n\nimport { ChevronLeft, X } from 'lucide-react';\nimport {\n type FC,\n type MouseEventHandler,\n type ReactNode,\n useEffect,\n useRef,\n} from 'react';\nimport { useShallow } from 'zustand/react/shallow';\nimport { useDevice } from '../../hooks/useDevice';\nimport { useScrollBlockage } from '../../hooks/useScrollBlockage';\nimport { Button, ButtonColor, ButtonSize, ButtonVariant } from '../Button';\nimport { Container } from '../Container';\nimport { MaxWidthSmoother } from '../MaxWidthSmoother/index';\nimport { isElementAtTopAndNotCovered } from './isElementAtTopAndNotCovered';\nimport { useRightDrawerStore } from './useRightDrawerStore';\n\ntype BackButtonProps = {\n onBack: () => void;\n text?: string;\n};\n\ntype RightDrawerProps = {\n title?: ReactNode;\n identifier: string;\n children?: ReactNode;\n header?: ReactNode;\n closeOnOutsideClick?: boolean;\n backButton?: BackButtonProps;\n isOpen?: boolean;\n onClose?: () => void;\n};\n\nexport const RightDrawer: FC<RightDrawerProps> = ({\n title,\n identifier,\n children,\n header,\n closeOnOutsideClick = true,\n backButton,\n isOpen: isOpenProp,\n onClose,\n}) => {\n const { isMobile } = useDevice('md');\n const panelRef = useRef<HTMLDivElement>(null);\n const childrenContainerRef = useRef<HTMLDivElement>(null);\n const { close, open, isOpen } = useRightDrawerStore(\n useShallow((s) => ({\n close: () => s.close(identifier),\n open: () => s.open(identifier),\n isOpen: s.isOpen(identifier),\n }))\n );\n\n useScrollBlockage({\n disableScroll: isOpen,\n key: identifier ? `right_drawer_${identifier}` : 'right_drawer',\n });\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n try {\n if (!panelRef.current) return;\n\n // Check if drawer is open and click outside is enabled\n const isClickAble = isOpen && closeOnOutsideClick;\n\n // Check if click is outside the drawer panel\n const isClickOutside =\n event.target && !panelRef.current.contains(event.target as Node);\n\n // Check if event propagation has been stopped\n const isAtTopAndVisible = isElementAtTopAndNotCovered(panelRef.current);\n\n if (\n (isClickAble && isClickOutside && isAtTopAndVisible) ||\n !event.target\n ) {\n close();\n onClose?.();\n }\n } catch (_e) {\n close();\n onClose?.();\n }\n };\n\n window.addEventListener('mousedown', handleClickOutside);\n return () => window.removeEventListener('mousedown', handleClickOutside);\n }, [isOpen, close, onClose, closeOnOutsideClick, identifier]); // Make sure the effect runs only if isOpen or close changes\n\n useEffect(() => {\n if (isOpenProp !== undefined) {\n if (isOpenProp) {\n open();\n } else {\n close();\n onClose?.();\n }\n }\n }, [close, open, onClose, isOpenProp, identifier]);\n\n const handleSpareSpaceClick: MouseEventHandler<HTMLDivElement> = (e) => {\n // Check if the click trigger the background\n if (e.target !== e.currentTarget) {\n return;\n }\n\n if (isMobile) {\n close();\n onClose?.();\n }\n };\n\n return (\n <div className=\"fixed right-0 top-0 z-50 flex h-full justify-end\">\n <MaxWidthSmoother isHidden={!isOpen} align=\"right\">\n <Container\n className=\"text-text relative flex h-screen w-screen flex-col md:w-[400px]\"\n ref={panelRef}\n roundedSize=\"none\"\n >\n <div className=\"flex flex-col gap-3 p-6\">\n <div className=\"flex justify-between gap-3\">\n <div>\n {backButton && (\n <Button\n variant={ButtonVariant.HOVERABLE}\n color={ButtonColor.TEXT}\n label={backButton.text ?? 'Go back'}\n onClick={backButton.onBack}\n Icon={ChevronLeft}\n >\n {backButton?.text}\n </Button>\n )}\n </div>\n <div>\n <Button\n variant={ButtonVariant.HOVERABLE}\n color={ButtonColor.TEXT}\n label=\"Close\"\n className=\"ml-auto\"\n onClick={close}\n Icon={X}\n size={ButtonSize.ICON_MD}\n />\n </div>\n </div>\n {title && (\n <h2 className=\"flex items-center justify-center text-lg font-bold\">\n {title}\n </h2>\n )}\n {header}\n </div>\n\n <div className=\"flex h-full flex-col overflow-y-auto p-2\">\n <div\n className=\"flex flex-1 flex-col\"\n onClick={handleSpareSpaceClick}\n ref={childrenContainerRef}\n >\n {children}\n </div>\n </div>\n </Container>\n </MaxWidthSmoother>\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RightDrawer.mjs","sources":["../../../src/components/RightDrawer/RightDrawer.tsx"],"sourcesContent":["'use client';\n\nimport { ChevronLeft, X } from 'lucide-react';\nimport {\n type FC,\n type MouseEventHandler,\n type ReactNode,\n useEffect,\n useRef,\n} from 'react';\nimport { useShallow } from 'zustand/react/shallow';\nimport { useDevice } from '../../hooks/useDevice';\nimport { useScrollBlockage } from '../../hooks/useScrollBlockage';\nimport { Button, ButtonColor, ButtonSize, ButtonVariant } from '../Button';\nimport { Container } from '../Container';\nimport { MaxWidthSmoother } from '../MaxWidthSmoother/index';\nimport { isElementAtTopAndNotCovered } from './isElementAtTopAndNotCovered';\nimport { useRightDrawerStore } from './useRightDrawerStore';\n\n/**\n * Configuration for the back button functionality in the RightDrawer\n *\n * @interface BackButtonProps\n */\ntype BackButtonProps = {\n /** Callback function triggered when the back button is clicked */\n onBack: () => void;\n /** Optional custom text for the back button. Defaults to \"Go back\" if not provided */\n text?: string;\n};\n\n/**\n * Props configuration for the RightDrawer component\n *\n * @interface RightDrawerProps\n */\ntype RightDrawerProps = {\n /**\n * Title displayed in the drawer header\n * @example\n * ```tsx\n * <RightDrawer title=\"User Settings\" identifier=\"settings\">\n * Content here\n * </RightDrawer>\n * ```\n */\n title?: ReactNode;\n\n /**\n * Unique identifier for the drawer instance. Required for store management\n * @example\n * ```tsx\n * <RightDrawer identifier=\"user-profile\" title=\"Profile\">\n * Profile content\n * </RightDrawer>\n * ```\n */\n identifier: string;\n\n /** The content to be displayed inside the drawer */\n children?: ReactNode;\n\n /**\n * Optional header content displayed below the title\n * @example\n * ```tsx\n * <RightDrawer\n * title=\"Settings\"\n * header={<div className=\"text-sm opacity-80\">Configure your preferences</div>}\n * identifier=\"settings\"\n * >\n * Settings content\n * </RightDrawer>\n * ```\n */\n header?: ReactNode;\n\n /**\n * Whether the drawer should close when clicking outside of it\n * @default true\n * @example\n * ```tsx\n * <RightDrawer closeOnOutsideClick={false} identifier=\"persistent\">\n * This drawer requires explicit close action\n * </RightDrawer>\n * ```\n */\n closeOnOutsideClick?: boolean;\n\n /**\n * Configuration for an optional back button in the drawer header\n * @example\n * ```tsx\n * <RightDrawer\n * backButton={{\n * text: \"Back to List\",\n * onBack: () => navigate('/list')\n * }}\n * identifier=\"detail-view\"\n * >\n * Detail content\n * </RightDrawer>\n * ```\n */\n backButton?: BackButtonProps;\n\n /**\n * External control for the open state. When provided, overrides internal store state\n * @example\n * ```tsx\n * const [isOpen, setIsOpen] = useState(false);\n *\n * <RightDrawer\n * isOpen={isOpen}\n * onClose={() => setIsOpen(false)}\n * identifier=\"controlled\"\n * >\n * Controlled drawer content\n * </RightDrawer>\n * ```\n */\n isOpen?: boolean;\n\n /**\n * Callback function triggered when the drawer is closed\n * @example\n * ```tsx\n * <RightDrawer\n * onClose={() => console.log('Drawer closed')}\n * identifier=\"tracked\"\n * >\n * Content with close tracking\n * </RightDrawer>\n * ```\n */\n onClose?: () => void;\n};\n\n/**\n * RightDrawer - A slide-out drawer panel that appears from the right side of the screen\n *\n * A versatile drawer component that provides an overlay panel for displaying secondary content,\n * forms, details, or navigation. Features responsive design that adapts to mobile devices,\n * configurable close behavior, and integrated state management through Zustand store.\n *\n * ## Key Features\n * - **Responsive Design**: Full-width on mobile, fixed 400px width on desktop\n * - **State Management**: Built-in Zustand store for managing multiple drawer instances\n * - **Accessibility**: Proper ARIA attributes, keyboard navigation, and focus management\n * - **Flexible Layout**: Customizable header, title, and content areas\n * - **Click Outside**: Configurable outside click detection for auto-closing\n * - **Scroll Management**: Automatic body scroll blocking when open\n *\n * ## Use Cases\n * - Navigation menus and sidebars\n * - Detail panels and forms\n * - Settings and configuration interfaces\n * - Shopping carts and checkout processes\n * - User profiles and account management\n * - Multi-step workflows and wizards\n *\n * ## Accessibility\n * - **Focus Management**: Traps focus within the drawer when open\n * - **Keyboard Navigation**: Escape key closes the drawer\n * - **Screen Reader Support**: Proper ARIA labels and announcements\n * - **Touch Support**: Mobile-optimized touch interactions\n *\n * ## State Management\n * The component uses a Zustand store (`useRightDrawerStore`) to manage drawer state:\n * - Multiple drawers can be managed simultaneously using unique identifiers\n * - External components can open/close drawers using the store\n * - Supports both controlled (via props) and uncontrolled (via store) patterns\n *\n * @example\n * Basic usage with store management:\n * ```tsx\n * // Opening the drawer from another component\n * const { open } = useRightDrawerStore();\n *\n * <button onClick={() => open('user-menu')}>\n * Open Menu\n * </button>\n *\n * <RightDrawer identifier=\"user-menu\" title=\"User Menu\">\n * <nav>Navigation items here</nav>\n * </RightDrawer>\n * ```\n *\n * @example\n * Controlled drawer with external state:\n * ```tsx\n * const [showDrawer, setShowDrawer] = useState(false);\n *\n * <RightDrawer\n * identifier=\"controlled-drawer\"\n * title=\"Settings\"\n * isOpen={showDrawer}\n * onClose={() => setShowDrawer(false)}\n * closeOnOutsideClick={false}\n * >\n * <SettingsForm onSave={() => setShowDrawer(false)} />\n * </RightDrawer>\n * ```\n *\n * @example\n * Complex drawer with back button and header:\n * ```tsx\n * <RightDrawer\n * identifier=\"product-detail\"\n * title=\"Product Details\"\n * header={\n * <div className=\"text-sm text-gray-600\">\n * SKU: {product.sku} | Stock: {product.stock}\n * </div>\n * }\n * backButton={{\n * text: \"Back to Catalog\",\n * onBack: () => navigate('/catalog')\n * }}\n * >\n * <ProductDetailView product={product} />\n * </RightDrawer>\n * ```\n */\nexport const RightDrawer: FC<RightDrawerProps> = ({\n title,\n identifier,\n children,\n header,\n closeOnOutsideClick = true,\n backButton,\n isOpen: isOpenProp,\n onClose,\n}) => {\n const { isMobile } = useDevice('md');\n const panelRef = useRef<HTMLDivElement>(null);\n const childrenContainerRef = useRef<HTMLDivElement>(null);\n const { close, open, isOpen } = useRightDrawerStore(\n useShallow((s) => ({\n close: () => s.close(identifier),\n open: () => s.open(identifier),\n isOpen: s.isOpen(identifier),\n }))\n );\n\n useScrollBlockage({\n disableScroll: isOpen,\n key: identifier ? `right_drawer_${identifier}` : 'right_drawer',\n });\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n try {\n if (!panelRef.current) return;\n\n // Check if drawer is open and click outside is enabled\n const isClickAble = isOpen && closeOnOutsideClick;\n\n // Check if click is outside the drawer panel\n const isClickOutside =\n event.target && !panelRef.current.contains(event.target as Node);\n\n // Check if event propagation has been stopped\n const isAtTopAndVisible = isElementAtTopAndNotCovered(panelRef.current);\n\n if (\n (isClickAble && isClickOutside && isAtTopAndVisible) ||\n !event.target\n ) {\n close();\n onClose?.();\n }\n } catch (_e) {\n close();\n onClose?.();\n }\n };\n\n window.addEventListener('mousedown', handleClickOutside);\n return () => window.removeEventListener('mousedown', handleClickOutside);\n }, [isOpen, close, onClose, closeOnOutsideClick, identifier]); // Make sure the effect runs only if isOpen or close changes\n\n useEffect(() => {\n if (isOpenProp !== undefined) {\n if (isOpenProp) {\n open();\n } else {\n close();\n onClose?.();\n }\n }\n }, [close, open, onClose, isOpenProp, identifier]);\n\n const handleSpareSpaceClick: MouseEventHandler<HTMLDivElement> = (e) => {\n // Check if the click trigger the background\n if (e.target !== e.currentTarget) {\n return;\n }\n\n if (isMobile) {\n close();\n onClose?.();\n }\n };\n\n return (\n <div className=\"fixed right-0 top-0 z-50 flex h-full justify-end\">\n <MaxWidthSmoother isHidden={!isOpen} align=\"right\">\n <Container\n className=\"text-text relative flex h-screen w-screen flex-col md:w-[400px]\"\n ref={panelRef}\n roundedSize=\"none\"\n >\n <div className=\"flex flex-col gap-3 p-6\">\n <div className=\"flex justify-between gap-3\">\n <div>\n {backButton && (\n <Button\n variant={ButtonVariant.HOVERABLE}\n color={ButtonColor.TEXT}\n label={backButton.text ?? 'Go back'}\n onClick={backButton.onBack}\n Icon={ChevronLeft}\n >\n {backButton?.text}\n </Button>\n )}\n </div>\n <div>\n <Button\n variant={ButtonVariant.HOVERABLE}\n color={ButtonColor.TEXT}\n label=\"Close\"\n className=\"ml-auto\"\n onClick={close}\n Icon={X}\n size={ButtonSize.ICON_MD}\n />\n </div>\n </div>\n {title && (\n <h2 className=\"flex items-center justify-center text-lg font-bold\">\n {title}\n </h2>\n )}\n {header}\n </div>\n\n <div className=\"flex h-full flex-col overflow-y-auto p-2\">\n <div\n className=\"flex flex-1 flex-col\"\n onClick={handleSpareSpaceClick}\n ref={childrenContainerRef}\n >\n {children}\n </div>\n </div>\n </Container>\n </MaxWidthSmoother>\n </div>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isElementAtTopAndNotCovered.cjs","sources":["../../../src/components/RightDrawer/isElementAtTopAndNotCovered.tsx"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"isElementAtTopAndNotCovered.cjs","sources":["../../../src/components/RightDrawer/isElementAtTopAndNotCovered.tsx"],"sourcesContent":["/**\n * Utility function to determine if an HTML element is at the top of the viewport and not covered by other elements\n *\n * This function is specifically used by the RightDrawer component to ensure that click-outside\n * detection only triggers when the drawer is actually visible and not obscured by other UI elements.\n *\n * ## Algorithm\n * 1. **Viewport Check**: Verifies the element is within the visible viewport bounds\n * 2. **Coverage Check**: Uses `document.elementFromPoint()` to ensure no other elements are covering the drawer\n * 3. **Center Point Testing**: Tests the center-top point of the element for accurate detection\n *\n * ## Use Cases\n * - Click-outside detection for modal and drawer components\n * - Visibility validation for overlay components\n * - Z-index conflict resolution\n * - Accessibility focus management\n *\n * @param element - The HTML element to check for visibility and coverage\n * @returns Boolean indicating if the element is visible at the top and not covered by other elements\n *\n * @example\n * Basic usage in click-outside detection:\n * ```tsx\n * const handleClickOutside = (event: MouseEvent) => {\n * if (!drawerRef.current) return;\n *\n * const isVisible = isElementAtTopAndNotCovered(drawerRef.current);\n * const isClickOutside = !drawerRef.current.contains(event.target as Node);\n *\n * if (isVisible && isClickOutside) {\n * closeDrawer();\n * }\n * };\n * ```\n *\n * @example\n * Checking multiple overlays:\n * ```tsx\n * const overlays = document.querySelectorAll('.overlay');\n * const visibleOverlays = Array.from(overlays).filter(overlay =>\n * isElementAtTopAndNotCovered(overlay as HTMLElement)\n * );\n * ```\n */\nexport const isElementAtTopAndNotCovered = (element: HTMLElement): boolean => {\n const rect = element.getBoundingClientRect();\n const elemTop = rect.top;\n const elemBottom = rect.bottom - 1; // -1 to avoid the border of the element\n\n // Check if element is at the top of the viewport\n const isVisibleAtTop = elemTop >= 0 && elemBottom <= window.innerHeight;\n\n // Further check if the element is not covered by any other element at the center point of its top boundary\n if (isVisibleAtTop) {\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + 10; // slight offset from the very top to ensure we're within the element bounds\n const topElement = document.elementFromPoint(centerX, centerY);\n\n // Check if our element is the topmost element at these coordinates or a child of the topmost element\n return element === topElement || element.contains(topElement);\n }\n\n return false;\n};\n"],"names":[],"mappings":";;AA4CO,MAAM,8BAA8B,CAAC,YAAkC;AAC5E,QAAM,OAAO,QAAQ,sBAAA;AACrB,QAAM,UAAU,KAAK;AACrB,QAAM,aAAa,KAAK,SAAS;AAGjC,QAAM,iBAAiB,WAAW,KAAK,cAAc,OAAO;AAG5D,MAAI,gBAAgB;AAClB,UAAM,UAAU,KAAK,OAAO,KAAK,QAAQ;AACzC,UAAM,UAAU,KAAK,MAAM;AAC3B,UAAM,aAAa,SAAS,iBAAiB,SAAS,OAAO;AAG7D,WAAO,YAAY,cAAc,QAAQ,SAAS,UAAU;AAAA,EAC9D;AAEA,SAAO;AACT;;"}
|
|
@@ -1,2 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility function to determine if an HTML element is at the top of the viewport and not covered by other elements
|
|
3
|
+
*
|
|
4
|
+
* This function is specifically used by the RightDrawer component to ensure that click-outside
|
|
5
|
+
* detection only triggers when the drawer is actually visible and not obscured by other UI elements.
|
|
6
|
+
*
|
|
7
|
+
* ## Algorithm
|
|
8
|
+
* 1. **Viewport Check**: Verifies the element is within the visible viewport bounds
|
|
9
|
+
* 2. **Coverage Check**: Uses `document.elementFromPoint()` to ensure no other elements are covering the drawer
|
|
10
|
+
* 3. **Center Point Testing**: Tests the center-top point of the element for accurate detection
|
|
11
|
+
*
|
|
12
|
+
* ## Use Cases
|
|
13
|
+
* - Click-outside detection for modal and drawer components
|
|
14
|
+
* - Visibility validation for overlay components
|
|
15
|
+
* - Z-index conflict resolution
|
|
16
|
+
* - Accessibility focus management
|
|
17
|
+
*
|
|
18
|
+
* @param element - The HTML element to check for visibility and coverage
|
|
19
|
+
* @returns Boolean indicating if the element is visible at the top and not covered by other elements
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* Basic usage in click-outside detection:
|
|
23
|
+
* ```tsx
|
|
24
|
+
* const handleClickOutside = (event: MouseEvent) => {
|
|
25
|
+
* if (!drawerRef.current) return;
|
|
26
|
+
*
|
|
27
|
+
* const isVisible = isElementAtTopAndNotCovered(drawerRef.current);
|
|
28
|
+
* const isClickOutside = !drawerRef.current.contains(event.target as Node);
|
|
29
|
+
*
|
|
30
|
+
* if (isVisible && isClickOutside) {
|
|
31
|
+
* closeDrawer();
|
|
32
|
+
* }
|
|
33
|
+
* };
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* Checking multiple overlays:
|
|
38
|
+
* ```tsx
|
|
39
|
+
* const overlays = document.querySelectorAll('.overlay');
|
|
40
|
+
* const visibleOverlays = Array.from(overlays).filter(overlay =>
|
|
41
|
+
* isElementAtTopAndNotCovered(overlay as HTMLElement)
|
|
42
|
+
* );
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
1
45
|
export declare const isElementAtTopAndNotCovered: (element: HTMLElement) => boolean;
|
|
2
46
|
//# sourceMappingURL=isElementAtTopAndNotCovered.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isElementAtTopAndNotCovered.d.ts","sourceRoot":"","sources":["../../../src/components/RightDrawer/isElementAtTopAndNotCovered.tsx"],"names":[],"mappings":"AAAA,eAAO,MAAM,2BAA2B,GAAI,SAAS,WAAW,
|
|
1
|
+
{"version":3,"file":"isElementAtTopAndNotCovered.d.ts","sourceRoot":"","sources":["../../../src/components/RightDrawer/isElementAtTopAndNotCovered.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,eAAO,MAAM,2BAA2B,GAAI,SAAS,WAAW,KAAG,OAmBlE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isElementAtTopAndNotCovered.mjs","sources":["../../../src/components/RightDrawer/isElementAtTopAndNotCovered.tsx"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"isElementAtTopAndNotCovered.mjs","sources":["../../../src/components/RightDrawer/isElementAtTopAndNotCovered.tsx"],"sourcesContent":["/**\n * Utility function to determine if an HTML element is at the top of the viewport and not covered by other elements\n *\n * This function is specifically used by the RightDrawer component to ensure that click-outside\n * detection only triggers when the drawer is actually visible and not obscured by other UI elements.\n *\n * ## Algorithm\n * 1. **Viewport Check**: Verifies the element is within the visible viewport bounds\n * 2. **Coverage Check**: Uses `document.elementFromPoint()` to ensure no other elements are covering the drawer\n * 3. **Center Point Testing**: Tests the center-top point of the element for accurate detection\n *\n * ## Use Cases\n * - Click-outside detection for modal and drawer components\n * - Visibility validation for overlay components\n * - Z-index conflict resolution\n * - Accessibility focus management\n *\n * @param element - The HTML element to check for visibility and coverage\n * @returns Boolean indicating if the element is visible at the top and not covered by other elements\n *\n * @example\n * Basic usage in click-outside detection:\n * ```tsx\n * const handleClickOutside = (event: MouseEvent) => {\n * if (!drawerRef.current) return;\n *\n * const isVisible = isElementAtTopAndNotCovered(drawerRef.current);\n * const isClickOutside = !drawerRef.current.contains(event.target as Node);\n *\n * if (isVisible && isClickOutside) {\n * closeDrawer();\n * }\n * };\n * ```\n *\n * @example\n * Checking multiple overlays:\n * ```tsx\n * const overlays = document.querySelectorAll('.overlay');\n * const visibleOverlays = Array.from(overlays).filter(overlay =>\n * isElementAtTopAndNotCovered(overlay as HTMLElement)\n * );\n * ```\n */\nexport const isElementAtTopAndNotCovered = (element: HTMLElement): boolean => {\n const rect = element.getBoundingClientRect();\n const elemTop = rect.top;\n const elemBottom = rect.bottom - 1; // -1 to avoid the border of the element\n\n // Check if element is at the top of the viewport\n const isVisibleAtTop = elemTop >= 0 && elemBottom <= window.innerHeight;\n\n // Further check if the element is not covered by any other element at the center point of its top boundary\n if (isVisibleAtTop) {\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + 10; // slight offset from the very top to ensure we're within the element bounds\n const topElement = document.elementFromPoint(centerX, centerY);\n\n // Check if our element is the topmost element at these coordinates or a child of the topmost element\n return element === topElement || element.contains(topElement);\n }\n\n return false;\n};\n"],"names":[],"mappings":"AA4CO,MAAM,8BAA8B,CAAC,YAAkC;AAC5E,QAAM,OAAO,QAAQ,sBAAA;AACrB,QAAM,UAAU,KAAK;AACrB,QAAM,aAAa,KAAK,SAAS;AAGjC,QAAM,iBAAiB,WAAW,KAAK,cAAc,OAAO;AAG5D,MAAI,gBAAgB;AAClB,UAAM,UAAU,KAAK,OAAO,KAAK,QAAQ;AACzC,UAAM,UAAU,KAAK,MAAM;AAC3B,UAAM,aAAa,SAAS,iBAAiB,SAAS,OAAO;AAG7D,WAAO,YAAY,cAAc,QAAQ,SAAS,UAAU;AAAA,EAC9D;AAEA,SAAO;AACT;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRightDrawerStore.cjs","sources":["../../../src/components/RightDrawer/useRightDrawerStore.ts"],"sourcesContent":["import { create } from 'zustand';\n\ntype RightDrawerStore = {\n drawers: Record<string, boolean>;\n open: (key: string) => void;\n close: (key: string) => void;\n isOpen: (key: string) => boolean;\n};\n\nexport const useRightDrawerStore = create<RightDrawerStore>((set, get) => ({\n drawers: {},\n open: (key: string) =>\n set((state) => ({\n drawers: {\n ...state.drawers,\n [key]: true,\n },\n })),\n close: (key: string) =>\n set((state) => ({\n drawers: {\n ...state.drawers,\n [key]: false,\n },\n })),\n isOpen: (key: string) => get().drawers[key] ?? false,\n}));\n"],"names":["create"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"useRightDrawerStore.cjs","sources":["../../../src/components/RightDrawer/useRightDrawerStore.ts"],"sourcesContent":["import { create } from 'zustand';\n\n/**\n * Type definition for the RightDrawer Zustand store state and actions\n *\n * @interface RightDrawerStore\n */\ntype RightDrawerStore = {\n /** Record of drawer identifiers and their open/closed states */\n drawers: Record<string, boolean>;\n\n /**\n * Opens a drawer with the specified identifier\n * @param key - Unique identifier for the drawer instance\n * @example\n * ```tsx\n * const { open } = useRightDrawerStore();\n * open('user-profile'); // Opens the drawer with identifier 'user-profile'\n * ```\n */\n open: (key: string) => void;\n\n /**\n * Closes a drawer with the specified identifier\n * @param key - Unique identifier for the drawer instance\n * @example\n * ```tsx\n * const { close } = useRightDrawerStore();\n * close('user-profile'); // Closes the drawer with identifier 'user-profile'\n * ```\n */\n close: (key: string) => void;\n\n /**\n * Checks if a drawer with the specified identifier is currently open\n * @param key - Unique identifier for the drawer instance\n * @returns Boolean indicating if the drawer is open (defaults to false if not found)\n * @example\n * ```tsx\n * const { isOpen } = useRightDrawerStore();\n * const isProfileOpen = isOpen('user-profile');\n * ```\n */\n isOpen: (key: string) => boolean;\n};\n\n/**\n * Zustand store for managing RightDrawer component states\n *\n * This store provides centralized state management for multiple drawer instances,\n * allowing different parts of the application to open, close, and check the status\n * of drawers using unique identifiers.\n *\n * ## Features\n * - **Multi-instance Management**: Handle multiple drawers simultaneously\n * - **Simple API**: Open, close, and check drawer states with string identifiers\n * - **Persistent State**: Drawer states persist until explicitly changed\n * - **Type Safety**: Full TypeScript support with proper type inference\n *\n * ## Usage Patterns\n *\n * ### Basic Usage\n * ```tsx\n * import { useRightDrawerStore } from './useRightDrawerStore';\n *\n * function NavigationButton() {\n * const { open } = useRightDrawerStore();\n *\n * return (\n * <button onClick={() => open('main-menu')}>\n * Open Menu\n * </button>\n * );\n * }\n * ```\n *\n * ### Conditional Rendering\n * ```tsx\n * function ConditionalContent() {\n * const isMenuOpen = useRightDrawerStore(state => state.isOpen('main-menu'));\n *\n * return (\n * <div>\n * {isMenuOpen ? 'Menu is open' : 'Menu is closed'}\n * </div>\n * );\n * }\n * ```\n *\n * ### Multiple Drawers\n * ```tsx\n * function MultiDrawerManager() {\n * const { open, close, isOpen } = useRightDrawerStore();\n *\n * return (\n * <div>\n * <button onClick={() => open('cart')}>Open Cart</button>\n * <button onClick={() => open('profile')}>Open Profile</button>\n * <button onClick={() => {\n * close('cart');\n * close('profile');\n * }}>Close All</button>\n *\n * <div>\n * Cart: {isOpen('cart') ? 'Open' : 'Closed'}\n * Profile: {isOpen('profile') ? 'Open' : 'Closed'}\n * </div>\n * </div>\n * );\n * }\n * ```\n *\n * @returns RightDrawerStore instance with drawer management capabilities\n */\nexport const useRightDrawerStore = create<RightDrawerStore>((set, get) => ({\n drawers: {},\n open: (key: string) =>\n set((state) => ({\n drawers: {\n ...state.drawers,\n [key]: true,\n },\n })),\n close: (key: string) =>\n set((state) => ({\n drawers: {\n ...state.drawers,\n [key]: false,\n },\n })),\n isOpen: (key: string) => get().drawers[key] ?? false,\n}));\n"],"names":["create"],"mappings":";;;AAkHO,MAAM,sBAAsBA,QAAAA,OAAyB,CAAC,KAAK,SAAS;AAAA,EACzE,SAAS,CAAA;AAAA,EACT,MAAM,CAAC,QACL,IAAI,CAAC,WAAW;AAAA,IACd,SAAS;AAAA,MACP,GAAG,MAAM;AAAA,MACT,CAAC,GAAG,GAAG;AAAA,IAAA;AAAA,EACT,EACA;AAAA,EACJ,OAAO,CAAC,QACN,IAAI,CAAC,WAAW;AAAA,IACd,SAAS;AAAA,MACP,GAAG,MAAM;AAAA,MACT,CAAC,GAAG,GAAG;AAAA,IAAA;AAAA,EACT,EACA;AAAA,EACJ,QAAQ,CAAC,QAAgB,MAAM,QAAQ,GAAG,KAAK;AACjD,EAAE;;"}
|
|
@@ -1,9 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definition for the RightDrawer Zustand store state and actions
|
|
3
|
+
*
|
|
4
|
+
* @interface RightDrawerStore
|
|
5
|
+
*/
|
|
1
6
|
type RightDrawerStore = {
|
|
7
|
+
/** Record of drawer identifiers and their open/closed states */
|
|
2
8
|
drawers: Record<string, boolean>;
|
|
9
|
+
/**
|
|
10
|
+
* Opens a drawer with the specified identifier
|
|
11
|
+
* @param key - Unique identifier for the drawer instance
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* const { open } = useRightDrawerStore();
|
|
15
|
+
* open('user-profile'); // Opens the drawer with identifier 'user-profile'
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
3
18
|
open: (key: string) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Closes a drawer with the specified identifier
|
|
21
|
+
* @param key - Unique identifier for the drawer instance
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* const { close } = useRightDrawerStore();
|
|
25
|
+
* close('user-profile'); // Closes the drawer with identifier 'user-profile'
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
4
28
|
close: (key: string) => void;
|
|
29
|
+
/**
|
|
30
|
+
* Checks if a drawer with the specified identifier is currently open
|
|
31
|
+
* @param key - Unique identifier for the drawer instance
|
|
32
|
+
* @returns Boolean indicating if the drawer is open (defaults to false if not found)
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* const { isOpen } = useRightDrawerStore();
|
|
36
|
+
* const isProfileOpen = isOpen('user-profile');
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
5
39
|
isOpen: (key: string) => boolean;
|
|
6
40
|
};
|
|
41
|
+
/**
|
|
42
|
+
* Zustand store for managing RightDrawer component states
|
|
43
|
+
*
|
|
44
|
+
* This store provides centralized state management for multiple drawer instances,
|
|
45
|
+
* allowing different parts of the application to open, close, and check the status
|
|
46
|
+
* of drawers using unique identifiers.
|
|
47
|
+
*
|
|
48
|
+
* ## Features
|
|
49
|
+
* - **Multi-instance Management**: Handle multiple drawers simultaneously
|
|
50
|
+
* - **Simple API**: Open, close, and check drawer states with string identifiers
|
|
51
|
+
* - **Persistent State**: Drawer states persist until explicitly changed
|
|
52
|
+
* - **Type Safety**: Full TypeScript support with proper type inference
|
|
53
|
+
*
|
|
54
|
+
* ## Usage Patterns
|
|
55
|
+
*
|
|
56
|
+
* ### Basic Usage
|
|
57
|
+
* ```tsx
|
|
58
|
+
* import { useRightDrawerStore } from './useRightDrawerStore';
|
|
59
|
+
*
|
|
60
|
+
* function NavigationButton() {
|
|
61
|
+
* const { open } = useRightDrawerStore();
|
|
62
|
+
*
|
|
63
|
+
* return (
|
|
64
|
+
* <button onClick={() => open('main-menu')}>
|
|
65
|
+
* Open Menu
|
|
66
|
+
* </button>
|
|
67
|
+
* );
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* ### Conditional Rendering
|
|
72
|
+
* ```tsx
|
|
73
|
+
* function ConditionalContent() {
|
|
74
|
+
* const isMenuOpen = useRightDrawerStore(state => state.isOpen('main-menu'));
|
|
75
|
+
*
|
|
76
|
+
* return (
|
|
77
|
+
* <div>
|
|
78
|
+
* {isMenuOpen ? 'Menu is open' : 'Menu is closed'}
|
|
79
|
+
* </div>
|
|
80
|
+
* );
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* ### Multiple Drawers
|
|
85
|
+
* ```tsx
|
|
86
|
+
* function MultiDrawerManager() {
|
|
87
|
+
* const { open, close, isOpen } = useRightDrawerStore();
|
|
88
|
+
*
|
|
89
|
+
* return (
|
|
90
|
+
* <div>
|
|
91
|
+
* <button onClick={() => open('cart')}>Open Cart</button>
|
|
92
|
+
* <button onClick={() => open('profile')}>Open Profile</button>
|
|
93
|
+
* <button onClick={() => {
|
|
94
|
+
* close('cart');
|
|
95
|
+
* close('profile');
|
|
96
|
+
* }}>Close All</button>
|
|
97
|
+
*
|
|
98
|
+
* <div>
|
|
99
|
+
* Cart: {isOpen('cart') ? 'Open' : 'Closed'}
|
|
100
|
+
* Profile: {isOpen('profile') ? 'Open' : 'Closed'}
|
|
101
|
+
* </div>
|
|
102
|
+
* </div>
|
|
103
|
+
* );
|
|
104
|
+
* }
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* @returns RightDrawerStore instance with drawer management capabilities
|
|
108
|
+
*/
|
|
7
109
|
export declare const useRightDrawerStore: import('zustand').UseBoundStore<import('zustand').StoreApi<RightDrawerStore>>;
|
|
8
110
|
export {};
|
|
9
111
|
//# sourceMappingURL=useRightDrawerStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRightDrawerStore.d.ts","sourceRoot":"","sources":["../../../src/components/RightDrawer/useRightDrawerStore.ts"],"names":[],"mappings":"AAEA,KAAK,gBAAgB,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"useRightDrawerStore.d.ts","sourceRoot":"","sources":["../../../src/components/RightDrawer/useRightDrawerStore.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,KAAK,gBAAgB,GAAG;IACtB,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEjC;;;;;;;;OAQG;IACH,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAE5B;;;;;;;;OAQG;IACH,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAE7B;;;;;;;;;OASG;IACH,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CAClC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,eAAO,MAAM,mBAAmB,+EAiB7B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRightDrawerStore.mjs","sources":["../../../src/components/RightDrawer/useRightDrawerStore.ts"],"sourcesContent":["import { create } from 'zustand';\n\ntype RightDrawerStore = {\n drawers: Record<string, boolean>;\n open: (key: string) => void;\n close: (key: string) => void;\n isOpen: (key: string) => boolean;\n};\n\nexport const useRightDrawerStore = create<RightDrawerStore>((set, get) => ({\n drawers: {},\n open: (key: string) =>\n set((state) => ({\n drawers: {\n ...state.drawers,\n [key]: true,\n },\n })),\n close: (key: string) =>\n set((state) => ({\n drawers: {\n ...state.drawers,\n [key]: false,\n },\n })),\n isOpen: (key: string) => get().drawers[key] ?? false,\n}));\n"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"useRightDrawerStore.mjs","sources":["../../../src/components/RightDrawer/useRightDrawerStore.ts"],"sourcesContent":["import { create } from 'zustand';\n\n/**\n * Type definition for the RightDrawer Zustand store state and actions\n *\n * @interface RightDrawerStore\n */\ntype RightDrawerStore = {\n /** Record of drawer identifiers and their open/closed states */\n drawers: Record<string, boolean>;\n\n /**\n * Opens a drawer with the specified identifier\n * @param key - Unique identifier for the drawer instance\n * @example\n * ```tsx\n * const { open } = useRightDrawerStore();\n * open('user-profile'); // Opens the drawer with identifier 'user-profile'\n * ```\n */\n open: (key: string) => void;\n\n /**\n * Closes a drawer with the specified identifier\n * @param key - Unique identifier for the drawer instance\n * @example\n * ```tsx\n * const { close } = useRightDrawerStore();\n * close('user-profile'); // Closes the drawer with identifier 'user-profile'\n * ```\n */\n close: (key: string) => void;\n\n /**\n * Checks if a drawer with the specified identifier is currently open\n * @param key - Unique identifier for the drawer instance\n * @returns Boolean indicating if the drawer is open (defaults to false if not found)\n * @example\n * ```tsx\n * const { isOpen } = useRightDrawerStore();\n * const isProfileOpen = isOpen('user-profile');\n * ```\n */\n isOpen: (key: string) => boolean;\n};\n\n/**\n * Zustand store for managing RightDrawer component states\n *\n * This store provides centralized state management for multiple drawer instances,\n * allowing different parts of the application to open, close, and check the status\n * of drawers using unique identifiers.\n *\n * ## Features\n * - **Multi-instance Management**: Handle multiple drawers simultaneously\n * - **Simple API**: Open, close, and check drawer states with string identifiers\n * - **Persistent State**: Drawer states persist until explicitly changed\n * - **Type Safety**: Full TypeScript support with proper type inference\n *\n * ## Usage Patterns\n *\n * ### Basic Usage\n * ```tsx\n * import { useRightDrawerStore } from './useRightDrawerStore';\n *\n * function NavigationButton() {\n * const { open } = useRightDrawerStore();\n *\n * return (\n * <button onClick={() => open('main-menu')}>\n * Open Menu\n * </button>\n * );\n * }\n * ```\n *\n * ### Conditional Rendering\n * ```tsx\n * function ConditionalContent() {\n * const isMenuOpen = useRightDrawerStore(state => state.isOpen('main-menu'));\n *\n * return (\n * <div>\n * {isMenuOpen ? 'Menu is open' : 'Menu is closed'}\n * </div>\n * );\n * }\n * ```\n *\n * ### Multiple Drawers\n * ```tsx\n * function MultiDrawerManager() {\n * const { open, close, isOpen } = useRightDrawerStore();\n *\n * return (\n * <div>\n * <button onClick={() => open('cart')}>Open Cart</button>\n * <button onClick={() => open('profile')}>Open Profile</button>\n * <button onClick={() => {\n * close('cart');\n * close('profile');\n * }}>Close All</button>\n *\n * <div>\n * Cart: {isOpen('cart') ? 'Open' : 'Closed'}\n * Profile: {isOpen('profile') ? 'Open' : 'Closed'}\n * </div>\n * </div>\n * );\n * }\n * ```\n *\n * @returns RightDrawerStore instance with drawer management capabilities\n */\nexport const useRightDrawerStore = create<RightDrawerStore>((set, get) => ({\n drawers: {},\n open: (key: string) =>\n set((state) => ({\n drawers: {\n ...state.drawers,\n [key]: true,\n },\n })),\n close: (key: string) =>\n set((state) => ({\n drawers: {\n ...state.drawers,\n [key]: false,\n },\n })),\n isOpen: (key: string) => get().drawers[key] ?? false,\n}));\n"],"names":[],"mappings":";AAkHO,MAAM,sBAAsB,OAAyB,CAAC,KAAK,SAAS;AAAA,EACzE,SAAS,CAAA;AAAA,EACT,MAAM,CAAC,QACL,IAAI,CAAC,WAAW;AAAA,IACd,SAAS;AAAA,MACP,GAAG,MAAM;AAAA,MACT,CAAC,GAAG,GAAG;AAAA,IAAA;AAAA,EACT,EACA;AAAA,EACJ,OAAO,CAAC,QACN,IAAI,CAAC,WAAW;AAAA,IACd,SAAS;AAAA,MACP,GAAG,MAAM;AAAA,MACT,CAAC,GAAG,GAAG;AAAA,IAAA;AAAA,EACT,EACA;AAAA,EACJ,QAAQ,CAAC,QAAgB,MAAM,QAAQ,GAAG,KAAK;AACjD,EAAE;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Multiselect.cjs","sources":["../../../src/components/Select/Multiselect.tsx"],"sourcesContent":["'use client';\n\nimport { Check, X as RemoveIcon } from 'lucide-react';\nimport {\n type ComponentProps,\n type Dispatch,\n type FC,\n type HTMLAttributes,\n type KeyboardEvent,\n type LegacyRef,\n type MouseEventHandler,\n type RefObject,\n type SetStateAction,\n type SyntheticEvent,\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../../utils/cn';\nimport { Badge, BadgeColor } from '../Badge';\nimport { Command, CommandRoot } from '../Command';\n\ntype MultiSelectContextProps = {\n value: string[];\n onValueChange: (value: string) => void;\n open: boolean;\n setOpen: (value: boolean) => void;\n inputValue: string;\n setInputValue: Dispatch<SetStateAction<string>>;\n activeIndex: number;\n setActiveIndex: Dispatch<SetStateAction<number>>;\n ref: RefObject<HTMLInputElement | null>;\n handleSelect: (e: SyntheticEvent<HTMLInputElement>) => void;\n};\n\nconst MultiSelectContext = createContext<MultiSelectContextProps | null>(null);\n\nconst useMultiSelect = () => {\n const context = useContext(MultiSelectContext);\n if (!context) {\n throw new Error('useMultiSelect must be used within MultiSelectProvider');\n }\n return context;\n};\n\n/**\n * MultiSelect Docs: {@link: https://shadcn-extension.vercel.app/docs/multi-select}\n */\n\ntype MultiSelectProps = ComponentProps<typeof CommandRoot> & {\n values?: string[];\n defaultValues?: string[];\n onValueChange?: (value: string[]) => void;\n loop?: boolean;\n};\n\n/**\n *\n * Usage example:\n * ```jsx\n * <MultiSelect\n * values={value}\n * onValuesChange={setValue}\n * loop\n * >\n * <MultiSelectTrigger>\n * <MultiSelectInput placeholder=\"Select your framework\" />\n * </MultiSelectTrigger>\n * <MultiSelectContent>\n * <MultiSelectList>\n * <MultiSelectItem value={\"React\"}>React</MultiSelectItem>\n * <MultiSelectItem value={\"Vue\"}>Vue</MultiSelectItem>\n * <MultiSelectItem value={\"Svelte\"}>Svelte</MultiSelectItem>\n * </MultiSelectList>\n * </MultiSelectContent>\n * </MultiSelect>\n * ```\n */\nconst MultiSelectRoot: FC<MultiSelectProps> = ({\n values: valuesProp,\n defaultValues,\n onValueChange: onValueChange,\n loop = false,\n className,\n children,\n dir,\n ...props\n}) => {\n const [value, setValue] = useState<string[]>(defaultValues ?? []);\n const [inputValue, setInputValue] = useState('');\n const [open, setOpen] = useState<boolean>(false);\n const [activeIndex, setActiveIndex] = useState<number>(-1);\n const inputRef = useRef<HTMLInputElement>(null);\n const [isValueSelected, setIsValueSelected] = useState(false);\n const [selectedValue, setSelectedValue] = useState('');\n\n useEffect(() => {\n if (valuesProp) {\n setValue(valuesProp);\n }\n }, [valuesProp]);\n\n const onValueChangeHandler = useCallback(\n (val: string) => {\n if (value.includes(val)) {\n const newValue = value.filter((item) => item !== val);\n setValue(newValue);\n onValueChange?.(newValue);\n } else {\n const newValue = [...value, val];\n setValue(newValue);\n onValueChange?.(newValue);\n }\n },\n\n [value]\n );\n\n const handleSelect = useCallback(\n (e: SyntheticEvent<HTMLInputElement>) => {\n e.preventDefault();\n const target = e.currentTarget;\n const selection = target.value.substring(\n target.selectionStart ?? 0,\n target.selectionEnd ?? 0\n );\n\n setSelectedValue(selection);\n setIsValueSelected(selection === inputValue);\n },\n [inputValue]\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n e.stopPropagation();\n const target = inputRef.current;\n\n if (!target) return;\n\n const moveNext = () => {\n const nextIndex = activeIndex + 1;\n setActiveIndex(\n nextIndex > value.length - 1 ? (loop ? 0 : -1) : nextIndex\n );\n };\n\n const movePrev = () => {\n const prevIndex = activeIndex - 1;\n setActiveIndex(prevIndex < 0 ? value.length - 1 : prevIndex);\n };\n\n const moveCurrent = () => {\n const newIndex =\n activeIndex - 1 <= 0\n ? value.length - 1 === 0\n ? -1\n : 0\n : activeIndex - 1;\n setActiveIndex(newIndex);\n };\n\n switch (e.key) {\n case 'ArrowLeft':\n if (dir === 'rtl') {\n if (value.length > 0 && (activeIndex !== -1 || loop)) {\n moveNext();\n }\n } else if (value.length > 0 && target.selectionStart === 0) {\n movePrev();\n }\n break;\n\n case 'ArrowRight':\n if (dir === 'rtl') {\n if (value.length > 0 && target.selectionStart === 0) {\n movePrev();\n }\n } else if (value.length > 0 && (activeIndex !== -1 || loop)) {\n moveNext();\n }\n break;\n\n case 'Backspace':\n case 'Delete':\n if (value.length > 0) {\n if (activeIndex !== -1 && activeIndex < value.length) {\n onValueChangeHandler(value[activeIndex]);\n moveCurrent();\n } else if (\n (target.selectionStart === 0 && selectedValue === inputValue) ||\n isValueSelected\n ) {\n onValueChangeHandler(value[value.length - 1]);\n }\n }\n break;\n\n case 'Enter':\n setOpen(true);\n break;\n\n case 'Escape':\n if (activeIndex !== -1) {\n setActiveIndex(-1);\n } else if (open) {\n setOpen(false);\n }\n break;\n }\n },\n\n [value, inputValue, activeIndex, loop]\n );\n\n const memoValue = useMemo(\n () => ({\n value,\n onValueChange: onValueChangeHandler,\n open,\n setOpen,\n inputValue,\n setInputValue,\n activeIndex,\n setActiveIndex,\n ref: inputRef,\n handleSelect,\n }),\n [\n value,\n onValueChangeHandler,\n open,\n setOpen,\n inputValue,\n setInputValue,\n activeIndex,\n setActiveIndex,\n inputRef,\n handleSelect,\n ]\n );\n\n return (\n <MultiSelectContext value={memoValue}>\n <CommandRoot\n onKeyDown={handleKeyDown}\n className={cn(\n 'flex w-full flex-col gap-2 overflow-visible bg-transparent',\n className\n )}\n dir={dir}\n {...props}\n >\n {children}\n </CommandRoot>\n </MultiSelectContext>\n );\n};\n\nconst MultiSelectTrigger: FC<\n HTMLAttributes<HTMLDivElement> & {\n getBadgeValue?: (value: string) => string;\n validationStyleEnabled?: boolean;\n }\n> = ({\n className,\n getBadgeValue = (value) => value,\n validationStyleEnabled = false,\n children,\n ...props\n}) => {\n const { value, onValueChange, activeIndex } = useMultiSelect();\n\n const mousePreventDefault: MouseEventHandler<HTMLButtonElement> = useCallback(\n (e) => {\n e.preventDefault();\n e.stopPropagation();\n },\n []\n );\n\n return (\n <div\n className={cn(\n 'flex w-full flex-col gap-3 rounded-lg p-1 py-2',\n 'border-input ring-offset-background placeholder:text-muted-foreground focus:ring-ring focus:outline-hidden flex w-full items-center justify-between whitespace-nowrap border px-3 py-2 text-sm focus:ring-1 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',\n 'bg-input-background text-input-text w-full select-text resize-none rounded-xl border-2 px-2 py-1 text-sm shadow-none outline-0 transition-all',\n 'border-input-border hover:border-input-border-hover focus:border-input-border-focus focus:outline-0 focus:[box-shadow:none]',\n 'aria-[invalid=true]:border-error',\n validationStyleEnabled && 'valid:border-success invalid:border-error',\n className\n )}\n {...props}\n >\n {value.length > 0 && (\n <div className=\"flex w-full flex-wrap gap-1\">\n {value.map((item, index) => (\n <Badge\n key={item}\n className={cn(\n 'flex items-center gap-1 rounded-xl px-1',\n activeIndex === index && 'ring-muted-foreground ring-2'\n )}\n color={BadgeColor.TEXT}\n >\n <span className=\"text-xs\">{getBadgeValue(item)}</span>\n <button\n aria-label={`Remove ${item} option`}\n aria-roledescription=\"button to remove option\"\n onMouseDown={mousePreventDefault}\n onClick={() => onValueChange(item)}\n >\n <span className=\"sr-only\">Remove {item} option</span>\n <RemoveIcon className=\"size-4 cursor-pointer\" />\n </button>\n </Badge>\n ))}\n </div>\n )}\n {children}\n </div>\n );\n};\n\nconst MultiSelectInput: FC<ComponentProps<typeof Command.Input>> = ({\n className,\n ...props\n}) => {\n const {\n setOpen,\n inputValue,\n setInputValue,\n activeIndex,\n setActiveIndex,\n handleSelect,\n ref: inputRef,\n } = useMultiSelect();\n\n return (\n <Command.Input\n {...props}\n tabIndex={0}\n ref={inputRef as LegacyRef<HTMLInputElement>}\n value={inputValue}\n onValueChange={activeIndex === -1 ? setInputValue : undefined}\n onSelect={handleSelect}\n onBlur={() => setOpen(false)}\n onFocus={() => setOpen(true)}\n onClick={() => setActiveIndex(-1)}\n className={cn(\n 'outline-hidden ml-2 flex-1 cursor-pointer',\n className,\n activeIndex !== -1 && 'caret-transparent'\n )}\n />\n );\n};\n\nconst MultiSelectContent: FC<HTMLAttributes<HTMLDivElement>> = ({\n children,\n}) => {\n const { open } = useMultiSelect();\n return <div className=\"relative\">{open && children}</div>;\n};\n\nconst MultiSelectList: typeof Command.List = ({ className, children }) => (\n <Command.List\n className={cn(\n 'border-muted bg-input-background absolute top-0 z-10 flex w-full flex-col gap-2 rounded-lg border p-2 shadow-md transition-colors',\n className\n )}\n >\n {children}\n <Command.Empty>\n <span className=\"text-muted-foreground\">No results found</span>\n </Command.Empty>\n </Command.List>\n);\n\nconst MultiSelectItem: FC<\n { value: string } & ComponentProps<typeof Command.Item>\n> = ({ className, value, children, ...props }) => {\n const { value: Options, onValueChange, setInputValue } = useMultiSelect();\n\n const mousePreventDefault: MouseEventHandler<HTMLDivElement> = useCallback(\n (e) => {\n e.preventDefault();\n e.stopPropagation();\n },\n []\n );\n\n const isIncluded = Options.includes(value);\n return (\n <Command.Item\n {...props}\n onSelect={() => {\n onValueChange(value);\n setInputValue('');\n }}\n className={cn(\n 'flex cursor-pointer justify-between rounded-lg px-2 py-1 transition-colors',\n 'hover:bg-neutral/10',\n className,\n isIncluded && 'opacity-50',\n props.disabled && 'cursor-not-allowed opacity-50'\n )}\n onMouseDown={mousePreventDefault}\n >\n {children}\n {isIncluded && <Check className=\"size-4\" />}\n </Command.Item>\n );\n};\n\ntype MultiSelectType = typeof MultiSelectRoot & {\n Trigger: typeof MultiSelectTrigger;\n Input: typeof MultiSelectInput;\n Content: typeof MultiSelectContent;\n List: typeof MultiSelectList;\n Item: typeof MultiSelectItem;\n};\n\n/**\n *\n * Usage example:\n * ```jsx\n * <MultiSelect\n * values={value}\n * onValuesChange={setValue}\n * loop\n * >\n * <MultiSelect.Trigger>\n * <MultiSelect.Input placeholder=\"Select your framework\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.List>\n * <MultiSelect.Item value={\"React\"}>React</MultiSelect.Item>\n * <MultiSelect.Item value={\"Vue\"}>Vue</MultiSelect.Item>\n * <MultiSelect.Item value={\"Svelte\"}>Svelte</MultiSelect.Item>\n * </MultiSelect.List>\n * </MultiSelect.Content>\n * </MultiSelect>\n * ```\n */\nexport const MultiSelect = MultiSelectRoot as MultiSelectType;\nMultiSelect.Trigger = MultiSelectTrigger;\nMultiSelect.Input = MultiSelectInput;\nMultiSelect.Content = MultiSelectContent;\nMultiSelect.List = MultiSelectList;\nMultiSelect.Item = MultiSelectItem;\n"],"names":["createContext","useContext","useState","useRef","useEffect","useCallback","useMemo","jsx","CommandRoot","cn","jsxs","Badge","BadgeColor","RemoveIcon","Command","Check"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Multiselect.cjs","sources":["../../../src/components/Select/Multiselect.tsx"],"sourcesContent":["'use client';\n\nimport { Check, X as RemoveIcon } from 'lucide-react';\nimport {\n type ComponentProps,\n type Dispatch,\n type FC,\n type HTMLAttributes,\n type KeyboardEvent,\n type LegacyRef,\n type MouseEventHandler,\n type RefObject,\n type SetStateAction,\n type SyntheticEvent,\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../../utils/cn';\nimport { Badge, BadgeColor } from '../Badge';\nimport { Command, CommandRoot } from '../Command';\n\n/**\n * Context properties for MultiSelect component state management\n *\n * @interface MultiSelectContextProps\n */\ntype MultiSelectContextProps = {\n /** Array of currently selected values */\n value: string[];\n /** Handler for value changes */\n onValueChange: (value: string) => void;\n /** Whether the dropdown is currently open */\n open: boolean;\n /** Function to set the open state */\n setOpen: (value: boolean) => void;\n /** Current input field value for filtering */\n inputValue: string;\n /** Function to set the input value */\n setInputValue: Dispatch<SetStateAction<string>>;\n /** Index of currently focused option for keyboard navigation */\n activeIndex: number;\n /** Function to set the active index */\n setActiveIndex: Dispatch<SetStateAction<number>>;\n /** Ref to the input element */\n ref: RefObject<HTMLInputElement | null>;\n /** Handler for option selection */\n handleSelect: (e: SyntheticEvent<HTMLInputElement>) => void;\n};\n\nconst MultiSelectContext = createContext<MultiSelectContextProps | null>(null);\n\n/**\n * Custom hook to access MultiSelect context\n *\n * Provides access to the internal state and methods of the MultiSelect component.\n * Must be used within a MultiSelect component tree.\n *\n * @returns MultiSelectContextProps - All context properties and methods\n * @throws Error when used outside of MultiSelect component\n *\n * @example\n * ```tsx\n * function CustomMultiSelectItem() {\n * const { value, onValueChange, open } = useMultiSelect();\n * // Use context properties...\n * }\n * ```\n */\nconst useMultiSelect = () => {\n const context = useContext(MultiSelectContext);\n if (!context) {\n throw new Error('useMultiSelect must be used within MultiSelectProvider');\n }\n return context;\n};\n\n/**\n * Props interface for the main MultiSelect component\n *\n * @interface MultiSelectProps\n */\ntype MultiSelectProps = ComponentProps<typeof CommandRoot> & {\n /**\n * Array of selected values (controlled mode)\n * @example\n * ```tsx\n * const [selected, setSelected] = useState(['react', 'vue']);\n * <MultiSelect values={selected} onValueChange={setSelected} />\n * ```\n */\n values?: string[];\n\n /**\n * Default selected values for uncontrolled mode\n * @example\n * ```tsx\n * <MultiSelect defaultValues={['react']} />\n * ```\n */\n defaultValues?: string[];\n\n /**\n * Callback fired when selection changes\n * @param value - New array of selected values\n * @example\n * ```tsx\n * <MultiSelect onValueChange={(values) => console.log('Selected:', values)} />\n * ```\n */\n onValueChange?: (value: string[]) => void;\n\n /**\n * Whether keyboard navigation should loop through options\n * @default false\n * @example\n * ```tsx\n * <MultiSelect loop /> // Arrow keys wrap around at list boundaries\n * ```\n */\n loop?: boolean;\n};\n\n/**\n * MultiSelect - A comprehensive multi-selection dropdown component\n *\n * An advanced multi-select component that combines the functionality of a searchable dropdown\n * with the ability to select multiple values. Built on top of Command component primitives,\n * it provides filtering, keyboard navigation, and visual feedback through badges.\n *\n * ## Key Features\n * - **Multi-Selection**: Select multiple options with visual badge representation\n * - **Searchable**: Built-in filtering to quickly find options in large lists\n * - **Keyboard Navigation**: Full arrow key navigation with optional looping\n * - **Accessibility**: Screen reader support, ARIA attributes, and focus management\n * - **Flexible State**: Both controlled and uncontrolled usage patterns\n * - **Rich UI**: Customizable badges, icons, and content layout\n *\n * ## Use Cases\n * - Tag/category selection in forms\n * - Multi-user assignment interfaces\n * - Feature/permission selection\n * - Filter selection in search interfaces\n * - Any multi-choice selection requirement\n *\n * ## Architecture\n * The component follows a compound pattern similar to Select:\n * - `MultiSelect` (root): Manages state and provides context\n * - `MultiSelect.Trigger`: Container for input and selected badges\n * - `MultiSelect.Input`: Searchable input field with filtering\n * - `MultiSelect.Content`: Dropdown container for options\n * - `MultiSelect.List`: Options container with keyboard navigation\n * - `MultiSelect.Item`: Individual selectable options\n *\n * ## Accessibility\n * - **Keyboard Navigation**: Arrow keys, Enter to select, Backspace to remove\n * - **Screen Readers**: Proper ARIA labels and live region announcements\n * - **Focus Management**: Clear focus indicators and logical tab flow\n * - **Search**: Real-time filtering with screen reader announcements\n *\n * @example\n * Basic multi-select usage:\n * ```tsx\n * const [frameworks, setFrameworks] = useState<string[]>([]);\n *\n * <MultiSelect values={frameworks} onValueChange={setFrameworks}>\n * <MultiSelect.Trigger>\n * <MultiSelect.Input placeholder=\"Select frameworks...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.List>\n * <MultiSelect.Item value=\"react\">React</MultiSelect.Item>\n * <MultiSelect.Item value=\"vue\">Vue</MultiSelect.Item>\n * <MultiSelect.Item value=\"svelte\">Svelte</MultiSelect.Item>\n * </MultiSelect.List>\n * </MultiSelect.Content>\n * </MultiSelect>\n * ```\n *\n * @example\n * Advanced usage with keyboard looping:\n * ```tsx\n * <MultiSelect defaultValues={['react']} loop>\n * <MultiSelect.Trigger>\n * <MultiSelect.Input placeholder=\"Choose technologies...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.List>\n * <MultiSelect.Item value=\"react\">⚛️ React</MultiSelect.Item>\n * <MultiSelect.Item value=\"vue\">💚 Vue</MultiSelect.Item>\n * <MultiSelect.Item value=\"angular\">🔴 Angular</MultiSelect.Item>\n * </MultiSelect.List>\n * </MultiSelect.Content>\n * </MultiSelect>\n * ```\n *\n * @example\n * Form integration with validation:\n * ```tsx\n * <form>\n * <MultiSelect\n * values={selectedSkills}\n * onValueChange={setSelectedSkills}\n * required\n * >\n * <MultiSelect.Trigger className=\"min-h-[2.5rem]\">\n * <MultiSelect.Input placeholder=\"Select your skills...\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.List>\n * <MultiSelect.Item value=\"javascript\">JavaScript</MultiSelect.Item>\n * <MultiSelect.Item value=\"typescript\">TypeScript</MultiSelect.Item>\n * <MultiSelect.Item value=\"python\">Python</MultiSelect.Item>\n * </MultiSelect.List>\n * </MultiSelect.Content>\n * </MultiSelect>\n * </form>\n * ```\n */\nconst MultiSelectRoot: FC<MultiSelectProps> = ({\n values: valuesProp,\n defaultValues,\n onValueChange: onValueChange,\n loop = false,\n className,\n children,\n dir,\n ...props\n}) => {\n const [value, setValue] = useState<string[]>(defaultValues ?? []);\n const [inputValue, setInputValue] = useState('');\n const [open, setOpen] = useState<boolean>(false);\n const [activeIndex, setActiveIndex] = useState<number>(-1);\n const inputRef = useRef<HTMLInputElement>(null);\n const [isValueSelected, setIsValueSelected] = useState(false);\n const [selectedValue, setSelectedValue] = useState('');\n\n useEffect(() => {\n if (valuesProp) {\n setValue(valuesProp);\n }\n }, [valuesProp]);\n\n const onValueChangeHandler = useCallback(\n (val: string) => {\n if (value.includes(val)) {\n const newValue = value.filter((item) => item !== val);\n setValue(newValue);\n onValueChange?.(newValue);\n } else {\n const newValue = [...value, val];\n setValue(newValue);\n onValueChange?.(newValue);\n }\n },\n\n [value]\n );\n\n const handleSelect = useCallback(\n (e: SyntheticEvent<HTMLInputElement>) => {\n e.preventDefault();\n const target = e.currentTarget;\n const selection = target.value.substring(\n target.selectionStart ?? 0,\n target.selectionEnd ?? 0\n );\n\n setSelectedValue(selection);\n setIsValueSelected(selection === inputValue);\n },\n [inputValue]\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n e.stopPropagation();\n const target = inputRef.current;\n\n if (!target) return;\n\n const moveNext = () => {\n const nextIndex = activeIndex + 1;\n setActiveIndex(\n nextIndex > value.length - 1 ? (loop ? 0 : -1) : nextIndex\n );\n };\n\n const movePrev = () => {\n const prevIndex = activeIndex - 1;\n setActiveIndex(prevIndex < 0 ? value.length - 1 : prevIndex);\n };\n\n const moveCurrent = () => {\n const newIndex =\n activeIndex - 1 <= 0\n ? value.length - 1 === 0\n ? -1\n : 0\n : activeIndex - 1;\n setActiveIndex(newIndex);\n };\n\n switch (e.key) {\n case 'ArrowLeft':\n if (dir === 'rtl') {\n if (value.length > 0 && (activeIndex !== -1 || loop)) {\n moveNext();\n }\n } else if (value.length > 0 && target.selectionStart === 0) {\n movePrev();\n }\n break;\n\n case 'ArrowRight':\n if (dir === 'rtl') {\n if (value.length > 0 && target.selectionStart === 0) {\n movePrev();\n }\n } else if (value.length > 0 && (activeIndex !== -1 || loop)) {\n moveNext();\n }\n break;\n\n case 'Backspace':\n case 'Delete':\n if (value.length > 0) {\n if (activeIndex !== -1 && activeIndex < value.length) {\n onValueChangeHandler(value[activeIndex]);\n moveCurrent();\n } else if (\n (target.selectionStart === 0 && selectedValue === inputValue) ||\n isValueSelected\n ) {\n onValueChangeHandler(value[value.length - 1]);\n }\n }\n break;\n\n case 'Enter':\n setOpen(true);\n break;\n\n case 'Escape':\n if (activeIndex !== -1) {\n setActiveIndex(-1);\n } else if (open) {\n setOpen(false);\n }\n break;\n }\n },\n\n [value, inputValue, activeIndex, loop]\n );\n\n const memoValue = useMemo(\n () => ({\n value,\n onValueChange: onValueChangeHandler,\n open,\n setOpen,\n inputValue,\n setInputValue,\n activeIndex,\n setActiveIndex,\n ref: inputRef,\n handleSelect,\n }),\n [\n value,\n onValueChangeHandler,\n open,\n setOpen,\n inputValue,\n setInputValue,\n activeIndex,\n setActiveIndex,\n inputRef,\n handleSelect,\n ]\n );\n\n return (\n <MultiSelectContext value={memoValue}>\n <CommandRoot\n onKeyDown={handleKeyDown}\n className={cn(\n 'flex w-full flex-col gap-2 overflow-visible bg-transparent',\n className\n )}\n dir={dir}\n {...props}\n >\n {children}\n </CommandRoot>\n </MultiSelectContext>\n );\n};\n\nconst MultiSelectTrigger: FC<\n HTMLAttributes<HTMLDivElement> & {\n getBadgeValue?: (value: string) => string;\n validationStyleEnabled?: boolean;\n }\n> = ({\n className,\n getBadgeValue = (value) => value,\n validationStyleEnabled = false,\n children,\n ...props\n}) => {\n const { value, onValueChange, activeIndex } = useMultiSelect();\n\n const mousePreventDefault: MouseEventHandler<HTMLButtonElement> = useCallback(\n (e) => {\n e.preventDefault();\n e.stopPropagation();\n },\n []\n );\n\n return (\n <div\n className={cn(\n 'flex w-full flex-col gap-3 rounded-lg p-1 py-2',\n 'border-input ring-offset-background placeholder:text-muted-foreground focus:ring-ring focus:outline-hidden flex w-full items-center justify-between whitespace-nowrap border px-3 py-2 text-sm focus:ring-1 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',\n 'bg-input-background text-input-text w-full select-text resize-none rounded-xl border-2 px-2 py-1 text-sm shadow-none outline-0 transition-all',\n 'border-input-border hover:border-input-border-hover focus:border-input-border-focus focus:outline-0 focus:[box-shadow:none]',\n 'aria-[invalid=true]:border-error',\n validationStyleEnabled && 'valid:border-success invalid:border-error',\n className\n )}\n {...props}\n >\n {value.length > 0 && (\n <div className=\"flex w-full flex-wrap gap-1\">\n {value.map((item, index) => (\n <Badge\n key={item}\n className={cn(\n 'flex items-center gap-1 rounded-xl px-1',\n activeIndex === index && 'ring-muted-foreground ring-2'\n )}\n color={BadgeColor.TEXT}\n >\n <span className=\"text-xs\">{getBadgeValue(item)}</span>\n <button\n aria-label={`Remove ${item} option`}\n aria-roledescription=\"button to remove option\"\n onMouseDown={mousePreventDefault}\n onClick={() => onValueChange(item)}\n >\n <span className=\"sr-only\">Remove {item} option</span>\n <RemoveIcon className=\"size-4 cursor-pointer\" />\n </button>\n </Badge>\n ))}\n </div>\n )}\n {children}\n </div>\n );\n};\n\nconst MultiSelectInput: FC<ComponentProps<typeof Command.Input>> = ({\n className,\n ...props\n}) => {\n const {\n setOpen,\n inputValue,\n setInputValue,\n activeIndex,\n setActiveIndex,\n handleSelect,\n ref: inputRef,\n } = useMultiSelect();\n\n return (\n <Command.Input\n {...props}\n tabIndex={0}\n ref={inputRef as LegacyRef<HTMLInputElement>}\n value={inputValue}\n onValueChange={activeIndex === -1 ? setInputValue : undefined}\n onSelect={handleSelect}\n onBlur={() => setOpen(false)}\n onFocus={() => setOpen(true)}\n onClick={() => setActiveIndex(-1)}\n className={cn(\n 'outline-hidden ml-2 flex-1 cursor-pointer',\n className,\n activeIndex !== -1 && 'caret-transparent'\n )}\n />\n );\n};\n\nconst MultiSelectContent: FC<HTMLAttributes<HTMLDivElement>> = ({\n children,\n}) => {\n const { open } = useMultiSelect();\n return <div className=\"relative\">{open && children}</div>;\n};\n\nconst MultiSelectList: typeof Command.List = ({ className, children }) => (\n <Command.List\n className={cn(\n 'border-muted bg-input-background absolute top-0 z-10 flex w-full flex-col gap-2 rounded-lg border p-2 shadow-md transition-colors',\n className\n )}\n >\n {children}\n <Command.Empty>\n <span className=\"text-muted-foreground\">No results found</span>\n </Command.Empty>\n </Command.List>\n);\n\nconst MultiSelectItem: FC<\n { value: string } & ComponentProps<typeof Command.Item>\n> = ({ className, value, children, ...props }) => {\n const { value: Options, onValueChange, setInputValue } = useMultiSelect();\n\n const mousePreventDefault: MouseEventHandler<HTMLDivElement> = useCallback(\n (e) => {\n e.preventDefault();\n e.stopPropagation();\n },\n []\n );\n\n const isIncluded = Options.includes(value);\n return (\n <Command.Item\n {...props}\n onSelect={() => {\n onValueChange(value);\n setInputValue('');\n }}\n className={cn(\n 'flex cursor-pointer justify-between rounded-lg px-2 py-1 transition-colors',\n 'hover:bg-neutral/10',\n className,\n isIncluded && 'opacity-50',\n props.disabled && 'cursor-not-allowed opacity-50'\n )}\n onMouseDown={mousePreventDefault}\n >\n {children}\n {isIncluded && <Check className=\"size-4\" />}\n </Command.Item>\n );\n};\n\ntype MultiSelectType = typeof MultiSelectRoot & {\n Trigger: typeof MultiSelectTrigger;\n Input: typeof MultiSelectInput;\n Content: typeof MultiSelectContent;\n List: typeof MultiSelectList;\n Item: typeof MultiSelectItem;\n};\n\n/**\n *\n * Usage example:\n * ```jsx\n * <MultiSelect\n * values={value}\n * onValuesChange={setValue}\n * loop\n * >\n * <MultiSelect.Trigger>\n * <MultiSelect.Input placeholder=\"Select your framework\" />\n * </MultiSelect.Trigger>\n * <MultiSelect.Content>\n * <MultiSelect.List>\n * <MultiSelect.Item value={\"React\"}>React</MultiSelect.Item>\n * <MultiSelect.Item value={\"Vue\"}>Vue</MultiSelect.Item>\n * <MultiSelect.Item value={\"Svelte\"}>Svelte</MultiSelect.Item>\n * </MultiSelect.List>\n * </MultiSelect.Content>\n * </MultiSelect>\n * ```\n */\nexport const MultiSelect = MultiSelectRoot as MultiSelectType;\nMultiSelect.Trigger = MultiSelectTrigger;\nMultiSelect.Input = MultiSelectInput;\nMultiSelect.Content = MultiSelectContent;\nMultiSelect.List = MultiSelectList;\nMultiSelect.Item = MultiSelectItem;\n"],"names":["createContext","useContext","useState","useRef","useEffect","useCallback","useMemo","jsx","CommandRoot","cn","jsxs","Badge","BadgeColor","RemoveIcon","Command","Check"],"mappings":"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"}
|