@intlayer/design-system 7.5.8 → 7.5.10
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/README.md +9 -2
- package/dist/esm/components/Accordion/Accordion.mjs.map +1 -1
- package/dist/esm/components/Avatar/index.mjs.map +1 -1
- package/dist/esm/components/Badge/index.mjs.map +1 -1
- package/dist/esm/components/Breadcrumb/index.mjs.map +1 -1
- package/dist/esm/components/Browser/Browser.mjs.map +1 -1
- package/dist/esm/components/Button/Button.mjs +1 -1
- package/dist/esm/components/Button/Button.mjs.map +1 -1
- package/dist/esm/components/Carousel/index.content.mjs +70 -0
- package/dist/esm/components/Carousel/index.content.mjs.map +1 -0
- package/dist/esm/components/Carousel/index.mjs +271 -0
- package/dist/esm/components/Carousel/index.mjs.map +1 -0
- package/dist/esm/components/CollapsibleTable/CollapsibleTable.mjs.map +1 -1
- package/dist/esm/components/Command/index.mjs.map +1 -1
- package/dist/esm/components/Container/index.mjs +1 -1
- package/dist/esm/components/Container/index.mjs.map +1 -1
- package/dist/esm/components/ContentEditor/ContentEditor.mjs.map +1 -1
- package/dist/esm/components/ContentEditor/ContentEditorTextArea.mjs.map +1 -1
- package/dist/esm/components/CopyToClipboard/index.mjs.map +1 -1
- package/dist/esm/components/DictionaryEditor/ItemLayout.mjs.map +1 -1
- package/dist/esm/components/DictionaryEditor/NodeWrapper/StringWrapper.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/ContentEditorView/TextEditor.mjs +118 -104
- package/dist/esm/components/DictionaryFieldEditor/ContentEditorView/TextEditor.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/DictionaryDetailsForm.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/SaveForm/SaveForm.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/StructureView/StructureView.mjs +1 -1
- package/dist/esm/components/DictionaryFieldEditor/StructureView/StructureView.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/VersionSwitcherDropDown/VersionSwitcher.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/VersionSwitcherDropDown/VersionSwitcherContext.mjs.map +1 -1
- package/dist/esm/components/DropDown/index.mjs.map +1 -1
- package/dist/esm/components/EditableField/EditableFieldLayout.mjs.map +1 -1
- package/dist/esm/components/ExpandCollapse/ExpandCollapse.mjs.map +1 -1
- package/dist/esm/components/Form/FormBase.mjs.map +1 -1
- package/dist/esm/components/Form/FormLabel.mjs.map +1 -1
- package/dist/esm/components/Form/elements/AutoSizeTextAreaElement.mjs.map +1 -1
- package/dist/esm/components/Form/elements/CheckboxElement.mjs.map +1 -1
- package/dist/esm/components/Form/elements/EditableFieldInputElement.mjs.map +1 -1
- package/dist/esm/components/Form/elements/EditableFieldTextAreaElement.mjs.map +1 -1
- package/dist/esm/components/Form/elements/InputElement.mjs.map +1 -1
- package/dist/esm/components/Form/elements/InputPasswordElement.mjs.map +1 -1
- package/dist/esm/components/Form/elements/MultiselectElement.mjs.map +1 -1
- package/dist/esm/components/Form/elements/OTPElement.mjs.map +1 -1
- package/dist/esm/components/Form/elements/SearchInputElement.mjs.map +1 -1
- package/dist/esm/components/Form/elements/SelectElement.mjs.map +1 -1
- package/dist/esm/components/Form/elements/SwitchSelectorElement.mjs.map +1 -1
- package/dist/esm/components/Form/elements/TextAreaElement.mjs.map +1 -1
- package/dist/esm/components/Form/layout/FormLabelLayout.mjs.map +1 -1
- package/dist/esm/components/Headers/index.mjs.map +1 -1
- package/dist/esm/components/HeightResizer/index.mjs +1 -1
- package/dist/esm/components/HeightResizer/index.mjs.map +1 -1
- package/dist/esm/components/HideShow/index.mjs.map +1 -1
- package/dist/esm/components/IDE/Code.mjs.map +1 -1
- package/dist/esm/components/IDE/CodeBlockClient.mjs.map +1 -1
- package/dist/esm/components/IDE/CodeBlockServer.mjs.map +1 -1
- package/dist/esm/components/IDE/CodeContext.mjs.map +1 -1
- package/dist/esm/components/IDE/CodeFormatSelector.mjs +4 -4
- package/dist/esm/components/IDE/CodeFormatSelector.mjs.map +1 -1
- package/dist/esm/components/IDE/ContentDeclarationFormatSelector.mjs +4 -4
- package/dist/esm/components/IDE/ContentDeclarationFormatSelector.mjs.map +1 -1
- package/dist/esm/components/IDE/CopyCode.mjs +1 -1
- package/dist/esm/components/IDE/FileTree.mjs.map +1 -1
- package/dist/esm/components/IDE/IDE.mjs.map +1 -1
- package/dist/esm/components/IDE/MonacoCode.mjs.map +1 -1
- package/dist/esm/components/IDE/PackageManagerSelector.mjs +5 -4
- package/dist/esm/components/IDE/PackageManagerSelector.mjs.map +1 -1
- package/dist/esm/components/IDE/selectors.content.mjs +120 -57
- package/dist/esm/components/IDE/selectors.content.mjs.map +1 -1
- package/dist/esm/components/InformationTag/index.mjs.map +1 -1
- package/dist/esm/components/Input/Checkbox.mjs.map +1 -1
- package/dist/esm/components/Input/OTPInput.mjs.map +1 -1
- package/dist/esm/components/Input/SearchInput.mjs.map +1 -1
- package/dist/esm/components/KeyboardScreenAdapter/index.mjs.map +1 -1
- package/dist/esm/components/KeyboardShortcut/KeyboardShortcut.mjs +5 -3
- package/dist/esm/components/KeyboardShortcut/KeyboardShortcut.mjs.map +1 -1
- package/dist/esm/components/Label/index.mjs.map +1 -1
- package/dist/esm/components/LanguageBackground/index.mjs +88 -0
- package/dist/esm/components/LanguageBackground/index.mjs.map +1 -0
- package/dist/esm/components/Link/Link.mjs +10 -53
- package/dist/esm/components/Link/Link.mjs.map +1 -1
- package/dist/esm/components/Loader/index.mjs.map +1 -1
- package/dist/esm/components/Loader/spinner.mjs.map +1 -1
- package/dist/esm/components/LocaleSwitcherContentDropDown/LocaleSwitcherContent.mjs.map +1 -1
- package/dist/esm/components/LocaleSwitcherContentDropDown/LocaleSwitcherContentContext.mjs.map +1 -1
- package/dist/esm/components/LocaleSwitcherDropDown/LocaleSwitcher.mjs +2 -0
- package/dist/esm/components/LocaleSwitcherDropDown/LocaleSwitcher.mjs.map +1 -1
- package/dist/esm/components/MarkDownRender/MarkDownRender.mjs.map +1 -1
- package/dist/esm/components/MaxHeightSmoother/index.mjs.map +1 -1
- package/dist/esm/components/MaxWidthSmoother/index.mjs.map +1 -1
- package/dist/esm/components/Modal/Modal.mjs +2 -2
- package/dist/esm/components/Modal/Modal.mjs.map +1 -1
- package/dist/esm/components/Navbar/Burger.mjs.map +1 -1
- package/dist/esm/components/Navbar/MobileNavbar.mjs.map +1 -1
- package/dist/esm/components/Navbar/index.mjs.map +1 -1
- package/dist/esm/components/Pagination/Pagination.mjs.map +1 -1
- package/dist/esm/components/Pattern/DotPattern.mjs.map +1 -1
- package/dist/esm/components/Pattern/GridPattern.mjs.map +1 -1
- package/dist/esm/components/Pattern/SpotLight.mjs.map +1 -1
- package/dist/esm/components/Popover/static.mjs.map +1 -1
- package/dist/esm/components/PressableSpan/PressableSpan.mjs.map +1 -1
- package/dist/esm/components/RightDrawer/RightDrawer.mjs +2 -2
- package/dist/esm/components/RightDrawer/RightDrawer.mjs.map +1 -1
- package/dist/esm/components/Select/Multiselect.mjs.map +1 -1
- package/dist/esm/components/Select/Select.mjs +1 -1
- package/dist/esm/components/Select/Select.mjs.map +1 -1
- package/dist/esm/components/SwitchSelector/index.mjs.map +1 -1
- package/dist/esm/components/Tab/Tab.mjs.map +1 -1
- package/dist/esm/components/TabSelector/TabSelector.mjs +1 -1
- package/dist/esm/components/TabSelector/TabSelector.mjs.map +1 -1
- package/dist/esm/components/Table/Table.mjs.map +1 -1
- package/dist/esm/components/Tag/index.mjs +2 -0
- package/dist/esm/components/Tag/index.mjs.map +1 -1
- package/dist/esm/components/Terminal/Terminal.mjs +2 -0
- package/dist/esm/components/Terminal/Terminal.mjs.map +1 -1
- package/dist/esm/components/TextArea/AutoSizeTextArea.mjs.map +1 -1
- package/dist/esm/components/TextArea/AutocompleteTextArea.mjs.map +1 -1
- package/dist/esm/components/TextArea/TextArea.mjs.map +1 -1
- package/dist/esm/components/ThemeSwitcherDropDown/MobileThemeSwitcher.mjs.map +1 -1
- package/dist/esm/components/Toaster/Toast.mjs.map +1 -1
- package/dist/esm/components/WithResizer/index.mjs +1 -1
- package/dist/esm/components/WithResizer/index.mjs.map +1 -1
- package/dist/esm/components/index.mjs +6 -4
- package/dist/esm/hooks/index.mjs +7 -7
- package/dist/esm/hooks/reactQuery.mjs +42 -3
- package/dist/esm/hooks/reactQuery.mjs.map +1 -1
- package/dist/esm/hooks/useAuth/useSession.mjs +2 -2
- package/dist/esm/hooks/useAuth/useSession.mjs.map +1 -1
- package/dist/esm/providers/ReactQueryProvider.mjs +2 -2
- package/dist/esm/providers/ReactQueryProvider.mjs.map +1 -1
- package/dist/types/components/Badge/index.d.ts +2 -2
- package/dist/types/components/Breadcrumb/breadcrumb.content.d.ts +3 -3
- package/dist/types/components/Breadcrumb/index.d.ts +2 -2
- package/dist/types/components/Breadcrumb/index.d.ts.map +1 -1
- package/dist/types/components/Browser/Browser.d.ts +2 -2
- package/dist/types/components/Browser/Browser.d.ts.map +1 -1
- package/dist/types/components/Browser/browser.content.d.ts +17 -17
- package/dist/types/components/Browser/browser.content.d.ts.map +1 -1
- package/dist/types/components/Button/Button.d.ts +7 -7
- package/dist/types/components/Button/Button.d.ts.map +1 -1
- package/dist/types/components/Carousel/index.content.d.ts +135 -0
- package/dist/types/components/Carousel/index.content.d.ts.map +1 -0
- package/dist/types/components/Carousel/index.d.ts +21 -0
- package/dist/types/components/Carousel/index.d.ts.map +1 -0
- package/dist/types/components/CollapsibleTable/CollapsibleTable.d.ts +1 -1
- package/dist/types/components/CollapsibleTable/CollapsibleTable.d.ts.map +1 -1
- package/dist/types/components/Command/index.d.ts +16 -16
- package/dist/types/components/Command/index.d.ts.map +1 -1
- package/dist/types/components/Container/index.d.ts +7 -7
- package/dist/types/components/Container/index.d.ts.map +1 -1
- package/dist/types/components/CopyButton/CopyButton.content.d.ts +3 -3
- package/dist/types/components/CopyButton/CopyButton.content.d.ts.map +1 -1
- package/dist/types/components/DictionaryFieldEditor/ContentEditorView/TextEditor.d.ts.map +1 -1
- package/dist/types/components/DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.d.ts.map +1 -1
- package/dist/types/components/DictionaryFieldEditor/DictionaryCreationForm/dictionaryCreationForm.content.d.ts +25 -25
- package/dist/types/components/DictionaryFieldEditor/DictionaryCreationForm/useDictionaryFormSchema.content.d.ts +9 -9
- package/dist/types/components/DictionaryFieldEditor/DictionaryCreationForm/useDictionaryFormSchema.content.d.ts.map +1 -1
- package/dist/types/components/DictionaryFieldEditor/DictionaryDetails/DictionaryDetailsForm.d.ts.map +1 -1
- package/dist/types/components/DictionaryFieldEditor/DictionaryDetails/dictionaryDetails.content.d.ts +33 -33
- package/dist/types/components/DictionaryFieldEditor/DictionaryDetails/useDictionaryDetailsSchema.content.d.ts +25 -25
- package/dist/types/components/DictionaryFieldEditor/NavigationView/navigationViewNode.content.d.ts +25 -25
- package/dist/types/components/DictionaryFieldEditor/NavigationView/navigationViewNode.content.d.ts.map +1 -1
- package/dist/types/components/DictionaryFieldEditor/SaveForm/saveForm.content.d.ts +33 -33
- package/dist/types/components/DictionaryFieldEditor/StructureView/StructureView.d.ts.map +1 -1
- package/dist/types/components/DictionaryFieldEditor/StructureView/structureView.content.d.ts +9 -9
- package/dist/types/components/DictionaryFieldEditor/VersionSwitcherDropDown/VersionSwitcher.d.ts +1 -1
- package/dist/types/components/DictionaryFieldEditor/VersionSwitcherDropDown/versionSwitcherDropDown.content.d.ts +7 -7
- package/dist/types/components/DictionaryFieldEditor/VersionSwitcherDropDown/versionSwitcherDropDown.content.d.ts.map +1 -1
- package/dist/types/components/DictionaryFieldEditor/dictionaryFieldEditor.content.d.ts +5 -5
- package/dist/types/components/DictionaryFieldEditor/nodeTypeSelector.content.d.ts +31 -31
- package/dist/types/components/ExpandCollapse/expandCollapse.content.d.ts +4 -4
- package/dist/types/components/Form/FormBase.d.ts +2 -2
- package/dist/types/components/Form/FormBase.d.ts.map +1 -1
- package/dist/types/components/Form/FormField.d.ts +2 -2
- package/dist/types/components/Form/FormField.d.ts.map +1 -1
- package/dist/types/components/Form/FormItem.d.ts +2 -2
- package/dist/types/components/Form/FormItem.d.ts.map +1 -1
- package/dist/types/components/Form/elements/AutoSizeTextAreaElement.d.ts +1 -1
- package/dist/types/components/Form/elements/CheckboxElement.d.ts +1 -2
- package/dist/types/components/Form/elements/CheckboxElement.d.ts.map +1 -1
- package/dist/types/components/Form/elements/EditableFieldInputElement.d.ts +3 -3
- package/dist/types/components/Form/elements/EditableFieldInputElement.d.ts.map +1 -1
- package/dist/types/components/Form/elements/EditableFieldTextAreaElement.d.ts +3 -3
- package/dist/types/components/Form/elements/EditableFieldTextAreaElement.d.ts.map +1 -1
- package/dist/types/components/Form/elements/FormElement.d.ts +2 -2
- package/dist/types/components/Form/elements/FormElement.d.ts.map +1 -1
- package/dist/types/components/Form/elements/InputElement.d.ts +1 -2
- package/dist/types/components/Form/elements/InputElement.d.ts.map +1 -1
- package/dist/types/components/Form/elements/InputPasswordElement.d.ts +1 -2
- package/dist/types/components/Form/elements/InputPasswordElement.d.ts.map +1 -1
- package/dist/types/components/Form/elements/MultiselectElement.d.ts +3 -3
- package/dist/types/components/Form/elements/OTPElement.d.ts +3 -3
- package/dist/types/components/Form/elements/OTPElement.d.ts.map +1 -1
- package/dist/types/components/Form/elements/SearchInputElement.d.ts +1 -2
- package/dist/types/components/Form/elements/SearchInputElement.d.ts.map +1 -1
- package/dist/types/components/Form/elements/SelectElement.d.ts +3 -3
- package/dist/types/components/Form/elements/SwitchSelectorElement.d.ts +3 -3
- package/dist/types/components/Form/elements/TextAreaElement.d.ts +1 -1
- package/dist/types/components/HeightResizer/index.d.ts.map +1 -1
- package/dist/types/components/IDE/CodeContext.d.ts +2 -2
- package/dist/types/components/IDE/code.content.d.ts +5 -5
- package/dist/types/components/IDE/code.content.d.ts.map +1 -1
- package/dist/types/components/IDE/copyCode.content.d.ts +5 -5
- package/dist/types/components/IDE/selectors.content.d.ts +130 -7
- package/dist/types/components/IDE/selectors.content.d.ts.map +1 -1
- package/dist/types/components/InformationTag/index.d.ts.map +1 -1
- package/dist/types/components/Input/Checkbox.d.ts +3 -3
- package/dist/types/components/Input/Checkbox.d.ts.map +1 -1
- package/dist/types/components/Input/Input.d.ts +2 -2
- package/dist/types/components/Input/OTPInput.d.ts +6 -6
- package/dist/types/components/Input/OTPInput.d.ts.map +1 -1
- package/dist/types/components/Input/SearchInput.d.ts +2 -2
- package/dist/types/components/KeyboardShortcut/KeyboardShortcut.d.ts +2 -0
- package/dist/types/components/KeyboardShortcut/KeyboardShortcut.d.ts.map +1 -1
- package/dist/types/components/LanguageBackground/index.d.ts +8 -0
- package/dist/types/components/LanguageBackground/index.d.ts.map +1 -0
- package/dist/types/components/Link/Link.d.ts +5 -91
- package/dist/types/components/Link/Link.d.ts.map +1 -1
- package/dist/types/components/Loader/index.content.d.ts +3 -3
- package/dist/types/components/Loader/index.content.d.ts.map +1 -1
- package/dist/types/components/Loader/spinner.d.ts +2 -2
- package/dist/types/components/Loader/spinner.d.ts.map +1 -1
- package/dist/types/components/LocaleSwitcherContentDropDown/localeSwitcher.content.d.ts +17 -17
- package/dist/types/components/LocaleSwitcherContentDropDown/localeSwitcher.content.d.ts.map +1 -1
- package/dist/types/components/LocaleSwitcherDropDown/localeSwitcher.content.d.ts +13 -13
- package/dist/types/components/LocaleSwitcherDropDown/localeSwitcher.content.d.ts.map +1 -1
- package/dist/types/components/MaxHeightSmoother/index.d.ts.map +1 -1
- package/dist/types/components/MaxWidthSmoother/index.d.ts +2 -2
- package/dist/types/components/MaxWidthSmoother/index.d.ts.map +1 -1
- package/dist/types/components/Navbar/Burger.d.ts +2 -2
- package/dist/types/components/Navbar/Burger.d.ts.map +1 -1
- package/dist/types/components/Navbar/DesktopNavbar.d.ts +2 -2
- package/dist/types/components/Navbar/MobileNavbar.d.ts +2 -2
- package/dist/types/components/Navbar/MobileNavbar.d.ts.map +1 -1
- package/dist/types/components/Navbar/index.d.ts +2 -2
- package/dist/types/components/Navbar/index.d.ts.map +1 -1
- package/dist/types/components/Pagination/Pagination.d.ts +1 -1
- package/dist/types/components/Pagination/Pagination.d.ts.map +1 -1
- package/dist/types/components/Pagination/pagination.content.d.ts +11 -11
- package/dist/types/components/Pattern/DotPattern.d.ts.map +1 -1
- package/dist/types/components/Pattern/GridPattern.d.ts.map +1 -1
- package/dist/types/components/Pattern/SpotLight.d.ts.map +1 -1
- package/dist/types/components/PressableSpan/PressableSpan.d.ts.map +1 -1
- package/dist/types/components/RightDrawer/RightDrawer.d.ts.map +1 -1
- package/dist/types/components/RightDrawer/rightDrawer.content.d.ts +5 -5
- package/dist/types/components/RightDrawer/rightDrawer.content.d.ts.map +1 -1
- package/dist/types/components/Select/Select.d.ts +3 -3
- package/dist/types/components/SocialNetworks/index.d.ts +2 -2
- package/dist/types/components/SocialNetworks/index.d.ts.map +1 -1
- package/dist/types/components/SwitchSelector/index.d.ts +2 -2
- package/dist/types/components/SwitchSelector/index.d.ts.map +1 -1
- package/dist/types/components/Tab/Tab.d.ts +5 -5
- package/dist/types/components/Tab/Tab.d.ts.map +1 -1
- package/dist/types/components/Tab/TabContext.d.ts +2 -2
- package/dist/types/components/Tab/TabContext.d.ts.map +1 -1
- package/dist/types/components/TabSelector/TabSelector.d.ts +6 -6
- package/dist/types/components/TabSelector/TabSelector.d.ts.map +1 -1
- package/dist/types/components/Table/Table.d.ts.map +1 -1
- package/dist/types/components/Table/table.content.d.ts +3 -3
- package/dist/types/components/Table/table.content.d.ts.map +1 -1
- package/dist/types/components/Tag/index.d.ts +6 -5
- package/dist/types/components/Tag/index.d.ts.map +1 -1
- package/dist/types/components/Terminal/Terminal.d.ts.map +1 -1
- package/dist/types/components/Terminal/terminal.content.d.ts +5 -5
- package/dist/types/components/Terminal/terminal.content.d.ts.map +1 -1
- package/dist/types/components/Toaster/Toast.d.ts +2 -2
- package/dist/types/components/Toaster/Toast.d.ts.map +1 -1
- package/dist/types/components/Toaster/Toaster.d.ts +2 -2
- package/dist/types/components/Toaster/Toaster.d.ts.map +1 -1
- package/dist/types/components/WithResizer/index.d.ts.map +1 -1
- package/dist/types/components/index.d.ts +7 -5
- package/dist/types/hooks/index.d.ts +3 -3
- package/dist/types/hooks/reactQuery.d.ts +9 -1
- package/dist/types/hooks/reactQuery.d.ts.map +1 -1
- package/dist/types/hooks/useItemSelector.d.ts.map +1 -1
- package/package.json +17 -17
|
@@ -4,63 +4,126 @@ import { t } from "intlayer";
|
|
|
4
4
|
const selectorsContent = {
|
|
5
5
|
key: "code-selectors",
|
|
6
6
|
content: {
|
|
7
|
-
packageManager: {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
7
|
+
packageManager: {
|
|
8
|
+
placeholder: t({
|
|
9
|
+
en: "Package Manager",
|
|
10
|
+
es: "Gestor de paquetes",
|
|
11
|
+
pt: "Gerenciador de pacotes",
|
|
12
|
+
fr: "Gestionnaire de paquets",
|
|
13
|
+
de: "Paketmanager",
|
|
14
|
+
it: "Gestore dei pacchetti",
|
|
15
|
+
ja: "パッケージマネージャー",
|
|
16
|
+
ko: "패키지 관리자",
|
|
17
|
+
zh: "包管理器",
|
|
18
|
+
hi: "पैकेज प्रबंधक",
|
|
19
|
+
"en-GB": "Package Manager",
|
|
20
|
+
ru: "Менеджер пакетов",
|
|
21
|
+
ar: "مدير الحزم",
|
|
22
|
+
tr: "Paket yöneticisi",
|
|
23
|
+
pl: "Menedżer pakietów",
|
|
24
|
+
id: "Pengelola paket",
|
|
25
|
+
vi: "Trình quản lý gói"
|
|
26
|
+
}),
|
|
27
|
+
label: t({
|
|
28
|
+
en: "Select package manager",
|
|
29
|
+
es: "Seleccionar gestor de paquetes",
|
|
30
|
+
pt: "Selecionar gerenciador de pacotes",
|
|
31
|
+
fr: "Sélectionner le gestionnaire de paquets",
|
|
32
|
+
de: "Paketmanager auswählen",
|
|
33
|
+
it: "Seleziona il gestore dei pacchetti",
|
|
34
|
+
ja: "パッケージマネージャーを選択",
|
|
35
|
+
ko: "패키지 관리자 선택",
|
|
36
|
+
zh: "选择包管理器",
|
|
37
|
+
hi: "पैकेज प्रबंधक चुनें",
|
|
38
|
+
"en-GB": "Select package manager",
|
|
39
|
+
ru: "Выбрать менеджер пакетов",
|
|
40
|
+
ar: "اختر مدير الحزم",
|
|
41
|
+
tr: "Paket yöneticisi seç",
|
|
42
|
+
pl: "Wybierz menedżera pakietów",
|
|
43
|
+
id: "Pilih pengelola paket",
|
|
44
|
+
vi: "Chọn trình quản lý gói"
|
|
45
|
+
})
|
|
46
|
+
},
|
|
47
|
+
codeFormat: {
|
|
48
|
+
placeholder: t({
|
|
49
|
+
en: "Code Format",
|
|
50
|
+
es: "Formato de código",
|
|
51
|
+
pt: "Formato de código",
|
|
52
|
+
fr: "Format de code",
|
|
53
|
+
de: "Code-Format",
|
|
54
|
+
it: "Formato del codice",
|
|
55
|
+
ja: "コード形式",
|
|
56
|
+
ko: "코드 형식",
|
|
57
|
+
zh: "代码格式",
|
|
58
|
+
hi: "कोड प्रारूप",
|
|
59
|
+
"en-GB": "Code Format",
|
|
60
|
+
ru: "Формат кода",
|
|
61
|
+
ar: "تنسيق الكود",
|
|
62
|
+
tr: "Kod formatı",
|
|
63
|
+
pl: "Format kodu",
|
|
64
|
+
id: "Format kode",
|
|
65
|
+
vi: "Định dạng mã"
|
|
66
|
+
}),
|
|
67
|
+
label: t({
|
|
68
|
+
en: "Select code format",
|
|
69
|
+
es: "Seleccionar formato de código",
|
|
70
|
+
pt: "Selecionar formato de código",
|
|
71
|
+
fr: "Sélectionner le format de code",
|
|
72
|
+
de: "Code-Format auswählen",
|
|
73
|
+
it: "Seleziona il formato del codice",
|
|
74
|
+
ja: "コード形式を選択",
|
|
75
|
+
ko: "코드 형식 선택",
|
|
76
|
+
zh: "选择代码格式",
|
|
77
|
+
hi: "कोड प्रारूप चुनें",
|
|
78
|
+
"en-GB": "Select code format",
|
|
79
|
+
ru: "Выбрать формат кода",
|
|
80
|
+
ar: "اختر تنسيق الكود",
|
|
81
|
+
tr: "Kod formatı seç",
|
|
82
|
+
pl: "Wybierz format kodu",
|
|
83
|
+
id: "Pilih format kode",
|
|
84
|
+
vi: "Chọn định dạng mã"
|
|
85
|
+
})
|
|
86
|
+
},
|
|
87
|
+
contentDeclarationFormat: {
|
|
88
|
+
placeholder: t({
|
|
89
|
+
en: "Dictionary Format",
|
|
90
|
+
es: "Formato de diccionario",
|
|
91
|
+
pt: "Formato de dicionário",
|
|
92
|
+
fr: "Format de dictionnaire",
|
|
93
|
+
de: "Wörterbuchformat",
|
|
94
|
+
it: "Formato del dizionario",
|
|
95
|
+
ja: "辞書形式",
|
|
96
|
+
ko: "사전 형식",
|
|
97
|
+
zh: "字典格式",
|
|
98
|
+
hi: "शब्दकोश प्रारूप",
|
|
99
|
+
"en-GB": "Dictionary Format",
|
|
100
|
+
ru: "Формат словаря",
|
|
101
|
+
ar: "تنسيق القاموس",
|
|
102
|
+
tr: "Sözlük formatı",
|
|
103
|
+
pl: "Format słownika",
|
|
104
|
+
id: "Format kamus",
|
|
105
|
+
vi: "Định dạng từ điển"
|
|
106
|
+
}),
|
|
107
|
+
label: t({
|
|
108
|
+
en: "Select dictionary format",
|
|
109
|
+
es: "Seleccionar formato de diccionario",
|
|
110
|
+
pt: "Selecionar formato de dicionário",
|
|
111
|
+
fr: "Sélectionner le format de dictionnaire",
|
|
112
|
+
de: "Wörterbuchformat auswählen",
|
|
113
|
+
it: "Seleziona il formato del dizionario",
|
|
114
|
+
ja: "辞書形式を選択",
|
|
115
|
+
ko: "사전 형식 선택",
|
|
116
|
+
zh: "选择字典格式",
|
|
117
|
+
hi: "शब्दकोश प्रारूप चुनें",
|
|
118
|
+
"en-GB": "Select dictionary format",
|
|
119
|
+
ru: "Выбрать формат словаря",
|
|
120
|
+
ar: "اختر تنسيق القاموس",
|
|
121
|
+
tr: "Sözlük formatı seç",
|
|
122
|
+
pl: "Wybierz format słownika",
|
|
123
|
+
id: "Pilih format kamus",
|
|
124
|
+
vi: "Chọn định dạng từ điển"
|
|
125
|
+
})
|
|
126
|
+
}
|
|
64
127
|
},
|
|
65
128
|
title: "Code selector accessibility labels",
|
|
66
129
|
description: "Accessible labels for code block selector buttons used by screen readers.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.content.mjs","names":[],"sources":["../../../../src/components/IDE/selectors.content.ts"],"sourcesContent":["import { type Dictionary, t } from 'intlayer';\n\nconst selectorsContent = {\n key: 'code-selectors',\n content: {\n packageManager: {\n label: t({\n en: 'Select package manager',\n es: 'Seleccionar gestor de paquetes',\n pt: 'Selecionar gerenciador de pacotes',\n fr: 'Sélectionner le gestionnaire de paquets',\n de: 'Paketmanager auswählen',\n it: 'Seleziona il gestore dei pacchetti',\n ja: 'パッケージマネージャーを選択',\n ko: '패키지 관리자 선택',\n zh: '选择包管理器',\n hi: 'पैकेज प्रबंधक चुनें',\n 'en-GB': 'Select package manager',\n ru: 'Выбрать менеджер пакетов',\n ar: 'اختر مدير الحزم',\n tr: 'Paket yöneticisi seç',\n pl: 'Wybierz menedżera pakietów',\n id: 'Pilih pengelola paket',\n vi: 'Chọn trình quản lý gói',\n }),\n },\n codeFormat: {\n label: t({\n en: 'Select code format',\n es: 'Seleccionar formato de código',\n pt: 'Selecionar formato de código',\n fr: 'Sélectionner le format de code',\n de: 'Code-Format auswählen',\n it: 'Seleziona il formato del codice',\n ja: 'コード形式を選択',\n ko: '코드 형식 선택',\n zh: '选择代码格式',\n hi: 'कोड प्रारूप चुनें',\n 'en-GB': 'Select code format',\n ru: 'Выбрать формат кода',\n ar: 'اختر تنسيق الكود',\n tr: 'Kod formatı seç',\n pl: 'Wybierz format kodu',\n id: 'Pilih format kode',\n vi: 'Chọn định dạng mã',\n }),\n },\n contentDeclarationFormat: {\n label: t({\n en: 'Select dictionary format',\n es: 'Seleccionar formato de diccionario',\n pt: 'Selecionar formato de dicionário',\n fr: 'Sélectionner le format de dictionnaire',\n de: 'Wörterbuchformat auswählen',\n it: 'Seleziona il formato del dizionario',\n ja: '辞書形式を選択',\n ko: '사전 형식 선택',\n zh: '选择字典格式',\n hi: 'शब्दकोश प्रारूप चुनें',\n 'en-GB': 'Select dictionary format',\n ru: 'Выбрать формат словаря',\n ar: 'اختر تنسيق القاموس',\n tr: 'Sözlük formatı seç',\n pl: 'Wybierz format słownika',\n id: 'Pilih format kamus',\n vi: 'Chọn định dạng từ điển',\n }),\n },\n },\n title: 'Code selector accessibility labels',\n description:\n 'Accessible labels for code block selector buttons used by screen readers.',\n tags: ['accessibility', 'code block', 'design system'],\n} satisfies Dictionary;\n\nexport default selectorsContent;\n"],"mappings":";;;AAEA,MAAM,mBAAmB;CACvB,KAAK;CACL,SAAS;EACP,gBAAgB,
|
|
1
|
+
{"version":3,"file":"selectors.content.mjs","names":[],"sources":["../../../../src/components/IDE/selectors.content.ts"],"sourcesContent":["import { type Dictionary, t } from 'intlayer';\n\nconst selectorsContent = {\n key: 'code-selectors',\n content: {\n packageManager: {\n placeholder: t({\n en: 'Package Manager',\n es: 'Gestor de paquetes',\n pt: 'Gerenciador de pacotes',\n fr: 'Gestionnaire de paquets',\n de: 'Paketmanager',\n it: 'Gestore dei pacchetti',\n ja: 'パッケージマネージャー',\n ko: '패키지 관리자',\n zh: '包管理器',\n hi: 'पैकेज प्रबंधक',\n 'en-GB': 'Package Manager',\n ru: 'Менеджер пакетов',\n ar: 'مدير الحزم',\n tr: 'Paket yöneticisi',\n pl: 'Menedżer pakietów',\n id: 'Pengelola paket',\n vi: 'Trình quản lý gói',\n }),\n label: t({\n en: 'Select package manager',\n es: 'Seleccionar gestor de paquetes',\n pt: 'Selecionar gerenciador de pacotes',\n fr: 'Sélectionner le gestionnaire de paquets',\n de: 'Paketmanager auswählen',\n it: 'Seleziona il gestore dei pacchetti',\n ja: 'パッケージマネージャーを選択',\n ko: '패키지 관리자 선택',\n zh: '选择包管理器',\n hi: 'पैकेज प्रबंधक चुनें',\n 'en-GB': 'Select package manager',\n ru: 'Выбрать менеджер пакетов',\n ar: 'اختر مدير الحزم',\n tr: 'Paket yöneticisi seç',\n pl: 'Wybierz menedżera pakietów',\n id: 'Pilih pengelola paket',\n vi: 'Chọn trình quản lý gói',\n }),\n },\n codeFormat: {\n placeholder: t({\n en: 'Code Format',\n es: 'Formato de código',\n pt: 'Formato de código',\n fr: 'Format de code',\n de: 'Code-Format',\n it: 'Formato del codice',\n ja: 'コード形式',\n ko: '코드 형식',\n zh: '代码格式',\n hi: 'कोड प्रारूप',\n 'en-GB': 'Code Format',\n ru: 'Формат кода',\n ar: 'تنسيق الكود',\n tr: 'Kod formatı',\n pl: 'Format kodu',\n id: 'Format kode',\n vi: 'Định dạng mã',\n }),\n label: t({\n en: 'Select code format',\n es: 'Seleccionar formato de código',\n pt: 'Selecionar formato de código',\n fr: 'Sélectionner le format de code',\n de: 'Code-Format auswählen',\n it: 'Seleziona il formato del codice',\n ja: 'コード形式を選択',\n ko: '코드 형식 선택',\n zh: '选择代码格式',\n hi: 'कोड प्रारूप चुनें',\n 'en-GB': 'Select code format',\n ru: 'Выбрать формат кода',\n ar: 'اختر تنسيق الكود',\n tr: 'Kod formatı seç',\n pl: 'Wybierz format kodu',\n id: 'Pilih format kode',\n vi: 'Chọn định dạng mã',\n }),\n },\n contentDeclarationFormat: {\n placeholder: t({\n en: 'Dictionary Format',\n es: 'Formato de diccionario',\n pt: 'Formato de dicionário',\n fr: 'Format de dictionnaire',\n de: 'Wörterbuchformat',\n it: 'Formato del dizionario',\n ja: '辞書形式',\n ko: '사전 형식',\n zh: '字典格式',\n hi: 'शब्दकोश प्रारूप',\n 'en-GB': 'Dictionary Format',\n ru: 'Формат словаря',\n ar: 'تنسيق القاموس',\n tr: 'Sözlük formatı',\n pl: 'Format słownika',\n id: 'Format kamus',\n vi: 'Định dạng từ điển',\n }),\n label: t({\n en: 'Select dictionary format',\n es: 'Seleccionar formato de diccionario',\n pt: 'Selecionar formato de dicionário',\n fr: 'Sélectionner le format de dictionnaire',\n de: 'Wörterbuchformat auswählen',\n it: 'Seleziona il formato del dizionario',\n ja: '辞書形式を選択',\n ko: '사전 형식 선택',\n zh: '选择字典格式',\n hi: 'शब्दकोश प्रारूप चुनें',\n 'en-GB': 'Select dictionary format',\n ru: 'Выбрать формат словаря',\n ar: 'اختر تنسيق القاموس',\n tr: 'Sözlük formatı seç',\n pl: 'Wybierz format słownika',\n id: 'Pilih format kamus',\n vi: 'Chọn định dạng từ điển',\n }),\n },\n },\n title: 'Code selector accessibility labels',\n description:\n 'Accessible labels for code block selector buttons used by screen readers.',\n tags: ['accessibility', 'code block', 'design system'],\n} satisfies Dictionary;\n\nexport default selectorsContent;\n"],"mappings":";;;AAEA,MAAM,mBAAmB;CACvB,KAAK;CACL,SAAS;EACP,gBAAgB;GACd,aAAa,EAAE;IACb,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,SAAS;IACT,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACL,CAAC;GACF,OAAO,EAAE;IACP,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,SAAS;IACT,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACL,CAAC;GACH;EACD,YAAY;GACV,aAAa,EAAE;IACb,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,SAAS;IACT,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACL,CAAC;GACF,OAAO,EAAE;IACP,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,SAAS;IACT,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACL,CAAC;GACH;EACD,0BAA0B;GACxB,aAAa,EAAE;IACb,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,SAAS;IACT,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACL,CAAC;GACF,OAAO,EAAE;IACP,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,SAAS;IACT,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACL,CAAC;GACH;EACF;CACD,OAAO;CACP,aACE;CACF,MAAM;EAAC;EAAiB;EAAc;EAAgB;CACvD;AAED,gCAAe"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["InformationTag: FC<CopiedTextInformationProps>"],"sources":["../../../../src/components/InformationTag/index.tsx"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["InformationTag: FC<CopiedTextInformationProps>"],"sources":["../../../../src/components/InformationTag/index.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport type { DetailedHTMLProps, FC } from 'react';\n\n/**\n * Props for the InformationTag component.\n * Extends standard HTML element attributes for maximum flexibility.\n */\ntype CopiedTextInformationProps = DetailedHTMLProps<\n React.HTMLAttributes<HTMLElement>,\n HTMLElement\n>;\n\n/**\n * InformationTag Component\n *\n * A lightweight component that displays informational text with a distinctive info icon (ⓘ).\n * Perfect for showing contextual hints, supplementary information, or subtle guidance text.\n *\n * @component\n * @example\n * Basic usage:\n * ```tsx\n * <InformationTag>This field is required</InformationTag>\n * ```\n *\n * @example\n * With custom styling:\n * ```tsx\n * <InformationTag className=\"text-blue-600 font-medium\">\n * Pro tip: Use keyboard shortcuts for faster navigation\n * </InformationTag>\n * ```\n *\n * @example\n * Form field context:\n * ```tsx\n * <div>\n * <input type=\"email\" placeholder=\"your@email.com\" />\n * <InformationTag>We'll never share your email address</InformationTag>\n * </div>\n * ```\n *\n * @example\n * Status information:\n * ```tsx\n * <InformationTag className=\"text-green-500\">\n * Changes saved automatically\n * </InformationTag>\n * ```\n *\n * Features:\n * - Lightweight and semantic HTML structure using <i> tag\n * - Distinctive info icon (ⓘ) for visual recognition\n * - Default subtle styling with neutral colors\n * - Fully customizable with className overrides\n * - Supports all standard HTML element attributes\n * - Screen reader friendly with meaningful semantic content\n *\n * Accessibility:\n * - Uses semantic <i> tag which is announced by screen readers\n * - Info icon (ⓘ) provides visual context for sighted users\n * - Text content is fully accessible and readable\n * - Supports ARIA attributes through props spreading\n *\n * @param props - Component props extending HTML element attributes\n * @param props.children - The informational text content to display\n * @param props.className - Additional CSS classes for custom styling\n * @param props.title - Optional tooltip text (HTML title attribute)\n * @param props.role - ARIA role (defaults to implicit role from <i> tag)\n * @param props.aria-label - ARIA label for screen readers\n * @param props.id - Unique identifier for the element\n * @param props.onClick - Click event handler\n * @param props.onMouseEnter - Mouse enter event handler\n * @param props.onMouseLeave - Mouse leave event handler\n * @param props.style - Inline styles object\n * @param props.data-* - Data attributes for testing or tracking\n * @param props...rest - All other standard HTML element attributes\n *\n * @returns A rendered information tag with icon and text content\n */\nexport const InformationTag: FC<CopiedTextInformationProps> = ({\n className,\n children,\n ...props\n}) => (\n <i className={cn('text-neutral-400 text-xs', className)} {...props}>\n ⓘ {children}\n </i>\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA,MAAaA,kBAAkD,EAC7D,WACA,UACA,GAAG,YAEH,qBAAC;CAAE,WAAW,GAAG,4BAA4B,UAAU;CAAE,GAAI;YAAO,MAC/D;EACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkbox.mjs","names":["Input: FC<CheckboxProps>","Checkbox: FC<CheckboxProps>"],"sources":["../../../../src/components/Input/Checkbox.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type {\n DetailedHTMLProps,\n FC,\n InputHTMLAttributes,\n ReactNode,\n} from 'react';\
|
|
1
|
+
{"version":3,"file":"Checkbox.mjs","names":["Input: FC<CheckboxProps>","Checkbox: FC<CheckboxProps>"],"sources":["../../../../src/components/Input/Checkbox.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type {\n DetailedHTMLProps,\n FC,\n InputHTMLAttributes,\n ReactNode,\n} from 'react';\n\nexport const checkboxVariants = cva(\n [\n 'appearance-none',\n 'pointer relative border-2',\n 'focus:outline-0',\n 'checked:border-current checked:bg-current checked:hover:bg-current/80',\n 'ring-current/20 ring-offset-current',\n 'hover:bg-current/20',\n 'disabled:opacity-50',\n\n // Ring + animation\n 'ring-0 transition-all duration-300 ease-in-out hover:ring-4 focus-visible:ring-6',\n\n // centered custom checkmark with text-opposite color\n \"checked:before:absolute checked:before:inset-0 checked:before:content-['✓']\",\n 'checked:before:flex checked:before:items-center checked:before:justify-center',\n 'checked:before:text-text-opposite/80',\n\n // Corner shape\n 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n ].join(' '),\n {\n variants: {\n variant: {\n default: '',\n },\n size: {\n sm: 'size-4 rounded-md',\n md: 'size-5 rounded-lg',\n lg: 'size-6 rounded-xl',\n },\n color: {\n primary: 'accent-primary',\n secondary: 'accent-secondary',\n destructive: 'accent-destructive',\n neutral: 'accent-neutral',\n light: 'accent-light',\n text: 'accent-text',\n dark: 'accent-dark',\n error: 'accent-error',\n success: 'accent-success',\n custom: 'accent-custom',\n },\n validationStyleEnabled: {\n disabled: '',\n enabled: 'valid:border-success invalid:border-error',\n },\n },\n defaultVariants: {\n variant: 'default',\n color: 'primary',\n validationStyleEnabled: 'disabled',\n size: 'md',\n },\n }\n);\n\nexport enum CheckboxSize {\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n}\n\nexport enum CheckboxColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n DESTRUCTIVE = 'destructive',\n NEUTRAL = 'neutral',\n LIGHT = 'light',\n TEXT = 'text',\n DARK = 'dark',\n ERROR = 'error',\n SUCCESS = 'success',\n CUSTOM = 'custom',\n}\n\nexport type CheckboxProps = Omit<\n DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>,\n 'size'\n> & {\n name: string;\n validationStyleEnabled?: boolean;\n label?: ReactNode;\n} & Omit<\n VariantProps<typeof checkboxVariants>,\n 'validationStyleEnabled' | 'size' | 'color'\n > & {\n size?: CheckboxSize | `${CheckboxSize}`;\n color?: CheckboxColor | `${CheckboxColor}`;\n labelClassName?: string;\n };\n\nconst Input: FC<CheckboxProps> = ({\n validationStyleEnabled = false,\n label,\n size,\n color,\n name,\n variant,\n className,\n labelClassName,\n ...props\n}) => (\n <input\n type=\"checkbox\"\n className={cn(\n checkboxVariants({\n variant,\n size,\n color,\n validationStyleEnabled: validationStyleEnabled ? 'enabled' : 'disabled',\n }),\n className\n )}\n {...props}\n />\n);\n\nexport const Checkbox: FC<CheckboxProps> = (props) => {\n const { label, name, id } = props;\n\n return label ? (\n <label\n htmlFor={id ?? name}\n className={cn(\n 'flex w-full cursor-pointer items-center gap-x-4 font-medium text-sm',\n props.labelClassName\n )}\n >\n <Input id={id ?? name} {...props} />\n {label}\n </label>\n ) : (\n <Input id={id ?? name} {...props} />\n );\n};\n"],"mappings":";;;;;AASA,MAAa,mBAAmB,IAC9B;CACE;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CAGA;CACA;CACA;CAGA;CACD,CAAC,KAAK,IAAI,EACX;CACE,UAAU;EACR,SAAS,EACP,SAAS,IACV;EACD,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACL;EACD,OAAO;GACL,SAAS;GACT,WAAW;GACX,aAAa;GACb,SAAS;GACT,OAAO;GACP,MAAM;GACN,MAAM;GACN,OAAO;GACP,SAAS;GACT,QAAQ;GACT;EACD,wBAAwB;GACtB,UAAU;GACV,SAAS;GACV;EACF;CACD,iBAAiB;EACf,SAAS;EACT,OAAO;EACP,wBAAwB;EACxB,MAAM;EACP;CACF,CACF;AAED,IAAY,wDAAL;AACL;AACA;AACA;;;AAGF,IAAY,0DAAL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAmBF,MAAMA,SAA4B,EAChC,yBAAyB,OACzB,OACA,MACA,OACA,MACA,SACA,WACA,gBACA,GAAG,YAEH,oBAAC;CACC,MAAK;CACL,WAAW,GACT,iBAAiB;EACf;EACA;EACA;EACA,wBAAwB,yBAAyB,YAAY;EAC9D,CAAC,EACF,UACD;CACD,GAAI;EACJ;AAGJ,MAAaC,YAA+B,UAAU;CACpD,MAAM,EAAE,OAAO,MAAM,OAAO;AAE5B,QAAO,QACL,qBAAC;EACC,SAAS,MAAM;EACf,WAAW,GACT,uEACA,MAAM,eACP;aAED,oBAAC;GAAM,IAAI,MAAM;GAAM,GAAI;IAAS,EACnC;GACK,GAER,oBAAC;EAAM,IAAI,MAAM;EAAM,GAAI;GAAS"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OTPInput.mjs","names":["OTPInput: FC<OTPInputProps>","maxLength","value","calculatedDirection: 'forward' | 'backward' | 'none'","dynamicInputStyle: CSSProperties","contextValue: RenderProps","InputOTP: FC<InputOTPProps>","InputOTPSlot: FC<InputOTPSlotProps>","InputOTPSeparator: FC<ComponentProps<'div'>>","InputIndicator: FC<ComponentProps<'div'>>"],"sources":["../../../../src/components/Input/OTPInput.tsx"],"sourcesContent":["'use client';\n\n/**\n * This component is a fork of https://github.com/guilhermerodz/input-otp\n */\n\nimport { cva } from 'class-variance-authority';\nimport { MinusIcon } from 'lucide-react';\nimport {\n type ChangeEvent,\n type ClipboardEvent,\n type ComponentProps,\n type CSSProperties,\n createContext,\n type FC,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type RefObject,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../../utils/cn';\nimport { Button, type ButtonProps } from '../Button';\n\n// ---------------- Utilities ----------------\n\nconst syncTimeouts = (cb: (...args: any[]) => unknown): number[] => {\n const t1 = setTimeout(cb, 0); // For faster machines\n const t2 = setTimeout(cb, 1_0);\n const t3 = setTimeout(cb, 5_0);\n return [t1, t2, t3];\n};\n\nconst safeInsertRule = (sheet: CSSStyleSheet, rule: string) => {\n try {\n sheet.insertRule(rule);\n } catch {\n console.error('input-otp could not insert CSS rule:', rule);\n }\n};\n\n// Decided to go with <noscript>\n// instead of `scripting` CSS media query\n// because it's a fallback for initial page load\n// and the <script> tag won't be loaded\n// unless the user has JS disabled.\nconst NOSCRIPT_CSS_FALLBACK = `\n[data-input-otp] {\n --nojs-bg: white !important;\n --nojs-fg: black !important;\n\n background-color: var(--nojs-bg) !important;\n color: var(--nojs-fg) !important;\n caret-color: var(--nojs-fg) !important;\n letter-spacing: .25em !important;\n text-align: center !important;\n border: 1px solid var(--nojs-fg) !important;\n border-radius: 4px !important;\n width: 100% !important;\n}\n@media (prefers-color-scheme: dark) {\n [data-input-otp] {\n --nojs-bg: black !important;\n --nojs-fg: white !important;\n }\n}`;\n\n// ---------------- Constants ----------------\n\nconst PWM_BADGE_MARGIN_RIGHT = 18;\nconst PWM_BADGE_SPACE_WIDTH_PX = 40;\nconst PWM_BADGE_SPACE_WIDTH = `${PWM_BADGE_SPACE_WIDTH_PX}px` as const;\n\nconst PASSWORD_MANAGERS_SELECTORS = [\n '[data-lastpass-icon-root]', // LastPass\n 'com-1password-button', // 1Password\n '[data-dashlanecreated]', // Dashlane\n '[style$=\"2147483647 !important;\"]', // Bitwarden\n].join(',');\n\n// ---------------- Types ----------------\n\nexport type SlotProps = {\n isActive: boolean;\n char: string | null;\n placeholderChar: string | null;\n hasFakeCaret: boolean;\n};\n\nexport type RenderProps = {\n slots: SlotProps[];\n isFocused: boolean;\n isHovering: boolean;\n setSelection: (index: number) => void;\n};\n\ntype OverrideProps<T, R> = Omit<T, keyof R> & R;\n\ntype OTPInputBaseProps = OverrideProps<\n InputHTMLAttributes<HTMLInputElement>,\n {\n value?: string;\n onChange?: (newValue: string) => unknown;\n\n maxLength: number;\n\n onComplete?: (...args: any[]) => unknown;\n onActiveSlotChange?: (activeSlotIndex: number | null) => unknown;\n pushPasswordManagerStrategy?: 'increase-width' | 'none';\n pasteTransformer?: (pasted: string) => string;\n\n containerClassName?: string;\n\n noScriptCSSFallback?: string | null;\n }\n>;\n\ntype InputOTPRenderFn = (props: RenderProps) => ReactNode;\n\nexport type OTPInputProps = OTPInputBaseProps &\n (\n | {\n render: InputOTPRenderFn;\n children?: never;\n }\n | {\n render?: never;\n children: ReactNode;\n }\n );\n\n// ---------------- Hooks ----------------\n\nexport const usePasswordManagerBadge = ({\n containerRef,\n inputRef,\n pushPasswordManagerStrategy,\n isFocused,\n}: {\n containerRef: RefObject<HTMLDivElement | null>;\n inputRef: RefObject<HTMLInputElement | null>;\n pushPasswordManagerStrategy: OTPInputProps['pushPasswordManagerStrategy'];\n isFocused: boolean;\n}) => {\n /** Password managers have a badge\n * and I'll use this state to push them\n * outside the input */\n const [hasPWMBadge, setHasPWMBadge] = useState(false);\n const [hasPWMBadgeSpace, setHasPWMBadgeSpace] = useState(false);\n const [done, setDone] = useState(false);\n\n const willPushPWMBadge =\n pushPasswordManagerStrategy === 'none'\n ? false\n : (pushPasswordManagerStrategy === 'increase-width' ||\n // TODO: remove 'experimental-no-flickering' support in 2.0.0\n pushPasswordManagerStrategy === 'experimental-no-flickering') &&\n hasPWMBadge &&\n hasPWMBadgeSpace;\n\n const trackPWMBadge = () => {\n const container = containerRef.current;\n const input = inputRef.current;\n if (\n !container ||\n !input ||\n done ||\n pushPasswordManagerStrategy === 'none'\n ) {\n return;\n }\n\n const elementToCompare = container;\n\n // Get the top right-center point of the container.\n // That is usually where most password managers place their badge.\n const rightCornerX =\n elementToCompare.getBoundingClientRect().left +\n elementToCompare.offsetWidth;\n const centereredY =\n elementToCompare.getBoundingClientRect().top +\n elementToCompare.offsetHeight / 2;\n const x = rightCornerX - PWM_BADGE_MARGIN_RIGHT;\n const y = centereredY;\n\n // Do an extra search to check for famous password managers\n const pmws = document.querySelectorAll(PASSWORD_MANAGERS_SELECTORS);\n\n // If no password manager is automatically detect,\n // we'll try to dispatch document.elementFromPoint\n // to identify badges\n if (pmws.length === 0) {\n const maybeBadgeEl = document.elementFromPoint(x, y);\n\n // If the found element is the input itself,\n // then we assume it's not a password manager badge.\n // We are not sure. Most times that means there isn't a badge.\n if (maybeBadgeEl === container) {\n return;\n }\n }\n\n setHasPWMBadge(true);\n setDone(true);\n };\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container || pushPasswordManagerStrategy === 'none') {\n return;\n }\n\n // Check if the PWM area is 100% visible\n const checkHasSpace = () => {\n const viewportWidth = window.innerWidth;\n const distanceToRightEdge =\n viewportWidth - container.getBoundingClientRect().right;\n setHasPWMBadgeSpace(distanceToRightEdge >= PWM_BADGE_SPACE_WIDTH_PX);\n };\n\n checkHasSpace();\n const interval = setInterval(checkHasSpace, 1000);\n\n return () => {\n clearInterval(interval);\n };\n }, [containerRef, pushPasswordManagerStrategy]);\n\n useEffect(() => {\n const _isFocused = isFocused || document.activeElement === inputRef.current;\n\n if (pushPasswordManagerStrategy === 'none' || !_isFocused) {\n return;\n }\n const t1 = setTimeout(trackPWMBadge, 0);\n const t2 = setTimeout(trackPWMBadge, 2000);\n const t3 = setTimeout(trackPWMBadge, 5000);\n const t4 = setTimeout(() => {\n setDone(true);\n }, 6000);\n return () => {\n clearTimeout(t1);\n clearTimeout(t2);\n clearTimeout(t3);\n clearTimeout(t4);\n };\n }, [inputRef, isFocused, pushPasswordManagerStrategy]);\n\n return { hasPWMBadge, willPushPWMBadge, PWM_BADGE_SPACE_WIDTH };\n};\n\nexport const usePrevious = <T,>(value: T): T | undefined => {\n const ref = useRef<T | undefined>(undefined);\n useEffect(() => {\n ref.current = value;\n });\n return ref.current;\n};\n\n// ---------------- Context ----------------\n\nexport const OTPInputContext = createContext<RenderProps>({} as RenderProps);\n\n// ---------------- Core Component ----------------\n\nexport const OTPInput: FC<OTPInputProps> = ({\n value: uncheckedValue,\n onChange: uncheckedOnChange,\n maxLength,\n pattern,\n placeholder,\n inputMode = 'numeric',\n onComplete,\n onActiveSlotChange,\n pushPasswordManagerStrategy = 'increase-width',\n pasteTransformer,\n containerClassName,\n noScriptCSSFallback = NOSCRIPT_CSS_FALLBACK,\n render,\n children,\n ...props\n}) => {\n // Only used when `value` state is not provided\n const [internalValue, setInternalValue] = useState(\n typeof props.defaultValue === 'string' ? props.defaultValue : ''\n );\n\n // Definitions\n const value = uncheckedValue ?? internalValue;\n const previousValue = usePrevious(value);\n const onChange = (newValue: string) => {\n uncheckedOnChange?.(newValue);\n setInternalValue(newValue);\n };\n const regexp =\n pattern !== undefined\n ? typeof pattern === 'string'\n ? new RegExp(pattern)\n : pattern\n : null;\n\n /** useRef */\n const inputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const initialLoadRef = useRef({\n value,\n onChange,\n isIOS:\n typeof window !== 'undefined' &&\n window?.CSS?.supports?.('-webkit-touch-callout', 'none'),\n });\n const inputMetadataRef = useRef<{\n prev: [number | null, number | null, 'none' | 'forward' | 'backward'];\n }>({\n prev: [\n inputRef.current?.selectionStart ?? null,\n inputRef.current?.selectionEnd ?? null,\n inputRef.current?.selectionDirection ?? 'none',\n ],\n });\n useEffect(() => {\n const input = inputRef.current;\n const container = containerRef.current;\n\n if (!input || !container) {\n return;\n }\n\n // Sync input value\n if (initialLoadRef.current.value !== input.value) {\n initialLoadRef.current.onChange(input.value);\n }\n\n // Previous selection\n inputMetadataRef.current.prev = [\n input.selectionStart,\n input.selectionEnd,\n input.selectionDirection ?? 'none',\n ];\n const onDocumentSelectionChange = () => {\n if (document.activeElement !== input) {\n setMirrorSelectionStart(null);\n setMirrorSelectionEnd(null);\n setActualCaretPosition(null);\n return;\n }\n\n const selectionStart = input.selectionStart;\n const selectionEnd = input.selectionEnd;\n const selectionDirection = input.selectionDirection;\n const maxLength = input.maxLength;\n const value = input.value;\n const previousSelection = inputMetadataRef.current.prev;\n\n let calculatedStart = -1;\n let calculatedEnd = -1;\n let calculatedDirection: 'forward' | 'backward' | 'none' =\n selectionDirection ?? 'none';\n\n if (\n value.length !== 0 &&\n selectionStart !== null &&\n selectionEnd !== null\n ) {\n const isSingleCaret = selectionStart === selectionEnd;\n const isInsertMode =\n selectionStart === value.length && value.length < maxLength;\n\n if (isSingleCaret && !isInsertMode) {\n const caretPosition = selectionStart;\n if (caretPosition === 0) {\n calculatedStart = 0;\n calculatedEnd = 1;\n calculatedDirection = 'forward';\n } else if (caretPosition === maxLength) {\n calculatedStart = caretPosition - 1;\n calculatedEnd = caretPosition;\n calculatedDirection = 'backward';\n } else if (maxLength > 1 && value.length > 1) {\n let offset = 0;\n if (\n previousSelection[0] !== null &&\n previousSelection[1] !== null\n ) {\n calculatedDirection =\n caretPosition < previousSelection[1] ? 'backward' : 'forward';\n const wasPreviouslyInserting =\n previousSelection[0] === previousSelection[1] &&\n previousSelection[0] < maxLength;\n if (\n calculatedDirection === 'backward' &&\n !wasPreviouslyInserting\n ) {\n offset = -1;\n }\n }\n\n calculatedStart = offset + caretPosition;\n calculatedEnd = offset + caretPosition + 1;\n }\n }\n\n if (\n calculatedStart !== -1 &&\n calculatedEnd !== -1 &&\n calculatedStart !== calculatedEnd\n ) {\n inputRef.current?.setSelectionRange(\n calculatedStart,\n calculatedEnd,\n calculatedDirection\n );\n }\n }\n\n const finalSelectionStart =\n calculatedStart !== -1 ? calculatedStart : selectionStart;\n const finalSelectionEnd =\n calculatedEnd !== -1 ? calculatedEnd : selectionEnd;\n const finalDirection = calculatedDirection;\n\n // Track actual caret position (before expansion) for active slot detection\n if (selectionStart !== null && selectionEnd !== null) {\n const isSingleCaret = selectionStart === selectionEnd;\n if (isSingleCaret) {\n setActualCaretPosition(selectionStart);\n } else {\n // When selection is expanded, use the start position as the caret\n setActualCaretPosition(finalSelectionStart);\n }\n } else {\n setActualCaretPosition(null);\n }\n\n setMirrorSelectionStart(finalSelectionStart);\n setMirrorSelectionEnd(finalSelectionEnd);\n inputMetadataRef.current.prev = [\n finalSelectionStart,\n finalSelectionEnd,\n finalDirection,\n ];\n };\n document.addEventListener('selectionchange', onDocumentSelectionChange, {\n capture: true,\n });\n\n // Set initial mirror state\n onDocumentSelectionChange();\n if (document.activeElement === input) {\n setIsFocused(true);\n }\n\n // Apply needed styles\n if (!document.getElementById('input-otp-style')) {\n const styleEl = document.createElement('style');\n styleEl.id = 'input-otp-style';\n document.head.appendChild(styleEl);\n\n if (styleEl.sheet) {\n const autofillStyles =\n 'background: transparent !important; color: transparent !important; border-color: transparent !important; opacity: 0 !important; box-shadow: none !important; -webkit-box-shadow: none !important; -webkit-text-fill-color: transparent !important;';\n\n safeInsertRule(\n styleEl.sheet,\n '[data-input-otp]::selection { background: transparent !important; color: transparent !important; }'\n );\n safeInsertRule(\n styleEl.sheet,\n `[data-input-otp]:autofill { ${autofillStyles} }`\n );\n safeInsertRule(\n styleEl.sheet,\n `[data-input-otp]:-webkit-autofill { ${autofillStyles} }`\n );\n // iOS\n safeInsertRule(\n styleEl.sheet,\n `@supports (-webkit-touch-callout: none) { [data-input-otp] { letter-spacing: -.6em !important; font-weight: 100 !important; font-stretch: ultra-condensed; font-optical-sizing: none !important; left: -1px !important; right: 1px !important; } }`\n );\n // PWM badges\n safeInsertRule(\n styleEl.sheet,\n `[data-input-otp] + * { pointer-events: all !important; }`\n );\n }\n }\n // Track root height\n const updateRootHeight = () => {\n if (container) {\n container.style.setProperty('--root-height', `${input.clientHeight}px`);\n }\n };\n updateRootHeight();\n const resizeObserver = new ResizeObserver(updateRootHeight);\n resizeObserver.observe(input);\n\n return () => {\n document.removeEventListener(\n 'selectionchange',\n onDocumentSelectionChange,\n { capture: true }\n );\n resizeObserver.disconnect();\n };\n }, []);\n\n /** Mirrors for UI rendering purpose only */\n const [isHoveringInput, setIsHoveringInput] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [mirrorSelectionStart, setMirrorSelectionStart] = useState<\n number | null\n >(null);\n const [mirrorSelectionEnd, setMirrorSelectionEnd] = useState<number | null>(\n null\n );\n const [actualCaretPosition, setActualCaretPosition] = useState<number | null>(\n null\n );\n\n /** Effects */\n useEffect(() => {\n syncTimeouts(() => {\n // Forcefully remove :autofill state\n inputRef.current?.dispatchEvent(new Event('input'));\n\n // Update the selection state\n const s = inputRef.current?.selectionStart ?? null;\n const e = inputRef.current?.selectionEnd ?? null;\n const dir = inputRef.current?.selectionDirection ?? 'none';\n if (s !== null && e !== null) {\n setMirrorSelectionStart(s);\n setMirrorSelectionEnd(e);\n // Track actual caret position (use start position as caret)\n setActualCaretPosition(s);\n inputMetadataRef.current.prev = [s, e, dir];\n }\n });\n }, [value, isFocused]);\n\n useEffect(() => {\n if (previousValue === undefined) {\n return;\n }\n\n if (\n value !== previousValue &&\n previousValue.length < maxLength &&\n value.length === maxLength\n ) {\n onComplete?.(value);\n }\n }, [maxLength, onComplete, previousValue, value]);\n\n // Track active slot changes\n const previousActiveSlot = useRef<number | null>(null);\n useEffect(() => {\n const activeSlotIndex =\n isFocused && actualCaretPosition !== null ? actualCaretPosition : null;\n\n if (activeSlotIndex !== previousActiveSlot.current) {\n previousActiveSlot.current = activeSlotIndex;\n onActiveSlotChange?.(activeSlotIndex);\n }\n }, [isFocused, actualCaretPosition, onActiveSlotChange]);\n\n const pwmb = usePasswordManagerBadge({\n containerRef,\n inputRef,\n pushPasswordManagerStrategy,\n isFocused,\n });\n\n /** Event handlers */\n const _changeListener = (e: ChangeEvent<HTMLInputElement>) => {\n const newValue = e.currentTarget.value.slice(0, maxLength);\n if (newValue.length > 0 && regexp && !regexp.test(newValue)) {\n e.preventDefault();\n return;\n }\n const maybeHasDeleted =\n typeof previousValue === 'string' &&\n newValue.length < previousValue.length;\n if (maybeHasDeleted) {\n // Since cutting/deleting text doesn't trigger\n // selectionchange event, we'll have to dispatch it manually.\n // NOTE: The following line also triggers when cmd+A then pasting\n // a value with smaller length, which is not ideal for performance.\n document.dispatchEvent(new Event('selectionchange'));\n }\n onChange(newValue);\n };\n const _focusListener = () => {\n if (inputRef.current) {\n const start = Math.min(inputRef.current.value.length, maxLength - 1);\n const end = inputRef.current.value.length;\n inputRef.current?.setSelectionRange(start, end);\n setMirrorSelectionStart(start);\n setMirrorSelectionEnd(end);\n }\n setIsFocused(true);\n };\n // Fix iOS pasting\n const _pasteListener = (e: ClipboardEvent<HTMLInputElement>) => {\n const input = inputRef.current;\n if (\n !pasteTransformer &&\n (!initialLoadRef.current.isIOS || !e.clipboardData || !input)\n ) {\n return;\n }\n\n const _content = e.clipboardData.getData('text/plain');\n const content = pasteTransformer ? pasteTransformer(_content) : _content;\n e.preventDefault();\n\n const start = inputRef.current?.selectionStart;\n const end = inputRef.current?.selectionEnd;\n\n const isReplacing = start !== end;\n\n const newValueUncapped = isReplacing\n ? value.slice(0, start ?? 0) + content + value.slice(end ?? 0) // Replacing\n : value.slice(0, start ?? 0) + content + value.slice(start ?? 0); // Inserting\n const newValue = newValueUncapped.slice(0, maxLength);\n\n if (newValue.length > 0 && regexp && !regexp.test(newValue)) {\n return;\n }\n\n if (input) {\n input.value = newValue;\n onChange(newValue);\n\n const _start = Math.min(newValue.length, maxLength - 1);\n const _end = newValue.length;\n\n input.setSelectionRange(_start, _end);\n setMirrorSelectionStart(_start);\n setMirrorSelectionEnd(_end);\n }\n };\n\n /** Styles - dynamic styles that can't be converted to Tailwind */\n const dynamicInputStyle: CSSProperties = {\n width: pwmb.willPushPWMBadge\n ? `calc(100% + ${pwmb.PWM_BADGE_SPACE_WIDTH})`\n : '100%',\n clipPath: pwmb.willPushPWMBadge\n ? `inset(0 ${pwmb.PWM_BADGE_SPACE_WIDTH} 0 0)`\n : undefined,\n fontSize: 'var(--root-height)',\n };\n\n /** Rendering */\n const renderedInput = (\n <input\n autoComplete={props.autoComplete || 'one-time-code'}\n {...props}\n data-input-otp\n data-input-otp-placeholder-shown={value.length === 0 || undefined}\n data-input-otp-mss={mirrorSelectionStart}\n data-input-otp-mse={mirrorSelectionEnd}\n inputMode={inputMode}\n pattern={regexp?.source}\n aria-placeholder={placeholder}\n className=\"pointer-events-auto absolute inset-0 -z-10 flex h-full border-0 border-transparent bg-transparent text-center font-mono text-transparent tabular-nums leading-none tracking-[-.5em] caret-transparent opacity-100 shadow-none outline-none\"\n style={dynamicInputStyle}\n maxLength={maxLength}\n value={value}\n ref={inputRef}\n onPaste={(e) => {\n _pasteListener(e);\n props.onPaste?.(e);\n }}\n onChange={_changeListener}\n onMouseOver={(e) => {\n setIsHoveringInput(true);\n props.onMouseOver?.(e);\n }}\n onMouseLeave={(e) => {\n setIsHoveringInput(false);\n props.onMouseLeave?.(e);\n }}\n onKeyDown={(e) => {\n // Track arrow key navigation to ensure active slot updates correctly\n if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {\n // Use requestAnimationFrame to check selection after browser has processed the key\n requestAnimationFrame(() => {\n const input = inputRef.current;\n if (input && document.activeElement === input) {\n const s = input.selectionStart;\n const end = input.selectionEnd;\n if (s !== null && end !== null) {\n // Update actual caret position - use start position as caret\n setActualCaretPosition(s);\n }\n }\n });\n }\n props.onKeyDown?.(e);\n }}\n onFocus={(e) => {\n _focusListener();\n props.onFocus?.(e);\n }}\n onBlur={(e) => {\n setIsFocused(false);\n props.onBlur?.(e);\n }}\n />\n );\n\n const setSelection = (index: number) => {\n const input = inputRef.current;\n if (!input || props.disabled) {\n return;\n }\n\n // Clamp index to valid range\n const clampedIndex = Math.max(0, Math.min(index, maxLength - 1));\n\n // Focus the input if not already focused\n if (document.activeElement !== input) {\n input.focus();\n }\n\n // Set selection to the clicked slot\n // If there's a character at that position, select it; otherwise just position the caret\n const hasChar = value[clampedIndex] !== undefined;\n const start = clampedIndex;\n const end = hasChar ? clampedIndex + 1 : clampedIndex;\n\n input.setSelectionRange(start, end);\n setMirrorSelectionStart(start);\n setMirrorSelectionEnd(end);\n setIsFocused(true);\n };\n\n const contextValue: RenderProps = {\n slots: Array.from({ length: maxLength }).map((_, slotIdx) => {\n const isActive =\n isFocused &&\n mirrorSelectionStart !== null &&\n mirrorSelectionEnd !== null &&\n ((mirrorSelectionStart === mirrorSelectionEnd &&\n slotIdx === mirrorSelectionStart) ||\n (slotIdx >= mirrorSelectionStart && slotIdx < mirrorSelectionEnd));\n\n const char = value[slotIdx] !== undefined ? value[slotIdx] : null;\n const placeholderChar =\n value[0] !== undefined ? null : (placeholder?.[slotIdx] ?? null);\n\n return {\n char,\n placeholderChar,\n isActive,\n hasFakeCaret: isActive && char === null,\n };\n }),\n isFocused,\n isHovering: !props.disabled && isHoveringInput,\n setSelection,\n };\n\n const renderedChildren =\n render !== undefined ? (\n render(contextValue)\n ) : (\n <OTPInputContext.Provider value={contextValue}>\n {children}\n </OTPInputContext.Provider>\n );\n\n return (\n <>\n {noScriptCSSFallback !== null && (\n <noscript>\n <style>{noScriptCSSFallback}</style>\n </noscript>\n )}\n\n <div\n ref={containerRef}\n className={cn(\n 'relative',\n props.disabled ? 'cursor-default' : 'cursor-text',\n containerClassName\n )}\n >\n {renderedChildren}\n\n <div className=\"absolute inset-0\">{renderedInput}</div>\n </div>\n </>\n );\n};\n\n// ---------------- Root ----------------\n\ntype InputOTPProps = Omit<ComponentProps<typeof OTPInput>, 'children'>;\n\nexport const inputSlotVariants = cva('block text-center', {\n variants: {\n size: {\n sm: 'h-4 w-3 text-sm',\n md: 'h-5 w-4 text-base',\n lg: 'h-6 w-5 text-lg',\n xl: 'h-7 w-6 text-xl',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\nexport const InputOTP: FC<InputOTPProps> = ({\n className,\n render,\n ...props\n}) => (\n <OTPInput\n containerClassName=\"relative flex items-center gap-2 has-disabled:opacity-50\"\n className={cn('disabled:cursor-not-allowed', className)}\n render={render!}\n {...props}\n />\n);\n\n// ---------------- Group ----------------\n\nexport const InputOTPGroup = ({\n className,\n ...props\n}: ComponentProps<'div'>) => (\n <div className={cn('z-10 flex items-center gap-3', className)} {...props} />\n);\n\n// ---------------- Slot ----------------\n\ntype InputOTPSlotProps = Omit<ButtonProps, 'variant' | 'label'> & {\n index: number;\n};\n\nexport const InputOTPSlot: FC<InputOTPSlotProps> = ({\n index,\n className,\n onClick,\n onKeyDown,\n ...props\n}) => {\n const inputOTPContext = useContext(OTPInputContext);\n const { char, isActive } = inputOTPContext?.slots[index] ?? {};\n const { setSelection } = inputOTPContext ?? {};\n\n const handleClick = (e: MouseEvent<HTMLButtonElement>) => {\n setSelection?.(index);\n onClick?.(e);\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setSelection?.(index);\n }\n onKeyDown?.(e);\n };\n\n return (\n <Button\n isSelected={isActive}\n variant=\"input\"\n color=\"custom\"\n tabIndex={-1}\n className={cn('relative z-10 px-2!', isActive && 'ring-4!', className)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n label={null}\n {...props}\n >\n {/* value */}\n <span className=\"relative z-10 flex h-6 w-4 items-center justify-center\">\n {char}\n </span>\n </Button>\n );\n};\n\n// ---------------- Separator ----------------\n\nexport const InputOTPSeparator: FC<ComponentProps<'div'>> = (props) => (\n <div\n aria-hidden\n className=\"z-0 table h-0.5 w-3 rounded-full bg-border text-text/50\"\n {...props}\n >\n <MinusIcon />\n </div>\n);\n\nexport const InputIndicator: FC<ComponentProps<'div'>> = (props) => (\n <div\n data-indicator\n className=\"absolute top-0 z-0 h-full w-auto rounded-xl bg-text/20 ring-4 ring-text/20 transition-[left,width] duration-300 ease-in-out [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl motion-reduce:transition-none\"\n {...props}\n />\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OTPInput.mjs","names":["OTPInput: FC<OTPInputProps>","maxLength","value","calculatedDirection: 'forward' | 'backward' | 'none'","dynamicInputStyle: CSSProperties","contextValue: RenderProps","InputOTP: FC<InputOTPProps>","InputOTPSlot: FC<InputOTPSlotProps>","InputOTPSeparator: FC<ComponentProps<'div'>>","InputIndicator: FC<ComponentProps<'div'>>"],"sources":["../../../../src/components/Input/OTPInput.tsx"],"sourcesContent":["'use client';\n\n/**\n * This component is a fork of https://github.com/guilhermerodz/input-otp\n */\n\nimport { cn } from '@utils/cn';\nimport { cva } from 'class-variance-authority';\nimport { MinusIcon } from 'lucide-react';\nimport {\n type ChangeEvent,\n type ClipboardEvent,\n type ComponentProps,\n type CSSProperties,\n createContext,\n type FC,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type RefObject,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { Button, type ButtonProps } from '../Button';\n\n// ---------------- Utilities ----------------\n\nconst syncTimeouts = (cb: (...args: any[]) => unknown): number[] => {\n const t1 = setTimeout(cb, 0); // For faster machines\n const t2 = setTimeout(cb, 1_0);\n const t3 = setTimeout(cb, 5_0);\n return [t1, t2, t3];\n};\n\nconst safeInsertRule = (sheet: CSSStyleSheet, rule: string) => {\n try {\n sheet.insertRule(rule);\n } catch {\n console.error('input-otp could not insert CSS rule:', rule);\n }\n};\n\n// Decided to go with <noscript>\n// instead of `scripting` CSS media query\n// because it's a fallback for initial page load\n// and the <script> tag won't be loaded\n// unless the user has JS disabled.\nconst NOSCRIPT_CSS_FALLBACK = `\n[data-input-otp] {\n --nojs-bg: white !important;\n --nojs-fg: black !important;\n\n background-color: var(--nojs-bg) !important;\n color: var(--nojs-fg) !important;\n caret-color: var(--nojs-fg) !important;\n letter-spacing: .25em !important;\n text-align: center !important;\n border: 1px solid var(--nojs-fg) !important;\n border-radius: 4px !important;\n width: 100% !important;\n}\n@media (prefers-color-scheme: dark) {\n [data-input-otp] {\n --nojs-bg: black !important;\n --nojs-fg: white !important;\n }\n}`;\n\n// ---------------- Constants ----------------\n\nconst PWM_BADGE_MARGIN_RIGHT = 18;\nconst PWM_BADGE_SPACE_WIDTH_PX = 40;\nconst PWM_BADGE_SPACE_WIDTH = `${PWM_BADGE_SPACE_WIDTH_PX}px` as const;\n\nconst PASSWORD_MANAGERS_SELECTORS = [\n '[data-lastpass-icon-root]', // LastPass\n 'com-1password-button', // 1Password\n '[data-dashlanecreated]', // Dashlane\n '[style$=\"2147483647 !important;\"]', // Bitwarden\n].join(',');\n\n// ---------------- Types ----------------\n\nexport type SlotProps = {\n isActive: boolean;\n char: string | null;\n placeholderChar: string | null;\n hasFakeCaret: boolean;\n};\n\nexport type RenderProps = {\n slots: SlotProps[];\n isFocused: boolean;\n isHovering: boolean;\n setSelection: (index: number) => void;\n};\n\ntype OverrideProps<T, R> = Omit<T, keyof R> & R;\n\ntype OTPInputBaseProps = OverrideProps<\n InputHTMLAttributes<HTMLInputElement>,\n {\n value?: string;\n onChange?: (newValue: string) => unknown;\n\n maxLength: number;\n\n onComplete?: (...args: any[]) => unknown;\n onActiveSlotChange?: (activeSlotIndex: number | null) => unknown;\n pushPasswordManagerStrategy?: 'increase-width' | 'none';\n pasteTransformer?: (pasted: string) => string;\n\n containerClassName?: string;\n\n noScriptCSSFallback?: string | null;\n }\n>;\n\ntype InputOTPRenderFn = (props: RenderProps) => ReactNode;\n\nexport type OTPInputProps = OTPInputBaseProps &\n (\n | {\n render: InputOTPRenderFn;\n children?: never;\n }\n | {\n render?: never;\n children: ReactNode;\n }\n );\n\n// ---------------- Hooks ----------------\n\nexport const usePasswordManagerBadge = ({\n containerRef,\n inputRef,\n pushPasswordManagerStrategy,\n isFocused,\n}: {\n containerRef: RefObject<HTMLDivElement | null>;\n inputRef: RefObject<HTMLInputElement | null>;\n pushPasswordManagerStrategy: OTPInputProps['pushPasswordManagerStrategy'];\n isFocused: boolean;\n}) => {\n /** Password managers have a badge\n * and I'll use this state to push them\n * outside the input */\n const [hasPWMBadge, setHasPWMBadge] = useState(false);\n const [hasPWMBadgeSpace, setHasPWMBadgeSpace] = useState(false);\n const [done, setDone] = useState(false);\n\n const willPushPWMBadge =\n pushPasswordManagerStrategy === 'none'\n ? false\n : (pushPasswordManagerStrategy === 'increase-width' ||\n // TODO: remove 'experimental-no-flickering' support in 2.0.0\n pushPasswordManagerStrategy === 'experimental-no-flickering') &&\n hasPWMBadge &&\n hasPWMBadgeSpace;\n\n const trackPWMBadge = () => {\n const container = containerRef.current;\n const input = inputRef.current;\n if (\n !container ||\n !input ||\n done ||\n pushPasswordManagerStrategy === 'none'\n ) {\n return;\n }\n\n const elementToCompare = container;\n\n // Get the top right-center point of the container.\n // That is usually where most password managers place their badge.\n const rightCornerX =\n elementToCompare.getBoundingClientRect().left +\n elementToCompare.offsetWidth;\n const centereredY =\n elementToCompare.getBoundingClientRect().top +\n elementToCompare.offsetHeight / 2;\n const x = rightCornerX - PWM_BADGE_MARGIN_RIGHT;\n const y = centereredY;\n\n // Do an extra search to check for famous password managers\n const pmws = document.querySelectorAll(PASSWORD_MANAGERS_SELECTORS);\n\n // If no password manager is automatically detect,\n // we'll try to dispatch document.elementFromPoint\n // to identify badges\n if (pmws.length === 0) {\n const maybeBadgeEl = document.elementFromPoint(x, y);\n\n // If the found element is the input itself,\n // then we assume it's not a password manager badge.\n // We are not sure. Most times that means there isn't a badge.\n if (maybeBadgeEl === container) {\n return;\n }\n }\n\n setHasPWMBadge(true);\n setDone(true);\n };\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container || pushPasswordManagerStrategy === 'none') {\n return;\n }\n\n // Check if the PWM area is 100% visible\n const checkHasSpace = () => {\n const viewportWidth = window.innerWidth;\n const distanceToRightEdge =\n viewportWidth - container.getBoundingClientRect().right;\n setHasPWMBadgeSpace(distanceToRightEdge >= PWM_BADGE_SPACE_WIDTH_PX);\n };\n\n checkHasSpace();\n const interval = setInterval(checkHasSpace, 1000);\n\n return () => {\n clearInterval(interval);\n };\n }, [containerRef, pushPasswordManagerStrategy]);\n\n useEffect(() => {\n const _isFocused = isFocused || document.activeElement === inputRef.current;\n\n if (pushPasswordManagerStrategy === 'none' || !_isFocused) {\n return;\n }\n const t1 = setTimeout(trackPWMBadge, 0);\n const t2 = setTimeout(trackPWMBadge, 2000);\n const t3 = setTimeout(trackPWMBadge, 5000);\n const t4 = setTimeout(() => {\n setDone(true);\n }, 6000);\n return () => {\n clearTimeout(t1);\n clearTimeout(t2);\n clearTimeout(t3);\n clearTimeout(t4);\n };\n }, [inputRef, isFocused, pushPasswordManagerStrategy]);\n\n return { hasPWMBadge, willPushPWMBadge, PWM_BADGE_SPACE_WIDTH };\n};\n\nexport const usePrevious = <T,>(value: T): T | undefined => {\n const ref = useRef<T | undefined>(undefined);\n useEffect(() => {\n ref.current = value;\n });\n return ref.current;\n};\n\n// ---------------- Context ----------------\n\nexport const OTPInputContext = createContext<RenderProps>({} as RenderProps);\n\n// ---------------- Core Component ----------------\n\nexport const OTPInput: FC<OTPInputProps> = ({\n value: uncheckedValue,\n onChange: uncheckedOnChange,\n maxLength,\n pattern,\n placeholder,\n inputMode = 'numeric',\n onComplete,\n onActiveSlotChange,\n pushPasswordManagerStrategy = 'increase-width',\n pasteTransformer,\n containerClassName,\n noScriptCSSFallback = NOSCRIPT_CSS_FALLBACK,\n render,\n children,\n ...props\n}) => {\n // Only used when `value` state is not provided\n const [internalValue, setInternalValue] = useState(\n typeof props.defaultValue === 'string' ? props.defaultValue : ''\n );\n\n // Definitions\n const value = uncheckedValue ?? internalValue;\n const previousValue = usePrevious(value);\n const onChange = (newValue: string) => {\n uncheckedOnChange?.(newValue);\n setInternalValue(newValue);\n };\n const regexp =\n pattern !== undefined\n ? typeof pattern === 'string'\n ? new RegExp(pattern)\n : pattern\n : null;\n\n /** useRef */\n const inputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const initialLoadRef = useRef({\n value,\n onChange,\n isIOS:\n typeof window !== 'undefined' &&\n window?.CSS?.supports?.('-webkit-touch-callout', 'none'),\n });\n const inputMetadataRef = useRef<{\n prev: [number | null, number | null, 'none' | 'forward' | 'backward'];\n }>({\n prev: [\n inputRef.current?.selectionStart ?? null,\n inputRef.current?.selectionEnd ?? null,\n inputRef.current?.selectionDirection ?? 'none',\n ],\n });\n useEffect(() => {\n const input = inputRef.current;\n const container = containerRef.current;\n\n if (!input || !container) {\n return;\n }\n\n // Sync input value\n if (initialLoadRef.current.value !== input.value) {\n initialLoadRef.current.onChange(input.value);\n }\n\n // Previous selection\n inputMetadataRef.current.prev = [\n input.selectionStart,\n input.selectionEnd,\n input.selectionDirection ?? 'none',\n ];\n const onDocumentSelectionChange = () => {\n if (document.activeElement !== input) {\n setMirrorSelectionStart(null);\n setMirrorSelectionEnd(null);\n setActualCaretPosition(null);\n return;\n }\n\n const selectionStart = input.selectionStart;\n const selectionEnd = input.selectionEnd;\n const selectionDirection = input.selectionDirection;\n const maxLength = input.maxLength;\n const value = input.value;\n const previousSelection = inputMetadataRef.current.prev;\n\n let calculatedStart = -1;\n let calculatedEnd = -1;\n let calculatedDirection: 'forward' | 'backward' | 'none' =\n selectionDirection ?? 'none';\n\n if (\n value.length !== 0 &&\n selectionStart !== null &&\n selectionEnd !== null\n ) {\n const isSingleCaret = selectionStart === selectionEnd;\n const isInsertMode =\n selectionStart === value.length && value.length < maxLength;\n\n if (isSingleCaret && !isInsertMode) {\n const caretPosition = selectionStart;\n if (caretPosition === 0) {\n calculatedStart = 0;\n calculatedEnd = 1;\n calculatedDirection = 'forward';\n } else if (caretPosition === maxLength) {\n calculatedStart = caretPosition - 1;\n calculatedEnd = caretPosition;\n calculatedDirection = 'backward';\n } else if (maxLength > 1 && value.length > 1) {\n let offset = 0;\n if (\n previousSelection[0] !== null &&\n previousSelection[1] !== null\n ) {\n calculatedDirection =\n caretPosition < previousSelection[1] ? 'backward' : 'forward';\n const wasPreviouslyInserting =\n previousSelection[0] === previousSelection[1] &&\n previousSelection[0] < maxLength;\n if (\n calculatedDirection === 'backward' &&\n !wasPreviouslyInserting\n ) {\n offset = -1;\n }\n }\n\n calculatedStart = offset + caretPosition;\n calculatedEnd = offset + caretPosition + 1;\n }\n }\n\n if (\n calculatedStart !== -1 &&\n calculatedEnd !== -1 &&\n calculatedStart !== calculatedEnd\n ) {\n inputRef.current?.setSelectionRange(\n calculatedStart,\n calculatedEnd,\n calculatedDirection\n );\n }\n }\n\n const finalSelectionStart =\n calculatedStart !== -1 ? calculatedStart : selectionStart;\n const finalSelectionEnd =\n calculatedEnd !== -1 ? calculatedEnd : selectionEnd;\n const finalDirection = calculatedDirection;\n\n // Track actual caret position (before expansion) for active slot detection\n if (selectionStart !== null && selectionEnd !== null) {\n const isSingleCaret = selectionStart === selectionEnd;\n if (isSingleCaret) {\n setActualCaretPosition(selectionStart);\n } else {\n // When selection is expanded, use the start position as the caret\n setActualCaretPosition(finalSelectionStart);\n }\n } else {\n setActualCaretPosition(null);\n }\n\n setMirrorSelectionStart(finalSelectionStart);\n setMirrorSelectionEnd(finalSelectionEnd);\n inputMetadataRef.current.prev = [\n finalSelectionStart,\n finalSelectionEnd,\n finalDirection,\n ];\n };\n document.addEventListener('selectionchange', onDocumentSelectionChange, {\n capture: true,\n });\n\n // Set initial mirror state\n onDocumentSelectionChange();\n if (document.activeElement === input) {\n setIsFocused(true);\n }\n\n // Apply needed styles\n if (!document.getElementById('input-otp-style')) {\n const styleEl = document.createElement('style');\n styleEl.id = 'input-otp-style';\n document.head.appendChild(styleEl);\n\n if (styleEl.sheet) {\n const autofillStyles =\n 'background: transparent !important; color: transparent !important; border-color: transparent !important; opacity: 0 !important; box-shadow: none !important; -webkit-box-shadow: none !important; -webkit-text-fill-color: transparent !important;';\n\n safeInsertRule(\n styleEl.sheet,\n '[data-input-otp]::selection { background: transparent !important; color: transparent !important; }'\n );\n safeInsertRule(\n styleEl.sheet,\n `[data-input-otp]:autofill { ${autofillStyles} }`\n );\n safeInsertRule(\n styleEl.sheet,\n `[data-input-otp]:-webkit-autofill { ${autofillStyles} }`\n );\n // iOS\n safeInsertRule(\n styleEl.sheet,\n `@supports (-webkit-touch-callout: none) { [data-input-otp] { letter-spacing: -.6em !important; font-weight: 100 !important; font-stretch: ultra-condensed; font-optical-sizing: none !important; left: -1px !important; right: 1px !important; } }`\n );\n // PWM badges\n safeInsertRule(\n styleEl.sheet,\n `[data-input-otp] + * { pointer-events: all !important; }`\n );\n }\n }\n // Track root height\n const updateRootHeight = () => {\n if (container) {\n container.style.setProperty('--root-height', `${input.clientHeight}px`);\n }\n };\n updateRootHeight();\n const resizeObserver = new ResizeObserver(updateRootHeight);\n resizeObserver.observe(input);\n\n return () => {\n document.removeEventListener(\n 'selectionchange',\n onDocumentSelectionChange,\n { capture: true }\n );\n resizeObserver.disconnect();\n };\n }, []);\n\n /** Mirrors for UI rendering purpose only */\n const [isHoveringInput, setIsHoveringInput] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [mirrorSelectionStart, setMirrorSelectionStart] = useState<\n number | null\n >(null);\n const [mirrorSelectionEnd, setMirrorSelectionEnd] = useState<number | null>(\n null\n );\n const [actualCaretPosition, setActualCaretPosition] = useState<number | null>(\n null\n );\n\n /** Effects */\n useEffect(() => {\n syncTimeouts(() => {\n // Forcefully remove :autofill state\n inputRef.current?.dispatchEvent(new Event('input'));\n\n // Update the selection state\n const s = inputRef.current?.selectionStart ?? null;\n const e = inputRef.current?.selectionEnd ?? null;\n const dir = inputRef.current?.selectionDirection ?? 'none';\n if (s !== null && e !== null) {\n setMirrorSelectionStart(s);\n setMirrorSelectionEnd(e);\n // Track actual caret position (use start position as caret)\n setActualCaretPosition(s);\n inputMetadataRef.current.prev = [s, e, dir];\n }\n });\n }, [value, isFocused]);\n\n useEffect(() => {\n if (previousValue === undefined) {\n return;\n }\n\n if (\n value !== previousValue &&\n previousValue.length < maxLength &&\n value.length === maxLength\n ) {\n onComplete?.(value);\n }\n }, [maxLength, onComplete, previousValue, value]);\n\n // Track active slot changes\n const previousActiveSlot = useRef<number | null>(null);\n useEffect(() => {\n const activeSlotIndex =\n isFocused && actualCaretPosition !== null ? actualCaretPosition : null;\n\n if (activeSlotIndex !== previousActiveSlot.current) {\n previousActiveSlot.current = activeSlotIndex;\n onActiveSlotChange?.(activeSlotIndex);\n }\n }, [isFocused, actualCaretPosition, onActiveSlotChange]);\n\n const pwmb = usePasswordManagerBadge({\n containerRef,\n inputRef,\n pushPasswordManagerStrategy,\n isFocused,\n });\n\n /** Event handlers */\n const _changeListener = (e: ChangeEvent<HTMLInputElement>) => {\n const newValue = e.currentTarget.value.slice(0, maxLength);\n if (newValue.length > 0 && regexp && !regexp.test(newValue)) {\n e.preventDefault();\n return;\n }\n const maybeHasDeleted =\n typeof previousValue === 'string' &&\n newValue.length < previousValue.length;\n if (maybeHasDeleted) {\n // Since cutting/deleting text doesn't trigger\n // selectionchange event, we'll have to dispatch it manually.\n // NOTE: The following line also triggers when cmd+A then pasting\n // a value with smaller length, which is not ideal for performance.\n document.dispatchEvent(new Event('selectionchange'));\n }\n onChange(newValue);\n };\n const _focusListener = () => {\n if (inputRef.current) {\n const start = Math.min(inputRef.current.value.length, maxLength - 1);\n const end = inputRef.current.value.length;\n inputRef.current?.setSelectionRange(start, end);\n setMirrorSelectionStart(start);\n setMirrorSelectionEnd(end);\n }\n setIsFocused(true);\n };\n // Fix iOS pasting\n const _pasteListener = (e: ClipboardEvent<HTMLInputElement>) => {\n const input = inputRef.current;\n if (\n !pasteTransformer &&\n (!initialLoadRef.current.isIOS || !e.clipboardData || !input)\n ) {\n return;\n }\n\n const _content = e.clipboardData.getData('text/plain');\n const content = pasteTransformer ? pasteTransformer(_content) : _content;\n e.preventDefault();\n\n const start = inputRef.current?.selectionStart;\n const end = inputRef.current?.selectionEnd;\n\n const isReplacing = start !== end;\n\n const newValueUncapped = isReplacing\n ? value.slice(0, start ?? 0) + content + value.slice(end ?? 0) // Replacing\n : value.slice(0, start ?? 0) + content + value.slice(start ?? 0); // Inserting\n const newValue = newValueUncapped.slice(0, maxLength);\n\n if (newValue.length > 0 && regexp && !regexp.test(newValue)) {\n return;\n }\n\n if (input) {\n input.value = newValue;\n onChange(newValue);\n\n const _start = Math.min(newValue.length, maxLength - 1);\n const _end = newValue.length;\n\n input.setSelectionRange(_start, _end);\n setMirrorSelectionStart(_start);\n setMirrorSelectionEnd(_end);\n }\n };\n\n /** Styles - dynamic styles that can't be converted to Tailwind */\n const dynamicInputStyle: CSSProperties = {\n width: pwmb.willPushPWMBadge\n ? `calc(100% + ${pwmb.PWM_BADGE_SPACE_WIDTH})`\n : '100%',\n clipPath: pwmb.willPushPWMBadge\n ? `inset(0 ${pwmb.PWM_BADGE_SPACE_WIDTH} 0 0)`\n : undefined,\n fontSize: 'var(--root-height)',\n };\n\n /** Rendering */\n const renderedInput = (\n <input\n autoComplete={props.autoComplete || 'one-time-code'}\n {...props}\n data-input-otp\n data-input-otp-placeholder-shown={value.length === 0 || undefined}\n data-input-otp-mss={mirrorSelectionStart}\n data-input-otp-mse={mirrorSelectionEnd}\n inputMode={inputMode}\n pattern={regexp?.source}\n aria-placeholder={placeholder}\n className=\"pointer-events-auto absolute inset-0 -z-10 flex h-full border-0 border-transparent bg-transparent text-center font-mono text-transparent tabular-nums leading-none tracking-[-.5em] caret-transparent opacity-100 shadow-none outline-none\"\n style={dynamicInputStyle}\n maxLength={maxLength}\n value={value}\n ref={inputRef}\n onPaste={(e) => {\n _pasteListener(e);\n props.onPaste?.(e);\n }}\n onChange={_changeListener}\n onMouseOver={(e) => {\n setIsHoveringInput(true);\n props.onMouseOver?.(e);\n }}\n onMouseLeave={(e) => {\n setIsHoveringInput(false);\n props.onMouseLeave?.(e);\n }}\n onKeyDown={(e) => {\n // Track arrow key navigation to ensure active slot updates correctly\n if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {\n // Use requestAnimationFrame to check selection after browser has processed the key\n requestAnimationFrame(() => {\n const input = inputRef.current;\n if (input && document.activeElement === input) {\n const s = input.selectionStart;\n const end = input.selectionEnd;\n if (s !== null && end !== null) {\n // Update actual caret position - use start position as caret\n setActualCaretPosition(s);\n }\n }\n });\n }\n props.onKeyDown?.(e);\n }}\n onFocus={(e) => {\n _focusListener();\n props.onFocus?.(e);\n }}\n onBlur={(e) => {\n setIsFocused(false);\n props.onBlur?.(e);\n }}\n />\n );\n\n const setSelection = (index: number) => {\n const input = inputRef.current;\n if (!input || props.disabled) {\n return;\n }\n\n // Clamp index to valid range\n const clampedIndex = Math.max(0, Math.min(index, maxLength - 1));\n\n // Focus the input if not already focused\n if (document.activeElement !== input) {\n input.focus();\n }\n\n // Set selection to the clicked slot\n // If there's a character at that position, select it; otherwise just position the caret\n const hasChar = value[clampedIndex] !== undefined;\n const start = clampedIndex;\n const end = hasChar ? clampedIndex + 1 : clampedIndex;\n\n input.setSelectionRange(start, end);\n setMirrorSelectionStart(start);\n setMirrorSelectionEnd(end);\n setIsFocused(true);\n };\n\n const contextValue: RenderProps = {\n slots: Array.from({ length: maxLength }).map((_, slotIdx) => {\n const isActive =\n isFocused &&\n mirrorSelectionStart !== null &&\n mirrorSelectionEnd !== null &&\n ((mirrorSelectionStart === mirrorSelectionEnd &&\n slotIdx === mirrorSelectionStart) ||\n (slotIdx >= mirrorSelectionStart && slotIdx < mirrorSelectionEnd));\n\n const char = value[slotIdx] !== undefined ? value[slotIdx] : null;\n const placeholderChar =\n value[0] !== undefined ? null : (placeholder?.[slotIdx] ?? null);\n\n return {\n char,\n placeholderChar,\n isActive,\n hasFakeCaret: isActive && char === null,\n };\n }),\n isFocused,\n isHovering: !props.disabled && isHoveringInput,\n setSelection,\n };\n\n const renderedChildren =\n render !== undefined ? (\n render(contextValue)\n ) : (\n <OTPInputContext.Provider value={contextValue}>\n {children}\n </OTPInputContext.Provider>\n );\n\n return (\n <>\n {noScriptCSSFallback !== null && (\n <noscript>\n <style>{noScriptCSSFallback}</style>\n </noscript>\n )}\n\n <div\n ref={containerRef}\n className={cn(\n 'relative',\n props.disabled ? 'cursor-default' : 'cursor-text',\n containerClassName\n )}\n >\n {renderedChildren}\n\n <div className=\"absolute inset-0\">{renderedInput}</div>\n </div>\n </>\n );\n};\n\n// ---------------- Root ----------------\n\ntype InputOTPProps = Omit<ComponentProps<typeof OTPInput>, 'children'>;\n\nexport const inputSlotVariants = cva('block text-center', {\n variants: {\n size: {\n sm: 'h-4 w-3 text-sm',\n md: 'h-5 w-4 text-base',\n lg: 'h-6 w-5 text-lg',\n xl: 'h-7 w-6 text-xl',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\nexport const InputOTP: FC<InputOTPProps> = ({\n className,\n render,\n ...props\n}) => (\n <OTPInput\n containerClassName=\"relative flex items-center gap-2 has-disabled:opacity-50\"\n className={cn('disabled:cursor-not-allowed', className)}\n render={render!}\n {...props}\n />\n);\n\n// ---------------- Group ----------------\n\nexport const InputOTPGroup = ({\n className,\n ...props\n}: ComponentProps<'div'>) => (\n <div className={cn('z-10 flex items-center gap-3', className)} {...props} />\n);\n\n// ---------------- Slot ----------------\n\ntype InputOTPSlotProps = Omit<ButtonProps, 'variant' | 'label'> & {\n index: number;\n};\n\nexport const InputOTPSlot: FC<InputOTPSlotProps> = ({\n index,\n className,\n onClick,\n onKeyDown,\n ...props\n}) => {\n const inputOTPContext = useContext(OTPInputContext);\n const { char, isActive } = inputOTPContext?.slots[index] ?? {};\n const { setSelection } = inputOTPContext ?? {};\n\n const handleClick = (e: MouseEvent<HTMLButtonElement>) => {\n setSelection?.(index);\n onClick?.(e);\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setSelection?.(index);\n }\n onKeyDown?.(e);\n };\n\n return (\n <Button\n isSelected={isActive}\n variant=\"input\"\n color=\"custom\"\n tabIndex={-1}\n className={cn('relative z-10 px-2!', isActive && 'ring-4!', className)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n label={null}\n {...props}\n >\n {/* value */}\n <span className=\"relative z-10 flex h-6 w-4 items-center justify-center\">\n {char}\n </span>\n </Button>\n );\n};\n\n// ---------------- Separator ----------------\n\nexport const InputOTPSeparator: FC<ComponentProps<'div'>> = (props) => (\n <div\n aria-hidden\n className=\"z-0 table h-0.5 w-3 rounded-full bg-border text-text/50\"\n {...props}\n >\n <MinusIcon />\n </div>\n);\n\nexport const InputIndicator: FC<ComponentProps<'div'>> = (props) => (\n <div\n data-indicator\n className=\"absolute top-0 z-0 h-full w-auto rounded-xl bg-text/20 ring-4 ring-text/20 transition-[left,width] duration-300 ease-in-out [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl motion-reduce:transition-none\"\n {...props}\n />\n);\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchInput.mjs","names":[],"sources":["../../../../src/components/Input/SearchInput.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"SearchInput.mjs","names":[],"sources":["../../../../src/components/Input/SearchInput.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { Search } from 'lucide-react';\nimport { Input, type InputProps } from './Input';\n\nexport const SearchInput = ({ className, ...props }: InputProps) => (\n <div className=\"relative flex w-full items-center gap-1\">\n <Search className=\"absolute left-2 size-4\" />\n <Input {...props} type=\"search\" className={cn('pl-8', className)} />\n </div>\n);\n"],"mappings":";;;;;;AAIA,MAAa,eAAe,EAAE,WAAW,GAAG,YAC1C,qBAAC;CAAI,WAAU;YACb,oBAAC,UAAO,WAAU,2BAA2B,EAC7C,oBAAC;EAAM,GAAI;EAAO,MAAK;EAAS,WAAW,GAAG,QAAQ,UAAU;GAAI;EAChE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["KeyboardScreenAdapter: FC<\n PropsWithChildren<HTMLAttributes<HTMLDivElement>>\n>"],"sources":["../../../../src/components/KeyboardScreenAdapter/index.tsx"],"sourcesContent":["'use client';\n\nimport
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["KeyboardScreenAdapter: FC<\n PropsWithChildren<HTMLAttributes<HTMLDivElement>>\n>"],"sources":["../../../../src/components/KeyboardScreenAdapter/index.tsx"],"sourcesContent":["'use client';\n\nimport { useKeyboardDetector } from '@hooks/useKeyboardDetector';\nimport { cn } from '@utils/cn';\nimport type { FC, HTMLAttributes, PropsWithChildren } from 'react';\n\n/**\n * KeyboardScreenAdapter Component\n *\n * A smart wrapper component that automatically adapts the viewport height\n * when virtual keyboards appear on mobile devices. This prevents content\n * from being hidden behind the keyboard and ensures optimal user experience\n * across all devices and orientations.\n *\n * @component\n * @example\n * Basic usage:\n * ```tsx\n * <KeyboardScreenAdapter>\n * <div>Your app content here</div>\n * </KeyboardScreenAdapter>\n * ```\n *\n * @example\n * With custom styling:\n * ```tsx\n * <KeyboardScreenAdapter className=\"bg-gray-100 p-4\">\n * <form>\n * <input type=\"text\" placeholder=\"Enter your name\" />\n * <input type=\"email\" placeholder=\"Enter your email\" />\n * <button type=\"submit\">Submit</button>\n * </form>\n * </KeyboardScreenAdapter>\n * ```\n *\n * @example\n * Mobile-first responsive design:\n * ```tsx\n * <KeyboardScreenAdapter className=\"md:min-h-screen\">\n * <div className=\"flex flex-col h-full\">\n * <header>Navigation</header>\n * <main className=\"flex-1 overflow-auto\">\n * <input type=\"search\" placeholder=\"Search...\" />\n * Content that needs keyboard adaptation\n * </main>\n * </div>\n * </KeyboardScreenAdapter>\n * ```\n *\n * Features:\n * - Automatic viewport height detection and adjustment\n * - Smooth transitions when keyboard shows/hides\n * - Works with both iOS and Android virtual keyboards\n * - Responsive design that adapts to device orientation changes\n * - Maintains scroll behavior and overflow handling\n * - Lightweight with minimal performance impact\n * - Client-side only (Next.js compatible with 'use client')\n *\n * How it works:\n * 1. Uses the useKeyboardDetector hook to monitor window height changes\n * 2. Detects when virtual keyboard appears (window height decreases)\n * 3. Automatically adjusts the container's max-height to fit visible area\n * 4. Provides smooth transitions for better user experience\n * 5. Restores original height when keyboard disappears\n *\n * Use cases:\n * - Mobile web applications with forms\n * - Chat interfaces and messaging apps\n * - Search interfaces and input-heavy UIs\n * - Progressive Web Apps (PWAs)\n * - Any mobile-first application requiring keyboard interaction\n *\n * Browser compatibility:\n * - iOS Safari (all versions)\n * - Chrome Mobile (Android)\n * - Samsung Internet\n * - Firefox Mobile\n * - Other mobile browsers with virtual keyboards\n *\n * Performance considerations:\n * - Uses ResizeObserver for efficient window monitoring\n * - Minimal re-renders through optimized state management\n * - CSS transitions handled by GPU acceleration\n * - No layout thrashing during keyboard transitions\n *\n * Accessibility:\n * - Maintains focus management during transitions\n * - Preserves scroll position and user context\n * - Compatible with screen readers and assistive technologies\n * - Supports keyboard navigation patterns\n *\n * @param props - Component props extending standard div attributes\n * @param props.children - Content to render within the adaptive container\n * @param props.className - Additional CSS classes for the container\n * @param props.style - Inline styles (note: maxHeight may be overridden)\n * @param props.id - Unique identifier for the container\n * @param props.role - ARIA role for accessibility\n * @param props.tabIndex - Tab index for focus management\n * @param props.onScroll - Scroll event handler\n * @param props.onTouchStart - Touch start event handler\n * @param props.onTouchMove - Touch move event handler\n * @param props.onTouchEnd - Touch end event handler\n * @param props...rest - All other standard HTML div attributes\n *\n * @returns A responsive container that adapts to keyboard visibility\n */\nexport const KeyboardScreenAdapter: FC<\n PropsWithChildren<HTMLAttributes<HTMLDivElement>>\n> = ({ children, className, ...props }) => {\n const { windowHeight } = useKeyboardDetector();\n\n return (\n <div\n className={cn(\n 'h-screen w-screen overflow-auto scroll-smooth transition',\n className\n )}\n style={{\n maxHeight: windowHeight ? `${windowHeight}px` : undefined,\n }}\n {...props}\n >\n {children}\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0GA,MAAaA,yBAER,EAAE,UAAU,WAAW,GAAG,YAAY;CACzC,MAAM,EAAE,iBAAiB,qBAAqB;AAE9C,QACE,oBAAC;EACC,WAAW,GACT,4DACA,UACD;EACD,OAAO,EACL,WAAW,eAAe,GAAG,aAAa,MAAM,QACjD;EACD,GAAI;EAEH;GACG"}
|
|
@@ -154,7 +154,7 @@ const getDisplayShortcut = (shortcut, isMac) => {
|
|
|
154
154
|
* />
|
|
155
155
|
* ```
|
|
156
156
|
*/
|
|
157
|
-
const KeyboardShortcut = ({ shortcut, onTriggered, display = true, className, size = "md" }) => {
|
|
157
|
+
const KeyboardShortcut = ({ shortcut, onTriggered, display = true, disabled = false, className, size = "md" }) => {
|
|
158
158
|
const { isMac } = useDevice();
|
|
159
159
|
const keys = parseShortcut(getDisplayShortcut(shortcut, isMac ?? false));
|
|
160
160
|
const [pressedKeys, setPressedKeys] = useState(/* @__PURE__ */ new Set());
|
|
@@ -173,7 +173,7 @@ const KeyboardShortcut = ({ shortcut, onTriggered, display = true, className, si
|
|
|
173
173
|
normalizedEventKeys.add(getDisplayKey(currentKey));
|
|
174
174
|
} else normalizedEventKeys.add(currentKey.toUpperCase());
|
|
175
175
|
setPressedKeys(normalizedEventKeys);
|
|
176
|
-
if (onTriggered && matchesShortcut(event, keys)) {
|
|
176
|
+
if (!disabled && onTriggered && matchesShortcut(event, keys)) {
|
|
177
177
|
const isEscapeShortcut = keys.includes("Escape");
|
|
178
178
|
if (isInputField && !isEscapeShortcut) return;
|
|
179
179
|
event.preventDefault();
|
|
@@ -194,7 +194,8 @@ const KeyboardShortcut = ({ shortcut, onTriggered, display = true, className, si
|
|
|
194
194
|
}, [
|
|
195
195
|
keys,
|
|
196
196
|
onTriggered,
|
|
197
|
-
isMac
|
|
197
|
+
isMac,
|
|
198
|
+
disabled
|
|
198
199
|
]);
|
|
199
200
|
if (!display) return null;
|
|
200
201
|
/**
|
|
@@ -217,6 +218,7 @@ const KeyboardShortcut = ({ shortcut, onTriggered, display = true, className, si
|
|
|
217
218
|
children: "+"
|
|
218
219
|
}), /* @__PURE__ */ jsx("span", {
|
|
219
220
|
className: cn("min-w-4 px-0.5", isKeyPressed(key) && "scale-120 font-bold text-text"),
|
|
221
|
+
suppressHydrationWarning: true,
|
|
220
222
|
children: displayKey
|
|
221
223
|
})]
|
|
222
224
|
}, keyId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KeyboardShortcut.mjs","names":["KeyboardShortcut: FC<KeyboardShortcutProps>"],"sources":["../../../../src/components/KeyboardShortcut/KeyboardShortcut.tsx"],"sourcesContent":["'use client';\n\nimport { type FC, useEffect, useState } from 'react';\nimport { useDevice } from '../../hooks/useDevice';\nimport { cn } from '../../utils/cn';\n\n/**\n * Enum for available keyboard keys\n */\nexport enum KeyList {\n '⌘' = '⌘',\n Ctrl = 'Ctrl',\n Alt = 'Alt',\n '⌥' = '⌥',\n Shift = 'Shift',\n Meta = 'Meta',\n F = 'F',\n K = 'K',\n L = 'L',\n P = 'P',\n S = 'S',\n A = 'A',\n B = 'B',\n C = 'C',\n D = 'D',\n E = 'E',\n G = 'G',\n H = 'H',\n I = 'I',\n J = 'J',\n M = 'M',\n N = 'N',\n O = 'O',\n Q = 'Q',\n R = 'R',\n T = 'T',\n U = 'U',\n V = 'V',\n W = 'W',\n X = 'X',\n Y = 'Y',\n Z = 'Z',\n Enter = 'Enter',\n Escape = 'Escape',\n Backspace = 'Backspace',\n Tab = 'Tab',\n Space = 'Space',\n ArrowUp = 'ArrowUp',\n ArrowDown = 'ArrowDown',\n ArrowLeft = 'ArrowLeft',\n ArrowRight = 'ArrowRight',\n '↑' = '↑',\n '↓' = '↓',\n '←' = '←',\n '→' = '→',\n}\n\n/**\n * Type-safe keyboard shortcut combinations\n * Note: Using string type to avoid union type complexity issues\n * Expected format: \"Key + Key\" (e.g., \"⌘ + F\", \"Ctrl + Shift + K\")\n */\nexport type KeyboardShortcutType = string;\n\nexport type KeyboardShortcutProps = {\n /** The keyboard shortcut combination (e.g., \"⌘ + F\" or \"Ctrl + K\") */\n shortcut: KeyboardShortcutType;\n /** Callback function triggered when the shortcut is pressed */\n onTriggered?: () => void;\n /** Whether to display the shortcut visually (default: true) */\n display?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Size of the keyboard shortcut display */\n size?: 'sm' | 'md' | 'lg';\n};\n\n/**\n * Parse keyboard shortcut string into individual keys\n */\nconst parseShortcut = (shortcut: string): string[] => {\n return shortcut.split(' + ').map((key) => key.trim());\n};\n\n/**\n * Normalize key name for event comparison\n */\nconst normalizeKey = (key: string): string => {\n const keyMap: Record<string, string> = {\n '⌘': 'Meta',\n Ctrl: 'Control',\n Control: 'Control',\n Alt: 'Alt',\n '⌥': 'Alt',\n Shift: 'Shift',\n Meta: 'Meta',\n '↑': 'ArrowUp',\n '↓': 'ArrowDown',\n '←': 'ArrowLeft',\n '→': 'ArrowRight',\n ArrowUp: 'ArrowUp',\n ArrowDown: 'ArrowDown',\n ArrowLeft: 'ArrowLeft',\n ArrowRight: 'ArrowRight',\n };\n\n return keyMap[key] || key;\n};\n\n/**\n * Check if the keyboard event matches the shortcut\n */\nconst matchesShortcut = (event: KeyboardEvent, keys: string[]): boolean => {\n const normalizedKeys = keys.map(normalizeKey);\n const hasModifiers = {\n Meta: normalizedKeys.includes('Meta'),\n Control: normalizedKeys.includes('Control'),\n Alt: normalizedKeys.includes('Alt'),\n Shift: normalizedKeys.includes('Shift'),\n };\n\n // Check if all required modifiers are pressed\n if (\n hasModifiers.Meta !== event.metaKey ||\n hasModifiers.Control !== event.ctrlKey ||\n hasModifiers.Alt !== event.altKey ||\n hasModifiers.Shift !== event.shiftKey\n ) {\n return false;\n }\n\n // Find the non-modifier key\n const nonModifierKey = keys.find(\n (key) =>\n !['⌘', 'Ctrl', 'Control', 'Alt', '⌥', 'Shift', 'Meta'].includes(\n normalizeKey(key)\n )\n );\n\n if (!nonModifierKey) return false;\n\n // Normalize the key for comparison\n const normalizedNonModifierKey = normalizeKey(nonModifierKey);\n\n // Compare the main key\n // For arrow keys, compare directly with event.key\n if (normalizedNonModifierKey.startsWith('Arrow')) {\n return event.key === normalizedNonModifierKey;\n }\n\n // For other keys, compare case-insensitive\n return event.key.toLowerCase() === normalizedNonModifierKey.toLowerCase();\n};\n\n/**\n * Get display key symbol for better visual representation\n */\nconst getDisplayKey = (key: string): string => {\n const displayMap: Record<string, string> = {\n ArrowUp: '↑',\n ArrowDown: '↓',\n ArrowLeft: '←',\n ArrowRight: '→',\n };\n\n return displayMap[key] || key;\n};\n\n/**\n * Get display shortcut based on OS (Mac uses ⌘ and ⌥, others use Ctrl and Alt)\n */\nconst getDisplayShortcut = (shortcut: string, isMac: boolean): string => {\n let result = shortcut;\n\n if (isMac) {\n result = result.replace(/Ctrl/g, '⌘');\n result = result.replace(/Alt/g, '⌥');\n } else {\n result = result.replace(/⌘/g, 'Ctrl');\n result = result.replace(/⌥/g, 'Alt');\n }\n\n // Replace arrow key names with symbols\n result = result.replace(/ArrowUp/g, '↑');\n result = result.replace(/ArrowDown/g, '↓');\n result = result.replace(/ArrowLeft/g, '←');\n result = result.replace(/ArrowRight/g, '→');\n\n return result;\n};\n\n/**\n * KeyboardShortcut Component\n *\n * A reusable component that displays keyboard shortcuts and listens for key combinations.\n * Automatically adapts to Mac (⌘, ⌥) and Windows/Linux (Ctrl, Alt) conventions.\n *\n * @example\n * ```tsx\n * <KeyboardShortcut\n * shortcut=\"⌘ + F\"\n * onTriggered={() => setShowSearch(true)}\n * />\n * ```\n */\nexport const KeyboardShortcut: FC<KeyboardShortcutProps> = ({\n shortcut,\n onTriggered,\n display = true,\n className,\n size = 'md',\n}) => {\n const { isMac } = useDevice();\n const displayShortcut = getDisplayShortcut(shortcut, isMac ?? false);\n const keys = parseShortcut(displayShortcut);\n const [pressedKeys, setPressedKeys] = useState<Set<string>>(new Set());\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n // 1. Identify input fields\n const target = event.target as HTMLElement;\n const isInputField =\n target.tagName === 'INPUT' ||\n target.tagName === 'TEXTAREA' ||\n target.isContentEditable;\n\n // ... (Your existing key visualization logic here) ...\n // Note: Copied your key tracking logic for context\n const currentKey = event.key;\n const normalizedEventKeys = new Set<string>();\n if (event.metaKey) normalizedEventKeys.add('⌘');\n if (event.ctrlKey) normalizedEventKeys.add('Ctrl');\n if (event.altKey) normalizedEventKeys.add(isMac ? '⌥' : 'Alt');\n if (event.shiftKey) normalizedEventKeys.add('Shift');\n\n if (currentKey.startsWith('Arrow')) {\n normalizedEventKeys.add(currentKey);\n normalizedEventKeys.add(getDisplayKey(currentKey));\n } else {\n normalizedEventKeys.add(currentKey.toUpperCase());\n }\n setPressedKeys(normalizedEventKeys);\n\n // 2. Trigger callback if shortcut matches\n if (onTriggered && matchesShortcut(event, keys)) {\n // FIX: Check if the required shortcut is \"Escape\"\n const isEscapeShortcut = keys.includes('Escape');\n\n // Only block if it is an input field AND the shortcut is NOT Escape\n if (isInputField && !isEscapeShortcut) {\n return;\n }\n\n event.preventDefault();\n onTriggered();\n }\n };\n\n const handleKeyUp = () => {\n setPressedKeys(new Set());\n };\n\n window.addEventListener('keydown', handleKeyDown);\n window.addEventListener('keyup', handleKeyUp);\n window.addEventListener('blur', handleKeyUp);\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown);\n window.removeEventListener('keyup', handleKeyUp);\n window.removeEventListener('blur', handleKeyUp);\n };\n }, [keys, onTriggered, isMac]);\n if (!display) return null;\n\n /**\n * Check if a key is currently pressed\n */\n const isKeyPressed = (key: string): boolean => {\n const upperKey = key.toUpperCase();\n const normalizedKey = normalizeKey(key);\n\n return (\n pressedKeys.has(key) ||\n pressedKeys.has(upperKey) ||\n pressedKeys.has(normalizedKey) ||\n // Check for modifier key matches\n (key === '⌘' && pressedKeys.has('Meta')) ||\n (key === 'Ctrl' && pressedKeys.has('Control')) ||\n (key === '⌥' && pressedKeys.has('Alt')) ||\n (key === 'Alt' && pressedKeys.has('Alt')) ||\n // Check for arrow key symbols\n (key === '←' && pressedKeys.has('ArrowLeft')) ||\n (key === '→' && pressedKeys.has('ArrowRight')) ||\n (key === '↑' && pressedKeys.has('ArrowUp')) ||\n (key === '↓' && pressedKeys.has('ArrowDown'))\n );\n };\n\n return (\n <kbd\n className={cn(\n 'inline-flex items-center justify-center gap-0.5 p-0.5',\n 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n 'font-medium font-sans',\n 'border-1 border-neutral/20 text-neutral',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n size === 'lg' && 'text-base',\n className\n )}\n >\n {keys.map((key, index) => {\n const keyId = `${key}-${index}-${shortcut}`;\n const displayKey = getDisplayKey(key);\n return (\n <span key={keyId} className=\"inline-flex items-center\">\n {index > 0 && <span className=\"text-neutral/50\">+</span>}\n <span\n className={cn(\n 'min-w-4 px-0.5',\n isKeyPressed(key) && 'scale-120 font-bold text-text'\n )}\n >\n {displayKey}\n </span>\n </span>\n );\n })}\n </kbd>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"KeyboardShortcut.mjs","names":["KeyboardShortcut: FC<KeyboardShortcutProps>"],"sources":["../../../../src/components/KeyboardShortcut/KeyboardShortcut.tsx"],"sourcesContent":["'use client';\n\nimport { useDevice } from '@hooks/useDevice';\nimport { cn } from '@utils/cn';\nimport { type FC, useEffect, useState } from 'react';\n\n/**\n * Enum for available keyboard keys\n */\nexport enum KeyList {\n '⌘' = '⌘',\n Ctrl = 'Ctrl',\n Alt = 'Alt',\n '⌥' = '⌥',\n Shift = 'Shift',\n Meta = 'Meta',\n F = 'F',\n K = 'K',\n L = 'L',\n P = 'P',\n S = 'S',\n A = 'A',\n B = 'B',\n C = 'C',\n D = 'D',\n E = 'E',\n G = 'G',\n H = 'H',\n I = 'I',\n J = 'J',\n M = 'M',\n N = 'N',\n O = 'O',\n Q = 'Q',\n R = 'R',\n T = 'T',\n U = 'U',\n V = 'V',\n W = 'W',\n X = 'X',\n Y = 'Y',\n Z = 'Z',\n Enter = 'Enter',\n Escape = 'Escape',\n Backspace = 'Backspace',\n Tab = 'Tab',\n Space = 'Space',\n ArrowUp = 'ArrowUp',\n ArrowDown = 'ArrowDown',\n ArrowLeft = 'ArrowLeft',\n ArrowRight = 'ArrowRight',\n '↑' = '↑',\n '↓' = '↓',\n '←' = '←',\n '→' = '→',\n}\n\n/**\n * Type-safe keyboard shortcut combinations\n * Note: Using string type to avoid union type complexity issues\n * Expected format: \"Key + Key\" (e.g., \"⌘ + F\", \"Ctrl + Shift + K\")\n */\nexport type KeyboardShortcutType = string;\n\nexport type KeyboardShortcutProps = {\n /** The keyboard shortcut combination (e.g., \"⌘ + F\" or \"Ctrl + K\") */\n shortcut: KeyboardShortcutType;\n /** Callback function triggered when the shortcut is pressed */\n onTriggered?: () => void;\n /** Whether to display the shortcut visually (default: true) */\n display?: boolean;\n /** Whether to disable the shortcut trigger (default: false) */\n disabled?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Size of the keyboard shortcut display */\n size?: 'sm' | 'md' | 'lg';\n};\n\n/**\n * Parse keyboard shortcut string into individual keys\n */\nconst parseShortcut = (shortcut: string): string[] => {\n return shortcut.split(' + ').map((key) => key.trim());\n};\n\n/**\n * Normalize key name for event comparison\n */\nconst normalizeKey = (key: string): string => {\n const keyMap: Record<string, string> = {\n '⌘': 'Meta',\n Ctrl: 'Control',\n Control: 'Control',\n Alt: 'Alt',\n '⌥': 'Alt',\n Shift: 'Shift',\n Meta: 'Meta',\n '↑': 'ArrowUp',\n '↓': 'ArrowDown',\n '←': 'ArrowLeft',\n '→': 'ArrowRight',\n ArrowUp: 'ArrowUp',\n ArrowDown: 'ArrowDown',\n ArrowLeft: 'ArrowLeft',\n ArrowRight: 'ArrowRight',\n };\n\n return keyMap[key] || key;\n};\n\n/**\n * Check if the keyboard event matches the shortcut\n */\nconst matchesShortcut = (event: KeyboardEvent, keys: string[]): boolean => {\n const normalizedKeys = keys.map(normalizeKey);\n const hasModifiers = {\n Meta: normalizedKeys.includes('Meta'),\n Control: normalizedKeys.includes('Control'),\n Alt: normalizedKeys.includes('Alt'),\n Shift: normalizedKeys.includes('Shift'),\n };\n\n // Check if all required modifiers are pressed\n if (\n hasModifiers.Meta !== event.metaKey ||\n hasModifiers.Control !== event.ctrlKey ||\n hasModifiers.Alt !== event.altKey ||\n hasModifiers.Shift !== event.shiftKey\n ) {\n return false;\n }\n\n // Find the non-modifier key\n const nonModifierKey = keys.find(\n (key) =>\n !['⌘', 'Ctrl', 'Control', 'Alt', '⌥', 'Shift', 'Meta'].includes(\n normalizeKey(key)\n )\n );\n\n if (!nonModifierKey) return false;\n\n // Normalize the key for comparison\n const normalizedNonModifierKey = normalizeKey(nonModifierKey);\n\n // Compare the main key\n // For arrow keys, compare directly with event.key\n if (normalizedNonModifierKey.startsWith('Arrow')) {\n return event.key === normalizedNonModifierKey;\n }\n\n // For other keys, compare case-insensitive\n return event.key.toLowerCase() === normalizedNonModifierKey.toLowerCase();\n};\n\n/**\n * Get display key symbol for better visual representation\n */\nconst getDisplayKey = (key: string): string => {\n const displayMap: Record<string, string> = {\n ArrowUp: '↑',\n ArrowDown: '↓',\n ArrowLeft: '←',\n ArrowRight: '→',\n };\n\n return displayMap[key] || key;\n};\n\n/**\n * Get display shortcut based on OS (Mac uses ⌘ and ⌥, others use Ctrl and Alt)\n */\nconst getDisplayShortcut = (shortcut: string, isMac: boolean): string => {\n let result = shortcut;\n\n if (isMac) {\n result = result.replace(/Ctrl/g, '⌘');\n result = result.replace(/Alt/g, '⌥');\n } else {\n result = result.replace(/⌘/g, 'Ctrl');\n result = result.replace(/⌥/g, 'Alt');\n }\n\n // Replace arrow key names with symbols\n result = result.replace(/ArrowUp/g, '↑');\n result = result.replace(/ArrowDown/g, '↓');\n result = result.replace(/ArrowLeft/g, '←');\n result = result.replace(/ArrowRight/g, '→');\n\n return result;\n};\n\n/**\n * KeyboardShortcut Component\n *\n * A reusable component that displays keyboard shortcuts and listens for key combinations.\n * Automatically adapts to Mac (⌘, ⌥) and Windows/Linux (Ctrl, Alt) conventions.\n *\n * @example\n * ```tsx\n * <KeyboardShortcut\n * shortcut=\"⌘ + F\"\n * onTriggered={() => setShowSearch(true)}\n * />\n * ```\n */\nexport const KeyboardShortcut: FC<KeyboardShortcutProps> = ({\n shortcut,\n onTriggered,\n display = true,\n disabled = false,\n className,\n size = 'md',\n}) => {\n const { isMac } = useDevice();\n const displayShortcut = getDisplayShortcut(shortcut, isMac ?? false);\n const keys = parseShortcut(displayShortcut);\n const [pressedKeys, setPressedKeys] = useState<Set<string>>(new Set());\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n // 1. Identify input fields\n const target = event.target as HTMLElement;\n const isInputField =\n target.tagName === 'INPUT' ||\n target.tagName === 'TEXTAREA' ||\n target.isContentEditable;\n\n // ... (Your existing key visualization logic here) ...\n // Note: Copied your key tracking logic for context\n const currentKey = event.key;\n const normalizedEventKeys = new Set<string>();\n if (event.metaKey) normalizedEventKeys.add('⌘');\n if (event.ctrlKey) normalizedEventKeys.add('Ctrl');\n if (event.altKey) normalizedEventKeys.add(isMac ? '⌥' : 'Alt');\n if (event.shiftKey) normalizedEventKeys.add('Shift');\n\n if (currentKey.startsWith('Arrow')) {\n normalizedEventKeys.add(currentKey);\n normalizedEventKeys.add(getDisplayKey(currentKey));\n } else {\n normalizedEventKeys.add(currentKey.toUpperCase());\n }\n setPressedKeys(normalizedEventKeys);\n\n // 2. Trigger callback if shortcut matches\n if (!disabled && onTriggered && matchesShortcut(event, keys)) {\n // FIX: Check if the required shortcut is \"Escape\"\n const isEscapeShortcut = keys.includes('Escape');\n\n // Only block if it is an input field AND the shortcut is NOT Escape\n if (isInputField && !isEscapeShortcut) {\n return;\n }\n\n event.preventDefault();\n onTriggered();\n }\n };\n\n const handleKeyUp = () => {\n setPressedKeys(new Set());\n };\n\n window.addEventListener('keydown', handleKeyDown);\n window.addEventListener('keyup', handleKeyUp);\n window.addEventListener('blur', handleKeyUp);\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown);\n window.removeEventListener('keyup', handleKeyUp);\n window.removeEventListener('blur', handleKeyUp);\n };\n }, [keys, onTriggered, isMac, disabled]);\n if (!display) return null;\n\n /**\n * Check if a key is currently pressed\n */\n const isKeyPressed = (key: string): boolean => {\n const upperKey = key.toUpperCase();\n const normalizedKey = normalizeKey(key);\n\n return (\n pressedKeys.has(key) ||\n pressedKeys.has(upperKey) ||\n pressedKeys.has(normalizedKey) ||\n // Check for modifier key matches\n (key === '⌘' && pressedKeys.has('Meta')) ||\n (key === 'Ctrl' && pressedKeys.has('Control')) ||\n (key === '⌥' && pressedKeys.has('Alt')) ||\n (key === 'Alt' && pressedKeys.has('Alt')) ||\n // Check for arrow key symbols\n (key === '←' && pressedKeys.has('ArrowLeft')) ||\n (key === '→' && pressedKeys.has('ArrowRight')) ||\n (key === '↑' && pressedKeys.has('ArrowUp')) ||\n (key === '↓' && pressedKeys.has('ArrowDown'))\n );\n };\n\n return (\n <kbd\n className={cn(\n 'inline-flex items-center justify-center gap-0.5 p-0.5',\n 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n 'font-medium font-sans',\n 'border-1 border-neutral/20 text-neutral',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n size === 'lg' && 'text-base',\n className\n )}\n >\n {keys.map((key, index) => {\n const keyId = `${key}-${index}-${shortcut}`;\n const displayKey = getDisplayKey(key);\n return (\n <span key={keyId} className=\"inline-flex items-center\">\n {index > 0 && <span className=\"text-neutral/50\">+</span>}\n <span\n className={cn(\n 'min-w-4 px-0.5',\n isKeyPressed(key) && 'scale-120 font-bold text-text'\n )}\n suppressHydrationWarning\n >\n {displayKey}\n </span>\n </span>\n );\n })}\n </kbd>\n );\n};\n"],"mappings":"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"}
|