@intlayer/design-system 8.10.1 → 8.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/api/hooks/ai.mjs +66 -0
- package/dist/esm/api/hooks/ai.mjs.map +1 -0
- package/dist/esm/api/hooks/audit.mjs +34 -0
- package/dist/esm/api/hooks/audit.mjs.map +1 -0
- package/dist/esm/api/hooks/auth.mjs +217 -0
- package/dist/esm/api/hooks/auth.mjs.map +1 -0
- package/dist/esm/api/hooks/bitbucket.mjs +39 -0
- package/dist/esm/api/hooks/bitbucket.mjs.map +1 -0
- package/dist/esm/api/hooks/dictionary.mjs +105 -0
- package/dist/esm/api/hooks/dictionary.mjs.map +1 -0
- package/dist/esm/api/hooks/discussions.mjs +37 -0
- package/dist/esm/api/hooks/discussions.mjs.map +1 -0
- package/dist/esm/api/hooks/editor.mjs +24 -0
- package/dist/esm/api/hooks/editor.mjs.map +1 -0
- package/dist/esm/api/hooks/github.mjs +54 -0
- package/dist/esm/api/hooks/github.mjs.map +1 -0
- package/dist/esm/api/hooks/gitlab.mjs +43 -0
- package/dist/esm/api/hooks/gitlab.mjs.map +1 -0
- package/dist/esm/api/hooks/newsletter.mjs +31 -0
- package/dist/esm/api/hooks/newsletter.mjs.map +1 -0
- package/dist/esm/api/hooks/organization.mjs +123 -0
- package/dist/esm/api/hooks/organization.mjs.map +1 -0
- package/dist/esm/api/hooks/project.mjs +187 -0
- package/dist/esm/api/hooks/project.mjs.map +1 -0
- package/dist/esm/api/hooks/reviewer.mjs +288 -0
- package/dist/esm/api/hooks/reviewer.mjs.map +1 -0
- package/dist/esm/api/hooks/search.mjs +18 -0
- package/dist/esm/api/hooks/search.mjs.map +1 -0
- package/dist/esm/api/hooks/showcaseProject.mjs +95 -0
- package/dist/esm/api/hooks/showcaseProject.mjs.map +1 -0
- package/dist/esm/api/hooks/stripe.mjs +261 -0
- package/dist/esm/api/hooks/stripe.mjs.map +1 -0
- package/dist/esm/api/hooks/tag.mjs +45 -0
- package/dist/esm/api/hooks/tag.mjs.map +1 -0
- package/dist/esm/api/hooks/translate.mjs +47 -0
- package/dist/esm/api/hooks/translate.mjs.map +1 -0
- package/dist/esm/api/hooks/user.mjs +58 -0
- package/dist/esm/api/hooks/user.mjs.map +1 -0
- package/dist/esm/api/hooks/utils.mjs +30 -0
- package/dist/esm/api/hooks/utils.mjs.map +1 -0
- package/dist/esm/api/index.mjs +26 -0
- package/dist/esm/{hooks → api}/useAuth/useAuth.mjs +1 -1
- package/dist/esm/api/useAuth/useAuth.mjs.map +1 -0
- package/dist/esm/{hooks → api}/useAuth/useOAuth2.mjs +3 -3
- package/dist/esm/api/useAuth/useOAuth2.mjs.map +1 -0
- package/dist/esm/{hooks → api}/useAuth/useSession.mjs +3 -4
- package/dist/esm/api/useAuth/useSession.mjs.map +1 -0
- package/dist/esm/api/useIntlayerAPI.mjs +123 -0
- package/dist/esm/api/useIntlayerAPI.mjs.map +1 -0
- package/dist/esm/{hooks → api}/useUser/index.mjs +2 -2
- package/dist/esm/api/useUser/index.mjs.map +1 -0
- package/dist/esm/components/Badge/index.mjs +1 -3
- package/dist/esm/components/Badge/index.mjs.map +1 -1
- package/dist/esm/components/Breadcrumb/index.mjs +0 -1
- package/dist/esm/components/Breadcrumb/index.mjs.map +1 -1
- package/dist/esm/components/Button/Button.mjs +3 -5
- package/dist/esm/components/Button/Button.mjs.map +1 -1
- package/dist/esm/components/Carousel/index.mjs +3 -3
- package/dist/esm/components/Carousel/index.mjs.map +1 -1
- package/dist/esm/components/ContentEditor/ContentEditorTextArea.mjs +1 -1
- package/dist/esm/components/ContentEditor/ContentEditorTextArea.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/ContentEditorView/TextEditor.mjs +1 -1
- package/dist/esm/components/DictionaryFieldEditor/ContentEditorView/TextEditor.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.mjs +3 -2
- package/dist/esm/components/DictionaryFieldEditor/DictionaryCreationForm/DictionaryCreationForm.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/DictionaryDetailsForm.mjs +4 -2
- package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/DictionaryDetailsForm.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/SaveForm/SaveForm.mjs +3 -2
- package/dist/esm/components/DictionaryFieldEditor/SaveForm/SaveForm.mjs.map +1 -1
- package/dist/esm/components/ExpandCollapse/ExpandCollapse.mjs +2 -2
- package/dist/esm/components/ExpandCollapse/ExpandCollapse.mjs.map +1 -1
- package/dist/esm/components/IDE/FileList.mjs +1 -1
- package/dist/esm/components/IDE/FileList.mjs.map +1 -1
- package/dist/esm/components/IDE/IDE.mjs +1 -1
- package/dist/esm/components/IDE/IDE.mjs.map +1 -1
- package/dist/esm/components/Input/Checkbox.mjs +1 -3
- package/dist/esm/components/Input/Checkbox.mjs.map +1 -1
- package/dist/esm/components/Label/index.mjs +2 -2
- package/dist/esm/components/Label/index.mjs.map +1 -1
- package/dist/esm/components/LanguageBackground/LanguageSection.mjs +8 -6
- package/dist/esm/components/LanguageBackground/LanguageSection.mjs.map +1 -1
- package/dist/esm/components/LanguageBackground/index.mjs +13 -5
- package/dist/esm/components/LanguageBackground/index.mjs.map +1 -1
- package/dist/esm/components/Link/Link.mjs +0 -7
- package/dist/esm/components/Link/Link.mjs.map +1 -1
- package/dist/esm/components/Loader/spinner.mjs +1 -1
- package/dist/esm/components/Loader/spinner.mjs.map +1 -1
- package/dist/esm/components/Pagination/Pagination.mjs +1 -2
- package/dist/esm/components/Pagination/Pagination.mjs.map +1 -1
- package/dist/esm/components/Popover/dynamic.mjs +2 -2
- package/dist/esm/components/Popover/dynamic.mjs.map +1 -1
- package/dist/esm/components/SwitchSelector/SwitchSelector.mjs +3 -5
- package/dist/esm/components/SwitchSelector/SwitchSelector.mjs.map +1 -1
- package/dist/esm/components/SwitchSelector/VerticalSwitchSelector.mjs +3 -3
- package/dist/esm/components/SwitchSelector/VerticalSwitchSelector.mjs.map +1 -1
- package/dist/esm/components/TabSelector/TabSelector.mjs +3 -3
- package/dist/esm/components/TabSelector/TabSelector.mjs.map +1 -1
- package/dist/esm/components/Tag/index.mjs +1 -1
- package/dist/esm/components/Tag/index.mjs.map +1 -1
- package/dist/esm/components/Terminal/Terminal.mjs +1 -1
- package/dist/esm/components/Terminal/Terminal.mjs.map +1 -1
- package/dist/esm/components/TextArea/AutoSizeTextArea.mjs +2 -2
- package/dist/esm/components/TextArea/AutoSizeTextArea.mjs.map +1 -1
- package/dist/esm/components/TextArea/ContentEditableTextArea.mjs +3 -3
- package/dist/esm/components/TextArea/ContentEditableTextArea.mjs.map +1 -1
- package/dist/esm/components/Toaster/Toast.mjs +3 -3
- package/dist/esm/components/Toaster/Toast.mjs.map +1 -1
- package/dist/esm/components/WithResizer/index.mjs +7 -2
- package/dist/esm/components/WithResizer/index.mjs.map +1 -1
- package/dist/esm/hooks/index.mjs +1 -7
- package/dist/esm/libs/auth.mjs +1 -1
- package/dist/esm/routes.mjs +23 -1
- package/dist/esm/routes.mjs.map +1 -1
- package/dist/types/api/hooks/ai.d.ts +12 -0
- package/dist/types/api/hooks/ai.d.ts.map +1 -0
- package/dist/types/api/hooks/audit.d.ts +10 -0
- package/dist/types/api/hooks/audit.d.ts.map +1 -0
- package/dist/types/api/hooks/auth.d.ts +29 -0
- package/dist/types/api/hooks/auth.d.ts.map +1 -0
- package/dist/types/api/hooks/bitbucket.d.ts +8 -0
- package/dist/types/api/hooks/bitbucket.d.ts.map +1 -0
- package/dist/types/api/hooks/dictionary.d.ts +15 -0
- package/dist/types/api/hooks/dictionary.d.ts.map +1 -0
- package/dist/types/api/hooks/discussions.d.ts +8 -0
- package/dist/types/api/hooks/discussions.d.ts.map +1 -0
- package/dist/types/api/hooks/editor.d.ts +6 -0
- package/dist/types/api/hooks/editor.d.ts.map +1 -0
- package/dist/types/api/hooks/github.d.ts +12 -0
- package/dist/types/api/hooks/github.d.ts.map +1 -0
- package/dist/types/api/hooks/gitlab.d.ts +8 -0
- package/dist/types/api/hooks/gitlab.d.ts.map +1 -0
- package/dist/types/api/hooks/newsletter.d.ts +7 -0
- package/dist/types/api/hooks/newsletter.d.ts.map +1 -0
- package/dist/types/api/hooks/organization.d.ts +16 -0
- package/dist/types/api/hooks/organization.d.ts.map +1 -0
- package/dist/types/api/hooks/project.d.ts +23 -0
- package/dist/types/api/hooks/project.d.ts.map +1 -0
- package/dist/types/api/hooks/reviewer.d.ts +39 -0
- package/dist/types/api/hooks/reviewer.d.ts.map +1 -0
- package/dist/types/api/hooks/search.d.ts +7 -0
- package/dist/types/api/hooks/search.d.ts.map +1 -0
- package/dist/types/api/hooks/showcaseProject.d.ts +16 -0
- package/dist/types/api/hooks/showcaseProject.d.ts.map +1 -0
- package/dist/types/api/hooks/stripe.d.ts +33 -0
- package/dist/types/api/hooks/stripe.d.ts.map +1 -0
- package/dist/types/api/hooks/tag.d.ts +11 -0
- package/dist/types/api/hooks/tag.d.ts.map +1 -0
- package/dist/types/api/hooks/translate.d.ts +8 -0
- package/dist/types/api/hooks/translate.d.ts.map +1 -0
- package/dist/types/api/hooks/user.d.ts +13 -0
- package/dist/types/api/hooks/user.d.ts.map +1 -0
- package/dist/types/api/hooks/utils.d.ts +23 -0
- package/dist/types/api/hooks/utils.d.ts.map +1 -0
- package/dist/types/api/index.d.ts +25 -0
- package/dist/types/{hooks → api}/useAuth/useAuth.d.ts +1 -1
- package/dist/types/api/useAuth/useAuth.d.ts.map +1 -0
- package/dist/types/{hooks → api}/useAuth/useOAuth2.d.ts +1 -1
- package/dist/types/api/useAuth/useOAuth2.d.ts.map +1 -0
- package/dist/types/{hooks → api}/useAuth/useSession.d.ts +1 -1
- package/dist/types/api/useAuth/useSession.d.ts.map +1 -0
- package/dist/types/api/useIntlayerAPI.d.ts +297 -0
- package/dist/types/api/useIntlayerAPI.d.ts.map +1 -0
- package/dist/types/{hooks → api}/useUser/index.d.ts +1 -1
- package/dist/types/api/useUser/index.d.ts.map +1 -0
- package/dist/types/components/Badge/index.d.ts +3 -4
- package/dist/types/components/Badge/index.d.ts.map +1 -1
- package/dist/types/components/Breadcrumb/index.d.ts.map +1 -1
- package/dist/types/components/Button/Button.d.ts +5 -6
- package/dist/types/components/Button/Button.d.ts.map +1 -1
- package/dist/types/components/Carousel/index.d.ts.map +1 -1
- package/dist/types/components/CollapsibleTable/CollapsibleTable.d.ts +1 -1
- package/dist/types/components/Container/index.d.ts +4 -4
- package/dist/types/components/DictionaryFieldEditor/ContentEditorView/TextEditor.d.ts.map +1 -1
- package/dist/types/components/ExpandCollapse/ExpandCollapse.d.ts.map +1 -1
- package/dist/types/components/Input/Checkbox.d.ts +1 -2
- package/dist/types/components/Input/Checkbox.d.ts.map +1 -1
- package/dist/types/components/LanguageBackground/index.d.ts.map +1 -1
- package/dist/types/components/Link/Link.d.ts +2 -3
- package/dist/types/components/Link/Link.d.ts.map +1 -1
- package/dist/types/components/Loader/spinner.d.ts +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/SwitchSelector/SwitchSelector.d.ts +2 -3
- package/dist/types/components/SwitchSelector/SwitchSelector.d.ts.map +1 -1
- package/dist/types/components/SwitchSelector/VerticalSwitchSelector.d.ts +1 -1
- package/dist/types/components/SwitchSelector/VerticalSwitchSelector.d.ts.map +1 -1
- package/dist/types/components/TabSelector/TabSelector.d.ts +2 -2
- package/dist/types/components/TabSelector/TabSelector.d.ts.map +1 -1
- package/dist/types/components/Tag/index.d.ts +2 -2
- package/dist/types/components/TextArea/ContentEditableTextArea.d.ts.map +1 -1
- package/dist/types/components/Toaster/Toast.d.ts +1 -1
- package/dist/types/hooks/index.d.ts +1 -7
- package/dist/types/providers/ReactQueryProvider.d.ts +1 -1
- package/dist/types/routes.d.ts +23 -1
- package/dist/types/routes.d.ts.map +1 -1
- package/package.json +35 -30
- package/tailwind.css +0 -19
- package/dist/esm/hooks/reactQuery.mjs +0 -1187
- package/dist/esm/hooks/reactQuery.mjs.map +0 -1
- package/dist/esm/hooks/useAuth/useAuth.mjs.map +0 -1
- package/dist/esm/hooks/useAuth/useOAuth2.mjs.map +0 -1
- package/dist/esm/hooks/useAuth/useSession.mjs.map +0 -1
- package/dist/esm/hooks/useIntlayerAPI.mjs +0 -22
- package/dist/esm/hooks/useIntlayerAPI.mjs.map +0 -1
- package/dist/esm/hooks/useUser/index.mjs.map +0 -1
- package/dist/types/hooks/reactQuery.d.ts +0 -188
- package/dist/types/hooks/reactQuery.d.ts.map +0 -1
- package/dist/types/hooks/useAuth/useAuth.d.ts.map +0 -1
- package/dist/types/hooks/useAuth/useOAuth2.d.ts.map +0 -1
- package/dist/types/hooks/useAuth/useSession.d.ts.map +0 -1
- package/dist/types/hooks/useIntlayerAPI.d.ts +0 -14
- package/dist/types/hooks/useIntlayerAPI.d.ts.map +0 -1
- package/dist/types/hooks/useUser/index.d.ts.map +0 -1
- /package/dist/esm/{hooks → api}/useAuth/index.mjs +0 -0
- /package/dist/types/{hooks → api}/useAuth/index.d.ts +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IDE.mjs","names":[],"sources":["../../../../src/components/IDE/IDE.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport { type FC, type HTMLAttributes, useEffect, useState } from 'react';\nimport { Container } from '../Container';\nimport { WithResizer } from '../WithResizer';\nimport { FileTree } from './FileTree';\nimport { MarkdownRenderer } from './MarkDownRender';\n\nexport type IDEProps = {\n pages: {\n path: string;\n content: string;\n isOpen?: boolean;\n }[];\n isDarkMode?: boolean;\n activeTab?: number;\n} & HTMLAttributes<HTMLDivElement>;\n\nexport const IDE: FC<IDEProps> = ({\n pages: initialPages,\n isDarkMode,\n className,\n activeTab: defaultActiveTab,\n ...props\n}) => {\n const [pages, setPages] = useState(initialPages);\n const tabs = pages.filter(({ isOpen }) => isOpen);\n\n const firstTabIndex = tabs.findIndex(({ isOpen }) => isOpen);\n const [activeTab, setActiveTab] = useState(defaultActiveTab ?? firstTabIndex);\n\n useEffect(() => {\n setActiveTab(defaultActiveTab ?? firstTabIndex);\n }, [initialPages, defaultActiveTab]);\n\n const { content, path } = pages[activeTab] ?? {};\n const filePaths = initialPages.map(({ path: title }) => title);\n\n const handleClickFile = (title: string) => {\n const page = pages.find(({ path: tabTitle }) => tabTitle === title);\n if (!page) return;\n\n const newPages = pages.map((page) => {\n if (page.path === title) {\n return { ...page, isOpen: true };\n }\n return page;\n });\n\n setPages(newPages);\n\n const newPageIndex = newPages.findIndex(\n ({ path: tabTitle }) => tabTitle === title\n );\n\n setActiveTab(newPageIndex);\n };\n\n return (\n <Container\n className={cn(\n 'flex size-full flex-col justify-start overflow-hidden shadow-lg',\n className\n )}\n roundedSize=\"3xl\"\n transparency=\"none\"\n {...props}\n >\n <div className=\"flex w-auto flex-row items-center justify-start gap-1 bg-neutral-200 text-neutral text-xs dark:bg-neutral-950\">\n <div className=\"mx-2 flex items-center justify-start gap-2 p-1\">\n <div className=\"size-3 rounded-full bg-
|
|
1
|
+
{"version":3,"file":"IDE.mjs","names":[],"sources":["../../../../src/components/IDE/IDE.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport { type FC, type HTMLAttributes, useEffect, useState } from 'react';\nimport { Container } from '../Container';\nimport { WithResizer } from '../WithResizer';\nimport { FileTree } from './FileTree';\nimport { MarkdownRenderer } from './MarkDownRender';\n\nexport type IDEProps = {\n pages: {\n path: string;\n content: string;\n isOpen?: boolean;\n }[];\n isDarkMode?: boolean;\n activeTab?: number;\n} & HTMLAttributes<HTMLDivElement>;\n\nexport const IDE: FC<IDEProps> = ({\n pages: initialPages,\n isDarkMode,\n className,\n activeTab: defaultActiveTab,\n ...props\n}) => {\n const [pages, setPages] = useState(initialPages);\n const tabs = pages.filter(({ isOpen }) => isOpen);\n\n const firstTabIndex = tabs.findIndex(({ isOpen }) => isOpen);\n const [activeTab, setActiveTab] = useState(defaultActiveTab ?? firstTabIndex);\n\n useEffect(() => {\n setActiveTab(defaultActiveTab ?? firstTabIndex);\n }, [initialPages, defaultActiveTab]);\n\n const { content, path } = pages[activeTab] ?? {};\n const filePaths = initialPages.map(({ path: title }) => title);\n\n const handleClickFile = (title: string) => {\n const page = pages.find(({ path: tabTitle }) => tabTitle === title);\n if (!page) return;\n\n const newPages = pages.map((page) => {\n if (page.path === title) {\n return { ...page, isOpen: true };\n }\n return page;\n });\n\n setPages(newPages);\n\n const newPageIndex = newPages.findIndex(\n ({ path: tabTitle }) => tabTitle === title\n );\n\n setActiveTab(newPageIndex);\n };\n\n return (\n <Container\n className={cn(\n 'flex size-full flex-col justify-start overflow-hidden shadow-lg',\n className\n )}\n roundedSize=\"3xl\"\n transparency=\"none\"\n {...props}\n >\n <div className=\"flex w-auto flex-row items-center justify-start gap-1 bg-neutral-200 text-neutral text-xs dark:bg-neutral-950\">\n <div className=\"mx-2 flex items-center justify-start gap-2 p-1\">\n <div className=\"size-3 rounded-full bg-error\" />\n <div className=\"size-3 rounded-full bg-yellow-500\" />\n <div className=\"size-3 rounded-full bg-green-500\" />\n </div>\n <div className=\"flex size-full overflow-y-auto\">\n {tabs.map(({ path }, index) => {\n const fullPath = path.split('/');\n const title = fullPath[fullPath.length - 1];\n const isActive = index === activeTab;\n\n return (\n <button\n className={cn(\n 'flex h-8 min-w-20 max-w-30 items-center justify-start truncate text-nowrap px-3 py-1 transition',\n isActive\n ? 'bg-card'\n : 'cursor-pointer bg-neutral-200 hover:bg-neutral-300 dark:bg-neutral-950'\n )}\n key={title}\n onClick={() => setActiveTab(index)}\n >\n {title}\n </button>\n );\n })}\n </div>\n </div>\n <div className=\"relative flex size-full flex-1 flex-row justify-start\">\n <div className=\"absolute top-0 left-0 size-full\">\n <div className=\"flex size-full\">\n <WithResizer initialWidth={150}>\n <div className=\"max-h-full flex-1 overflow-y-auto\">\n <FileTree\n filesPaths={filePaths}\n activeFile={path}\n onClickFile={handleClickFile}\n />\n </div>\n </WithResizer>\n\n <div className=\"size-full flex-1 overflow-auto pt-2 text-xs\">\n <MarkdownRenderer isDarkMode={isDarkMode}>\n {content}\n </MarkdownRenderer>\n </div>\n </div>\n </div>\n </div>\n </Container>\n );\n};\n"],"mappings":";;;;;;;;;;;AAmBA,MAAa,OAAqB,EAChC,OAAO,cACP,YACA,WACA,WAAW,kBACX,GAAG,YACC;CACJ,MAAM,CAAC,OAAO,YAAY,SAAS,YAAY;CAC/C,MAAM,OAAO,MAAM,QAAQ,EAAE,aAAa,MAAM;CAEhD,MAAM,gBAAgB,KAAK,WAAW,EAAE,aAAa,MAAM;CAC3D,MAAM,CAAC,WAAW,gBAAgB,SAAS,oBAAoB,aAAa;CAE5E,gBAAgB;EACd,aAAa,oBAAoB,aAAa;CAChD,GAAG,CAAC,cAAc,gBAAgB,CAAC;CAEnC,MAAM,EAAE,SAAS,SAAS,MAAM,cAAc,CAAC;CAC/C,MAAM,YAAY,aAAa,KAAK,EAAE,MAAM,YAAY,KAAK;CAE7D,MAAM,mBAAmB,UAAkB;EAEzC,IAAI,CADS,MAAM,MAAM,EAAE,MAAM,eAAe,aAAa,KACrD,GAAG;EAEX,MAAM,WAAW,MAAM,KAAK,SAAS;GACnC,IAAI,KAAK,SAAS,OAChB,OAAO;IAAE,GAAG;IAAM,QAAQ;GAAK;GAEjC,OAAO;EACT,CAAC;EAED,SAAS,QAAQ;EAMjB,aAJqB,SAAS,WAC3B,EAAE,MAAM,eAAe,aAAa,KAGf,CAAC;CAC3B;CAEA,OACE,qBAAC,WAAD;EACE,WAAW,GACT,mEACA,SACF;EACA,aAAY;EACZ,cAAa;EACb,GAAI;YAPN,CASE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,qBAAC,OAAD;IAAK,WAAU;cAAf;KACE,oBAAC,OAAD,EAAK,WAAU,+BAAgC;KAC/C,oBAAC,OAAD,EAAK,WAAU,oCAAqC;KACpD,oBAAC,OAAD,EAAK,WAAU,mCAAoC;IAChD;OACL,oBAAC,OAAD;IAAK,WAAU;cACZ,KAAK,KAAK,EAAE,QAAQ,UAAU;KAC7B,MAAM,WAAW,KAAK,MAAM,GAAG;KAC/B,MAAM,QAAQ,SAAS,SAAS,SAAS;KAGzC,OACE,oBAAC,UAAD;MACE,WAAW,GACT,mGALW,UAAU,YAOjB,YACA,wEACN;MAEA,eAAe,aAAa,KAAK;gBAEhC;KACK,GAJD,KAIC;IAEZ,CAAC;GACE,EACF;MACL,oBAAC,OAAD;GAAK,WAAU;aACb,oBAAC,OAAD;IAAK,WAAU;cACb,qBAAC,OAAD;KAAK,WAAU;eAAf,CACE,oBAAC,aAAD;MAAa,cAAc;gBACzB,oBAAC,OAAD;OAAK,WAAU;iBACb,oBAAC,UAAD;QACE,YAAY;QACZ,YAAY;QACZ,aAAa;OACd;MACE;KACM,IAEb,oBAAC,OAAD;MAAK,WAAU;gBACb,oBAAC,kBAAD;OAA8B;iBAC3B;MACe;KACf,EACF;;GACF;EACF,EACI;;AAEf"}
|
|
@@ -29,7 +29,6 @@ const checkboxVariants = cva([
|
|
|
29
29
|
color: {
|
|
30
30
|
primary: "border-primary/30 text-primary ring-primary/20 checked:border-primary checked:bg-primary",
|
|
31
31
|
secondary: "border-secondary/30 text-secondary ring-secondary/20 checked:border-secondary checked:bg-secondary",
|
|
32
|
-
destructive: "border-destructive/30 text-destructive ring-destructive/20 checked:border-destructive checked:bg-destructive",
|
|
33
32
|
neutral: "border-neutral/30 text-neutral ring-neutral/20 checked:border-neutral checked:bg-neutral",
|
|
34
33
|
light: "border-white/30 text-white ring-white/20 checked:border-white checked:bg-white",
|
|
35
34
|
text: "border-text/30 text-text ring-text/20 checked:border-text checked:bg-text",
|
|
@@ -46,7 +45,7 @@ const checkboxVariants = cva([
|
|
|
46
45
|
},
|
|
47
46
|
defaultVariants: {
|
|
48
47
|
variant: "default",
|
|
49
|
-
color: "
|
|
48
|
+
color: "text",
|
|
50
49
|
validationStyleEnabled: "disabled",
|
|
51
50
|
size: "md"
|
|
52
51
|
}
|
|
@@ -61,7 +60,6 @@ let CheckboxSize = /* @__PURE__ */ function(CheckboxSize) {
|
|
|
61
60
|
let CheckboxColor = /* @__PURE__ */ function(CheckboxColor) {
|
|
62
61
|
CheckboxColor["PRIMARY"] = "primary";
|
|
63
62
|
CheckboxColor["SECONDARY"] = "secondary";
|
|
64
|
-
CheckboxColor["DESTRUCTIVE"] = "destructive";
|
|
65
63
|
CheckboxColor["NEUTRAL"] = "neutral";
|
|
66
64
|
CheckboxColor["LIGHT"] = "light";
|
|
67
65
|
CheckboxColor["TEXT"] = "text";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkbox.mjs","names":[],"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 'relative cursor-pointer border-2',\n 'focus:outline-0',\n 'checked:hover:opacity-80',\n 'ring-offset-background',\n 'hover:bg-neutral-500/10',\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\n \"after:absolute after:-inset-2 after:content-['']\",\n ].join(' '),\n {\n variants: {\n variant: {\n default: '',\n },\n size: {\n xs: 'size-3 rounded-sm',\n sm: 'size-4 rounded-md',\n md: 'size-5 rounded-lg',\n lg: 'size-6 rounded-xl',\n },\n color: {\n primary:\n 'border-primary/30 text-primary ring-primary/20 checked:border-primary checked:bg-primary',\n secondary:\n 'border-secondary/30 text-secondary ring-secondary/20 checked:border-secondary checked:bg-secondary',\n
|
|
1
|
+
{"version":3,"file":"Checkbox.mjs","names":[],"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 'relative cursor-pointer border-2',\n 'focus:outline-0',\n 'checked:hover:opacity-80',\n 'ring-offset-background',\n 'hover:bg-neutral-500/10',\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\n \"after:absolute after:-inset-2 after:content-['']\",\n ].join(' '),\n {\n variants: {\n variant: {\n default: '',\n },\n size: {\n xs: 'size-3 rounded-sm',\n sm: 'size-4 rounded-md',\n md: 'size-5 rounded-lg',\n lg: 'size-6 rounded-xl',\n },\n color: {\n primary:\n 'border-primary/30 text-primary ring-primary/20 checked:border-primary checked:bg-primary',\n secondary:\n 'border-secondary/30 text-secondary ring-secondary/20 checked:border-secondary checked:bg-secondary',\n neutral:\n 'border-neutral/30 text-neutral ring-neutral/20 checked:border-neutral checked:bg-neutral',\n light:\n 'border-white/30 text-white ring-white/20 checked:border-white checked:bg-white',\n text: 'border-text/30 text-text ring-text/20 checked:border-text checked:bg-text',\n ['text-inverse']:\n 'border-text-inverse/30 text-text-inverse ring-text-inverse/20 checked:border-text-inverse checked:bg-text-inverse',\n dark: 'border-neutral-800/30 text-neutral-800 ring-neutral-800/20 checked:border-neutral-800 checked:bg-neutral-800',\n error:\n 'border-error/30 text-error ring-error/20 checked:border-error checked:bg-error',\n success:\n 'border-success/30 text-success ring-success/20 checked:border-success checked:bg-success',\n custom:\n 'border-custom/30 text-custom ring-custom/20 checked:border-custom checked:bg-custom',\n },\n validationStyleEnabled: {\n disabled: '',\n enabled: 'valid:border-success invalid:border-error',\n },\n },\n defaultVariants: {\n variant: 'default',\n color: 'text',\n validationStyleEnabled: 'disabled',\n size: 'md',\n },\n }\n);\n\nexport enum CheckboxSize {\n XS = 'xs',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n}\n\nexport enum CheckboxColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n NEUTRAL = 'neutral',\n LIGHT = 'light',\n TEXT = 'text',\n TEXT_INVERSE = 'text-inverse',\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.size === 'xs' && 'text-xs',\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;CAEA;AACF,EAAE,KAAK,GAAG,GACV;CACE,UAAU;EACR,SAAS,EACP,SAAS,GACX;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;EACA,OAAO;GACL,SACE;GACF,WACE;GACF,SACE;GACF,OACE;GACF,MAAM;IACL,iBACC;GACF,MAAM;GACN,OACE;GACF,SACE;GACF,QACE;EACJ;EACA,wBAAwB;GACtB,UAAU;GACV,SAAS;EACX;CACF;CACA,iBAAiB;EACf,SAAS;EACT,OAAO;EACP,wBAAwB;EACxB,MAAM;CACR;AACF,CACF;AAEA,IAAY,eAAL;CACL;CACA;CACA;CACA;;AACF;AAEA,IAAY,gBAAL;CACL;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;;AACF;AAkBA,MAAM,SAA4B,EAChC,yBAAyB,OACzB,OACA,MACA,OACA,MACA,SACA,WACA,gBACA,GAAG,YAEH,oBAAC,SAAD;CACE,MAAK;CACL,WAAW,GACT,iBAAiB;EACf;EACA;EACA;EACA,wBAAwB,yBAAyB,YAAY;CAC/D,CAAC,GACD,SACF;CACA,GAAI;AACL;AAGH,MAAa,YAA+B,UAAU;CACpD,MAAM,EAAE,OAAO,MAAM,OAAO;CAE5B,OAAO,QACL,qBAAC,SAAD;EACE,SAAS,MAAM;EACf,WAAW,GACT,uEACA,MAAM,SAAS,QAAQ,WACvB,MAAM,cACR;YANF,CAQE,oBAAC,OAAD;GAAO,IAAI,MAAM;GAAM,GAAI;EAAQ,IAClC,KACI;MAEP,oBAAC,OAAD;EAAO,IAAI,MAAM;EAAM,GAAI;CAAQ;AAEvC"}
|
|
@@ -43,8 +43,8 @@ const Label = ({ htmlFor, required = false, disabled = false, className, childre
|
|
|
43
43
|
suppressHydrationWarning: true,
|
|
44
44
|
...props,
|
|
45
45
|
children: [children, required && /* @__PURE__ */ jsx("span", {
|
|
46
|
-
className: "ml-1 text-
|
|
47
|
-
"aria-
|
|
46
|
+
className: "ml-1 text-error",
|
|
47
|
+
"aria-hidden": "true",
|
|
48
48
|
title: "This field is required",
|
|
49
49
|
children: "*"
|
|
50
50
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Label/index.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport type { FC, LabelHTMLAttributes } from 'react';\n\n/**\n * Props for the Label component\n */\nexport interface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {\n /**\n * The ID of the form control this label is associated with.\n * This creates the accessible relationship between the label and its control.\n * @example \"email-input\"\n * @example \"password-field\"\n */\n htmlFor?: string;\n\n /**\n * Whether the associated form control is required.\n * Adds visual indicator and updates ARIA attributes.\n * @default false\n */\n required?: boolean;\n\n /**\n * Whether the associated form control is disabled.\n * Updates styling to indicate disabled state.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Additional CSS classes for custom styling\n * @example \"text-red-600 font-bold\"\n */\n className?: string;\n}\n\n/**\n * Label Component\n *\n * A form label component that provides accessible labeling for form controls.\n * Establishes proper relationships between labels and their associated form elements\n * with visual indicators for required and disabled states.\n *\n * @example\n * ```tsx\n * // Basic usage\n * <Label htmlFor=\"email\">Email Address</Label>\n * <input id=\"email\" type=\"email\" />\n *\n * // Required field\n * <Label htmlFor=\"password\" required>Password</Label>\n * <input id=\"password\" type=\"password\" required />\n *\n * // Disabled field\n * <Label htmlFor=\"disabled-field\" disabled>Disabled Field</Label>\n * <input id=\"disabled-field\" type=\"text\" disabled />\n *\n * // With custom styling\n * <Label htmlFor=\"custom\" className=\"text-blue-600 font-semibold\">\n * Custom Styled Label\n * </Label>\n * ```\n *\n * @component\n * @accessibility\n * - Uses semantic HTML <label> element\n * - Properly associates with form controls via htmlFor/id relationship\n * - Supports click-to-focus behavior automatically\n * - Visual indicators for required and disabled states\n * - Screen reader compatible with proper ARIA relationships\n */\nexport const Label: FC<LabelProps> = ({\n htmlFor,\n required = false,\n disabled = false,\n className,\n children,\n ...props\n}) => (\n <label\n className={cn(\n 'select-none font-medium text-sm leading-none',\n 'peer-disabled:cursor-not-allowed peer-disabled:opacity-70',\n disabled && 'cursor-not-allowed text-muted-foreground opacity-70',\n className\n )}\n htmlFor={htmlFor}\n suppressHydrationWarning\n {...props}\n >\n {children}\n {required && (\n <span\n className=\"ml-1 text-
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Label/index.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport type { FC, LabelHTMLAttributes } from 'react';\n\n/**\n * Props for the Label component\n */\nexport interface LabelProps extends LabelHTMLAttributes<HTMLLabelElement> {\n /**\n * The ID of the form control this label is associated with.\n * This creates the accessible relationship between the label and its control.\n * @example \"email-input\"\n * @example \"password-field\"\n */\n htmlFor?: string;\n\n /**\n * Whether the associated form control is required.\n * Adds visual indicator and updates ARIA attributes.\n * @default false\n */\n required?: boolean;\n\n /**\n * Whether the associated form control is disabled.\n * Updates styling to indicate disabled state.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Additional CSS classes for custom styling\n * @example \"text-red-600 font-bold\"\n */\n className?: string;\n}\n\n/**\n * Label Component\n *\n * A form label component that provides accessible labeling for form controls.\n * Establishes proper relationships between labels and their associated form elements\n * with visual indicators for required and disabled states.\n *\n * @example\n * ```tsx\n * // Basic usage\n * <Label htmlFor=\"email\">Email Address</Label>\n * <input id=\"email\" type=\"email\" />\n *\n * // Required field\n * <Label htmlFor=\"password\" required>Password</Label>\n * <input id=\"password\" type=\"password\" required />\n *\n * // Disabled field\n * <Label htmlFor=\"disabled-field\" disabled>Disabled Field</Label>\n * <input id=\"disabled-field\" type=\"text\" disabled />\n *\n * // With custom styling\n * <Label htmlFor=\"custom\" className=\"text-blue-600 font-semibold\">\n * Custom Styled Label\n * </Label>\n * ```\n *\n * @component\n * @accessibility\n * - Uses semantic HTML <label> element\n * - Properly associates with form controls via htmlFor/id relationship\n * - Supports click-to-focus behavior automatically\n * - Visual indicators for required and disabled states\n * - Screen reader compatible with proper ARIA relationships\n */\nexport const Label: FC<LabelProps> = ({\n htmlFor,\n required = false,\n disabled = false,\n className,\n children,\n ...props\n}) => (\n <label\n className={cn(\n 'select-none font-medium text-sm leading-none',\n 'peer-disabled:cursor-not-allowed peer-disabled:opacity-70',\n disabled && 'cursor-not-allowed text-muted-foreground opacity-70',\n className\n )}\n htmlFor={htmlFor}\n suppressHydrationWarning\n {...props}\n >\n {children}\n {required && (\n <span\n className=\"ml-1 text-error\"\n aria-hidden=\"true\"\n title=\"This field is required\"\n >\n *\n </span>\n )}\n </label>\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuEA,MAAa,SAAyB,EACpC,SACA,WAAW,OACX,WAAW,OACX,WACA,UACA,GAAG,YAEH,qBAAC,SAAD;CACE,WAAW,GACT,gDACA,6DACA,YAAY,uDACZ,SACF;CACS;CACT;CACA,GAAI;WATN,CAWG,UACA,YACC,oBAAC,QAAD;EACE,WAAU;EACV,eAAY;EACZ,OAAM;YACP;CAEK,EAEH"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { cn } from "../../utils/cn.mjs";
|
|
4
4
|
import { Container } from "../Container/index.mjs";
|
|
5
5
|
import { Flag } from "../Flags/Flag.mjs";
|
|
6
|
-
import {
|
|
6
|
+
import { startTransition, useEffect, useState } from "react";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { ALL_LOCALES, getHTMLTextDir, getLocaleName } from "intlayer";
|
|
9
9
|
|
|
@@ -41,7 +41,7 @@ const LocalCardList = ({ localeList, className, ...props }) => /* @__PURE__ */ j
|
|
|
41
41
|
...props,
|
|
42
42
|
children: /* @__PURE__ */ jsxs("div", {
|
|
43
43
|
className: cn("inline-flex shrink-0 will-change-transform", className),
|
|
44
|
-
children: [localeList.map((locale
|
|
44
|
+
children: [localeList.map((locale) => /* @__PURE__ */ jsx(LocalCard, { locale }, `${locale}-first`)), localeList.map((locale) => /* @__PURE__ */ jsx(LocalCard, { locale }, `${locale}-second`))]
|
|
45
45
|
})
|
|
46
46
|
});
|
|
47
47
|
const NUM_OF_LOCALES = 15;
|
|
@@ -51,14 +51,16 @@ const LanguageSection = ({ className, ...props }) => {
|
|
|
51
51
|
const [localeList, setLocaleList] = useState(emptyArrayOfLocale);
|
|
52
52
|
const [firstPart, secondPart, thirdPart, fourthPart] = localeList;
|
|
53
53
|
useEffect(() => {
|
|
54
|
-
|
|
54
|
+
startTransition(() => {
|
|
55
|
+
setLocaleList(arrayOfLocale);
|
|
56
|
+
});
|
|
55
57
|
}, []);
|
|
56
58
|
return /* @__PURE__ */ jsx("section", {
|
|
57
59
|
className: cn("mask-[linear-gradient(to_right,transparent_0,black_128px,black_calc(100%-128px),transparent_100%)] my-10 w-full overflow-hidden", className),
|
|
58
60
|
...props,
|
|
59
|
-
children: /* @__PURE__ */
|
|
61
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
60
62
|
className: "relative flex w-full flex-col gap-5 py-3",
|
|
61
|
-
children:
|
|
63
|
+
children: [
|
|
62
64
|
/* @__PURE__ */ jsx(LocalCardList, {
|
|
63
65
|
localeList: firstPart,
|
|
64
66
|
className: "horizontal-loop-1"
|
|
@@ -75,7 +77,7 @@ const LanguageSection = ({ className, ...props }) => {
|
|
|
75
77
|
localeList: fourthPart,
|
|
76
78
|
className: "horizontal-loop-2"
|
|
77
79
|
})
|
|
78
|
-
]
|
|
80
|
+
]
|
|
79
81
|
})
|
|
80
82
|
});
|
|
81
83
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LanguageSection.mjs","names":[],"sources":["../../../../src/components/LanguageBackground/LanguageSection.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport {\n ALL_LOCALES,\n getHTMLTextDir,\n getLocaleName,\n type Locale,\n} from 'intlayer';\nimport {\n type FC,\n type HTMLAttributes,\n
|
|
1
|
+
{"version":3,"file":"LanguageSection.mjs","names":[],"sources":["../../../../src/components/LanguageBackground/LanguageSection.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport {\n ALL_LOCALES,\n getHTMLTextDir,\n getLocaleName,\n type Locale,\n} from 'intlayer';\nimport {\n type FC,\n type HTMLAttributes,\n startTransition,\n useEffect,\n useState,\n} from 'react';\nimport { Container } from '../Container';\nimport { Flag } from '../Flags';\n\nconst shuffleArray = (array: string[], limit?: number) => {\n const shuffled = [...array];\n\n for (let i = shuffled.length - 1; i > 0; i--) {\n const randomIndex = Math.floor(Math.random() * (i + 1));\n\n [shuffled[i], shuffled[randomIndex]] = [shuffled[randomIndex], shuffled[i]];\n }\n\n return limit ? shuffled.slice(0, limit) : shuffled;\n};\n\nconst LocalCard: FC<{ locale: string }> = ({ locale, ...props }) => (\n <div\n className=\"group z-10 mx-8 inline-flex shrink-0 transition-transform duration-300 hover:scale-105\"\n {...props}\n >\n <Container\n roundedSize=\"xl\"\n className=\"flex flex-row items-center gap-5 p-3\"\n >\n <Flag\n locale={locale as Locale}\n className=\"max-h-5 max-w-5 rounded-sm grayscale-80 transition duration-300 group-hover:grayscale-0\"\n width={640}\n height={480}\n loading=\"lazy\"\n />\n <span\n dir={getHTMLTextDir(locale as Locale)}\n lang={locale as Locale}\n className=\"flex text-nowrap\"\n >\n {getLocaleName(locale as Locale)}\n </span>\n </Container>\n </div>\n);\n\nconst LocalCardList: FC<{ localeList: string[]; className?: string }> = ({\n localeList,\n className,\n ...props\n}) => (\n <div className=\"relative flex w-full overflow-hidden\" {...props}>\n <div\n className={cn('inline-flex shrink-0 will-change-transform', className)}\n >\n {/* First set of cards */}\n {localeList.map((locale) => (\n <LocalCard key={`${locale}-first`} locale={locale} />\n ))}\n {/* Duplicate set for seamless loop */}\n {localeList.map((locale) => (\n <LocalCard key={`${locale}-second`} locale={locale} />\n ))}\n </div>\n </div>\n);\n\nconst NUM_OF_LOCALES = 15;\n\nconst emptyArrayOfLocale: string[][] = new Array(4).fill(0).map(() => []);\nconst arrayOfLocale: string[][] = new Array(4)\n .fill(0)\n .map(() => shuffleArray(Object.values(ALL_LOCALES), NUM_OF_LOCALES));\n\nexport const LanguageSection: FC<HTMLAttributes<HTMLElement>> = ({\n className,\n ...props\n}) => {\n const [localeList, setLocaleList] = useState(emptyArrayOfLocale);\n const [firstPart, secondPart, thirdPart, fourthPart] = localeList;\n\n useEffect(() => {\n startTransition(() => {\n setLocaleList(arrayOfLocale);\n });\n }, []);\n\n return (\n <section\n className={cn(\n 'mask-[linear-gradient(to_right,transparent_0,black_128px,black_calc(100%-128px),transparent_100%)] my-10 w-full overflow-hidden',\n className\n )}\n {...props}\n >\n <div className=\"relative flex w-full flex-col gap-5 py-3\">\n <LocalCardList localeList={firstPart} className=\"horizontal-loop-1\" />\n <LocalCardList localeList={secondPart} className=\"horizontal-loop-2\" />\n <LocalCardList localeList={thirdPart} className=\"horizontal-loop-1\" />\n <LocalCardList localeList={fourthPart} className=\"horizontal-loop-2\" />\n </div>\n </section>\n );\n};\n"],"mappings":";;;;;;;;;;AAmBA,MAAM,gBAAgB,OAAiB,UAAmB;CACxD,MAAM,WAAW,CAAC,GAAG,KAAK;CAE1B,KAAK,IAAI,IAAI,SAAS,SAAS,GAAG,IAAI,GAAG,KAAK;EAC5C,MAAM,cAAc,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI,EAAE;EAEtD,CAAC,SAAS,IAAI,SAAS,gBAAgB,CAAC,SAAS,cAAc,SAAS,EAAE;CAC5E;CAEA,OAAO,QAAQ,SAAS,MAAM,GAAG,KAAK,IAAI;AAC5C;AAEA,MAAM,aAAqC,EAAE,QAAQ,GAAG,YACtD,oBAAC,OAAD;CACE,WAAU;CACV,GAAI;WAEJ,qBAAC,WAAD;EACE,aAAY;EACZ,WAAU;YAFZ,CAIE,oBAAC,MAAD;GACU;GACR,WAAU;GACV,OAAO;GACP,QAAQ;GACR,SAAQ;EACT,IACD,oBAAC,QAAD;GACE,KAAK,eAAe,MAAgB;GACpC,MAAM;GACN,WAAU;aAET,cAAc,MAAgB;EAC3B,EACG;;AACR;AAGP,MAAM,iBAAmE,EACvE,YACA,WACA,GAAG,YAEH,oBAAC,OAAD;CAAK,WAAU;CAAuC,GAAI;WACxD,qBAAC,OAAD;EACE,WAAW,GAAG,8CAA8C,SAAS;YADvE,CAIG,WAAW,KAAK,WACf,oBAAC,WAAD,EAA2C,OAAS,GAApC,GAAG,OAAO,OAA0B,CACrD,GAEA,WAAW,KAAK,WACf,oBAAC,WAAD,EAA4C,OAAS,GAArC,GAAG,OAAO,QAA2B,CACtD,CACE;;AACF;AAGP,MAAM,iBAAiB;AAEvB,MAAM,qBAAiC,IAAI,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC;AACxE,MAAM,gBAA4B,IAAI,MAAM,CAAC,EAC1C,KAAK,CAAC,EACN,UAAU,aAAa,OAAO,OAAO,WAAW,GAAG,cAAc,CAAC;AAErE,MAAa,mBAAoD,EAC/D,WACA,GAAG,YACC;CACJ,MAAM,CAAC,YAAY,iBAAiB,SAAS,kBAAkB;CAC/D,MAAM,CAAC,WAAW,YAAY,WAAW,cAAc;CAEvD,gBAAgB;EACd,sBAAsB;GACpB,cAAc,aAAa;EAC7B,CAAC;CACH,GAAG,CAAC,CAAC;CAEL,OACE,oBAAC,WAAD;EACE,WAAW,GACT,mIACA,SACF;EACA,GAAI;YAEJ,qBAAC,OAAD;GAAK,WAAU;aAAf;IACE,oBAAC,eAAD;KAAe,YAAY;KAAW,WAAU;IAAqB;IACrE,oBAAC,eAAD;KAAe,YAAY;KAAY,WAAU;IAAqB;IACtE,oBAAC,eAAD;KAAe,YAAY;KAAW,WAAU;IAAqB;IACrE,oBAAC,eAAD;KAAe,YAAY;KAAY,WAAU;IAAqB;GACnE;;CACE;AAEb"}
|
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { LanguageSection } from "./LanguageSection.mjs";
|
|
4
|
-
import { Suspense, lazy } from "react";
|
|
4
|
+
import { Suspense, lazy, startTransition, useEffect, useState } from "react";
|
|
5
5
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
|
|
7
7
|
//#region src/components/LanguageBackground/index.tsx
|
|
8
8
|
const LazyLanguageSection = lazy(() => import("./LanguageSection.mjs").then((m) => ({ default: m.LanguageSection })));
|
|
9
|
-
const LanguageBackground = ({ children }) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const LanguageBackground = ({ children }) => {
|
|
10
|
+
const [mounted, setMounted] = useState(false);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
startTransition(() => {
|
|
13
|
+
setMounted(true);
|
|
14
|
+
});
|
|
15
|
+
}, []);
|
|
16
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [children, /* @__PURE__ */ jsx("div", {
|
|
17
|
+
className: "absolute top-0 left-0 -z-1 flex size-full items-center justify-center",
|
|
18
|
+
children: mounted && /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(LazyLanguageSection, { className: "mt-[30%]" }) })
|
|
19
|
+
})] });
|
|
20
|
+
};
|
|
13
21
|
|
|
14
22
|
//#endregion
|
|
15
23
|
export { LanguageBackground, LanguageSection };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/LanguageBackground/index.tsx"],"sourcesContent":["'use client';\n\nimport {
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/LanguageBackground/index.tsx"],"sourcesContent":["'use client';\n\nimport {\n type FC,\n lazy,\n type PropsWithChildren,\n Suspense,\n startTransition,\n useEffect,\n useState,\n} from 'react';\n\nconst LazyLanguageSection = lazy(() =>\n import('./LanguageSection').then((m) => ({ default: m.LanguageSection }))\n);\n\nexport { LanguageSection } from './LanguageSection';\n\nexport const LanguageBackground: FC<PropsWithChildren> = ({ children }) => {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n // startTransition defers the background as a low-priority update so the\n // sign-in form paints before React starts loading the flag section chunk.\n startTransition(() => {\n setMounted(true);\n });\n }, []);\n\n return (\n <>\n {children}\n <div className=\"absolute top-0 left-0 -z-1 flex size-full items-center justify-center\">\n {mounted && (\n <Suspense>\n <LazyLanguageSection className=\"mt-[30%]\" />\n </Suspense>\n )}\n </div>\n </>\n );\n};\n"],"mappings":";;;;;;;AAYA,MAAM,sBAAsB,WAC1B,OAAO,yBAAqB,MAAM,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAC1E;AAIA,MAAa,sBAA6C,EAAE,eAAe;CACzE,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAE5C,gBAAgB;EAGd,sBAAsB;GACpB,WAAW,IAAI;EACjB,CAAC;CACH,GAAG,CAAC,CAAC;CAEL,OACE,8CACG,UACD,oBAAC,OAAD;EAAK,WAAU;YACZ,WACC,oBAAC,UAAD,YACE,oBAAC,qBAAD,EAAqB,WAAU,WAAY,GACnC;CAET,EACL;AAEN"}
|
|
@@ -23,7 +23,6 @@ let LinkVariant = /* @__PURE__ */ function(LinkVariant) {
|
|
|
23
23
|
let LinkColor = /* @__PURE__ */ function(LinkColor) {
|
|
24
24
|
LinkColor["PRIMARY"] = "primary";
|
|
25
25
|
LinkColor["SECONDARY"] = "secondary";
|
|
26
|
-
LinkColor["DESTRUCTIVE"] = "destructive";
|
|
27
26
|
LinkColor["NEUTRAL"] = "neutral";
|
|
28
27
|
LinkColor["LIGHT"] = "light";
|
|
29
28
|
LinkColor["DARK"] = "dark";
|
|
@@ -81,7 +80,6 @@ const linkVariants = cva("gap-3 transition-all duration-300 focus-visible:outlin
|
|
|
81
80
|
color: {
|
|
82
81
|
[`primary`]: "text-primary",
|
|
83
82
|
[`secondary`]: "text-secondary",
|
|
84
|
-
[`destructive`]: "text-destructive",
|
|
85
83
|
[`neutral`]: "text-neutral",
|
|
86
84
|
[`light`]: "text-white",
|
|
87
85
|
[`dark`]: "text-neutral-800",
|
|
@@ -145,11 +143,6 @@ const linkVariants = cva("gap-3 transition-all duration-300 focus-visible:outlin
|
|
|
145
143
|
color: "secondary",
|
|
146
144
|
class: "ring-secondary/20"
|
|
147
145
|
},
|
|
148
|
-
{
|
|
149
|
-
variant: ["button", "button-outlined"],
|
|
150
|
-
color: "destructive",
|
|
151
|
-
class: "ring-destructive/20"
|
|
152
|
-
},
|
|
153
146
|
{
|
|
154
147
|
variant: ["button", "button-outlined"],
|
|
155
148
|
color: "neutral",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.mjs","names":[],"sources":["../../../../src/components/Link/Link.tsx"],"sourcesContent":["import { getLocalizedUrl } from '@intlayer/core/localization';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ExternalLink, MoveRight } from 'lucide-react';\nimport {\n type AnchorHTMLAttributes,\n type DetailedHTMLProps,\n type FC,\n isValidElement,\n type ReactNode,\n} from 'react';\n\n/**\n * Visual style variants for Link component\n */\nexport enum LinkVariant {\n DEFAULT = 'default',\n INVISIBLE_LINK = 'invisible-link',\n BUTTON = 'button',\n BUTTON_OUTLINED = 'button-outlined',\n HOVERABLE = 'hoverable',\n}\n\n/**\n * Color theme variants for Link component\n */\nexport enum LinkColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n DESTRUCTIVE = 'destructive',\n NEUTRAL = 'neutral',\n LIGHT = 'light',\n DARK = 'dark',\n TEXT = 'text',\n TEXT_INVERSE = 'text-inverse',\n ERROR = 'error',\n SUCCESS = 'success',\n CUSTOM = 'custom',\n}\n\nexport enum LinkRoundedSize {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n TWO_XL = '2xl',\n THREE_XL = '3xl',\n FULL = 'full',\n}\n\nexport enum LinkSize {\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n CUSTOM = 'custom',\n}\n\nexport enum LinkUnderlined {\n DEFAULT = 'default',\n TRUE = 'true',\n FALSE = 'false',\n}\n\nexport const linkVariants = cva(\n 'gap-3 transition-all duration-300 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n [`${LinkVariant.DEFAULT}`]:\n 'h-auto justify-start border-inherit bg-current/0 px-1 font-medium decoration-[1.5] underline-offset-5 hover:bg-current/0 hover:text-current/80 hover:underline hover:underline-offset-6',\n [`${LinkVariant.INVISIBLE_LINK}`]:\n 'h-auto justify-start border-inherit bg-current/0 px-1 underline-offset-5 hover:bg-current/0 aria-[current]:bg-current/5',\n\n [`${LinkVariant.BUTTON}`]:\n 'relative flex cursor-pointer flex-row items-center justify-center gap-2 rounded-full bg-current text-center font-medium text-text ring-0 *:text-text-opposite hover:bg-current/90 hover:ring-5 aria-selected:ring-5 aria-[current]:ring-5',\n\n [`${LinkVariant.BUTTON_OUTLINED}`]:\n 'relative flex cursor-pointer flex-row items-center justify-center gap-2 rounded-full border-[1.3px] border-current text-center font-medium text-text ring-0 *:text-text hover:bg-current/20 hover:ring-5 aria-selected:ring-5 aria-[current]:ring-5',\n\n [`${LinkVariant.HOVERABLE}`]:\n 'rounded-lg border-none bg-current/0 transition *:text-current! hover:bg-current/20 aria-[current]:bg-current/5',\n },\n roundedSize: {\n [`${LinkRoundedSize.NONE}`]: 'rounded-none',\n [`${LinkRoundedSize.SM}`]:\n 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n [`${LinkRoundedSize.MD}`]:\n 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n [`${LinkRoundedSize.LG}`]:\n 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n [`${LinkRoundedSize.XL}`]:\n 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n [`${LinkRoundedSize.TWO_XL}`]:\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n [`${LinkRoundedSize.THREE_XL}`]:\n 'rounded-[2.5rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[3rem]',\n [`${LinkRoundedSize.FULL}`]: 'rounded-full',\n },\n color: {\n [`${LinkColor.PRIMARY}`]: 'text-primary',\n [`${LinkColor.SECONDARY}`]: 'text-secondary',\n [`${LinkColor.DESTRUCTIVE}`]: 'text-destructive',\n [`${LinkColor.NEUTRAL}`]: 'text-neutral',\n [`${LinkColor.LIGHT}`]: 'text-white',\n [`${LinkColor.DARK}`]: 'text-neutral-800',\n [`${LinkColor.TEXT}`]: 'text-text',\n [`${LinkColor.TEXT_INVERSE}`]: 'text-text-opposite',\n [`${LinkColor.ERROR}`]: 'text-error',\n [`${LinkColor.SUCCESS}`]: 'text-success',\n [`${LinkColor.CUSTOM}`]: '',\n },\n size: {\n [`${LinkSize.SM}`]: 'text-sm',\n [`${LinkSize.MD}`]: 'text-base',\n [`${LinkSize.LG}`]: 'text-lg',\n [`${LinkSize.XL}`]: 'text-xl',\n [`${LinkSize.CUSTOM}`]: '',\n },\n underlined: {\n [LinkUnderlined.DEFAULT]: '',\n [LinkUnderlined.TRUE]: 'underline',\n [LinkUnderlined.FALSE]: 'no-underline',\n },\n },\n // Compound variants handle height and padding\n compoundVariants: [\n // ---------------------------------------------------------\n // FIX START: Correctly Handle Contrast for TEXT_INVERSE\n // ---------------------------------------------------------\n {\n // Filled Button + Inverse Color (e.g., White Button):\n // We DO NOT override parent text color (it must remain 'text-opposite' so bg-current is white).\n // We ONLY override children to be 'text-text' (Dark) so they show up on white.\n variant: LinkVariant.BUTTON,\n color: LinkColor.TEXT_INVERSE,\n class: '*:text-text',\n },\n {\n // Outlined Button + Inverse Color (e.g., White Border):\n // Parent is 'text-opposite' (Border is white).\n // Children must also be 'text-opposite' (White text) to show on dark background.\n variant: LinkVariant.BUTTON_OUTLINED,\n color: LinkColor.TEXT_INVERSE,\n class: 'text-text-opposite *:text-text-opposite',\n },\n\n // Min height and padding for button variants\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.SM,\n class: 'min-h-7 px-3 max-md:py-1',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.MD,\n class: 'min-h-8 px-6 max-md:py-2',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.LG,\n class: 'min-h-10 px-8 max-md:py-3',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.XL,\n class: 'min-h-11 px-10 max-md:py-4',\n },\n // Ring color variants\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.PRIMARY,\n class: 'ring-primary/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.SECONDARY,\n class: 'ring-secondary/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.DESTRUCTIVE,\n class: 'ring-destructive/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.NEUTRAL,\n class: 'ring-neutral/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.LIGHT,\n class: 'ring-white/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.DARK,\n class: 'ring-neutral-800/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.TEXT,\n class: 'ring-text/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.TEXT_INVERSE,\n class: 'ring-text-opposite/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.ERROR,\n class: 'ring-error/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.SUCCESS,\n class: 'ring-success/20',\n },\n ],\n\n defaultVariants: {\n variant: LinkVariant.DEFAULT,\n roundedSize: LinkRoundedSize.MD,\n underlined: LinkUnderlined.DEFAULT,\n size: LinkSize.MD,\n },\n }\n);\n\nexport type LinkProps = DetailedHTMLProps<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n HTMLAnchorElement\n> &\n VariantProps<typeof linkVariants> & {\n label: string;\n isExternalLink?: boolean;\n isPageSection?: boolean;\n isActive?: boolean;\n locale?: LocalesValues;\n };\n\nexport const checkIsExternalLink = ({\n href,\n isExternalLink: isExternalLinkProp,\n}: Pick<LinkProps, 'href' | 'isExternalLink'>): boolean => {\n const isValidHref = typeof href === 'string' && href.trim() !== '';\n const isExternalLink =\n isExternalLinkProp === true ||\n (typeof isExternalLinkProp === 'undefined' &&\n isValidHref &&\n /^https?:\\/\\//.test(href));\n\n return isExternalLink;\n};\n\nexport const isTextChildren = (children: ReactNode): boolean => {\n if (typeof children === 'string' || typeof children === 'number') {\n return true;\n }\n if (Array.isArray(children)) {\n return children.every(isTextChildren);\n }\n if (isValidElement(children)) {\n return isTextChildren(\n (children.props as { children?: ReactNode }).children\n );\n }\n return false;\n};\n\nexport const Link: FC<LinkProps> = (props) => {\n const {\n variant = LinkVariant.DEFAULT,\n color = LinkColor.CUSTOM,\n roundedSize,\n children,\n label,\n className,\n isActive,\n underlined,\n locale,\n size,\n isExternalLink: isExternalLinkProp,\n isPageSection: isPageSectionProp,\n href: hrefProp,\n ...otherProps\n } = props;\n\n const isExternalLink = isExternalLinkProp ?? checkIsExternalLink(props);\n const isPageSection = isPageSectionProp ?? hrefProp?.startsWith('#') ?? false;\n\n const isChildrenString = isTextChildren(children);\n const isButton =\n variant === LinkVariant.BUTTON || variant === LinkVariant.BUTTON_OUTLINED;\n\n const rel = isExternalLink ? 'noopener noreferrer nofollow' : undefined;\n\n const target = isExternalLink ? '_blank' : '_self';\n\n const resolvedHref =\n locale && hrefProp && !isExternalLink && !isPageSection\n ? getLocalizedUrl(hrefProp, locale)\n : hrefProp;\n\n const href = resolvedHref === '' ? undefined : resolvedHref;\n\n return (\n <a\n href={href}\n aria-label={label}\n rel={rel}\n target={target}\n aria-current={isActive ? 'page' : undefined}\n suppressHydrationWarning\n className={cn(\n linkVariants({\n variant,\n color,\n roundedSize,\n underlined,\n size,\n className,\n })\n )}\n {...otherProps}\n >\n {isButton && isChildrenString ? <span>{children}</span> : children}\n\n {isExternalLink && isChildrenString && (\n <ExternalLink className=\"ml-2 inline-block size-4\" />\n )}\n {isPageSection && <MoveRight className=\"ml-2 inline-block size-4\" />}\n </a>\n );\n};\n"],"mappings":";;;;;;;;;;;AAgBA,IAAY,cAAL;CACL;CACA;CACA;CACA;CACA;;AACF;;;;AAKA,IAAY,YAAL;CACL;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;;AACF;AAEA,IAAY,kBAAL;CACL;CACA;CACA;CACA;CACA;CACA;CACA;CACA;;AACF;AAEA,IAAY,WAAL;CACL;CACA;CACA;CACA;CACA;;AACF;AAEA,IAAY,iBAAL;CACL;CACA;CACA;;AACF;AAEA,MAAa,eAAe,IAC1B,iHACA;CACE,UAAU;EACR,SAAS;IACN,YACC;IACD,mBACC;IAED,WACC;IAED,oBACC;IAED,cACC;EACJ;EACA,aAAa;IACV,SAA4B;IAC5B,OACC;IACD,OACC;IACD,OACC;IACD,OACC;IACD,QACC;IACD,QACC;IACD,SAA4B;EAC/B;EACA,OAAO;IACJ,YAAyB;IACzB,cAA2B;IAC3B,gBAA6B;IAC7B,YAAyB;IACzB,UAAuB;IACvB,SAAsB;IACtB,SAAsB;IACtB,iBAA8B;IAC9B,UAAuB;IACvB,YAAyB;IACzB,WAAwB;EAC3B;EACA,MAAM;IACH,OAAmB;IACnB,OAAmB;IACnB,OAAmB;IACnB,OAAmB;IACnB,WAAuB;EAC1B;EACA,YAAY;gBACgB;aACH;cACC;EAC1B;CACF;CAEA,kBAAkB;EAIhB;GAIE;GACA;GACA,OAAO;EACT;EACA;GAIE;GACA;GACA,OAAO;EACT;EAGA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EAEA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;CACF;CAEA,iBAAiB;EACf;EACA;EACA;EACA;CACF;AACF,CACF;AAcA,MAAa,uBAAuB,EAClC,MACA,gBAAgB,yBACyC;CACzD,MAAM,cAAc,OAAO,SAAS,YAAY,KAAK,KAAK,MAAM;CAOhE,OALE,uBAAuB,QACtB,OAAO,uBAAuB,eAC7B,eACA,eAAe,KAAK,IAAI;AAG9B;AAEA,MAAa,kBAAkB,aAAiC;CAC9D,IAAI,OAAO,aAAa,YAAY,OAAO,aAAa,UACtD,OAAO;CAET,IAAI,MAAM,QAAQ,QAAQ,GACxB,OAAO,SAAS,MAAM,cAAc;CAEtC,IAAI,eAAe,QAAQ,GACzB,OAAO,eACJ,SAAS,MAAmC,QAC/C;CAEF,OAAO;AACT;AAEA,MAAa,QAAuB,UAAU;CAC5C,MAAM,EACJ,qBACA,kBACA,aACA,UACA,OACA,WACA,UACA,YACA,QACA,MACA,gBAAgB,oBAChB,eAAe,mBACf,MAAM,UACN,GAAG,eACD;CAEJ,MAAM,iBAAiB,sBAAsB,oBAAoB,KAAK;CACtE,MAAM,gBAAgB,qBAAqB,UAAU,WAAW,GAAG,KAAK;CAExE,MAAM,mBAAmB,eAAe,QAAQ;CAChD,MAAM,WACJ,wBAAkC;CAEpC,MAAM,MAAM,iBAAiB,iCAAiC;CAE9D,MAAM,SAAS,iBAAiB,WAAW;CAE3C,MAAM,eACJ,UAAU,YAAY,CAAC,kBAAkB,CAAC,gBACtC,gBAAgB,UAAU,MAAM,IAChC;CAIN,OACE,qBAAC,KAAD;EACE,MAJS,iBAAiB,KAAK,SAAY;EAK3C,cAAY;EACP;EACG;EACR,gBAAc,WAAW,SAAS;EAClC;EACA,WAAW,GACT,aAAa;GACX;GACA;GACA;GACA;GACA;GACA;EACF,CAAC,CACH;EACA,GAAI;YAjBN;GAmBG,YAAY,mBAAmB,oBAAC,QAAD,EAAO,SAAe,KAAI;GAEzD,kBAAkB,oBACjB,oBAAC,cAAD,EAAc,WAAU,2BAA4B;GAErD,iBAAiB,oBAAC,WAAD,EAAW,WAAU,2BAA4B;EAClE;;AAEP"}
|
|
1
|
+
{"version":3,"file":"Link.mjs","names":[],"sources":["../../../../src/components/Link/Link.tsx"],"sourcesContent":["import { getLocalizedUrl } from '@intlayer/core/localization';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ExternalLink, MoveRight } from 'lucide-react';\nimport {\n type AnchorHTMLAttributes,\n type DetailedHTMLProps,\n type FC,\n isValidElement,\n type ReactNode,\n} from 'react';\n\n/**\n * Visual style variants for Link component\n */\nexport enum LinkVariant {\n DEFAULT = 'default',\n INVISIBLE_LINK = 'invisible-link',\n BUTTON = 'button',\n BUTTON_OUTLINED = 'button-outlined',\n HOVERABLE = 'hoverable',\n}\n\n/**\n * Color theme variants for Link component\n */\nexport enum LinkColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n NEUTRAL = 'neutral',\n LIGHT = 'light',\n DARK = 'dark',\n TEXT = 'text',\n TEXT_INVERSE = 'text-inverse',\n ERROR = 'error',\n SUCCESS = 'success',\n CUSTOM = 'custom',\n}\n\nexport enum LinkRoundedSize {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n TWO_XL = '2xl',\n THREE_XL = '3xl',\n FULL = 'full',\n}\n\nexport enum LinkSize {\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n CUSTOM = 'custom',\n}\n\nexport enum LinkUnderlined {\n DEFAULT = 'default',\n TRUE = 'true',\n FALSE = 'false',\n}\n\nexport const linkVariants = cva(\n 'gap-3 transition-all duration-300 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n [`${LinkVariant.DEFAULT}`]:\n 'h-auto justify-start border-inherit bg-current/0 px-1 font-medium decoration-[1.5] underline-offset-5 hover:bg-current/0 hover:text-current/80 hover:underline hover:underline-offset-6',\n [`${LinkVariant.INVISIBLE_LINK}`]:\n 'h-auto justify-start border-inherit bg-current/0 px-1 underline-offset-5 hover:bg-current/0 aria-[current]:bg-current/5',\n\n [`${LinkVariant.BUTTON}`]:\n 'relative flex cursor-pointer flex-row items-center justify-center gap-2 rounded-full bg-current text-center font-medium text-text ring-0 *:text-text-opposite hover:bg-current/90 hover:ring-5 aria-selected:ring-5 aria-[current]:ring-5',\n\n [`${LinkVariant.BUTTON_OUTLINED}`]:\n 'relative flex cursor-pointer flex-row items-center justify-center gap-2 rounded-full border-[1.3px] border-current text-center font-medium text-text ring-0 *:text-text hover:bg-current/20 hover:ring-5 aria-selected:ring-5 aria-[current]:ring-5',\n\n [`${LinkVariant.HOVERABLE}`]:\n 'rounded-lg border-none bg-current/0 transition *:text-current! hover:bg-current/20 aria-[current]:bg-current/5',\n },\n roundedSize: {\n [`${LinkRoundedSize.NONE}`]: 'rounded-none',\n [`${LinkRoundedSize.SM}`]:\n 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n [`${LinkRoundedSize.MD}`]:\n 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n [`${LinkRoundedSize.LG}`]:\n 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n [`${LinkRoundedSize.XL}`]:\n 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n [`${LinkRoundedSize.TWO_XL}`]:\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n [`${LinkRoundedSize.THREE_XL}`]:\n 'rounded-[2.5rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[3rem]',\n [`${LinkRoundedSize.FULL}`]: 'rounded-full',\n },\n color: {\n [`${LinkColor.PRIMARY}`]: 'text-primary',\n [`${LinkColor.SECONDARY}`]: 'text-secondary',\n [`${LinkColor.NEUTRAL}`]: 'text-neutral',\n [`${LinkColor.LIGHT}`]: 'text-white',\n [`${LinkColor.DARK}`]: 'text-neutral-800',\n [`${LinkColor.TEXT}`]: 'text-text',\n [`${LinkColor.TEXT_INVERSE}`]: 'text-text-opposite',\n [`${LinkColor.ERROR}`]: 'text-error',\n [`${LinkColor.SUCCESS}`]: 'text-success',\n [`${LinkColor.CUSTOM}`]: '',\n },\n size: {\n [`${LinkSize.SM}`]: 'text-sm',\n [`${LinkSize.MD}`]: 'text-base',\n [`${LinkSize.LG}`]: 'text-lg',\n [`${LinkSize.XL}`]: 'text-xl',\n [`${LinkSize.CUSTOM}`]: '',\n },\n underlined: {\n [LinkUnderlined.DEFAULT]: '',\n [LinkUnderlined.TRUE]: 'underline',\n [LinkUnderlined.FALSE]: 'no-underline',\n },\n },\n // Compound variants handle height and padding\n compoundVariants: [\n // ---------------------------------------------------------\n // FIX START: Correctly Handle Contrast for TEXT_INVERSE\n // ---------------------------------------------------------\n {\n // Filled Button + Inverse Color (e.g., White Button):\n // We DO NOT override parent text color (it must remain 'text-opposite' so bg-current is white).\n // We ONLY override children to be 'text-text' (Dark) so they show up on white.\n variant: LinkVariant.BUTTON,\n color: LinkColor.TEXT_INVERSE,\n class: '*:text-text',\n },\n {\n // Outlined Button + Inverse Color (e.g., White Border):\n // Parent is 'text-opposite' (Border is white).\n // Children must also be 'text-opposite' (White text) to show on dark background.\n variant: LinkVariant.BUTTON_OUTLINED,\n color: LinkColor.TEXT_INVERSE,\n class: 'text-text-opposite *:text-text-opposite',\n },\n\n // Min height and padding for button variants\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.SM,\n class: 'min-h-7 px-3 max-md:py-1',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.MD,\n class: 'min-h-8 px-6 max-md:py-2',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.LG,\n class: 'min-h-10 px-8 max-md:py-3',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.XL,\n class: 'min-h-11 px-10 max-md:py-4',\n },\n // Ring color variants\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.PRIMARY,\n class: 'ring-primary/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.SECONDARY,\n class: 'ring-secondary/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.NEUTRAL,\n class: 'ring-neutral/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.LIGHT,\n class: 'ring-white/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.DARK,\n class: 'ring-neutral-800/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.TEXT,\n class: 'ring-text/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.TEXT_INVERSE,\n class: 'ring-text-opposite/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.ERROR,\n class: 'ring-error/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.SUCCESS,\n class: 'ring-success/20',\n },\n ],\n\n defaultVariants: {\n variant: LinkVariant.DEFAULT,\n roundedSize: LinkRoundedSize.MD,\n underlined: LinkUnderlined.DEFAULT,\n size: LinkSize.MD,\n },\n }\n);\n\nexport type LinkProps = DetailedHTMLProps<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n HTMLAnchorElement\n> &\n VariantProps<typeof linkVariants> & {\n label: string;\n isExternalLink?: boolean;\n isPageSection?: boolean;\n isActive?: boolean;\n locale?: LocalesValues;\n };\n\nexport const checkIsExternalLink = ({\n href,\n isExternalLink: isExternalLinkProp,\n}: Pick<LinkProps, 'href' | 'isExternalLink'>): boolean => {\n const isValidHref = typeof href === 'string' && href.trim() !== '';\n const isExternalLink =\n isExternalLinkProp === true ||\n (typeof isExternalLinkProp === 'undefined' &&\n isValidHref &&\n /^https?:\\/\\//.test(href));\n\n return isExternalLink;\n};\n\nexport const isTextChildren = (children: ReactNode): boolean => {\n if (typeof children === 'string' || typeof children === 'number') {\n return true;\n }\n if (Array.isArray(children)) {\n return children.every(isTextChildren);\n }\n if (isValidElement(children)) {\n return isTextChildren(\n (children.props as { children?: ReactNode }).children\n );\n }\n return false;\n};\n\nexport const Link: FC<LinkProps> = (props) => {\n const {\n variant = LinkVariant.DEFAULT,\n color = LinkColor.CUSTOM,\n roundedSize,\n children,\n label,\n className,\n isActive,\n underlined,\n locale,\n size,\n isExternalLink: isExternalLinkProp,\n isPageSection: isPageSectionProp,\n href: hrefProp,\n ...otherProps\n } = props;\n\n const isExternalLink = isExternalLinkProp ?? checkIsExternalLink(props);\n const isPageSection = isPageSectionProp ?? hrefProp?.startsWith('#') ?? false;\n\n const isChildrenString = isTextChildren(children);\n const isButton =\n variant === LinkVariant.BUTTON || variant === LinkVariant.BUTTON_OUTLINED;\n\n const rel = isExternalLink ? 'noopener noreferrer nofollow' : undefined;\n\n const target = isExternalLink ? '_blank' : '_self';\n\n const resolvedHref =\n locale && hrefProp && !isExternalLink && !isPageSection\n ? getLocalizedUrl(hrefProp, locale)\n : hrefProp;\n\n const href = resolvedHref === '' ? undefined : resolvedHref;\n\n return (\n <a\n href={href}\n aria-label={label}\n rel={rel}\n target={target}\n aria-current={isActive ? 'page' : undefined}\n suppressHydrationWarning\n className={cn(\n linkVariants({\n variant,\n color,\n roundedSize,\n underlined,\n size,\n className,\n })\n )}\n {...otherProps}\n >\n {isButton && isChildrenString ? <span>{children}</span> : children}\n\n {isExternalLink && isChildrenString && (\n <ExternalLink className=\"ml-2 inline-block size-4\" />\n )}\n {isPageSection && <MoveRight className=\"ml-2 inline-block size-4\" />}\n </a>\n );\n};\n"],"mappings":";;;;;;;;;;;AAgBA,IAAY,cAAL;CACL;CACA;CACA;CACA;CACA;;AACF;;;;AAKA,IAAY,YAAL;CACL;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;;AACF;AAEA,IAAY,kBAAL;CACL;CACA;CACA;CACA;CACA;CACA;CACA;CACA;;AACF;AAEA,IAAY,WAAL;CACL;CACA;CACA;CACA;CACA;;AACF;AAEA,IAAY,iBAAL;CACL;CACA;CACA;;AACF;AAEA,MAAa,eAAe,IAC1B,iHACA;CACE,UAAU;EACR,SAAS;IACN,YACC;IACD,mBACC;IAED,WACC;IAED,oBACC;IAED,cACC;EACJ;EACA,aAAa;IACV,SAA4B;IAC5B,OACC;IACD,OACC;IACD,OACC;IACD,OACC;IACD,QACC;IACD,QACC;IACD,SAA4B;EAC/B;EACA,OAAO;IACJ,YAAyB;IACzB,cAA2B;IAC3B,YAAyB;IACzB,UAAuB;IACvB,SAAsB;IACtB,SAAsB;IACtB,iBAA8B;IAC9B,UAAuB;IACvB,YAAyB;IACzB,WAAwB;EAC3B;EACA,MAAM;IACH,OAAmB;IACnB,OAAmB;IACnB,OAAmB;IACnB,OAAmB;IACnB,WAAuB;EAC1B;EACA,YAAY;gBACgB;aACH;cACC;EAC1B;CACF;CAEA,kBAAkB;EAIhB;GAIE;GACA;GACA,OAAO;EACT;EACA;GAIE;GACA;GACA,OAAO;EACT;EAGA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EAEA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;EACA;GACE,SAAS,4BAAgD;GACzD;GACA,OAAO;EACT;CACF;CAEA,iBAAiB;EACf;EACA;EACA;EACA;CACF;AACF,CACF;AAcA,MAAa,uBAAuB,EAClC,MACA,gBAAgB,yBACyC;CACzD,MAAM,cAAc,OAAO,SAAS,YAAY,KAAK,KAAK,MAAM;CAOhE,OALE,uBAAuB,QACtB,OAAO,uBAAuB,eAC7B,eACA,eAAe,KAAK,IAAI;AAG9B;AAEA,MAAa,kBAAkB,aAAiC;CAC9D,IAAI,OAAO,aAAa,YAAY,OAAO,aAAa,UACtD,OAAO;CAET,IAAI,MAAM,QAAQ,QAAQ,GACxB,OAAO,SAAS,MAAM,cAAc;CAEtC,IAAI,eAAe,QAAQ,GACzB,OAAO,eACJ,SAAS,MAAmC,QAC/C;CAEF,OAAO;AACT;AAEA,MAAa,QAAuB,UAAU;CAC5C,MAAM,EACJ,qBACA,kBACA,aACA,UACA,OACA,WACA,UACA,YACA,QACA,MACA,gBAAgB,oBAChB,eAAe,mBACf,MAAM,UACN,GAAG,eACD;CAEJ,MAAM,iBAAiB,sBAAsB,oBAAoB,KAAK;CACtE,MAAM,gBAAgB,qBAAqB,UAAU,WAAW,GAAG,KAAK;CAExE,MAAM,mBAAmB,eAAe,QAAQ;CAChD,MAAM,WACJ,wBAAkC;CAEpC,MAAM,MAAM,iBAAiB,iCAAiC;CAE9D,MAAM,SAAS,iBAAiB,WAAW;CAE3C,MAAM,eACJ,UAAU,YAAY,CAAC,kBAAkB,CAAC,gBACtC,gBAAgB,UAAU,MAAM,IAChC;CAIN,OACE,qBAAC,KAAD;EACE,MAJS,iBAAiB,KAAK,SAAY;EAK3C,cAAY;EACP;EACG;EACR,gBAAc,WAAW,SAAS;EAClC;EACA,WAAW,GACT,aAAa;GACX;GACA;GACA;GACA;GACA;GACA;EACF,CAAC,CACH;EACA,GAAI;YAjBN;GAmBG,YAAY,mBAAmB,oBAAC,QAAD,EAAO,SAAe,KAAI;GAEzD,kBAAkB,oBACjB,oBAAC,cAAD,EAAc,WAAU,2BAA4B;GAErD,iBAAiB,oBAAC,WAAD,EAAW,WAAU,2BAA4B;EAClE;;AAEP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spinner.mjs","names":[],"sources":["../../../../src/components/Loader/spinner.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport type { SVGProps } from 'react';\n\n/**\n * Props for the Spinner component\n */\ntype SpinnerProps = SVGProps<SVGSVGElement> & {\n /** Stroke width for the spinner animation circles. Defaults to 4 */\n strokeWidth?: number;\n};\n\n/**\n * Spinner Component\n *\n * An animated SVG spinner that displays two expanding and fading circles\n * to indicate loading or processing states. Uses smooth CSS animations\n * with spline curves for natural motion.\n *\n * @component\n * @example\n * Basic usage:\n * ```tsx\n * <Spinner />\n * ```\n *\n * @example\n * Custom stroke width:\n * ```tsx\n * <Spinner strokeWidth={6} className=\"text-blue-500\" />\n * ```\n *\n * @example\n * Custom size:\n * ```tsx\n * <Spinner className=\"size-8 text-
|
|
1
|
+
{"version":3,"file":"spinner.mjs","names":[],"sources":["../../../../src/components/Loader/spinner.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport type { SVGProps } from 'react';\n\n/**\n * Props for the Spinner component\n */\ntype SpinnerProps = SVGProps<SVGSVGElement> & {\n /** Stroke width for the spinner animation circles. Defaults to 4 */\n strokeWidth?: number;\n};\n\n/**\n * Spinner Component\n *\n * An animated SVG spinner that displays two expanding and fading circles\n * to indicate loading or processing states. Uses smooth CSS animations\n * with spline curves for natural motion.\n *\n * @component\n * @example\n * Basic usage:\n * ```tsx\n * <Spinner />\n * ```\n *\n * @example\n * Custom stroke width:\n * ```tsx\n * <Spinner strokeWidth={6} className=\"text-blue-500\" />\n * ```\n *\n * @example\n * Custom size:\n * ```tsx\n * <Spinner className=\"size-8 text-error\" strokeWidth={2} />\n * ```\n *\n * Features:\n * - Smooth expanding circle animation\n * - Customizable stroke width\n * - Inherits text color from parent (currentColor)\n * - Responsive sizing through className\n * - Infinite loop animation\n * - Two-phase animation with offset timing\n * - Optimized SVG with minimal DOM impact\n *\n * Animation Details:\n * - Duration: 1.8 seconds per cycle\n * - Two circles with 0.9s offset\n * - Radius expands from 1 to 20\n * - Opacity fades from 1 to 0\n * - Spline easing for natural motion\n *\n * @param props - SVG props with custom spinner options\n * @param props.className - CSS classes for styling and sizing\n * @param props.strokeWidth - Line thickness for the animated circles\n * @param props.color - SVG color (use className with text-color for easier styling)\n * @param props.width - SVG width (defaults to 44, use className for responsive sizing)\n * @param props.height - SVG height (defaults to 44, use className for responsive sizing)\n * @param props...rest - All other standard SVG element attributes\n *\n * @returns An animated SVG spinner element\n */\nexport const Spinner = ({ className, strokeWidth = 4 }: SpinnerProps) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"44\"\n height=\"44\"\n viewBox=\"0 0 44 44\"\n stroke=\"currentColor\"\n role=\"img\"\n aria-label=\"Spinner\"\n className={cn('size-full', className)}\n >\n <g fill=\"none\" fillRule=\"evenodd\" strokeWidth={strokeWidth}>\n <circle cx=\"22\" cy=\"22\" r=\"1\">\n <animate\n attributeName=\"r\"\n begin=\"0s\"\n dur=\"1.8s\"\n values=\"1; 20\"\n calcMode=\"spline\"\n keyTimes=\"0; 1\"\n keySplines=\"0.165, 0.84, 0.44, 1\"\n repeatCount=\"indefinite\"\n />\n <animate\n attributeName=\"stroke-opacity\"\n begin=\"0s\"\n dur=\"1.8s\"\n values=\"1; 0\"\n calcMode=\"spline\"\n keyTimes=\"0; 1\"\n keySplines=\"0.3, 0.61, 0.355, 1\"\n repeatCount=\"indefinite\"\n />\n </circle>\n <circle cx=\"22\" cy=\"22\" r=\"1\">\n <animate\n attributeName=\"r\"\n begin=\"-0.9s\"\n dur=\"1.8s\"\n values=\"1; 20\"\n calcMode=\"spline\"\n keyTimes=\"0; 1\"\n keySplines=\"0.165, 0.84, 0.44, 1\"\n repeatCount=\"indefinite\"\n />\n <animate\n attributeName=\"stroke-opacity\"\n begin=\"-0.9s\"\n dur=\"1.8s\"\n values=\"1; 0\"\n calcMode=\"spline\"\n keyTimes=\"0; 1\"\n keySplines=\"0.3, 0.61, 0.355, 1\"\n repeatCount=\"indefinite\"\n />\n </circle>\n </g>\n </svg>\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DA,MAAa,WAAW,EAAE,WAAW,cAAc,QACjD,oBAAC,OAAD;CACE,OAAM;CACN,OAAM;CACN,QAAO;CACP,SAAQ;CACR,QAAO;CACP,MAAK;CACL,cAAW;CACX,WAAW,GAAG,aAAa,SAAS;WAEpC,qBAAC,KAAD;EAAG,MAAK;EAAO,UAAS;EAAuB;YAA/C,CACE,qBAAC,UAAD;GAAQ,IAAG;GAAK,IAAG;GAAK,GAAE;aAA1B,CACE,oBAAC,WAAD;IACE,eAAc;IACd,OAAM;IACN,KAAI;IACJ,QAAO;IACP,UAAS;IACT,UAAS;IACT,YAAW;IACX,aAAY;GACb,IACD,oBAAC,WAAD;IACE,eAAc;IACd,OAAM;IACN,KAAI;IACJ,QAAO;IACP,UAAS;IACT,UAAS;IACT,YAAW;IACX,aAAY;GACb,EACK;MACR,qBAAC,UAAD;GAAQ,IAAG;GAAK,IAAG;GAAK,GAAE;aAA1B,CACE,oBAAC,WAAD;IACE,eAAc;IACd,OAAM;IACN,KAAI;IACJ,QAAO;IACP,UAAS;IACT,UAAS;IACT,YAAW;IACX,aAAY;GACb,IACD,oBAAC,WAAD;IACE,eAAc;IACd,OAAM;IACN,KAAI;IACJ,QAAO;IACP,UAAS;IACT,UAAS;IACT,YAAW;IACX,aAAY;GACb,EACK;IACP;;AACA"}
|
|
@@ -21,8 +21,7 @@ const paginationVariants = cva("flex items-center justify-center gap-1", {
|
|
|
21
21
|
text: "background-text",
|
|
22
22
|
primary: "background-primary",
|
|
23
23
|
secondary: "background-secondary",
|
|
24
|
-
neutral: "background-neutral"
|
|
25
|
-
destructive: "background-destructive"
|
|
24
|
+
neutral: "background-neutral"
|
|
26
25
|
},
|
|
27
26
|
variant: {
|
|
28
27
|
default: "",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pagination.mjs","names":[],"sources":["../../../../src/components/Pagination/Pagination.tsx"],"sourcesContent":["'use client';\n\nimport { useItemSelector } from '@hooks/useItemSelector';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react';\nimport {\n type ComponentProps,\n type FC,\n type HTMLAttributes,\n useEffect,\n useRef,\n} from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { Button, ButtonColor, ButtonSize, ButtonVariant } from '../Button';\n\nexport const paginationVariants = cva(\n 'flex items-center justify-center gap-1',\n {\n variants: {\n size: {\n sm: 'gap-1',\n md: 'gap-2',\n lg: 'gap-3',\n },\n color: {\n text: 'background-text',\n primary: 'background-primary',\n secondary: 'background-secondary',\n neutral: 'background-neutral',\n destructive: 'background-destructive',\n },\n variant: {\n default: '',\n bordered: 'rounded-lg border border-border p-2',\n ghost: 'bg-transparent',\n },\n },\n defaultVariants: {\n size: 'md',\n variant: 'default',\n },\n }\n);\n\nexport enum PaginationSize {\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n}\n\nexport enum PaginationVariant {\n DEFAULT = 'default',\n BORDERED = 'bordered',\n GHOST = 'ghost',\n}\n\nexport type PaginationProps = HTMLAttributes<HTMLDivElement> &\n VariantProps<typeof paginationVariants> & {\n currentPage: number;\n totalPages: number;\n onPageChange: (page: number) => void;\n showFirstLast?: boolean;\n showPrevNext?: boolean;\n maxVisiblePages?: number;\n disabled?: boolean;\n };\n\nconst generatePageNumbers = (\n currentPage: number,\n totalPages: number,\n maxVisiblePages: number\n): (number | 'ellipsis')[] => {\n if (totalPages <= maxVisiblePages) {\n return Array.from({ length: totalPages }, (_, i) => i + 1);\n }\n\n const pages: (number | 'ellipsis')[] = [];\n const halfVisible = Math.floor(maxVisiblePages / 2);\n\n pages.push(1);\n\n if (currentPage <= halfVisible + 2) {\n for (let i = 2; i <= Math.min(maxVisiblePages - 1, totalPages - 1); i++) {\n pages.push(i);\n }\n if (totalPages > maxVisiblePages) {\n pages.push('ellipsis');\n }\n if (totalPages > 1) {\n pages.push(totalPages);\n }\n } else if (currentPage >= totalPages - halfVisible - 1) {\n if (totalPages > maxVisiblePages) {\n pages.push('ellipsis');\n }\n for (\n let i = Math.max(2, totalPages - maxVisiblePages + 2);\n i <= totalPages;\n i++\n ) {\n pages.push(i);\n }\n } else {\n pages.push('ellipsis');\n const start = currentPage - halfVisible;\n const end = currentPage + halfVisible;\n for (let i = start; i <= end; i++) {\n pages.push(i);\n }\n pages.push('ellipsis');\n pages.push(totalPages);\n }\n\n return pages;\n};\n\nconst selector = (option: HTMLElement) =>\n option?.getAttribute('aria-current') === 'true';\n\nconst getButtonSize = (size?: PaginationSize | `${PaginationSize}` | null) => {\n if (size === PaginationSize.SM) {\n return ButtonSize.ICON_SM;\n } else if (size === PaginationSize.LG) {\n return ButtonSize.ICON_LG;\n } else {\n return ButtonSize.ICON_MD;\n }\n};\n\nconst InputIndicator: FC<ComponentProps<'div'>> = (props) => (\n <div\n className=\"absolute top-0 z-0 h-full w-auto rounded-xl bg-text/20 ring-4 ring-text/10 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\nexport const Pagination: FC<PaginationProps> = ({\n currentPage,\n totalPages,\n onPageChange,\n showFirstLast = false,\n showPrevNext = true,\n maxVisiblePages = 5,\n disabled = false,\n size = PaginationSize.MD,\n variant = PaginationVariant.DEFAULT,\n color = ButtonColor.TEXT,\n className,\n ...props\n}) => {\n const { goToNextPage, goToPreviousPage } = useIntlayer('pagination');\n\n const pageNumbers = generatePageNumbers(\n currentPage,\n totalPages,\n maxVisiblePages\n );\n\n const buttonSize = getButtonSize(size);\n const isFirstPage = currentPage === 1;\n const isLastPage = currentPage === totalPages;\n\n const optionsRefs = useRef<HTMLElement[]>([]);\n const indicatorRef = useRef<HTMLDivElement | null>(null);\n const { choiceIndicatorPosition, calculatePosition } = useItemSelector(\n optionsRefs,\n {\n selector,\n isHoverable: true,\n }\n );\n\n useEffect(() => {\n const timer = setTimeout(() => {\n calculatePosition();\n }, 300);\n\n return () => clearTimeout(timer);\n }, [currentPage, calculatePosition]);\n\n if (totalPages <= 1) return null;\n\n const handlePageChange = (page: number) => {\n if (!disabled && page >= 1 && page <= totalPages && page !== currentPage) {\n onPageChange(page);\n }\n };\n\n return (\n <div\n className={cn(paginationVariants({ size, variant }), className)}\n {...props}\n >\n <div className=\"relative flex items-center gap-1\">\n {choiceIndicatorPosition && (\n <InputIndicator style={choiceIndicatorPosition} ref={indicatorRef} />\n )}\n\n {showPrevNext && (\n <Button\n variant={ButtonVariant.OUTLINE}\n size={buttonSize}\n color={ButtonColor.TEXT}\n onClick={() => handlePageChange(currentPage - 1)}\n disabled={disabled || isFirstPage}\n label={goToPreviousPage.value}\n Icon={ChevronLeft}\n ref={(el) => {\n if (el) optionsRefs.current[0] = el;\n }}\n className=\"min-w-0 px-2\"\n />\n )}\n\n <div className=\"flex items-center gap-1 max-md:gap-0.5\">\n {pageNumbers.map((page, index) => {\n if (page === 'ellipsis') {\n const isFirstEllipsis = index === pageNumbers.indexOf('ellipsis');\n const ellipsisKey = isFirstEllipsis\n ? 'ellipsis-start'\n : 'ellipsis-end';\n return (\n <div\n key={ellipsisKey}\n className=\"flex h-8 min-w-8 items-center justify-center px-1\"\n >\n <MoreHorizontal className=\"h-4 w-4 text-muted-foreground\" />\n </div>\n );\n }\n\n const isActive = page === currentPage;\n // Calculate ref index: offset by 1 if showPrevNext, then count only non-ellipsis items\n const refIndex =\n (showPrevNext ? 1 : 0) +\n pageNumbers.slice(0, index).filter((p) => p !== 'ellipsis')\n .length;\n\n return (\n <Button\n key={page}\n variant={\n isActive ? ButtonVariant.DEFAULT : ButtonVariant.OUTLINE\n }\n size={buttonSize}\n color={ButtonColor.TEXT}\n onClick={() => handlePageChange(page)}\n disabled={disabled}\n label={`Go to page ${page}`}\n aria-current={isActive ? 'true' : 'false'}\n ref={(el) => {\n if (el) optionsRefs.current[refIndex] = el;\n }}\n className={cn(\n 'flex aspect-square h-8 w-8 min-w-0 items-center justify-center p-0 text-sm',\n size === 'sm' && 'h-6 w-6 text-xs',\n size === 'lg' && 'size-10 text-base',\n isActive && 'font-semibold'\n )}\n >\n {page}\n </Button>\n );\n })}\n </div>\n\n {showPrevNext && (\n <Button\n variant={ButtonVariant.OUTLINE}\n size={buttonSize}\n color={ButtonColor.TEXT}\n onClick={() => handlePageChange(currentPage + 1)}\n disabled={disabled || isLastPage}\n label={goToNextPage.value}\n Icon={ChevronRight}\n ref={(el) => {\n const lastRefIndex =\n (showPrevNext ? 1 : 0) +\n pageNumbers.filter((p) => p !== 'ellipsis').length;\n if (el) optionsRefs.current[lastRefIndex] = el;\n }}\n className=\"min-w-0 px-2\"\n />\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Pagination.mjs","names":[],"sources":["../../../../src/components/Pagination/Pagination.tsx"],"sourcesContent":["'use client';\n\nimport { useItemSelector } from '@hooks/useItemSelector';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react';\nimport {\n type ComponentProps,\n type FC,\n type HTMLAttributes,\n useEffect,\n useRef,\n} from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { Button, ButtonColor, ButtonSize, ButtonVariant } from '../Button';\n\nexport const paginationVariants = cva(\n 'flex items-center justify-center gap-1',\n {\n variants: {\n size: {\n sm: 'gap-1',\n md: 'gap-2',\n lg: 'gap-3',\n },\n color: {\n text: 'background-text',\n primary: 'background-primary',\n secondary: 'background-secondary',\n neutral: 'background-neutral',\n },\n variant: {\n default: '',\n bordered: 'rounded-lg border border-border p-2',\n ghost: 'bg-transparent',\n },\n },\n defaultVariants: {\n size: 'md',\n variant: 'default',\n },\n }\n);\n\nexport enum PaginationSize {\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n}\n\nexport enum PaginationVariant {\n DEFAULT = 'default',\n BORDERED = 'bordered',\n GHOST = 'ghost',\n}\n\nexport type PaginationProps = HTMLAttributes<HTMLDivElement> &\n VariantProps<typeof paginationVariants> & {\n currentPage: number;\n totalPages: number;\n onPageChange: (page: number) => void;\n showFirstLast?: boolean;\n showPrevNext?: boolean;\n maxVisiblePages?: number;\n disabled?: boolean;\n };\n\nconst generatePageNumbers = (\n currentPage: number,\n totalPages: number,\n maxVisiblePages: number\n): (number | 'ellipsis')[] => {\n if (totalPages <= maxVisiblePages) {\n return Array.from({ length: totalPages }, (_, i) => i + 1);\n }\n\n const pages: (number | 'ellipsis')[] = [];\n const halfVisible = Math.floor(maxVisiblePages / 2);\n\n pages.push(1);\n\n if (currentPage <= halfVisible + 2) {\n for (let i = 2; i <= Math.min(maxVisiblePages - 1, totalPages - 1); i++) {\n pages.push(i);\n }\n if (totalPages > maxVisiblePages) {\n pages.push('ellipsis');\n }\n if (totalPages > 1) {\n pages.push(totalPages);\n }\n } else if (currentPage >= totalPages - halfVisible - 1) {\n if (totalPages > maxVisiblePages) {\n pages.push('ellipsis');\n }\n for (\n let i = Math.max(2, totalPages - maxVisiblePages + 2);\n i <= totalPages;\n i++\n ) {\n pages.push(i);\n }\n } else {\n pages.push('ellipsis');\n const start = currentPage - halfVisible;\n const end = currentPage + halfVisible;\n for (let i = start; i <= end; i++) {\n pages.push(i);\n }\n pages.push('ellipsis');\n pages.push(totalPages);\n }\n\n return pages;\n};\n\nconst selector = (option: HTMLElement) =>\n option?.getAttribute('aria-current') === 'true';\n\nconst getButtonSize = (size?: PaginationSize | `${PaginationSize}` | null) => {\n if (size === PaginationSize.SM) {\n return ButtonSize.ICON_SM;\n } else if (size === PaginationSize.LG) {\n return ButtonSize.ICON_LG;\n } else {\n return ButtonSize.ICON_MD;\n }\n};\n\nconst InputIndicator: FC<ComponentProps<'div'>> = (props) => (\n <div\n className=\"absolute top-0 z-0 h-full w-auto rounded-xl bg-text/20 ring-4 ring-text/10 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\nexport const Pagination: FC<PaginationProps> = ({\n currentPage,\n totalPages,\n onPageChange,\n showFirstLast = false,\n showPrevNext = true,\n maxVisiblePages = 5,\n disabled = false,\n size = PaginationSize.MD,\n variant = PaginationVariant.DEFAULT,\n color = ButtonColor.TEXT,\n className,\n ...props\n}) => {\n const { goToNextPage, goToPreviousPage } = useIntlayer('pagination');\n\n const pageNumbers = generatePageNumbers(\n currentPage,\n totalPages,\n maxVisiblePages\n );\n\n const buttonSize = getButtonSize(size);\n const isFirstPage = currentPage === 1;\n const isLastPage = currentPage === totalPages;\n\n const optionsRefs = useRef<HTMLElement[]>([]);\n const indicatorRef = useRef<HTMLDivElement | null>(null);\n const { choiceIndicatorPosition, calculatePosition } = useItemSelector(\n optionsRefs,\n {\n selector,\n isHoverable: true,\n }\n );\n\n useEffect(() => {\n const timer = setTimeout(() => {\n calculatePosition();\n }, 300);\n\n return () => clearTimeout(timer);\n }, [currentPage, calculatePosition]);\n\n if (totalPages <= 1) return null;\n\n const handlePageChange = (page: number) => {\n if (!disabled && page >= 1 && page <= totalPages && page !== currentPage) {\n onPageChange(page);\n }\n };\n\n return (\n <div\n className={cn(paginationVariants({ size, variant }), className)}\n {...props}\n >\n <div className=\"relative flex items-center gap-1\">\n {choiceIndicatorPosition && (\n <InputIndicator style={choiceIndicatorPosition} ref={indicatorRef} />\n )}\n\n {showPrevNext && (\n <Button\n variant={ButtonVariant.OUTLINE}\n size={buttonSize}\n color={ButtonColor.TEXT}\n onClick={() => handlePageChange(currentPage - 1)}\n disabled={disabled || isFirstPage}\n label={goToPreviousPage.value}\n Icon={ChevronLeft}\n ref={(el) => {\n if (el) optionsRefs.current[0] = el;\n }}\n className=\"min-w-0 px-2\"\n />\n )}\n\n <div className=\"flex items-center gap-1 max-md:gap-0.5\">\n {pageNumbers.map((page, index) => {\n if (page === 'ellipsis') {\n const isFirstEllipsis = index === pageNumbers.indexOf('ellipsis');\n const ellipsisKey = isFirstEllipsis\n ? 'ellipsis-start'\n : 'ellipsis-end';\n return (\n <div\n key={ellipsisKey}\n className=\"flex h-8 min-w-8 items-center justify-center px-1\"\n >\n <MoreHorizontal className=\"h-4 w-4 text-muted-foreground\" />\n </div>\n );\n }\n\n const isActive = page === currentPage;\n // Calculate ref index: offset by 1 if showPrevNext, then count only non-ellipsis items\n const refIndex =\n (showPrevNext ? 1 : 0) +\n pageNumbers.slice(0, index).filter((p) => p !== 'ellipsis')\n .length;\n\n return (\n <Button\n key={page}\n variant={\n isActive ? ButtonVariant.DEFAULT : ButtonVariant.OUTLINE\n }\n size={buttonSize}\n color={ButtonColor.TEXT}\n onClick={() => handlePageChange(page)}\n disabled={disabled}\n label={`Go to page ${page}`}\n aria-current={isActive ? 'true' : 'false'}\n ref={(el) => {\n if (el) optionsRefs.current[refIndex] = el;\n }}\n className={cn(\n 'flex aspect-square h-8 w-8 min-w-0 items-center justify-center p-0 text-sm',\n size === 'sm' && 'h-6 w-6 text-xs',\n size === 'lg' && 'size-10 text-base',\n isActive && 'font-semibold'\n )}\n >\n {page}\n </Button>\n );\n })}\n </div>\n\n {showPrevNext && (\n <Button\n variant={ButtonVariant.OUTLINE}\n size={buttonSize}\n color={ButtonColor.TEXT}\n onClick={() => handlePageChange(currentPage + 1)}\n disabled={disabled || isLastPage}\n label={goToNextPage.value}\n Icon={ChevronRight}\n ref={(el) => {\n const lastRefIndex =\n (showPrevNext ? 1 : 0) +\n pageNumbers.filter((p) => p !== 'ellipsis').length;\n if (el) optionsRefs.current[lastRefIndex] = el;\n }}\n className=\"min-w-0 px-2\"\n />\n )}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;AAgBA,MAAa,qBAAqB,IAChC,0CACA;CACE,UAAU;EACR,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;EACA,OAAO;GACL,MAAM;GACN,SAAS;GACT,WAAW;GACX,SAAS;EACX;EACA,SAAS;GACP,SAAS;GACT,UAAU;GACV,OAAO;EACT;CACF;CACA,iBAAiB;EACf,MAAM;EACN,SAAS;CACX;AACF,CACF;AAEA,IAAY,iBAAL;CACL;CACA;CACA;;AACF;AAEA,IAAY,oBAAL;CACL;CACA;CACA;;AACF;AAaA,MAAM,uBACJ,aACA,YACA,oBAC4B;CAC5B,IAAI,cAAc,iBAChB,OAAO,MAAM,KAAK,EAAE,QAAQ,WAAW,IAAI,GAAG,MAAM,IAAI,CAAC;CAG3D,MAAM,QAAiC,CAAC;CACxC,MAAM,cAAc,KAAK,MAAM,kBAAkB,CAAC;CAElD,MAAM,KAAK,CAAC;CAEZ,IAAI,eAAe,cAAc,GAAG;EAClC,KAAK,IAAI,IAAI,GAAG,KAAK,KAAK,IAAI,kBAAkB,GAAG,aAAa,CAAC,GAAG,KAClE,MAAM,KAAK,CAAC;EAEd,IAAI,aAAa,iBACf,MAAM,KAAK,UAAU;EAEvB,IAAI,aAAa,GACf,MAAM,KAAK,UAAU;CAEzB,OAAO,IAAI,eAAe,aAAa,cAAc,GAAG;EACtD,IAAI,aAAa,iBACf,MAAM,KAAK,UAAU;EAEvB,KACE,IAAI,IAAI,KAAK,IAAI,GAAG,aAAa,kBAAkB,CAAC,GACpD,KAAK,YACL,KAEA,MAAM,KAAK,CAAC;CAEhB,OAAO;EACL,MAAM,KAAK,UAAU;EACrB,MAAM,QAAQ,cAAc;EAC5B,MAAM,MAAM,cAAc;EAC1B,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,KAC5B,MAAM,KAAK,CAAC;EAEd,MAAM,KAAK,UAAU;EACrB,MAAM,KAAK,UAAU;CACvB;CAEA,OAAO;AACT;AAEA,MAAM,YAAY,WAChB,QAAQ,aAAa,cAAc,MAAM;AAE3C,MAAM,iBAAiB,SAAuD;CAC5E,IAAI,eACF;MACK,IAAI,eACT;MAEA;AAEJ;AAEA,MAAM,kBAA6C,UACjD,oBAAC,OAAD;CACE,WAAU;CACV,GAAI;AACL;AAGH,MAAa,cAAmC,EAC9C,aACA,YACA,cACA,gBAAgB,OAChB,eAAe,MACf,kBAAkB,GAClB,WAAW,OACX,aACA,qBACA,gBACA,WACA,GAAG,YACC;CACJ,MAAM,EAAE,cAAc,qBAAqB,YAAY,YAAY;CAEnE,MAAM,cAAc,oBAClB,aACA,YACA,eACF;CAEA,MAAM,aAAa,cAAc,IAAI;CACrC,MAAM,cAAc,gBAAgB;CACpC,MAAM,aAAa,gBAAgB;CAEnC,MAAM,cAAc,OAAsB,CAAC,CAAC;CAC5C,MAAM,eAAe,OAA8B,IAAI;CACvD,MAAM,EAAE,yBAAyB,sBAAsB,gBACrD,aACA;EACE;EACA,aAAa;CACf,CACF;CAEA,gBAAgB;EACd,MAAM,QAAQ,iBAAiB;GAC7B,kBAAkB;EACpB,GAAG,GAAG;EAEN,aAAa,aAAa,KAAK;CACjC,GAAG,CAAC,aAAa,iBAAiB,CAAC;CAEnC,IAAI,cAAc,GAAG,OAAO;CAE5B,MAAM,oBAAoB,SAAiB;EACzC,IAAI,CAAC,YAAY,QAAQ,KAAK,QAAQ,cAAc,SAAS,aAC3D,aAAa,IAAI;CAErB;CAEA,OACE,oBAAC,OAAD;EACE,WAAW,GAAG,mBAAmB;GAAE;GAAM;EAAQ,CAAC,GAAG,SAAS;EAC9D,GAAI;YAEJ,qBAAC,OAAD;GAAK,WAAU;aAAf;IACG,2BACC,oBAAC,gBAAD;KAAgB,OAAO;KAAyB,KAAK;IAAe;IAGrE,gBACC,oBAAC,QAAD;KACE;KACA,MAAM;KACN;KACA,eAAe,iBAAiB,cAAc,CAAC;KAC/C,UAAU,YAAY;KACtB,OAAO,iBAAiB;KACxB,MAAM;KACN,MAAM,OAAO;MACX,IAAI,IAAI,YAAY,QAAQ,KAAK;KACnC;KACA,WAAU;IACX;IAGH,oBAAC,OAAD;KAAK,WAAU;eACZ,YAAY,KAAK,MAAM,UAAU;MAChC,IAAI,SAAS,YAAY;OAEvB,MAAM,cADkB,UAAU,YAAY,QAAQ,UAAU,IAE5D,mBACA;OACJ,OACE,oBAAC,OAAD;QAEE,WAAU;kBAEV,oBAAC,gBAAD,EAAgB,WAAU,gCAAiC;OACxD,GAJE,WAIF;MAET;MAEA,MAAM,WAAW,SAAS;MAE1B,MAAM,YACH,eAAe,IAAI,KACpB,YAAY,MAAM,GAAG,KAAK,EAAE,QAAQ,MAAM,MAAM,UAAU,EACvD;MAEL,OACE,oBAAC,QAAD;OAEE,SACE;OAEF,MAAM;OACN;OACA,eAAe,iBAAiB,IAAI;OAC1B;OACV,OAAO,cAAc;OACrB,gBAAc,WAAW,SAAS;OAClC,MAAM,OAAO;QACX,IAAI,IAAI,YAAY,QAAQ,YAAY;OAC1C;OACA,WAAW,GACT,8EACA,SAAS,QAAQ,mBACjB,SAAS,QAAQ,qBACjB,YAAY,eACd;iBAEC;MACK,GArBD,IAqBC;KAEZ,CAAC;IACE;IAEJ,gBACC,oBAAC,QAAD;KACE;KACA,MAAM;KACN;KACA,eAAe,iBAAiB,cAAc,CAAC;KAC/C,UAAU,YAAY;KACtB,OAAO,aAAa;KACpB,MAAM;KACN,MAAM,OAAO;MACX,MAAM,gBACH,eAAe,IAAI,KACpB,YAAY,QAAQ,MAAM,MAAM,UAAU,EAAE;MAC9C,IAAI,IAAI,YAAY,QAAQ,gBAAgB;KAC9C;KACA,WAAU;IACX;GAEA;;CACF;AAET"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { Detail as Detail$1, PopoverStatic, PopoverXAlign, PopoverYAlign } from "./static.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { useLayoutEffect, useRef, useState } from "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
|
|
7
7
|
//#region src/components/Popover/dynamic.tsx
|
|
@@ -38,7 +38,7 @@ const Detail = ({ xAlign = "start", yAlign = "bellow", ...props }) => {
|
|
|
38
38
|
const [computedXAlign, setComputedXAlign] = useState(xAlign);
|
|
39
39
|
const [computedYAlign, setComputedYAlign] = useState(yAlign);
|
|
40
40
|
const [maxWidth, setMaxWidth] = useState(void 0);
|
|
41
|
-
|
|
41
|
+
useLayoutEffect(() => {
|
|
42
42
|
const adjustPosition = () => {
|
|
43
43
|
if (!popoverRef.current) return;
|
|
44
44
|
const popoverElement = popoverRef.current;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic.mjs","names":["StaticDetail"],"sources":["../../../../src/components/Popover/dynamic.tsx"],"sourcesContent":["'use client';\n\nimport type { FC } from 'react';\nimport {
|
|
1
|
+
{"version":3,"file":"dynamic.mjs","names":["StaticDetail"],"sources":["../../../../src/components/Popover/dynamic.tsx"],"sourcesContent":["'use client';\n\nimport type { FC } from 'react';\nimport { useLayoutEffect, useRef, useState } from 'react';\nimport {\n type DetailProps,\n type PopoverProps,\n PopoverStatic,\n type PopoverType,\n PopoverXAlign,\n PopoverYAlign,\n Detail as StaticDetail,\n} from './static';\n\n/**\n * Popover Component (Client-side)\n *\n * Client-side wrapper around the static Popover component.\n * Reuses the server-side compatible implementation.\n *\n * @param props - Popover component props\n * @returns Trigger container with popover functionality\n */\nconst PopoverComponent: FC<PopoverProps> = (props) => {\n return <PopoverStatic {...props} />;\n};\n\n/**\n * Popover Detail Component (Client-side)\n *\n * Client-side wrapper around the static Detail component that adds automatic\n * positioning logic based on viewport constraints.\n *\n * Features:\n * - Reuses server-side compatible static Detail component\n * - Adds automatic positioning adjustment based on viewport\n * - Calculates optimal X/Y alignment to prevent overflow\n * - Dynamically adjusts max-width based on available space\n * - Listens to window resize and scroll events\n *\n * @param props - Popover Detail component props\n * @returns Positioned popover content with animations and accessibility\n */\nconst Detail: FC<DetailProps> = ({\n xAlign = PopoverXAlign.START,\n yAlign = PopoverYAlign.BELOW,\n ...props\n}) => {\n const popoverRef = useRef<HTMLDivElement>(null);\n const [computedXAlign, setComputedXAlign] = useState(xAlign);\n const [computedYAlign, setComputedYAlign] = useState(yAlign);\n const [maxWidth, setMaxWidth] = useState<number | undefined>(undefined);\n\n useLayoutEffect(() => {\n const adjustPosition = () => {\n if (!popoverRef.current) return;\n\n const popoverElement = popoverRef.current;\n const triggerElement = document.getElementById(\n `unrollable-panel-button-${props.identifier}`\n );\n\n if (!triggerElement) return;\n\n const triggerRect = triggerElement.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n const gap = 16; // 1rem gap\n const padding = 16; // Additional padding from viewport edges\n\n // Calculate maximum width based on viewport and trigger position\n const maxWidthFromLeft = viewportWidth - triggerRect.left - padding;\n const maxWidthFromRight = triggerRect.right - padding;\n\n // Use the larger space to ensure popover can fit\n const absoluteMaxWidth = Math.max(maxWidthFromLeft, maxWidthFromRight);\n\n setMaxWidth(absoluteMaxWidth);\n\n // Force a layout calculation by temporarily making visible if needed\n const wasInvisible = popoverElement.classList.contains('invisible');\n if (wasInvisible) {\n popoverElement.style.visibility = 'hidden';\n popoverElement.classList.remove('invisible');\n }\n\n // Small delay to ensure max-width is applied and content reflows\n requestAnimationFrame(() => {\n const popoverRect = popoverElement.getBoundingClientRect();\n\n // Restore invisible state if it was invisible\n if (wasInvisible) {\n popoverElement.style.visibility = '';\n popoverElement.classList.add('invisible');\n }\n\n // Determine optimal Y alignment\n let newYAlign = yAlign;\n const spaceBelow = viewportHeight - triggerRect.bottom - gap;\n const spaceAbove = triggerRect.top - gap;\n\n if (yAlign === PopoverYAlign.BELOW && spaceBelow < popoverRect.height) {\n // Not enough space below, try above\n if (spaceAbove >= popoverRect.height) {\n newYAlign = PopoverYAlign.ABOVE;\n }\n } else if (\n yAlign === PopoverYAlign.ABOVE &&\n spaceAbove < popoverRect.height\n ) {\n // Not enough space above, try below\n if (spaceBelow >= popoverRect.height) {\n newYAlign = PopoverYAlign.BELOW;\n }\n }\n\n // Determine optimal X alignment\n let newXAlign = xAlign;\n const spaceRight = viewportWidth - triggerRect.left - padding;\n const spaceLeft = triggerRect.right - padding;\n\n if (xAlign === PopoverXAlign.START && spaceRight < popoverRect.width) {\n // Not enough space on the right, try left\n if (spaceLeft >= popoverRect.width) {\n newXAlign = PopoverXAlign.END;\n }\n } else if (\n xAlign === PopoverXAlign.END &&\n spaceLeft < popoverRect.width\n ) {\n // Not enough space on the left, try right\n if (spaceRight >= popoverRect.width) {\n newXAlign = PopoverXAlign.START;\n }\n }\n\n setComputedYAlign(newYAlign);\n setComputedXAlign(newXAlign);\n });\n };\n\n // Adjust position with a slight delay to ensure DOM is ready\n const timeoutId = setTimeout(adjustPosition, 0);\n\n // Listen to mouse enter on the trigger to recalculate\n const triggerElement = document.getElementById(\n `unrollable-panel-button-${props.identifier}`\n );\n\n if (triggerElement) {\n triggerElement.addEventListener('mouseenter', adjustPosition);\n triggerElement.addEventListener('focusin', adjustPosition);\n }\n\n // Use ResizeObserver to detect popover content size changes\n const resizeObserver = new ResizeObserver(() => {\n adjustPosition();\n });\n\n if (popoverRef.current) {\n resizeObserver.observe(popoverRef.current);\n }\n\n window.addEventListener('resize', adjustPosition);\n window.addEventListener('scroll', adjustPosition, true);\n\n return () => {\n clearTimeout(timeoutId);\n if (triggerElement) {\n triggerElement.removeEventListener('mouseenter', adjustPosition);\n triggerElement.removeEventListener('focusin', adjustPosition);\n }\n resizeObserver.disconnect();\n window.removeEventListener('resize', adjustPosition);\n window.removeEventListener('scroll', adjustPosition, true);\n };\n }, [props.identifier, xAlign, yAlign]);\n\n // Use the static Detail component with computed alignment values\n return (\n <StaticDetail\n {...props}\n xAlign={computedXAlign}\n yAlign={computedYAlign}\n ref={popoverRef}\n style={{\n ...props.style,\n maxWidth: maxWidth ? `${maxWidth}px` : undefined,\n }}\n />\n );\n};\n\n// Create Popover with Detail attached\nexport const Popover: PopoverType = PopoverComponent as PopoverType;\n\nPopover.Detail = Detail;\n"],"mappings":"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"}
|
|
@@ -17,7 +17,6 @@ const defaultChoices = [{
|
|
|
17
17
|
let SwitchSelectorColor = /* @__PURE__ */ function(SwitchSelectorColor) {
|
|
18
18
|
SwitchSelectorColor["PRIMARY"] = "primary";
|
|
19
19
|
SwitchSelectorColor["SECONDARY"] = "secondary";
|
|
20
|
-
SwitchSelectorColor["DESTRUCTIVE"] = "destructive";
|
|
21
20
|
SwitchSelectorColor["NEUTRAL"] = "neutral";
|
|
22
21
|
SwitchSelectorColor["LIGHT"] = "light";
|
|
23
22
|
SwitchSelectorColor["DARK"] = "dark";
|
|
@@ -36,7 +35,6 @@ const switchSelectorVariant = cva("flex h-fit w-fit cursor-pointer flex-row gap-
|
|
|
36
35
|
color: {
|
|
37
36
|
[`primary`]: "border-primary text-primary",
|
|
38
37
|
[`secondary`]: "border-secondary text-secondary",
|
|
39
|
-
[`destructive`]: "border-destructive bg-destructive text-destructive",
|
|
40
38
|
[`neutral`]: "border-neutral text-neutral",
|
|
41
39
|
[`light`]: "border-white text-white",
|
|
42
40
|
[`dark`]: "border-neutral-800 text-neutral-800",
|
|
@@ -48,7 +46,7 @@ const switchSelectorVariant = cva("flex h-fit w-fit cursor-pointer flex-row gap-
|
|
|
48
46
|
}
|
|
49
47
|
},
|
|
50
48
|
defaultVariants: {
|
|
51
|
-
color: `
|
|
49
|
+
color: `text`,
|
|
52
50
|
disabled: false
|
|
53
51
|
}
|
|
54
52
|
});
|
|
@@ -64,7 +62,7 @@ const choiceVariant = cva("z-1 flex-1 cursor-pointer font-medium text-sm transit
|
|
|
64
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: {
|
|
65
63
|
[`primary`]: "bg-primary data-[indicator=true]:text-text",
|
|
66
64
|
[`secondary`]: "bg-secondary data-[indicator=true]:text-text",
|
|
67
|
-
[`
|
|
65
|
+
[`${SwitchSelectorColor.ERROR}`]: "bg-error data-[indicator=true]:text-text",
|
|
68
66
|
[`neutral`]: "bg-neutral data-[indicator=true]:text-white",
|
|
69
67
|
[`light`]: "bg-white data-[indicator=true]:text-black",
|
|
70
68
|
[`dark`]: "bg-neutral-800 data-[indicator=true]:text-white",
|
|
@@ -75,7 +73,7 @@ const indicatorVariant = cva("absolute top-0 z-0 h-full w-auto rounded-full tran
|
|
|
75
73
|
* This component is horizontal.
|
|
76
74
|
*/
|
|
77
75
|
const SwitchSelector = (props) => {
|
|
78
|
-
const { choices = defaultChoices, color = "primary", size = "md", className, itemClassName
|
|
76
|
+
const { choices = defaultChoices, color = "primary", size = "md", className, itemClassName } = props;
|
|
79
77
|
const { selectedIndex, indicatorIndex, handleChange, optionsRefs, indicatorRef, choiceIndicatorPosition, setHoveredIndex, disabled } = useSwitchSelector({
|
|
80
78
|
choices,
|
|
81
79
|
value: props.value,
|