@intlayer/design-system 8.7.12 → 8.7.14

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.
Files changed (83) hide show
  1. package/README.md +1 -1
  2. package/dist/esm/components/DictionaryEditor/NodeWrapper/BooleanWrapper.mjs +1 -1
  3. package/dist/esm/components/DictionaryFieldEditor/ContentEditorView/TextEditor.mjs +1 -1
  4. package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/DictionaryDetailsForm.mjs +2 -0
  5. package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/DictionaryDetailsForm.mjs.map +1 -1
  6. package/dist/esm/components/DictionaryFieldEditor/DictionaryFieldEditor.mjs +1 -1
  7. package/dist/esm/components/DictionaryFieldEditor/DictionaryFieldEditor.mjs.map +1 -1
  8. package/dist/esm/components/Form/elements/SwitchSelectorElement.mjs +1 -1
  9. package/dist/esm/components/IDE/Code.mjs +4 -1
  10. package/dist/esm/components/IDE/Code.mjs.map +1 -1
  11. package/dist/esm/components/IDE/CodeBlockClient.mjs.map +1 -1
  12. package/dist/esm/components/IDE/CodeBlockHighlight.mjs +2 -2
  13. package/dist/esm/components/IDE/CodeBlockHighlight.mjs.map +1 -1
  14. package/dist/esm/components/IDE/CodeBlockShiki.mjs +1 -1
  15. package/dist/esm/components/IDE/CodeBlockShiki.mjs.map +1 -1
  16. package/dist/esm/components/Input/Checkbox.mjs +13 -13
  17. package/dist/esm/components/Input/Checkbox.mjs.map +1 -1
  18. package/dist/esm/components/Link/Link.mjs +3 -3
  19. package/dist/esm/components/Link/Link.mjs.map +1 -1
  20. package/dist/esm/components/LocaleSwitcherContentDropDown/LocaleSwitcherContent.mjs +2 -1
  21. package/dist/esm/components/LocaleSwitcherContentDropDown/LocaleSwitcherContent.mjs.map +1 -1
  22. package/dist/esm/components/Navbar/index.mjs.map +1 -1
  23. package/dist/esm/components/Popover/static.mjs +1 -1
  24. package/dist/esm/components/Popover/static.mjs.map +1 -1
  25. package/dist/esm/components/SwitchSelector/SwitchSelector.mjs +127 -0
  26. package/dist/esm/components/SwitchSelector/SwitchSelector.mjs.map +1 -0
  27. package/dist/esm/components/SwitchSelector/VerticalSwitchSelector.mjs +105 -0
  28. package/dist/esm/components/SwitchSelector/VerticalSwitchSelector.mjs.map +1 -0
  29. package/dist/esm/components/SwitchSelector/index.mjs +3 -179
  30. package/dist/esm/components/SwitchSelector/useSwitchSelector.mjs +44 -0
  31. package/dist/esm/components/SwitchSelector/useSwitchSelector.mjs.map +1 -0
  32. package/dist/esm/components/index.mjs +3 -2
  33. package/dist/esm/hooks/index.mjs +2 -2
  34. package/dist/esm/hooks/reactQuery.mjs +41 -12
  35. package/dist/esm/hooks/reactQuery.mjs.map +1 -1
  36. package/dist/esm/hooks/useAuth/useOAuth2.mjs +2 -2
  37. package/dist/esm/hooks/useAuth/useOAuth2.mjs.map +1 -1
  38. package/dist/esm/hooks/useAuth/useSession.mjs +6 -4
  39. package/dist/esm/hooks/useAuth/useSession.mjs.map +1 -1
  40. package/dist/esm/hooks/useItemSelector.mjs +33 -20
  41. package/dist/esm/hooks/useItemSelector.mjs.map +1 -1
  42. package/dist/esm/providers/ReactQueryProvider.mjs +56 -21
  43. package/dist/esm/providers/ReactQueryProvider.mjs.map +1 -1
  44. package/dist/types/components/Badge/index.d.ts +3 -3
  45. package/dist/types/components/Button/Button.d.ts +5 -5
  46. package/dist/types/components/CollapsibleTable/CollapsibleTable.d.ts +1 -1
  47. package/dist/types/components/Command/index.d.ts +3 -3
  48. package/dist/types/components/Container/index.d.ts +8 -8
  49. package/dist/types/components/IDE/Code.d.ts +2 -2
  50. package/dist/types/components/IDE/Code.d.ts.map +1 -1
  51. package/dist/types/components/IDE/CodeBlockClient.d.ts +3 -3
  52. package/dist/types/components/IDE/CodeBlockClient.d.ts.map +1 -1
  53. package/dist/types/components/IDE/CodeBlockHighlight.d.ts +2 -1
  54. package/dist/types/components/IDE/CodeBlockHighlight.d.ts.map +1 -1
  55. package/dist/types/components/IDE/CodeBlockShiki.d.ts +2 -2
  56. package/dist/types/components/IDE/CodeBlockShiki.d.ts.map +1 -1
  57. package/dist/types/components/Input/Checkbox.d.ts +3 -3
  58. package/dist/types/components/Input/Checkbox.d.ts.map +1 -1
  59. package/dist/types/components/Input/Input.d.ts +1 -1
  60. package/dist/types/components/Link/Link.d.ts +4 -4
  61. package/dist/types/components/Navbar/index.d.ts.map +1 -1
  62. package/dist/types/components/Pagination/Pagination.d.ts +1 -1
  63. package/dist/types/components/SwitchSelector/SwitchSelector.d.ts +56 -0
  64. package/dist/types/components/SwitchSelector/SwitchSelector.d.ts.map +1 -0
  65. package/dist/types/components/SwitchSelector/VerticalSwitchSelector.d.ts +22 -0
  66. package/dist/types/components/SwitchSelector/VerticalSwitchSelector.d.ts.map +1 -0
  67. package/dist/types/components/SwitchSelector/index.d.ts +3 -79
  68. package/dist/types/components/SwitchSelector/useSwitchSelector.d.ts +27 -0
  69. package/dist/types/components/SwitchSelector/useSwitchSelector.d.ts.map +1 -0
  70. package/dist/types/components/Tab/Tab.d.ts +1 -1
  71. package/dist/types/components/TabSelector/TabSelector.d.ts +1 -1
  72. package/dist/types/components/Tag/index.d.ts +3 -3
  73. package/dist/types/components/Toaster/Toast.d.ts +1 -1
  74. package/dist/types/components/index.d.ts +3 -2
  75. package/dist/types/hooks/index.d.ts +2 -2
  76. package/dist/types/hooks/reactQuery.d.ts +4 -1
  77. package/dist/types/hooks/reactQuery.d.ts.map +1 -1
  78. package/dist/types/hooks/useAuth/useOAuth2.d.ts.map +1 -1
  79. package/dist/types/providers/ReactQueryProvider.d.ts +5 -2
  80. package/dist/types/providers/ReactQueryProvider.d.ts.map +1 -1
  81. package/package.json +24 -21
  82. package/dist/esm/components/SwitchSelector/index.mjs.map +0 -1
  83. package/dist/types/components/SwitchSelector/index.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"LocaleSwitcherContent.mjs","names":[],"sources":["../../../../src/components/LocaleSwitcherContentDropDown/LocaleSwitcherContent.tsx"],"sourcesContent":["'use client';\n\nimport { usePersistedStore } from '@hooks/usePersistedStore';\nimport { getHTMLTextDir, getLocaleName } from '@intlayer/core/localization';\nimport { ENGLISH } from '@intlayer/types/locales';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport Fuse, { type IFuseOptions } from 'fuse.js';\nimport { Check, Globe, MoveVertical } from 'lucide-react';\nimport { type FC, useMemo, useRef, useState } from 'react';\nimport { useIntlayer, useLocale } from 'react-intlayer';\nimport {\n Button,\n ButtonColor,\n ButtonSize,\n ButtonTextAlign,\n ButtonVariant,\n} from '../Button';\nimport { Container } from '../Container';\nimport { DropDown, type PanelProps } from '../DropDown';\nimport { Input } from '../Input';\nimport {\n SwitchSelector,\n SwitchSelectorColor,\n SwitchSelectorSize,\n} from '../SwitchSelector';\nimport { useLocaleSwitcherContent } from './LocaleSwitcherContentContext';\n\nexport type LocaleSwitcherContentProps = {\n panelProps?: Omit<PanelProps, 'identifier'>;\n isMultilingual?: boolean;\n};\n\nconst DROPDOWN_IDENTIFIER = 'locale-switcher-content';\n\ntype MultilingualAvailableLocales = {\n locale: LocalesValues;\n englishName: string;\n currentLocaleName: string;\n ownLocaleName: string;\n};\n\nexport const LocaleSwitcherContent: FC<LocaleSwitcherContentProps> = ({\n panelProps,\n isMultilingual = true,\n}) => {\n const {\n switchTo,\n searchInput,\n localeSwitcherLabel,\n languageListLabel,\n seeAllLocalesSwitch,\n } = useIntlayer('locale-switcher-content');\n const inputRef = useRef<HTMLInputElement>(null);\n const { locale } = useLocale();\n const { availableLocales, selectedLocales, setSelectedLocales } =\n useLocaleSwitcherContent();\n\n // 1. Memoize the list construction so it doesn't rebuild every render\n const multilingualAvailableLocales: MultilingualAvailableLocales[] = useMemo(\n () =>\n availableLocales.map((localeEl) => {\n const englishName = getLocaleName(localeEl, ENGLISH);\n const currentLocaleName = getLocaleName(localeEl, locale);\n const ownLocaleName = getLocaleName(localeEl);\n return {\n locale: localeEl,\n englishName,\n currentLocaleName,\n ownLocaleName,\n };\n }),\n [availableLocales, locale]\n );\n\n // 2. State for Search Query only (Source of Truth)\n const [searchQuery, setSearchQuery] = useState('');\n\n const [seeAllLocales, setSeeAllLocales] = usePersistedStore(\n 'locale-content-selector-see-all-locales',\n false\n );\n\n // 3. Memoize Fuse instance\n const fuse = useMemo(() => {\n const fuseOptions: IFuseOptions<MultilingualAvailableLocales> = {\n keys: [\n { name: 'ownLocaleName', weight: 0.4 },\n { name: 'englishName', weight: 0.2 },\n { name: 'currentLocaleName', weight: 0.2 },\n { name: 'locale', weight: 0.2 },\n ],\n threshold: 0.02,\n };\n return new Fuse(multilingualAvailableLocales, fuseOptions);\n }, [multilingualAvailableLocales]);\n\n // 4. Derive results from Search Query\n const results = useMemo(() => {\n if (!searchQuery) {\n return multilingualAvailableLocales;\n }\n return fuse.search(searchQuery).map((result) => result.item);\n }, [searchQuery, multilingualAvailableLocales, fuse]);\n\n const handleClickLocale = (localeItem: LocalesValues) => {\n if (isMultilingual) {\n if (selectedLocales.includes(localeItem)) {\n if (selectedLocales.length > 1) {\n setSelectedLocales((prev) => prev.filter((el) => el !== localeItem));\n }\n } else {\n setSelectedLocales((prev) => [...prev, localeItem]);\n }\n } else {\n setSelectedLocales([localeItem]);\n }\n };\n\n const handleSeeAllLocales = (value: boolean) => {\n setSeeAllLocales(value);\n\n if (value) {\n setSelectedLocales(availableLocales);\n } else {\n setSelectedLocales([locale]);\n }\n };\n\n return (\n <div className=\"rounded-xl border border-text text-text transition-colors\">\n <DropDown identifier={DROPDOWN_IDENTIFIER}>\n <DropDown.Trigger\n identifier={DROPDOWN_IDENTIFIER}\n label={localeSwitcherLabel.value}\n className=\"p-0!\"\n roundedSize=\"3xl\"\n color=\"text\"\n >\n <div className=\"flex w-full items-center justify-between text-text\">\n <div className=\"px-2 py-1\">\n <Globe size={16} />\n </div>\n <MoveVertical className=\"self-center\" size={16} />\n </div>\n </DropDown.Trigger>\n\n <DropDown.Panel\n identifier={DROPDOWN_IDENTIFIER}\n isOverable\n isFocusable\n align=\"end\"\n {...panelProps}\n >\n <Container\n className=\"max-h-[60vh] min-w-28\"\n separator=\"y\"\n role=\"listbox\"\n transparency=\"xs\"\n border\n roundedSize=\"3xl\"\n borderColor=\"text\"\n aria-label={languageListLabel.value}\n >\n {isMultilingual && (\n <div className=\"m-auto p-2\">\n <SwitchSelector\n defaultValue={seeAllLocales} // Ensure this uses the persisted state\n onChange={handleSeeAllLocales}\n color={SwitchSelectorColor.TEXT}\n size={SwitchSelectorSize.SM}\n className=\"!w-60\"\n choices={[\n {\n content: seeAllLocalesSwitch.true.value,\n value: true,\n },\n {\n content: seeAllLocalesSwitch.false.value,\n value: false,\n },\n ]}\n />\n </div>\n )}\n\n {!(isMultilingual && seeAllLocales) && (\n <>\n <div className=\"p-3\">\n <Input\n type=\"search\"\n aria-label={searchInput.ariaLabel.value}\n placeholder={searchInput.placeholder.value}\n // Update search query state directly\n onChange={(e) => setSearchQuery(e.target.value)}\n ref={inputRef}\n />\n </div>\n <ol className=\"divide-y divide-dashed divide-text/20 overflow-y-auto p-1\">\n {results.map(\n ({\n locale: localeItem,\n currentLocaleName,\n ownLocaleName,\n }) => (\n <li className=\"px-1.5 py-1\" key={localeItem}>\n <Button\n onClick={() => handleClickLocale(localeItem)}\n label={`${switchTo} ${currentLocaleName}`}\n disabled={\n !(availableLocales ?? availableLocales).includes(\n localeItem\n )\n }\n isActive={selectedLocales.includes(localeItem)}\n variant={ButtonVariant.HOVERABLE}\n color={ButtonColor.TEXT}\n isFullWidth\n textAlign={ButtonTextAlign.LEFT}\n size={ButtonSize.SM}\n >\n <div className=\"flex flex-row items-center justify-between gap-3 px-2 py-1\">\n {isMultilingual && (\n <div className=\"w-4\">\n {selectedLocales.includes(localeItem) && (\n <Check className=\"size-full\" />\n )}\n </div>\n )}\n <div className=\"flex flex-1 flex-row items-center justify-between gap-3 px-2 py-1\">\n <div className=\"flex flex-col text-nowrap\">\n <span\n dir={getHTMLTextDir(localeItem)}\n lang={localeItem}\n >\n {ownLocaleName}\n </span>\n <span className=\"text-neutral text-xs\">\n {currentLocaleName}\n </span>\n </div>\n <span className=\"text-neutral text-sm\">\n {localeItem.toUpperCase()}\n </span>\n </div>\n </div>\n </Button>\n </li>\n )\n )}\n </ol>\n </>\n )}\n </Container>\n </DropDown.Panel>\n </DropDown>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAgCA,MAAM,sBAAsB;AAS5B,MAAa,yBAAyD,EACpE,YACA,iBAAiB,WACb;CACJ,MAAM,EACJ,UACA,aACA,qBACA,mBACA,wBACE,YAAY,0BAA0B;CAC1C,MAAM,WAAW,OAAyB,KAAK;CAC/C,MAAM,EAAE,WAAW,WAAW;CAC9B,MAAM,EAAE,kBAAkB,iBAAiB,uBACzC,0BAA0B;CAG5B,MAAM,+BAA+D,cAEjE,iBAAiB,KAAK,aAAa;AAIjC,SAAO;GACL,QAAQ;GACR,aALkB,cAAc,UAAU,QAK/B;GACX,mBALwB,cAAc,UAAU,OAK/B;GACjB,eALoB,cAAc,SAKrB;GACd;GACD,EACJ,CAAC,kBAAkB,OAAO,CAC3B;CAGD,MAAM,CAAC,aAAa,kBAAkB,SAAS,GAAG;CAElD,MAAM,CAAC,eAAe,oBAAoB,kBACxC,2CACA,MACD;CAGD,MAAM,OAAO,cAAc;AAUzB,SAAO,IAAI,KAAK,8BAA8B;GAR5C,MAAM;IACJ;KAAE,MAAM;KAAiB,QAAQ;KAAK;IACtC;KAAE,MAAM;KAAe,QAAQ;KAAK;IACpC;KAAE,MAAM;KAAqB,QAAQ;KAAK;IAC1C;KAAE,MAAM;KAAU,QAAQ;KAAK;IAChC;GACD,WAAW;GAE4C,CAAC;IACzD,CAAC,6BAA6B,CAAC;CAGlC,MAAM,UAAU,cAAc;AAC5B,MAAI,CAAC,YACH,QAAO;AAET,SAAO,KAAK,OAAO,YAAY,CAAC,KAAK,WAAW,OAAO,KAAK;IAC3D;EAAC;EAAa;EAA8B;EAAK,CAAC;CAErD,MAAM,qBAAqB,eAA8B;AACvD,MAAI,eACF,KAAI,gBAAgB,SAAS,WAAW,EACtC;OAAI,gBAAgB,SAAS,EAC3B,qBAAoB,SAAS,KAAK,QAAQ,OAAO,OAAO,WAAW,CAAC;QAGtE,qBAAoB,SAAS,CAAC,GAAG,MAAM,WAAW,CAAC;MAGrD,oBAAmB,CAAC,WAAW,CAAC;;CAIpC,MAAM,uBAAuB,UAAmB;AAC9C,mBAAiB,MAAM;AAEvB,MAAI,MACF,oBAAmB,iBAAiB;MAEpC,oBAAmB,CAAC,OAAO,CAAC;;AAIhC,QACE,oBAAC,OAAD;EAAK,WAAU;YACb,qBAAC,UAAD;GAAU,YAAY;aAAtB,CACE,oBAAC,SAAS,SAAV;IACE,YAAY;IACZ,OAAO,oBAAoB;IAC3B,WAAU;IACV,aAAY;IACZ,OAAM;cAEN,qBAAC,OAAD;KAAK,WAAU;eAAf,CACE,oBAAC,OAAD;MAAK,WAAU;gBACb,oBAAC,OAAD,EAAO,MAAM,IAAM;MACf,GACN,oBAAC,cAAD;MAAc,WAAU;MAAc,MAAM;MAAM,EAC9C;;IACW,GAEnB,oBAAC,SAAS,OAAV;IACE,YAAY;IACZ;IACA;IACA,OAAM;IACN,GAAI;cAEJ,qBAAC,WAAD;KACE,WAAU;KACV,WAAU;KACV,MAAK;KACL,cAAa;KACb;KACA,aAAY;KACZ,aAAY;KACZ,cAAY,kBAAkB;eARhC,CAUG,kBACC,oBAAC,OAAD;MAAK,WAAU;gBACb,oBAAC,gBAAD;OACE,cAAc;OACd,UAAU;OACV;OACA;OACA,WAAU;OACV,SAAS,CACP;QACE,SAAS,oBAAoB,KAAK;QAClC,OAAO;QACR,EACD;QACE,SAAS,oBAAoB,MAAM;QACnC,OAAO;QACR,CACF;OACD;MACE,GAGP,EAAE,kBAAkB,kBACnB,8CACE,oBAAC,OAAD;MAAK,WAAU;gBACb,oBAAC,OAAD;OACE,MAAK;OACL,cAAY,YAAY,UAAU;OAClC,aAAa,YAAY,YAAY;OAErC,WAAW,MAAM,eAAe,EAAE,OAAO,MAAM;OAC/C,KAAK;OACL;MACE,GACN,oBAAC,MAAD;MAAI,WAAU;gBACX,QAAQ,KACN,EACC,QAAQ,YACR,mBACA,oBAEA,oBAAC,MAAD;OAAI,WAAU;iBACZ,oBAAC,QAAD;QACE,eAAe,kBAAkB,WAAW;QAC5C,OAAO,GAAG,SAAS,GAAG;QACtB,UACE,EAAE,oBAAoB,kBAAkB,SACtC,WACD;QAEH,UAAU,gBAAgB,SAAS,WAAW;QAC9C;QACA;QACA;QACA;QACA;kBAEA,qBAAC,OAAD;SAAK,WAAU;mBAAf,CACG,kBACC,oBAAC,OAAD;UAAK,WAAU;oBACZ,gBAAgB,SAAS,WAAW,IACnC,oBAAC,OAAD,EAAO,WAAU,aAAc;UAE7B,GAER,qBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,qBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,oBAAC,QAAD;YACE,KAAK,eAAe,WAAW;YAC/B,MAAM;sBAEL;YACI,GACP,oBAAC,QAAD;YAAM,WAAU;sBACb;YACI,EACH;cACN,oBAAC,QAAD;WAAM,WAAU;qBACb,WAAW,aAAa;WACpB,EACH;YACF;;QACC;OACN,EA1C4B,WA0C5B,CAER;MACE,EACJ,IAEK;;IACG,EACR;;EACP"}
1
+ {"version":3,"file":"LocaleSwitcherContent.mjs","names":[],"sources":["../../../../src/components/LocaleSwitcherContentDropDown/LocaleSwitcherContent.tsx"],"sourcesContent":["'use client';\n\nimport { usePersistedStore } from '@hooks/usePersistedStore';\nimport { getHTMLTextDir, getLocaleName } from '@intlayer/core/localization';\nimport { ENGLISH } from '@intlayer/types/locales';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport Fuse, { type IFuseOptions } from 'fuse.js';\nimport { Check, Globe, MoveVertical } from 'lucide-react';\nimport { type FC, useMemo, useRef, useState } from 'react';\nimport { useIntlayer, useLocale } from 'react-intlayer';\nimport {\n Button,\n ButtonColor,\n ButtonSize,\n ButtonTextAlign,\n ButtonVariant,\n} from '../Button';\nimport { Container } from '../Container';\nimport { DropDown, type PanelProps } from '../DropDown';\nimport { Input } from '../Input';\nimport {\n SwitchSelector,\n SwitchSelectorColor,\n SwitchSelectorSize,\n} from '../SwitchSelector';\nimport { useLocaleSwitcherContent } from './LocaleSwitcherContentContext';\n\nexport type LocaleSwitcherContentProps = {\n panelProps?: Omit<PanelProps, 'identifier'>;\n isMultilingual?: boolean;\n};\n\nconst DROPDOWN_IDENTIFIER = 'locale-switcher-content';\n\ntype MultilingualAvailableLocales = {\n locale: LocalesValues;\n englishName: string;\n currentLocaleName: string;\n ownLocaleName: string;\n};\n\nexport const LocaleSwitcherContent: FC<LocaleSwitcherContentProps> = ({\n panelProps,\n isMultilingual = true,\n}) => {\n const {\n switchTo,\n searchInput,\n localeSwitcherLabel,\n languageListLabel,\n seeAllLocalesSwitch,\n } = useIntlayer('locale-switcher-content');\n const inputRef = useRef<HTMLInputElement>(null);\n const { locale } = useLocale();\n const { availableLocales, selectedLocales, setSelectedLocales } =\n useLocaleSwitcherContent();\n\n // 1. Memoize the list construction so it doesn't rebuild every render\n const multilingualAvailableLocales: MultilingualAvailableLocales[] = useMemo(\n () =>\n availableLocales.map((localeEl) => {\n const englishName = getLocaleName(localeEl, ENGLISH);\n const currentLocaleName = getLocaleName(localeEl, locale);\n const ownLocaleName = getLocaleName(localeEl);\n return {\n locale: localeEl,\n englishName,\n currentLocaleName,\n ownLocaleName,\n };\n }),\n [availableLocales, locale]\n );\n\n // 2. State for Search Query only (Source of Truth)\n const [searchQuery, setSearchQuery] = useState('');\n\n const [seeAllLocales, setSeeAllLocales] = usePersistedStore(\n 'locale-content-selector-see-all-locales',\n false\n );\n\n // 3. Memoize Fuse instance\n const fuse = useMemo(() => {\n const fuseOptions: IFuseOptions<MultilingualAvailableLocales> = {\n keys: [\n { name: 'ownLocaleName', weight: 0.4 },\n { name: 'englishName', weight: 0.2 },\n { name: 'currentLocaleName', weight: 0.2 },\n { name: 'locale', weight: 0.2 },\n ],\n threshold: 0.02,\n };\n return new Fuse(multilingualAvailableLocales, fuseOptions);\n }, [multilingualAvailableLocales]);\n\n // 4. Derive results from Search Query\n const results = useMemo(() => {\n if (!searchQuery) {\n return multilingualAvailableLocales;\n }\n return fuse.search(searchQuery).map((result) => result.item);\n }, [searchQuery, multilingualAvailableLocales, fuse]);\n\n const handleClickLocale = (localeItem: LocalesValues) => {\n if (isMultilingual) {\n if (selectedLocales.includes(localeItem)) {\n if (selectedLocales.length > 1) {\n setSelectedLocales((prev) => prev.filter((el) => el !== localeItem));\n }\n } else {\n setSelectedLocales((prev) => [...prev, localeItem]);\n }\n } else {\n setSelectedLocales([localeItem]);\n }\n };\n\n const handleSeeAllLocales = (value: boolean) => {\n setSeeAllLocales(value);\n\n if (value) {\n setSelectedLocales(availableLocales);\n } else {\n setSelectedLocales([locale]);\n }\n };\n\n return (\n <div className=\"rounded-xl border border-text text-text transition-colors\">\n <DropDown identifier={DROPDOWN_IDENTIFIER}>\n <DropDown.Trigger\n identifier={DROPDOWN_IDENTIFIER}\n label={localeSwitcherLabel.value}\n className=\"p-0!\"\n roundedSize=\"3xl\"\n color=\"text\"\n variant=\"hoverable\"\n >\n <div className=\"flex w-full items-center justify-between text-text\">\n <div className=\"px-2 py-1\">\n <Globe size={16} />\n </div>\n <MoveVertical className=\"self-center\" size={16} />\n </div>\n </DropDown.Trigger>\n\n <DropDown.Panel\n identifier={DROPDOWN_IDENTIFIER}\n isOverable\n isFocusable\n align=\"end\"\n {...panelProps}\n >\n <Container\n className=\"max-h-[60vh] min-w-28\"\n separator=\"y\"\n role=\"listbox\"\n transparency=\"xs\"\n border\n roundedSize=\"3xl\"\n borderColor=\"text\"\n aria-label={languageListLabel.value}\n >\n {isMultilingual && (\n <div className=\"m-auto p-2\">\n <SwitchSelector\n defaultValue={seeAllLocales} // Ensure this uses the persisted state\n onChange={handleSeeAllLocales}\n color={SwitchSelectorColor.TEXT}\n size={SwitchSelectorSize.SM}\n className=\"!w-60\"\n choices={[\n {\n content: seeAllLocalesSwitch.true.value,\n value: true,\n },\n {\n content: seeAllLocalesSwitch.false.value,\n value: false,\n },\n ]}\n />\n </div>\n )}\n\n {!(isMultilingual && seeAllLocales) && (\n <>\n <div className=\"p-3\">\n <Input\n type=\"search\"\n aria-label={searchInput.ariaLabel.value}\n placeholder={searchInput.placeholder.value}\n // Update search query state directly\n onChange={(e) => setSearchQuery(e.target.value)}\n ref={inputRef}\n />\n </div>\n <ol className=\"divide-y divide-dashed divide-text/20 overflow-y-auto p-1\">\n {results.map(\n ({\n locale: localeItem,\n currentLocaleName,\n ownLocaleName,\n }) => (\n <li className=\"px-1.5 py-1\" key={localeItem}>\n <Button\n onClick={() => handleClickLocale(localeItem)}\n label={`${switchTo} ${currentLocaleName}`}\n disabled={\n !(availableLocales ?? availableLocales).includes(\n localeItem\n )\n }\n isActive={selectedLocales.includes(localeItem)}\n variant={ButtonVariant.HOVERABLE}\n color={ButtonColor.TEXT}\n isFullWidth\n textAlign={ButtonTextAlign.LEFT}\n size={ButtonSize.SM}\n >\n <div className=\"flex flex-row items-center justify-between gap-3 px-2 py-1\">\n {isMultilingual && (\n <div className=\"w-4\">\n {selectedLocales.includes(localeItem) && (\n <Check className=\"size-full\" />\n )}\n </div>\n )}\n <div className=\"flex flex-1 flex-row items-center justify-between gap-3 px-2 py-1\">\n <div className=\"flex flex-col text-nowrap\">\n <span\n dir={getHTMLTextDir(localeItem)}\n lang={localeItem}\n >\n {ownLocaleName}\n </span>\n <span className=\"text-neutral text-xs\">\n {currentLocaleName}\n </span>\n </div>\n <span className=\"text-neutral text-sm\">\n {localeItem.toUpperCase()}\n </span>\n </div>\n </div>\n </Button>\n </li>\n )\n )}\n </ol>\n </>\n )}\n </Container>\n </DropDown.Panel>\n </DropDown>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Navbar/index.tsx"],"sourcesContent":["'use client';\n\nimport { useDevice } from '@hooks/useDevice';\nimport { useIsMounted } from '@hooks/useIsMounted';\nimport type { ReactElement, ReactNode } from 'react';\nimport type { TabSelectorItemProps } from '../TabSelector';\nimport { DesktopNavbar } from './DesktopNavbar';\nimport { MobileNavbar } from './MobileNavbar';\n\n/**\n * Props for the responsive Navbar component\n * @template T - The tab props type extending TabProps\n */\ntype NavbarProps<T extends TabSelectorItemProps> = {\n /** Logo component or element to display in navbar */\n logo: ReactNode;\n /** Currently selected tab key for active state management */\n selectedChoice: T['key'];\n /** Navigation sections displayed on desktop layout */\n desktopSections?: ReactElement<T>[];\n /** Additional content displayed at top of mobile navbar */\n mobileTopChildren?: ReactNode;\n /** Navigation sections displayed at top of mobile navbar */\n mobileTopSections?: ReactElement<T>[];\n /** Additional content displayed at bottom of mobile navbar */\n mobileBottomChildren?: ReactNode;\n /** Navigation sections displayed at bottom of mobile navbar */\n mobileBottomSections?: ReactElement<T>[];\n /** Right-aligned items for desktop navbar (e.g., user menu, settings) */\n rightItemsDesktop?: ReactNode;\n /** Right-aligned items for mobile navbar */\n rightItemsMobile?: ReactNode;\n /** Whether the mobile navbar should be rollable (default: true) */\n mobileRollable?: boolean;\n};\n\n/**\n * Responsive Navbar Component\n *\n * A highly adaptable navigation component that automatically switches between desktop and mobile\n * layouts based on screen size. Provides comprehensive navigation structure with flexible content areas.\n *\n * Features:\n * - Automatic responsive switching at 'lg' breakpoint (1024px)\n * - Separate section configurations for desktop and mobile layouts\n * - Support for logo placement and right-aligned utility items\n * - Generic typing for tab properties and selected states\n * - Mobile-specific top/bottom content areas for enhanced mobile UX\n * - Hydration-safe rendering with useIsMounted hook\n *\n * @example\n * Basic usage:\n * ```tsx\n * const navSections = [\n * { key: 'home', label: 'Home', href: '/' },\n * { key: 'about', label: 'About', href: '/about' }\n * ];\n *\n * <Navbar\n * logo={<Logo />}\n * selectedChoice=\"home\"\n * desktopSections={navSections}\n * mobileTopSections={navSections}\n * rightItemsDesktop={<UserMenu />}\n * />\n * ```\n *\n * @example\n * Advanced mobile configuration:\n * ```tsx\n * <Navbar\n * logo={<Logo />}\n * selectedChoice={activeTab}\n * desktopSections={mainNavItems}\n * mobileTopSections={primaryMobileNavItems}\n * mobileTopChildren={<SearchBar />}\n * mobileBottomSections={secondaryMobileNavItems}\n * mobileBottomChildren={<UserProfile />}\n * rightItemsDesktop={<DesktopActions />}\n * rightItemsMobile={<MobileActions />}\n * />\n * ```\n *\n * Responsive Behavior:\n * - Desktop (≥1024px): Shows DesktopNavbar with horizontal layout\n * - Mobile (<1024px): Shows MobileNavbar with collapsible vertical layout\n * - Automatic detection with no flash of unstyled content\n *\n * @template T - Tab properties type extending TabProps for type safety\n * @param props - Navbar component props\n * @returns Responsive navbar JSX element\n */\nexport { Burger } from './Burger';\nexport { DesktopNavbar } from './DesktopNavbar';\nexport { MobileNavbar } from './MobileNavbar';\n\nexport const Navbar = <T extends TabSelectorItemProps>({\n logo,\n mobileTopChildren,\n desktopSections = [],\n mobileTopSections = [],\n mobileBottomChildren,\n mobileBottomSections = [],\n rightItemsDesktop,\n rightItemsMobile,\n selectedChoice,\n mobileRollable = true,\n}: NavbarProps<T>) => {\n const { isMobile } = useDevice('lg');\n\n return isMobile ? (\n <MobileNavbar\n topChildren={mobileTopChildren}\n topSections={mobileTopSections}\n bottomChildren={mobileBottomChildren}\n bottomSections={mobileBottomSections}\n logo={logo}\n rightItems={rightItemsMobile}\n rollable={mobileRollable}\n />\n ) : (\n <DesktopNavbar\n sections={desktopSections}\n rightItems={rightItemsDesktop}\n logo={logo}\n selectedChoice={selectedChoice}\n />\n );\n};\n"],"mappings":";;;;;;;;;AAgGA,MAAa,UAA0C,EACrD,MACA,mBACA,kBAAkB,EAAE,EACpB,oBAAoB,EAAE,EACtB,sBACA,uBAAuB,EAAE,EACzB,mBACA,kBACA,gBACA,iBAAiB,WACG;CACpB,MAAM,EAAE,aAAa,UAAU,KAAK;AAEpC,QAAO,WACL,oBAAC,cAAD;EACE,aAAa;EACb,aAAa;EACb,gBAAgB;EAChB,gBAAgB;EACV;EACN,YAAY;EACZ,UAAU;EACV,IAEF,oBAAC,eAAD;EACE,UAAU;EACV,YAAY;EACN;EACU;EAChB"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Navbar/index.tsx"],"sourcesContent":["'use client';\n\nimport { useDevice } from '@hooks/useDevice';\nimport type { ReactElement, ReactNode } from 'react';\nimport type { TabSelectorItemProps } from '../TabSelector';\nimport { DesktopNavbar } from './DesktopNavbar';\nimport { MobileNavbar } from './MobileNavbar';\n\n/**\n * Props for the responsive Navbar component\n * @template T - The tab props type extending TabProps\n */\ntype NavbarProps<T extends TabSelectorItemProps> = {\n /** Logo component or element to display in navbar */\n logo: ReactNode;\n /** Currently selected tab key for active state management */\n selectedChoice: T['key'];\n /** Navigation sections displayed on desktop layout */\n desktopSections?: ReactElement<T>[];\n /** Additional content displayed at top of mobile navbar */\n mobileTopChildren?: ReactNode;\n /** Navigation sections displayed at top of mobile navbar */\n mobileTopSections?: ReactElement<T>[];\n /** Additional content displayed at bottom of mobile navbar */\n mobileBottomChildren?: ReactNode;\n /** Navigation sections displayed at bottom of mobile navbar */\n mobileBottomSections?: ReactElement<T>[];\n /** Right-aligned items for desktop navbar (e.g., user menu, settings) */\n rightItemsDesktop?: ReactNode;\n /** Right-aligned items for mobile navbar */\n rightItemsMobile?: ReactNode;\n /** Whether the mobile navbar should be rollable (default: true) */\n mobileRollable?: boolean;\n};\n\n/**\n * Responsive Navbar Component\n *\n * A highly adaptable navigation component that automatically switches between desktop and mobile\n * layouts based on screen size. Provides comprehensive navigation structure with flexible content areas.\n *\n * Features:\n * - Automatic responsive switching at 'lg' breakpoint (1024px)\n * - Separate section configurations for desktop and mobile layouts\n * - Support for logo placement and right-aligned utility items\n * - Generic typing for tab properties and selected states\n * - Mobile-specific top/bottom content areas for enhanced mobile UX\n * - Hydration-safe rendering with useIsMounted hook\n *\n * @example\n * Basic usage:\n * ```tsx\n * const navSections = [\n * { key: 'home', label: 'Home', href: '/' },\n * { key: 'about', label: 'About', href: '/about' }\n * ];\n *\n * <Navbar\n * logo={<Logo />}\n * selectedChoice=\"home\"\n * desktopSections={navSections}\n * mobileTopSections={navSections}\n * rightItemsDesktop={<UserMenu />}\n * />\n * ```\n *\n * @example\n * Advanced mobile configuration:\n * ```tsx\n * <Navbar\n * logo={<Logo />}\n * selectedChoice={activeTab}\n * desktopSections={mainNavItems}\n * mobileTopSections={primaryMobileNavItems}\n * mobileTopChildren={<SearchBar />}\n * mobileBottomSections={secondaryMobileNavItems}\n * mobileBottomChildren={<UserProfile />}\n * rightItemsDesktop={<DesktopActions />}\n * rightItemsMobile={<MobileActions />}\n * />\n * ```\n *\n * Responsive Behavior:\n * - Desktop (≥1024px): Shows DesktopNavbar with horizontal layout\n * - Mobile (<1024px): Shows MobileNavbar with collapsible vertical layout\n * - Automatic detection with no flash of unstyled content\n *\n * @template T - Tab properties type extending TabProps for type safety\n * @param props - Navbar component props\n * @returns Responsive navbar JSX element\n */\nexport { Burger } from './Burger';\nexport { DesktopNavbar } from './DesktopNavbar';\nexport { MobileNavbar } from './MobileNavbar';\n\nexport const Navbar = <T extends TabSelectorItemProps>({\n logo,\n mobileTopChildren,\n desktopSections = [],\n mobileTopSections = [],\n mobileBottomChildren,\n mobileBottomSections = [],\n rightItemsDesktop,\n rightItemsMobile,\n selectedChoice,\n mobileRollable = true,\n}: NavbarProps<T>) => {\n const { isMobile } = useDevice('lg');\n\n return isMobile ? (\n <MobileNavbar\n topChildren={mobileTopChildren}\n topSections={mobileTopSections}\n bottomChildren={mobileBottomChildren}\n bottomSections={mobileBottomSections}\n logo={logo}\n rightItems={rightItemsMobile}\n rollable={mobileRollable}\n />\n ) : (\n <DesktopNavbar\n sections={desktopSections}\n rightItems={rightItemsDesktop}\n logo={logo}\n selectedChoice={selectedChoice}\n />\n );\n};\n"],"mappings":";;;;;;;;;AA+FA,MAAa,UAA0C,EACrD,MACA,mBACA,kBAAkB,EAAE,EACpB,oBAAoB,EAAE,EACtB,sBACA,uBAAuB,EAAE,EACzB,mBACA,kBACA,gBACA,iBAAiB,WACG;CACpB,MAAM,EAAE,aAAa,UAAU,KAAK;AAEpC,QAAO,WACL,oBAAC,cAAD;EACE,aAAa;EACb,aAAa;EACb,gBAAgB;EAChB,gBAAgB;EACV;EACN,YAAY;EACZ,UAAU;EACV,IAEF,oBAAC,eAAD;EACE,UAAU;EACV,YAAY;EACN;EACU;EAChB"}
@@ -182,7 +182,7 @@ const Detail = ({ children, isHidden = void 0, isOverable = true, isFocusable =
182
182
  "aria-hidden": isHidden,
183
183
  "aria-labelledby": `unrollable-panel-button-${identifier}`,
184
184
  id: `unrollable-panel-${identifier}`,
185
- className: cn("absolute z-50 min-w-full rounded-md ring-1 ring-neutral", xAlign === "start" && "left-0", xAlign === "center" && "left-1/2 -translate-x-1/2", xAlign === "end" && "right-0", yAlign === "bellow" && "top-[calc(100%+1rem)]", yAlign === "above" && "bottom-[calc(100%+1rem)]", displayArrow && "before:absolute before:z-[999] before:h-0 before:w-0 before:content-[\"\"]", displayArrow && xAlign === "start" && "before:left-2", displayArrow && xAlign === "center" && "before:left-1/2 before:-translate-x-1/2", displayArrow && xAlign === "end" && "before:right-2", displayArrow && yAlign === "bellow" && "before:-top-[10px] before:border-r-[10px] before:border-r-transparent before:border-b-[10px] before:border-b-neutral before:border-l-[10px] before:border-l-transparent", displayArrow && yAlign === "above" && "before:-bottom-[10px] before:border-t-[10px] before:border-t-neutral before:border-r-[10px] before:border-r-transparent before:border-l-[10px] before:border-l-transparent", "overflow-x-visible opacity-0 transition-all duration-400 ease-in-out", isHidden !== false ? "invisible" : "visible opacity-100 delay-800", isOverable && `group-hover/popover:visible group-hover/popover:opacity-100 group-hover/popover:delay-800`, isFocusable && `group-focus-within/popover:visible group-focus-within/popover:opacity-100 group-focus-within/popover:delay-800`, className),
185
+ className: cn("absolute z-60 min-w-full rounded-md ring-1 ring-neutral", xAlign === "start" && "left-0", xAlign === "center" && "left-1/2 -translate-x-1/2", xAlign === "end" && "right-0", yAlign === "bellow" && "top-[calc(100%+1rem)]", yAlign === "above" && "bottom-[calc(100%+1rem)]", displayArrow && "before:absolute before:z-[999] before:h-0 before:w-0 before:content-[\"\"]", displayArrow && xAlign === "start" && "before:left-2", displayArrow && xAlign === "center" && "before:left-1/2 before:-translate-x-1/2", displayArrow && xAlign === "end" && "before:right-2", displayArrow && yAlign === "bellow" && "before:-top-[10px] before:border-r-[10px] before:border-r-transparent before:border-b-[10px] before:border-b-neutral before:border-l-[10px] before:border-l-transparent", displayArrow && yAlign === "above" && "before:-bottom-[10px] before:border-t-[10px] before:border-t-neutral before:border-r-[10px] before:border-r-transparent before:border-l-[10px] before:border-l-transparent", "overflow-x-visible opacity-0 transition-all duration-400 ease-in-out", isHidden !== false ? "invisible" : "visible opacity-100 delay-800", isOverable && `group-hover/popover:visible group-hover/popover:opacity-100 group-hover/popover:delay-800`, isFocusable && `group-focus-within/popover:visible group-focus-within/popover:opacity-100 group-focus-within/popover:delay-800`, className),
186
186
  ...props,
187
187
  children
188
188
  });
@@ -1 +1 @@
1
- {"version":3,"file":"static.mjs","names":[],"sources":["../../../../src/components/Popover/static.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport type { DetailedHTMLProps, FC, HTMLAttributes } from 'react';\nimport { Container } from '../Container';\n\n/**\n * Props for the main Popover component\n * Extends HTMLDivElement attributes for full DOM compatibility\n */\nexport type PopoverProps = DetailedHTMLProps<\n HTMLAttributes<HTMLDivElement>,\n HTMLDivElement\n> & {\n /** Unique identifier linking the trigger to its popover content for accessibility */\n identifier: string;\n};\n\n/**\n * Composite type for the Popover component with Detail subcomponent\n * Allows for Popover.Detail usage pattern\n */\nexport type PopoverType = FC<PopoverProps> & {\n Detail: FC<DetailProps>;\n};\n\n/**\n * Horizontal alignment options for popover positioning\n */\nexport enum PopoverXAlign {\n /** Align popover to start (left) of trigger */\n START = 'start',\n /** Align popover to center of trigger */\n CENTER = 'center',\n /** Align popover to end (right) of trigger */\n END = 'end',\n}\n\n/**\n * Vertical alignment options for popover positioning\n */\nexport enum PopoverYAlign {\n /** Position popover below the trigger */\n BELOW = 'bellow',\n /** Position popover above the trigger */\n ABOVE = 'above',\n}\n\n/**\n * Popover Component\n *\n * A versatile popover container that displays contextual content when triggered by hover\n * or focus interactions. Built with accessibility in mind and supports multiple positioning\n * options with smooth animations.\n *\n * Features:\n * - Hover and focus-based triggering\n * - Multiple positioning options (above/below, start/center/end)\n * - Accessibility compliant with ARIA attributes\n * - Smooth animations with configurable delays\n * - Optional directional arrows\n * - Automatic z-index management\n * - Responsive design support\n *\n * Architecture:\n * - Main Popover acts as trigger container\n * - Popover.Detail renders the actual popover content\n * - Uses CSS groups for coordinated hover/focus states\n * - Unique identifier system prevents conflicts\n *\n * @example\n * Basic hover popover:\n * ```jsx\n * <Popover identifier=\"help-tooltip\">\n * <button>Need Help?</button>\n *\n * <Popover.Detail identifier=\"help-tooltip\">\n * <div>This is helpful information!</div>\n * </Popover.Detail>\n * </Popover>\n * ```\n *\n * @example\n * Focus-triggered popover:\n * ```jsx\n * <Popover identifier=\"focus-menu\">\n * <input placeholder=\"Focus me\" />\n *\n * <Popover.Detail\n * identifier=\"focus-menu\"\n * isFocusable\n * isOverable={false}\n * >\n * <div>Focus-only menu content</div>\n * </Popover.Detail>\n * </Popover>\n * ```\n *\n * @example\n * Positioned popover with custom alignment:\n * ```jsx\n * <Popover identifier=\"positioned\">\n * <span>Hover me</span>\n *\n * <Popover.Detail\n * identifier=\"positioned\"\n * xAlign={PopoverXAlign.END}\n * yAlign={PopoverYAlign.ABOVE}\n * displayArrow={false}\n * >\n * <div>Above and right-aligned</div>\n * </Popover.Detail>\n * </Popover>\n * ```\n *\n * Accessibility Features:\n * - Proper ARIA labeling and relationships\n * - Keyboard navigation support\n * - Screen reader compatibility\n * - Focus management\n *\n * Performance Considerations:\n * - CSS-only animations for smooth transitions\n * - Efficient group-based state management\n * - Minimal DOM updates during interactions\n *\n * @param props - Popover component props\n * @returns Trigger container with popover functionality\n */\nexport const PopoverStatic: PopoverType = ({\n children,\n className,\n identifier,\n ...props\n}) => (\n <div\n className={cn(`group/popover relative flex cursor-pointer`, className)}\n id={`unrollable-panel-button-${identifier}`}\n aria-haspopup\n {...props}\n >\n {children}\n </div>\n);\n\n/**\n * Props for the Popover.Detail component\n * Extends HTMLDivElement attributes for styling flexibility\n */\nexport type DetailProps = HTMLAttributes<HTMLDivElement> & {\n /** Whether the popover responds to focus events on the trigger */\n isFocusable?: boolean;\n /** Controls visibility state - undefined allows automatic hover/focus control */\n isHidden?: boolean;\n /** Whether the popover responds to hover events on the trigger */\n isOverable?: boolean;\n /** Unique identifier matching the trigger's identifier for accessibility */\n identifier: string;\n /** Horizontal positioning relative to trigger */\n xAlign?: PopoverXAlign | `${PopoverXAlign}`;\n /** Vertical positioning relative to trigger */\n yAlign?: PopoverYAlign | `${PopoverYAlign}`;\n /** Whether to display the directional arrow indicator */\n displayArrow?: boolean;\n};\n\n/**\n * Popover Detail Component\n *\n * The actual popover content container with advanced positioning, animation, and\n * accessibility features. Automatically manages visibility based on trigger interactions.\n *\n * Features:\n * - Precise positioning with alignment options\n * - Smooth fade and slide animations\n * - Configurable directional arrows\n * - Hover and focus interaction support\n * - Accessibility-compliant ARIA attributes\n * - High z-index for overlay behavior\n * - Automatic visibility management\n *\n * Positioning System:\n * - X-axis: START (left-aligned), CENTER (centered), or END (right-aligned)\n * - Y-axis: BELOW (underneath) or ABOVE (on top)\n * - Automatic spacing with 1rem gap from trigger\n * - Responsive minimum width matching trigger\n *\n * Arrow Indicators:\n * - CSS-generated triangular arrows\n * - Positioned based on alignment settings\n * - Points toward trigger for visual connection\n * - Can be disabled for clean, minimal appearance\n *\n * Animation Behavior:\n * - Starts invisible with opacity: 0\n * - Smooth 400ms transitions with easing\n * - 800ms delay for hover states (prevents flicker)\n * - Immediate hiding when trigger loses focus/hover\n *\n * @example\n * Rich content popover:\n * ```jsx\n * <Popover.Detail identifier=\"rich-content\">\n * <div className=\"p-4\">\n * <h3>Popover Title</h3>\n * <p>Detailed information with multiple paragraphs.</p>\n * <button>Action Button</button>\n * </div>\n * </Popover.Detail>\n * ```\n *\n * @example\n * Menu-style popover:\n * ```jsx\n * <Popover.Detail\n * identifier=\"context-menu\"\n * displayArrow={false}\n * xAlign={PopoverXAlign.END}\n * >\n * <ul className=\"py-2\">\n * <li><button className=\"w-full px-4 py-2\">Edit</button></li>\n * <li><button className=\"w-full px-4 py-2\">Delete</button></li>\n * </ul>\n * </Popover.Detail>\n * ```\n *\n * @param props - Popover Detail component props\n * @returns Positioned popover content with animations and accessibility\n */\nconst Detail: FC<DetailProps> = ({\n children,\n isHidden = undefined,\n isOverable = true,\n isFocusable = false,\n xAlign = PopoverXAlign.START,\n yAlign = PopoverYAlign.BELOW,\n identifier,\n className,\n displayArrow = true,\n ...props\n}) => (\n <Container\n transparency=\"xs\"\n role=\"group\"\n aria-hidden={isHidden}\n aria-labelledby={`unrollable-panel-button-${identifier}`}\n id={`unrollable-panel-${identifier}`}\n className={cn(\n 'absolute z-50 min-w-full rounded-md ring-1 ring-neutral',\n\n /* Positioning */\n xAlign === 'start' && 'left-0',\n xAlign === 'center' && 'left-1/2 -translate-x-1/2',\n xAlign === 'end' && 'right-0',\n yAlign === 'bellow' && 'top-[calc(100%+1rem)]',\n yAlign === 'above' && 'bottom-[calc(100%+1rem)]',\n\n /* Arrow indicator */\n displayArrow &&\n 'before:absolute before:z-[999] before:h-0 before:w-0 before:content-[\"\"]',\n\n /* Horizontal positioning */\n displayArrow && xAlign === 'start' && 'before:left-2',\n displayArrow &&\n xAlign === 'center' &&\n 'before:left-1/2 before:-translate-x-1/2',\n displayArrow && xAlign === 'end' && 'before:right-2',\n\n /* Arrow pointing up (when popover is below trigger) */\n displayArrow &&\n yAlign === 'bellow' &&\n 'before:-top-[10px] before:border-r-[10px] before:border-r-transparent before:border-b-[10px] before:border-b-neutral before:border-l-[10px] before:border-l-transparent',\n\n /* Arrow pointing down (when popover is above trigger) */\n displayArrow &&\n yAlign === 'above' &&\n 'before:-bottom-[10px] before:border-t-[10px] before:border-t-neutral before:border-r-[10px] before:border-r-transparent before:border-l-[10px] before:border-l-transparent',\n\n /* Visibility management */\n 'overflow-x-visible opacity-0 transition-all duration-400 ease-in-out',\n isHidden !== false ? 'invisible' : 'visible opacity-100 delay-800',\n isOverable &&\n `group-hover/popover:visible group-hover/popover:opacity-100 group-hover/popover:delay-800`,\n isFocusable &&\n `group-focus-within/popover:visible group-focus-within/popover:opacity-100 group-focus-within/popover:delay-800`,\n className\n )}\n {...props}\n >\n {children}\n </Container>\n);\n\nPopoverStatic.Detail = Detail;\n\n// Export Detail for use in dynamic version\nexport { Detail };\n"],"mappings":";;;;;;;;AA2BA,IAAY,gBAAL;;AAEL;;AAEA;;AAEA;;KACD;;;;AAKD,IAAY,gBAAL;;AAEL;;AAEA;;KACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmFD,MAAa,iBAA8B,EACzC,UACA,WACA,YACA,GAAG,YAEH,oBAAC,OAAD;CACE,WAAW,GAAG,8CAA8C,UAAU;CACtE,IAAI,2BAA2B;CAC/B;CACA,GAAI;CAEH;CACG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuFR,MAAM,UAA2B,EAC/B,UACA,WAAW,QACX,aAAa,MACb,cAAc,OACd,kBACA,mBACA,YACA,WACA,eAAe,MACf,GAAG,YAEH,oBAAC,WAAD;CACE,cAAa;CACb,MAAK;CACL,eAAa;CACb,mBAAiB,2BAA2B;CAC5C,IAAI,oBAAoB;CACxB,WAAW,GACT,2DAGA,WAAW,WAAW,UACtB,WAAW,YAAY,6BACvB,WAAW,SAAS,WACpB,WAAW,YAAY,yBACvB,WAAW,WAAW,4BAGtB,gBACE,8EAGF,gBAAgB,WAAW,WAAW,iBACtC,gBACE,WAAW,YACX,2CACF,gBAAgB,WAAW,SAAS,kBAGpC,gBACE,WAAW,YACX,2KAGF,gBACE,WAAW,WACX,8KAGF,wEACA,aAAa,QAAQ,cAAc,iCACnC,cACE,6FACF,eACE,kHACF,UACD;CACD,GAAI;CAEH;CACS;AAGd,cAAc,SAAS"}
1
+ {"version":3,"file":"static.mjs","names":[],"sources":["../../../../src/components/Popover/static.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport type { DetailedHTMLProps, FC, HTMLAttributes } from 'react';\nimport { Container } from '../Container';\n\n/**\n * Props for the main Popover component\n * Extends HTMLDivElement attributes for full DOM compatibility\n */\nexport type PopoverProps = DetailedHTMLProps<\n HTMLAttributes<HTMLDivElement>,\n HTMLDivElement\n> & {\n /** Unique identifier linking the trigger to its popover content for accessibility */\n identifier: string;\n};\n\n/**\n * Composite type for the Popover component with Detail subcomponent\n * Allows for Popover.Detail usage pattern\n */\nexport type PopoverType = FC<PopoverProps> & {\n Detail: FC<DetailProps>;\n};\n\n/**\n * Horizontal alignment options for popover positioning\n */\nexport enum PopoverXAlign {\n /** Align popover to start (left) of trigger */\n START = 'start',\n /** Align popover to center of trigger */\n CENTER = 'center',\n /** Align popover to end (right) of trigger */\n END = 'end',\n}\n\n/**\n * Vertical alignment options for popover positioning\n */\nexport enum PopoverYAlign {\n /** Position popover below the trigger */\n BELOW = 'bellow',\n /** Position popover above the trigger */\n ABOVE = 'above',\n}\n\n/**\n * Popover Component\n *\n * A versatile popover container that displays contextual content when triggered by hover\n * or focus interactions. Built with accessibility in mind and supports multiple positioning\n * options with smooth animations.\n *\n * Features:\n * - Hover and focus-based triggering\n * - Multiple positioning options (above/below, start/center/end)\n * - Accessibility compliant with ARIA attributes\n * - Smooth animations with configurable delays\n * - Optional directional arrows\n * - Automatic z-index management\n * - Responsive design support\n *\n * Architecture:\n * - Main Popover acts as trigger container\n * - Popover.Detail renders the actual popover content\n * - Uses CSS groups for coordinated hover/focus states\n * - Unique identifier system prevents conflicts\n *\n * @example\n * Basic hover popover:\n * ```jsx\n * <Popover identifier=\"help-tooltip\">\n * <button>Need Help?</button>\n *\n * <Popover.Detail identifier=\"help-tooltip\">\n * <div>This is helpful information!</div>\n * </Popover.Detail>\n * </Popover>\n * ```\n *\n * @example\n * Focus-triggered popover:\n * ```jsx\n * <Popover identifier=\"focus-menu\">\n * <input placeholder=\"Focus me\" />\n *\n * <Popover.Detail\n * identifier=\"focus-menu\"\n * isFocusable\n * isOverable={false}\n * >\n * <div>Focus-only menu content</div>\n * </Popover.Detail>\n * </Popover>\n * ```\n *\n * @example\n * Positioned popover with custom alignment:\n * ```jsx\n * <Popover identifier=\"positioned\">\n * <span>Hover me</span>\n *\n * <Popover.Detail\n * identifier=\"positioned\"\n * xAlign={PopoverXAlign.END}\n * yAlign={PopoverYAlign.ABOVE}\n * displayArrow={false}\n * >\n * <div>Above and right-aligned</div>\n * </Popover.Detail>\n * </Popover>\n * ```\n *\n * Accessibility Features:\n * - Proper ARIA labeling and relationships\n * - Keyboard navigation support\n * - Screen reader compatibility\n * - Focus management\n *\n * Performance Considerations:\n * - CSS-only animations for smooth transitions\n * - Efficient group-based state management\n * - Minimal DOM updates during interactions\n *\n * @param props - Popover component props\n * @returns Trigger container with popover functionality\n */\nexport const PopoverStatic: PopoverType = ({\n children,\n className,\n identifier,\n ...props\n}) => (\n <div\n className={cn(`group/popover relative flex cursor-pointer`, className)}\n id={`unrollable-panel-button-${identifier}`}\n aria-haspopup\n {...props}\n >\n {children}\n </div>\n);\n\n/**\n * Props for the Popover.Detail component\n * Extends HTMLDivElement attributes for styling flexibility\n */\nexport type DetailProps = HTMLAttributes<HTMLDivElement> & {\n /** Whether the popover responds to focus events on the trigger */\n isFocusable?: boolean;\n /** Controls visibility state - undefined allows automatic hover/focus control */\n isHidden?: boolean;\n /** Whether the popover responds to hover events on the trigger */\n isOverable?: boolean;\n /** Unique identifier matching the trigger's identifier for accessibility */\n identifier: string;\n /** Horizontal positioning relative to trigger */\n xAlign?: PopoverXAlign | `${PopoverXAlign}`;\n /** Vertical positioning relative to trigger */\n yAlign?: PopoverYAlign | `${PopoverYAlign}`;\n /** Whether to display the directional arrow indicator */\n displayArrow?: boolean;\n};\n\n/**\n * Popover Detail Component\n *\n * The actual popover content container with advanced positioning, animation, and\n * accessibility features. Automatically manages visibility based on trigger interactions.\n *\n * Features:\n * - Precise positioning with alignment options\n * - Smooth fade and slide animations\n * - Configurable directional arrows\n * - Hover and focus interaction support\n * - Accessibility-compliant ARIA attributes\n * - High z-index for overlay behavior\n * - Automatic visibility management\n *\n * Positioning System:\n * - X-axis: START (left-aligned), CENTER (centered), or END (right-aligned)\n * - Y-axis: BELOW (underneath) or ABOVE (on top)\n * - Automatic spacing with 1rem gap from trigger\n * - Responsive minimum width matching trigger\n *\n * Arrow Indicators:\n * - CSS-generated triangular arrows\n * - Positioned based on alignment settings\n * - Points toward trigger for visual connection\n * - Can be disabled for clean, minimal appearance\n *\n * Animation Behavior:\n * - Starts invisible with opacity: 0\n * - Smooth 400ms transitions with easing\n * - 800ms delay for hover states (prevents flicker)\n * - Immediate hiding when trigger loses focus/hover\n *\n * @example\n * Rich content popover:\n * ```jsx\n * <Popover.Detail identifier=\"rich-content\">\n * <div className=\"p-4\">\n * <h3>Popover Title</h3>\n * <p>Detailed information with multiple paragraphs.</p>\n * <button>Action Button</button>\n * </div>\n * </Popover.Detail>\n * ```\n *\n * @example\n * Menu-style popover:\n * ```jsx\n * <Popover.Detail\n * identifier=\"context-menu\"\n * displayArrow={false}\n * xAlign={PopoverXAlign.END}\n * >\n * <ul className=\"py-2\">\n * <li><button className=\"w-full px-4 py-2\">Edit</button></li>\n * <li><button className=\"w-full px-4 py-2\">Delete</button></li>\n * </ul>\n * </Popover.Detail>\n * ```\n *\n * @param props - Popover Detail component props\n * @returns Positioned popover content with animations and accessibility\n */\nconst Detail: FC<DetailProps> = ({\n children,\n isHidden = undefined,\n isOverable = true,\n isFocusable = false,\n xAlign = PopoverXAlign.START,\n yAlign = PopoverYAlign.BELOW,\n identifier,\n className,\n displayArrow = true,\n ...props\n}) => (\n <Container\n transparency=\"xs\"\n role=\"group\"\n aria-hidden={isHidden}\n aria-labelledby={`unrollable-panel-button-${identifier}`}\n id={`unrollable-panel-${identifier}`}\n className={cn(\n 'absolute z-60 min-w-full rounded-md ring-1 ring-neutral',\n\n /* Positioning */\n xAlign === 'start' && 'left-0',\n xAlign === 'center' && 'left-1/2 -translate-x-1/2',\n xAlign === 'end' && 'right-0',\n yAlign === 'bellow' && 'top-[calc(100%+1rem)]',\n yAlign === 'above' && 'bottom-[calc(100%+1rem)]',\n\n /* Arrow indicator */\n displayArrow &&\n 'before:absolute before:z-[999] before:h-0 before:w-0 before:content-[\"\"]',\n\n /* Horizontal positioning */\n displayArrow && xAlign === 'start' && 'before:left-2',\n displayArrow &&\n xAlign === 'center' &&\n 'before:left-1/2 before:-translate-x-1/2',\n displayArrow && xAlign === 'end' && 'before:right-2',\n\n /* Arrow pointing up (when popover is below trigger) */\n displayArrow &&\n yAlign === 'bellow' &&\n 'before:-top-[10px] before:border-r-[10px] before:border-r-transparent before:border-b-[10px] before:border-b-neutral before:border-l-[10px] before:border-l-transparent',\n\n /* Arrow pointing down (when popover is above trigger) */\n displayArrow &&\n yAlign === 'above' &&\n 'before:-bottom-[10px] before:border-t-[10px] before:border-t-neutral before:border-r-[10px] before:border-r-transparent before:border-l-[10px] before:border-l-transparent',\n\n /* Visibility management */\n 'overflow-x-visible opacity-0 transition-all duration-400 ease-in-out',\n isHidden !== false ? 'invisible' : 'visible opacity-100 delay-800',\n isOverable &&\n `group-hover/popover:visible group-hover/popover:opacity-100 group-hover/popover:delay-800`,\n isFocusable &&\n `group-focus-within/popover:visible group-focus-within/popover:opacity-100 group-focus-within/popover:delay-800`,\n className\n )}\n {...props}\n >\n {children}\n </Container>\n);\n\nPopoverStatic.Detail = Detail;\n\n// Export Detail for use in dynamic version\nexport { Detail };\n"],"mappings":";;;;;;;;AA2BA,IAAY,gBAAL;;AAEL;;AAEA;;AAEA;;KACD;;;;AAKD,IAAY,gBAAL;;AAEL;;AAEA;;KACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmFD,MAAa,iBAA8B,EACzC,UACA,WACA,YACA,GAAG,YAEH,oBAAC,OAAD;CACE,WAAW,GAAG,8CAA8C,UAAU;CACtE,IAAI,2BAA2B;CAC/B;CACA,GAAI;CAEH;CACG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuFR,MAAM,UAA2B,EAC/B,UACA,WAAW,QACX,aAAa,MACb,cAAc,OACd,kBACA,mBACA,YACA,WACA,eAAe,MACf,GAAG,YAEH,oBAAC,WAAD;CACE,cAAa;CACb,MAAK;CACL,eAAa;CACb,mBAAiB,2BAA2B;CAC5C,IAAI,oBAAoB;CACxB,WAAW,GACT,2DAGA,WAAW,WAAW,UACtB,WAAW,YAAY,6BACvB,WAAW,SAAS,WACpB,WAAW,YAAY,yBACvB,WAAW,WAAW,4BAGtB,gBACE,8EAGF,gBAAgB,WAAW,WAAW,iBACtC,gBACE,WAAW,YACX,2CACF,gBAAgB,WAAW,SAAS,kBAGpC,gBACE,WAAW,YACX,2KAGF,gBACE,WAAW,WACX,8KAGF,wEACA,aAAa,QAAQ,cAAc,iCACnC,cACE,6FACF,eACE,kHACF,UACD;CACD,GAAI;CAEH;CACS;AAGd,cAAc,SAAS"}
@@ -0,0 +1,127 @@
1
+ 'use client';
2
+
3
+ import { cn } from "../../utils/cn.mjs";
4
+ import { useSwitchSelector } from "./useSwitchSelector.mjs";
5
+ import { createElement } from "react";
6
+ import { cva } from "class-variance-authority";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+
9
+ //#region src/components/SwitchSelector/SwitchSelector.tsx
10
+ const defaultChoices = [{
11
+ content: "Off",
12
+ value: false
13
+ }, {
14
+ content: "On",
15
+ value: true
16
+ }];
17
+ let SwitchSelectorColor = /* @__PURE__ */ function(SwitchSelectorColor) {
18
+ SwitchSelectorColor["PRIMARY"] = "primary";
19
+ SwitchSelectorColor["SECONDARY"] = "secondary";
20
+ SwitchSelectorColor["DESTRUCTIVE"] = "destructive";
21
+ SwitchSelectorColor["NEUTRAL"] = "neutral";
22
+ SwitchSelectorColor["LIGHT"] = "light";
23
+ SwitchSelectorColor["DARK"] = "dark";
24
+ SwitchSelectorColor["TEXT"] = "text";
25
+ return SwitchSelectorColor;
26
+ }({});
27
+ let SwitchSelectorSize = /* @__PURE__ */ function(SwitchSelectorSize) {
28
+ SwitchSelectorSize["SM"] = "sm";
29
+ SwitchSelectorSize["MD"] = "md";
30
+ SwitchSelectorSize["LG"] = "lg";
31
+ return SwitchSelectorSize;
32
+ }({});
33
+ const switchSelectorVariant = cva("flex h-fit w-fit cursor-pointer flex-row gap-2 rounded-full border-[1.3px] p-[1.5px]", {
34
+ variants: {
35
+ color: {
36
+ [`primary`]: "border-primary text-primary",
37
+ [`secondary`]: "border-secondary text-secondary",
38
+ [`destructive`]: "border-destructive bg-destructive text-destructive",
39
+ [`neutral`]: "border-neutral text-neutral",
40
+ [`light`]: "border-white text-white",
41
+ [`dark`]: "border-neutral-800 text-neutral-800",
42
+ [`text`]: "border-text text-text"
43
+ },
44
+ disabled: {
45
+ true: "cursor-not-allowed opacity-50",
46
+ false: ""
47
+ }
48
+ },
49
+ defaultVariants: {
50
+ color: `primary`,
51
+ disabled: false
52
+ }
53
+ });
54
+ const choiceVariant = cva("z-1 flex-1 cursor-pointer font-medium text-sm transition-all duration-300 ease-in-out aria-selected:cursor-default data-[indicator=true]:text-text-opposite motion-reduce:transition-none", {
55
+ variants: { size: {
56
+ [`sm`]: "px-2 py-1 text-xs",
57
+ [`md`]: "p-2 text-sm",
58
+ [`lg`]: "p-4 text-base"
59
+ } },
60
+ defaultVariants: { size: `md` }
61
+ });
62
+ const indicatorVariant = cva("absolute top-0 z-0 h-full w-auto rounded-full transition-all duration-300 ease-in-out motion-reduce:transition-none", { variants: { color: {
63
+ [`primary`]: "bg-primary data-[indicator=true]:text-text",
64
+ [`secondary`]: "bg-secondary data-[indicator=true]:text-text",
65
+ [`destructive`]: "bg-destructive data-[indicator=true]:text-text",
66
+ [`neutral`]: "bg-neutral data-[indicator=true]:text-white",
67
+ [`light`]: "bg-white data-[indicator=true]:text-black",
68
+ [`dark`]: "bg-neutral-800 data-[indicator=true]:text-white",
69
+ [`text`]: "bg-text data-[indicator=true]:text-text-opposite"
70
+ } } });
71
+ /**
72
+ * Component that allows the user to select one of the provided choices.
73
+ * This component is horizontal.
74
+ */
75
+ const SwitchSelector = (props) => {
76
+ const { choices = defaultChoices, color = "primary", size = "md", className, itemClassName, ...baseProps } = props;
77
+ const { selectedIndex, indicatorIndex, handleChange, optionsRefs, indicatorRef, choiceIndicatorPosition, setHoveredIndex, disabled } = useSwitchSelector({
78
+ choices,
79
+ value: props.value,
80
+ defaultValue: props.defaultValue,
81
+ onChange: props.onChange,
82
+ hoverable: props.hoverable,
83
+ disabled: props.disabled
84
+ }, "horizontal");
85
+ return /* @__PURE__ */ jsx("div", {
86
+ className: switchSelectorVariant({
87
+ color,
88
+ disabled,
89
+ className
90
+ }),
91
+ role: "tablist",
92
+ "aria-disabled": disabled ? "true" : void 0,
93
+ children: /* @__PURE__ */ jsxs("div", {
94
+ className: "relative flex h-full w-full flex-row items-center justify-center",
95
+ children: [choices.map((choice, index) => {
96
+ const { content, value, ...buttonProps } = choice;
97
+ const isKeyOfKey = typeof value === "string" || typeof value === "number";
98
+ const isSelected = index === selectedIndex;
99
+ const isIndicatorOwner = index === indicatorIndex;
100
+ return /* @__PURE__ */ createElement("button", {
101
+ ...buttonProps,
102
+ className: cn(choiceVariant({ size }), disabled && "cursor-not-allowed", itemClassName),
103
+ key: isKeyOfKey ? value : index,
104
+ role: "tab",
105
+ onClick: () => handleChange(value),
106
+ "aria-selected": isSelected ? "true" : void 0,
107
+ "data-indicator": isIndicatorOwner ? "true" : void 0,
108
+ disabled,
109
+ tabIndex: isSelected ? 0 : -1,
110
+ ref: (el) => {
111
+ optionsRefs.current[index] = el;
112
+ },
113
+ onMouseEnter: () => !disabled && setHoveredIndex(index),
114
+ onMouseLeave: () => !disabled && setHoveredIndex(null)
115
+ }, content);
116
+ }), choiceIndicatorPosition && /* @__PURE__ */ jsx("div", {
117
+ className: cn(indicatorVariant({ color })),
118
+ style: choiceIndicatorPosition,
119
+ ref: indicatorRef
120
+ })]
121
+ })
122
+ });
123
+ };
124
+
125
+ //#endregion
126
+ export { SwitchSelector, SwitchSelectorColor, SwitchSelectorSize, choiceVariant, defaultChoices, indicatorVariant, switchSelectorVariant };
127
+ //# sourceMappingURL=SwitchSelector.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwitchSelector.mjs","names":[],"sources":["../../../../src/components/SwitchSelector/SwitchSelector.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type { HTMLAttributes, ReactNode } from 'react';\nimport { useSwitchSelector } from './useSwitchSelector';\n\nexport type SwitchSelectorChoice<T = boolean> = {\n content: ReactNode;\n value: T;\n} & HTMLAttributes<HTMLButtonElement>;\nexport type SwitchSelectorChoices<T> = SwitchSelectorChoice<T>[];\n\nexport const defaultChoices: SwitchSelectorChoices<boolean> = [\n { content: 'Off', value: false },\n { content: 'On', value: true },\n];\n\nexport enum SwitchSelectorColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n DESTRUCTIVE = 'destructive',\n NEUTRAL = 'neutral',\n LIGHT = 'light',\n DARK = 'dark',\n TEXT = 'text',\n}\n\nexport enum SwitchSelectorSize {\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n}\n\nexport type SwitchSelectorBaseProps<T = boolean> = {\n choices?: SwitchSelectorChoices<T>;\n value?: T;\n defaultValue?: T;\n onChange?: (choice: T) => void;\n className?: string;\n itemClassName?: string;\n hoverable?: boolean;\n disabled?: boolean;\n [key: string]: any;\n};\n\nexport type SwitchSelectorProps<T = boolean> = SwitchSelectorBaseProps<T> &\n VariantProps<typeof switchSelectorVariant> &\n VariantProps<typeof choiceVariant>;\n\nexport const switchSelectorVariant = cva(\n 'flex h-fit w-fit cursor-pointer flex-row gap-2 rounded-full border-[1.3px] p-[1.5px]',\n {\n variants: {\n color: {\n [`${SwitchSelectorColor.PRIMARY}`]: 'border-primary text-primary',\n [`${SwitchSelectorColor.SECONDARY}`]: 'border-secondary text-secondary',\n [`${SwitchSelectorColor.DESTRUCTIVE}`]:\n 'border-destructive bg-destructive text-destructive',\n [`${SwitchSelectorColor.NEUTRAL}`]: 'border-neutral text-neutral',\n [`${SwitchSelectorColor.LIGHT}`]: 'border-white text-white',\n [`${SwitchSelectorColor.DARK}`]: 'border-neutral-800 text-neutral-800',\n [`${SwitchSelectorColor.TEXT}`]: 'border-text text-text',\n },\n disabled: {\n true: 'cursor-not-allowed opacity-50',\n false: '',\n },\n },\n defaultVariants: {\n color: `${SwitchSelectorColor.PRIMARY}`,\n disabled: false,\n },\n }\n);\n\nexport const choiceVariant = cva(\n 'z-1 flex-1 cursor-pointer font-medium text-sm transition-all duration-300 ease-in-out aria-selected:cursor-default data-[indicator=true]:text-text-opposite motion-reduce:transition-none',\n {\n variants: {\n size: {\n [`${SwitchSelectorSize.SM}`]: 'px-2 py-1 text-xs',\n [`${SwitchSelectorSize.MD}`]: 'p-2 text-sm',\n [`${SwitchSelectorSize.LG}`]: 'p-4 text-base',\n },\n },\n defaultVariants: {\n size: `${SwitchSelectorSize.MD}`,\n },\n }\n);\n\nexport const indicatorVariant = cva(\n 'absolute top-0 z-0 h-full w-auto rounded-full transition-all duration-300 ease-in-out motion-reduce:transition-none',\n {\n variants: {\n color: {\n [`${SwitchSelectorColor.PRIMARY}`]:\n 'bg-primary data-[indicator=true]:text-text',\n [`${SwitchSelectorColor.SECONDARY}`]:\n 'bg-secondary data-[indicator=true]:text-text',\n [`${SwitchSelectorColor.DESTRUCTIVE}`]:\n 'bg-destructive data-[indicator=true]:text-text',\n [`${SwitchSelectorColor.NEUTRAL}`]:\n 'bg-neutral data-[indicator=true]:text-white',\n [`${SwitchSelectorColor.LIGHT}`]:\n 'bg-white data-[indicator=true]:text-black',\n [`${SwitchSelectorColor.DARK}`]:\n 'bg-neutral-800 data-[indicator=true]:text-white',\n [`${SwitchSelectorColor.TEXT}`]:\n 'bg-text data-[indicator=true]:text-text-opposite',\n },\n },\n }\n);\n\n/**\n * Component that allows the user to select one of the provided choices.\n * This component is horizontal.\n */\nexport const SwitchSelector = <T,>(props: SwitchSelectorProps<T>) => {\n const {\n choices = defaultChoices as SwitchSelectorChoices<T>,\n color = SwitchSelectorColor.PRIMARY,\n size = SwitchSelectorSize.MD,\n className,\n itemClassName,\n ...baseProps\n } = props;\n\n const {\n selectedIndex,\n indicatorIndex,\n handleChange,\n optionsRefs,\n indicatorRef,\n choiceIndicatorPosition,\n setHoveredIndex,\n disabled,\n } = useSwitchSelector(\n {\n choices,\n value: props.value,\n defaultValue: props.defaultValue,\n onChange: props.onChange,\n hoverable: props.hoverable,\n disabled: props.disabled,\n },\n 'horizontal'\n );\n\n return (\n <div\n className={switchSelectorVariant({\n color,\n disabled,\n className,\n })}\n role=\"tablist\"\n aria-disabled={disabled ? 'true' : undefined}\n >\n <div className=\"relative flex h-full w-full flex-row items-center justify-center\">\n {choices.map((choice, index) => {\n const { content, value, ...buttonProps } = choice;\n\n const isKeyOfKey =\n typeof value === 'string' || typeof value === 'number';\n\n const isSelected = index === selectedIndex;\n const isIndicatorOwner = index === indicatorIndex;\n\n return (\n <button\n {...buttonProps}\n className={cn(\n choiceVariant({\n size,\n }),\n disabled && 'cursor-not-allowed',\n itemClassName\n )}\n key={isKeyOfKey ? value : index}\n role=\"tab\"\n onClick={() => handleChange(value)}\n aria-selected={isSelected ? 'true' : undefined}\n data-indicator={isIndicatorOwner ? 'true' : undefined}\n disabled={disabled}\n tabIndex={isSelected ? 0 : -1}\n ref={(el) => {\n optionsRefs.current[index] = el!;\n }}\n onMouseEnter={() => !disabled && setHoveredIndex(index)}\n onMouseLeave={() => !disabled && setHoveredIndex(null)}\n >\n {content}\n </button>\n );\n })}\n\n {choiceIndicatorPosition && (\n <div\n className={cn(\n indicatorVariant({\n color,\n })\n )}\n style={choiceIndicatorPosition}\n ref={indicatorRef}\n />\n )}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;AAaA,MAAa,iBAAiD,CAC5D;CAAE,SAAS;CAAO,OAAO;CAAO,EAChC;CAAE,SAAS;CAAM,OAAO;CAAM,CAC/B;AAED,IAAY,sBAAL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;;KACD;AAED,IAAY,qBAAL;AACL;AACA;AACA;;KACD;AAkBD,MAAa,wBAAwB,IACnC,wFACA;CACE,UAAU;EACR,OAAO;IACJ,YAAmC;IACnC,cAAqC;IACrC,gBACC;IACD,YAAmC;IACnC,UAAiC;IACjC,SAAgC;IAChC,SAAgC;GAClC;EACD,UAAU;GACR,MAAM;GACN,OAAO;GACR;EACF;CACD,iBAAiB;EACf,OAAO;EACP,UAAU;EACX;CACF,CACF;AAED,MAAa,gBAAgB,IAC3B,6LACA;CACE,UAAU,EACR,MAAM;GACH,OAA6B;GAC7B,OAA6B;GAC7B,OAA6B;EAC/B,EACF;CACD,iBAAiB,EACf,MAAM,MACP;CACF,CACF;AAED,MAAa,mBAAmB,IAC9B,uHACA,EACE,UAAU,EACR,OAAO;EACJ,YACC;EACD,cACC;EACD,gBACC;EACD,YACC;EACD,UACC;EACD,SACC;EACD,SACC;CACH,EACF,EACF,CACF;;;;;AAMD,MAAa,kBAAsB,UAAkC;CACnE,MAAM,EACJ,UAAU,gBACV,mBACA,aACA,WACA,eACA,GAAG,cACD;CAEJ,MAAM,EACJ,eACA,gBACA,cACA,aACA,cACA,yBACA,iBACA,aACE,kBACF;EACE;EACA,OAAO,MAAM;EACb,cAAc,MAAM;EACpB,UAAU,MAAM;EAChB,WAAW,MAAM;EACjB,UAAU,MAAM;EACjB,EACD,aACD;AAED,QACE,oBAAC,OAAD;EACE,WAAW,sBAAsB;GAC/B;GACA;GACA;GACD,CAAC;EACF,MAAK;EACL,iBAAe,WAAW,SAAS;YAEnC,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,QAAQ,KAAK,QAAQ,UAAU;IAC9B,MAAM,EAAE,SAAS,OAAO,GAAG,gBAAgB;IAE3C,MAAM,aACJ,OAAO,UAAU,YAAY,OAAO,UAAU;IAEhD,MAAM,aAAa,UAAU;IAC7B,MAAM,mBAAmB,UAAU;AAEnC,WACE,8BAAC,UAAD;KACE,GAAI;KACJ,WAAW,GACT,cAAc,EACZ,MACD,CAAC,EACF,YAAY,sBACZ,cACD;KACD,KAAK,aAAa,QAAQ;KAC1B,MAAK;KACL,eAAe,aAAa,MAAM;KAClC,iBAAe,aAAa,SAAS;KACrC,kBAAgB,mBAAmB,SAAS;KAClC;KACV,UAAU,aAAa,IAAI;KAC3B,MAAM,OAAO;AACX,kBAAY,QAAQ,SAAS;;KAE/B,oBAAoB,CAAC,YAAY,gBAAgB,MAAM;KACvD,oBAAoB,CAAC,YAAY,gBAAgB,KAAK;KAG/C,EADN,QACM;KAEX,EAED,2BACC,oBAAC,OAAD;IACE,WAAW,GACT,iBAAiB,EACf,OACD,CAAC,CACH;IACD,OAAO;IACP,KAAK;IACL,EAEA;;EACF"}
@@ -0,0 +1,105 @@
1
+ 'use client';
2
+
3
+ import { cn } from "../../utils/cn.mjs";
4
+ import { useSwitchSelector } from "./useSwitchSelector.mjs";
5
+ import { SwitchSelectorColor, SwitchSelectorSize, defaultChoices } from "./SwitchSelector.mjs";
6
+ import { createElement } from "react";
7
+ import { cva } from "class-variance-authority";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+
10
+ //#region src/components/SwitchSelector/VerticalSwitchSelector.tsx
11
+ const verticalSwitchSelectorVariant = cva("flex h-fit w-fit cursor-pointer flex-col gap-2 rounded-2xl border-[1.3px] p-1", {
12
+ variants: {
13
+ color: {
14
+ [`${"primary"}`]: "border-primary text-primary",
15
+ [`${"secondary"}`]: "border-secondary text-secondary",
16
+ [`${"destructive"}`]: "border-destructive bg-destructive text-destructive",
17
+ [`${"neutral"}`]: "border-neutral text-neutral",
18
+ [`${"light"}`]: "border-white text-white",
19
+ [`${"dark"}`]: "border-neutral-800 text-neutral-800",
20
+ [`${"text"}`]: "border-text text-text"
21
+ },
22
+ disabled: {
23
+ true: "cursor-not-allowed opacity-50",
24
+ false: ""
25
+ }
26
+ },
27
+ defaultVariants: {
28
+ color: `${"primary"}`,
29
+ disabled: false
30
+ }
31
+ });
32
+ const verticalChoiceVariant = cva("z-1 w-full cursor-pointer font-medium text-sm transition-all duration-300 ease-in-out aria-selected:cursor-default data-[indicator=true]:text-text-opposite motion-reduce:transition-none", {
33
+ variants: { size: {
34
+ [`${"sm"}`]: "px-2 py-1 text-xs",
35
+ [`${"md"}`]: "p-2 text-sm",
36
+ [`${"lg"}`]: "p-4 text-base"
37
+ } },
38
+ defaultVariants: { size: `${"md"}` }
39
+ });
40
+ const verticalIndicatorVariant = cva("absolute left-0 z-0 h-auto w-full rounded-xl transition-all duration-300 ease-in-out motion-reduce:transition-none", { variants: { color: {
41
+ [`${"primary"}`]: "bg-primary data-[indicator=true]:text-text",
42
+ [`${"secondary"}`]: "bg-secondary data-[indicator=true]:text-text",
43
+ [`${"destructive"}`]: "bg-destructive data-[indicator=true]:text-text",
44
+ [`${"neutral"}`]: "bg-neutral data-[indicator=true]:text-white",
45
+ [`${"light"}`]: "bg-white data-[indicator=true]:text-black",
46
+ [`${"dark"}`]: "bg-neutral-800 data-[indicator=true]:text-white",
47
+ [`${"text"}`]: "bg-text data-[indicator=true]:text-text-opposite"
48
+ } } });
49
+ /**
50
+ * Component that allows the user to select one of the provided choices.
51
+ * This component is vertical.
52
+ */
53
+ const VerticalSwitchSelector = (props) => {
54
+ const { choices = defaultChoices, color = "primary", size = "md", className, itemClassName, ...baseProps } = props;
55
+ const { selectedIndex, indicatorIndex, handleChange, optionsRefs, indicatorRef, choiceIndicatorPosition, setHoveredIndex, disabled } = useSwitchSelector({
56
+ choices,
57
+ value: props.value,
58
+ defaultValue: props.defaultValue,
59
+ onChange: props.onChange,
60
+ hoverable: props.hoverable,
61
+ disabled: props.disabled
62
+ }, "vertical");
63
+ return /* @__PURE__ */ jsx("div", {
64
+ className: verticalSwitchSelectorVariant({
65
+ color,
66
+ disabled,
67
+ className
68
+ }),
69
+ role: "tablist",
70
+ "aria-disabled": disabled ? "true" : void 0,
71
+ children: /* @__PURE__ */ jsxs("div", {
72
+ className: "relative flex h-fit w-full flex-col items-center justify-center",
73
+ children: [choices.map((choice, index) => {
74
+ const { content, value, ...buttonProps } = choice;
75
+ const isKeyOfKey = typeof value === "string" || typeof value === "number";
76
+ const isSelected = index === selectedIndex;
77
+ const isIndicatorOwner = index === indicatorIndex;
78
+ return /* @__PURE__ */ createElement("button", {
79
+ ...buttonProps,
80
+ className: cn(verticalChoiceVariant({ size }), disabled && "cursor-not-allowed", itemClassName),
81
+ key: isKeyOfKey ? value : index,
82
+ role: "tab",
83
+ onClick: () => handleChange(value),
84
+ "aria-selected": isSelected ? "true" : void 0,
85
+ "data-indicator": isIndicatorOwner ? "true" : void 0,
86
+ disabled: disabled || isSelected,
87
+ tabIndex: isSelected ? 0 : -1,
88
+ ref: (el) => {
89
+ optionsRefs.current[index] = el;
90
+ },
91
+ onMouseEnter: () => !disabled && setHoveredIndex(index),
92
+ onMouseLeave: () => !disabled && setHoveredIndex(null)
93
+ }, content);
94
+ }), choiceIndicatorPosition && /* @__PURE__ */ jsx("div", {
95
+ className: cn(verticalIndicatorVariant({ color })),
96
+ style: choiceIndicatorPosition,
97
+ ref: indicatorRef
98
+ })]
99
+ })
100
+ });
101
+ };
102
+
103
+ //#endregion
104
+ export { VerticalSwitchSelector };
105
+ //# sourceMappingURL=VerticalSwitchSelector.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VerticalSwitchSelector.mjs","names":[],"sources":["../../../../src/components/SwitchSelector/VerticalSwitchSelector.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n defaultChoices,\n type SwitchSelectorBaseProps,\n type SwitchSelectorChoices,\n SwitchSelectorColor,\n SwitchSelectorSize,\n} from './SwitchSelector';\nimport { useSwitchSelector } from './useSwitchSelector';\n\nconst verticalSwitchSelectorVariant = cva(\n 'flex h-fit w-fit cursor-pointer flex-col gap-2 rounded-2xl border-[1.3px] p-1',\n {\n variants: {\n color: {\n [`${SwitchSelectorColor.PRIMARY}`]: 'border-primary text-primary',\n [`${SwitchSelectorColor.SECONDARY}`]: 'border-secondary text-secondary',\n [`${SwitchSelectorColor.DESTRUCTIVE}`]:\n 'border-destructive bg-destructive text-destructive',\n [`${SwitchSelectorColor.NEUTRAL}`]: 'border-neutral text-neutral',\n [`${SwitchSelectorColor.LIGHT}`]: 'border-white text-white',\n [`${SwitchSelectorColor.DARK}`]: 'border-neutral-800 text-neutral-800',\n [`${SwitchSelectorColor.TEXT}`]: 'border-text text-text',\n },\n disabled: {\n true: 'cursor-not-allowed opacity-50',\n false: '',\n },\n },\n defaultVariants: {\n color: `${SwitchSelectorColor.PRIMARY}`,\n disabled: false,\n },\n }\n);\n\nconst verticalChoiceVariant = cva(\n 'z-1 w-full cursor-pointer font-medium text-sm transition-all duration-300 ease-in-out aria-selected:cursor-default data-[indicator=true]:text-text-opposite motion-reduce:transition-none',\n {\n variants: {\n size: {\n [`${SwitchSelectorSize.SM}`]: 'px-2 py-1 text-xs',\n [`${SwitchSelectorSize.MD}`]: 'p-2 text-sm',\n [`${SwitchSelectorSize.LG}`]: 'p-4 text-base',\n },\n },\n defaultVariants: {\n size: `${SwitchSelectorSize.MD}`,\n },\n }\n);\n\nconst verticalIndicatorVariant = cva(\n 'absolute left-0 z-0 h-auto w-full rounded-xl transition-all duration-300 ease-in-out motion-reduce:transition-none',\n {\n variants: {\n color: {\n [`${SwitchSelectorColor.PRIMARY}`]:\n 'bg-primary data-[indicator=true]:text-text',\n [`${SwitchSelectorColor.SECONDARY}`]:\n 'bg-secondary data-[indicator=true]:text-text',\n [`${SwitchSelectorColor.DESTRUCTIVE}`]:\n 'bg-destructive data-[indicator=true]:text-text',\n [`${SwitchSelectorColor.NEUTRAL}`]:\n 'bg-neutral data-[indicator=true]:text-white',\n [`${SwitchSelectorColor.LIGHT}`]:\n 'bg-white data-[indicator=true]:text-black',\n [`${SwitchSelectorColor.DARK}`]:\n 'bg-neutral-800 data-[indicator=true]:text-white',\n [`${SwitchSelectorColor.TEXT}`]:\n 'bg-text data-[indicator=true]:text-text-opposite',\n },\n },\n }\n);\n\nexport type VerticalSwitchSelectorProps<T = boolean> =\n SwitchSelectorBaseProps<T> &\n VariantProps<typeof verticalSwitchSelectorVariant> &\n VariantProps<typeof verticalChoiceVariant>;\n\n/**\n * Component that allows the user to select one of the provided choices.\n * This component is vertical.\n */\nexport const VerticalSwitchSelector = <T,>(\n props: VerticalSwitchSelectorProps<T>\n) => {\n const {\n choices = defaultChoices as SwitchSelectorChoices<T>,\n color = SwitchSelectorColor.PRIMARY,\n size = SwitchSelectorSize.MD,\n className,\n itemClassName,\n ...baseProps\n } = props;\n\n const {\n selectedIndex,\n indicatorIndex,\n handleChange,\n optionsRefs,\n indicatorRef,\n choiceIndicatorPosition,\n setHoveredIndex,\n disabled,\n } = useSwitchSelector(\n {\n choices,\n value: props.value,\n defaultValue: props.defaultValue,\n onChange: props.onChange,\n hoverable: props.hoverable,\n disabled: props.disabled,\n },\n 'vertical'\n );\n\n return (\n <div\n className={verticalSwitchSelectorVariant({\n color,\n disabled,\n className,\n })}\n role=\"tablist\"\n aria-disabled={disabled ? 'true' : undefined}\n >\n <div className=\"relative flex h-fit w-full flex-col items-center justify-center\">\n {choices.map((choice, index) => {\n const { content, value, ...buttonProps } = choice;\n\n const isKeyOfKey =\n typeof value === 'string' || typeof value === 'number';\n\n const isSelected = index === selectedIndex;\n const isIndicatorOwner = index === indicatorIndex;\n\n return (\n <button\n {...buttonProps}\n className={cn(\n verticalChoiceVariant({\n size,\n }),\n disabled && 'cursor-not-allowed',\n itemClassName\n )}\n key={isKeyOfKey ? value : index}\n role=\"tab\"\n onClick={() => handleChange(value)}\n aria-selected={isSelected ? 'true' : undefined}\n data-indicator={isIndicatorOwner ? 'true' : undefined}\n disabled={disabled || isSelected}\n tabIndex={isSelected ? 0 : -1}\n ref={(el) => {\n optionsRefs.current[index] = el!;\n }}\n onMouseEnter={() => !disabled && setHoveredIndex(index)}\n onMouseLeave={() => !disabled && setHoveredIndex(null)}\n >\n {content}\n </button>\n );\n })}\n\n {choiceIndicatorPosition && (\n <div\n className={cn(\n verticalIndicatorVariant({\n color,\n })\n )}\n style={choiceIndicatorPosition}\n ref={indicatorRef}\n />\n )}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;AAaA,MAAM,gCAAgC,IACpC,iFACA;CACE,UAAU;EACR,OAAO;IACJ,iBAAmC;IACnC,mBAAqC;IACrC,qBACC;IACD,iBAAmC;IACnC,eAAiC;IACjC,cAAgC;IAChC,cAAgC;GAClC;EACD,UAAU;GACR,MAAM;GACN,OAAO;GACR;EACF;CACD,iBAAiB;EACf,OAAO;EACP,UAAU;EACX;CACF,CACF;AAED,MAAM,wBAAwB,IAC5B,6LACA;CACE,UAAU,EACR,MAAM;GACH,YAA6B;GAC7B,YAA6B;GAC7B,YAA6B;EAC/B,EACF;CACD,iBAAiB,EACf,MAAM,WACP;CACF,CACF;AAED,MAAM,2BAA2B,IAC/B,sHACA,EACE,UAAU,EACR,OAAO;EACJ,iBACC;EACD,mBACC;EACD,qBACC;EACD,iBACC;EACD,eACC;EACD,cACC;EACD,cACC;CACH,EACF,EACF,CACF;;;;;AAWD,MAAa,0BACX,UACG;CACH,MAAM,EACJ,UAAU,gBACV,mBACA,aACA,WACA,eACA,GAAG,cACD;CAEJ,MAAM,EACJ,eACA,gBACA,cACA,aACA,cACA,yBACA,iBACA,aACE,kBACF;EACE;EACA,OAAO,MAAM;EACb,cAAc,MAAM;EACpB,UAAU,MAAM;EAChB,WAAW,MAAM;EACjB,UAAU,MAAM;EACjB,EACD,WACD;AAED,QACE,oBAAC,OAAD;EACE,WAAW,8BAA8B;GACvC;GACA;GACA;GACD,CAAC;EACF,MAAK;EACL,iBAAe,WAAW,SAAS;YAEnC,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,QAAQ,KAAK,QAAQ,UAAU;IAC9B,MAAM,EAAE,SAAS,OAAO,GAAG,gBAAgB;IAE3C,MAAM,aACJ,OAAO,UAAU,YAAY,OAAO,UAAU;IAEhD,MAAM,aAAa,UAAU;IAC7B,MAAM,mBAAmB,UAAU;AAEnC,WACE,8BAAC,UAAD;KACE,GAAI;KACJ,WAAW,GACT,sBAAsB,EACpB,MACD,CAAC,EACF,YAAY,sBACZ,cACD;KACD,KAAK,aAAa,QAAQ;KAC1B,MAAK;KACL,eAAe,aAAa,MAAM;KAClC,iBAAe,aAAa,SAAS;KACrC,kBAAgB,mBAAmB,SAAS;KAC5C,UAAU,YAAY;KACtB,UAAU,aAAa,IAAI;KAC3B,MAAM,OAAO;AACX,kBAAY,QAAQ,SAAS;;KAE/B,oBAAoB,CAAC,YAAY,gBAAgB,MAAM;KACvD,oBAAoB,CAAC,YAAY,gBAAgB,KAAK;KAG/C,EADN,QACM;KAEX,EAED,2BACC,oBAAC,OAAD;IACE,WAAW,GACT,yBAAyB,EACvB,OACD,CAAC,CACH;IACD,OAAO;IACP,KAAK;IACL,EAEA;;EACF"}
@@ -1,180 +1,4 @@
1
- 'use client';
1
+ import { SwitchSelector, SwitchSelectorColor, SwitchSelectorSize, choiceVariant, defaultChoices, indicatorVariant, switchSelectorVariant } from "./SwitchSelector.mjs";
2
+ import { VerticalSwitchSelector } from "./VerticalSwitchSelector.mjs";
2
3
 
3
- import { cn } from "../../utils/cn.mjs";
4
- import { useItemSelector } from "../../hooks/useItemSelector.mjs";
5
- import { createElement, useEffect, useRef, useState } from "react";
6
- import { cva } from "class-variance-authority";
7
- import { jsx, jsxs } from "react/jsx-runtime";
8
-
9
- //#region src/components/SwitchSelector/index.tsx
10
- const defaultChoices = [{
11
- content: "Off",
12
- value: false
13
- }, {
14
- content: "On",
15
- value: true
16
- }];
17
- let SwitchSelectorColor = /* @__PURE__ */ function(SwitchSelectorColor) {
18
- SwitchSelectorColor["PRIMARY"] = "primary";
19
- SwitchSelectorColor["SECONDARY"] = "secondary";
20
- SwitchSelectorColor["DESTRUCTIVE"] = "destructive";
21
- SwitchSelectorColor["NEUTRAL"] = "neutral";
22
- SwitchSelectorColor["LIGHT"] = "light";
23
- SwitchSelectorColor["DARK"] = "dark";
24
- SwitchSelectorColor["TEXT"] = "text";
25
- return SwitchSelectorColor;
26
- }({});
27
- const switchSelectorVariant = cva("flex h-fit w-fit cursor-pointer gap-2 border-[1.3px] p-[1.5px]", {
28
- variants: {
29
- color: {
30
- [`primary`]: "border-primary text-primary",
31
- [`secondary`]: "border-secondary text-secondary",
32
- [`destructive`]: "border-destructive bg-destructive text-destructive",
33
- [`neutral`]: "border-neutral text-neutral",
34
- [`light`]: "border-white text-white",
35
- [`dark`]: "border-neutral-800 text-neutral-800",
36
- [`text`]: "border-text text-text"
37
- },
38
- orientation: {
39
- horizontal: "flex-row rounded-full",
40
- vertical: "flex-col rounded-2xl"
41
- },
42
- disabled: {
43
- true: "cursor-not-allowed opacity-50",
44
- false: ""
45
- }
46
- },
47
- defaultVariants: {
48
- color: `primary`,
49
- orientation: "horizontal",
50
- disabled: false
51
- }
52
- });
53
- let SwitchSelectorSize = /* @__PURE__ */ function(SwitchSelectorSize) {
54
- SwitchSelectorSize["SM"] = "sm";
55
- SwitchSelectorSize["MD"] = "md";
56
- SwitchSelectorSize["LG"] = "lg";
57
- return SwitchSelectorSize;
58
- }({});
59
- const choiceVariant = cva("z-1 w-full cursor-pointer font-medium text-sm transition-all duration-300 ease-in-out aria-selected:cursor-default data-[indicator=true]:text-text-opposite motion-reduce:transition-none", {
60
- variants: {
61
- size: {
62
- [`sm`]: "px-2 py-1 text-xs",
63
- [`md`]: "p-2 text-sm",
64
- [`lg`]: "p-4 text-base"
65
- },
66
- orientation: {
67
- horizontal: "flex-1",
68
- vertical: ""
69
- }
70
- },
71
- defaultVariants: {
72
- size: `md`,
73
- orientation: "horizontal"
74
- }
75
- });
76
- const indicatorVariant = cva("absolute z-0 transition-all duration-300 ease-in-out motion-reduce:transition-none", {
77
- variants: {
78
- color: {
79
- [`primary`]: "bg-primary data-[indicator=true]:text-text",
80
- [`secondary`]: "bg-secondary data-[indicator=true]:text-text",
81
- [`destructive`]: "bg-destructive data-[indicator=true]:text-text",
82
- [`neutral`]: "bg-neutral data-[indicator=true]:text-white",
83
- [`light`]: "bg-white data-[indicator=true]:text-black",
84
- [`dark`]: "bg-neutral-800 data-[indicator=true]:text-white",
85
- [`text`]: "bg-text data-[indicator=true]:text-text-opposite"
86
- },
87
- orientation: {
88
- horizontal: "top-0 h-full w-auto rounded-full",
89
- vertical: "left-0 h-auto w-full rounded-xl"
90
- }
91
- },
92
- defaultVariants: { orientation: "horizontal" }
93
- });
94
- /**
95
- *
96
- * Component that allows the user to select one of the provided choices.
97
- *
98
- * Example:
99
- * ```jsx
100
- * <SwitchSelector
101
- * choices={[
102
- * { content: 'Option 1', value: 'option1' },
103
- * { content: 'Option 2', value: 'option2' },
104
- * { content: 'Option 3', value: 'option3' },
105
- * ]}
106
- * value="option1"
107
- * onChange={(choice) => console.log(choice)}
108
- * />
109
- * ```
110
- */
111
- const SwitchSelector = ({ choices = defaultChoices, value, defaultValue, onChange, color = "primary", size = "md", className, itemClassName, hoverable = true, disabled = false, orientation = "horizontal" }) => {
112
- const [valueState, setValue] = useState(value ?? defaultValue ?? choices[0].value);
113
- const [hoveredIndex, setHoveredIndex] = useState(null);
114
- const optionsRefs = useRef([]);
115
- const indicatorRef = useRef(null);
116
- const { choiceIndicatorPosition } = useItemSelector(optionsRefs, {
117
- selector: (el) => el.getAttribute("data-indicator") === "true",
118
- isHoverable: false,
119
- orientation
120
- });
121
- const selectedIndex = choices.findIndex((choice) => choice.value === valueState);
122
- const indicatorIndex = hoverable && hoveredIndex !== null ? hoveredIndex : selectedIndex;
123
- const handleChange = (newValue) => {
124
- setValue(newValue);
125
- onChange?.(newValue);
126
- };
127
- useEffect(() => {
128
- if (value === void 0) return;
129
- setValue(value);
130
- }, [value]);
131
- return /* @__PURE__ */ jsx("div", {
132
- className: switchSelectorVariant({
133
- color,
134
- disabled,
135
- orientation,
136
- className
137
- }),
138
- role: "tablist",
139
- "aria-disabled": disabled ? "true" : void 0,
140
- children: /* @__PURE__ */ jsxs("div", {
141
- className: cn("relative flex w-full items-center justify-center", orientation === "horizontal" ? "h-full flex-row" : "h-fit flex-col"),
142
- children: [choices.map((choice, index) => {
143
- const { content, value, ...buttonProps } = choice;
144
- const isKeyOfKey = typeof value === "string" || typeof value === "number";
145
- const isSelected = index === selectedIndex;
146
- const isIndicatorOwner = index === indicatorIndex;
147
- return /* @__PURE__ */ createElement("button", {
148
- ...buttonProps,
149
- className: cn(choiceVariant({
150
- size,
151
- orientation
152
- }), disabled && "cursor-not-allowed", itemClassName),
153
- key: isKeyOfKey ? value : index,
154
- role: "tab",
155
- onClick: () => handleChange(value),
156
- "aria-selected": isSelected ? "true" : void 0,
157
- "data-indicator": isIndicatorOwner ? "true" : void 0,
158
- disabled: disabled || isSelected,
159
- tabIndex: isSelected ? 0 : -1,
160
- ref: (el) => {
161
- optionsRefs.current[index] = el;
162
- },
163
- onMouseEnter: () => !disabled && setHoveredIndex(index),
164
- onMouseLeave: () => !disabled && setHoveredIndex(null)
165
- }, content);
166
- }), choiceIndicatorPosition && /* @__PURE__ */ jsx("div", {
167
- className: cn(indicatorVariant({
168
- color,
169
- orientation
170
- })),
171
- style: choiceIndicatorPosition,
172
- ref: indicatorRef
173
- })]
174
- })
175
- });
176
- };
177
-
178
- //#endregion
179
- export { SwitchSelector, SwitchSelectorColor, SwitchSelectorSize };
180
- //# sourceMappingURL=index.mjs.map
4
+ export { SwitchSelector, SwitchSelectorColor, SwitchSelectorSize, VerticalSwitchSelector, choiceVariant, defaultChoices, indicatorVariant, switchSelectorVariant };