@intlayer/design-system 8.11.0-canary.0 → 8.11.1
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 +1 -1
- package/dist/esm/api/useAuth/useOAuth2.mjs.map +1 -0
- package/dist/esm/{hooks → api}/useAuth/useSession.mjs +2 -3
- 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 +2 -4
- package/dist/esm/components/Button/Button.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 +2 -2
- 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 +5 -3
- package/dist/esm/components/DictionaryFieldEditor/DictionaryDetails/DictionaryDetailsForm.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/DictionaryFieldEditor.mjs +1 -1
- package/dist/esm/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.mjs +1 -1
- package/dist/esm/components/DictionaryFieldEditor/SaveForm/SaveForm.mjs +4 -3
- package/dist/esm/components/DictionaryFieldEditor/SaveForm/SaveForm.mjs.map +1 -1
- package/dist/esm/components/DictionaryFieldEditor/StructureView/StructureView.mjs +1 -1
- package/dist/esm/components/Form/elements/OTPElement.mjs +1 -1
- package/dist/esm/components/Input/Checkbox.mjs +0 -2
- 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 +7 -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/LocaleSwitcherContentDropDown/LocaleSwitcherContent.mjs +1 -1
- package/dist/esm/components/Modal/Modal.mjs +2 -2
- package/dist/esm/components/Navbar/MobileNavbar.mjs +1 -1
- package/dist/esm/components/Pagination/Pagination.mjs +2 -3
- package/dist/esm/components/Pagination/Pagination.mjs.map +1 -1
- package/dist/esm/components/RightDrawer/RightDrawer.mjs +3 -3
- 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/Tab/Tab.mjs +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/Toaster/Toast.mjs +3 -3
- package/dist/esm/components/Toaster/Toast.mjs.map +1 -1
- package/dist/esm/hooks/index.mjs +9 -15
- package/dist/esm/routes.mjs +4 -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/CollapsibleTable/CollapsibleTable.d.ts +2 -2
- package/dist/types/components/Command/index.d.ts +2 -2
- package/dist/types/components/Container/index.d.ts +6 -6
- package/dist/types/components/Input/Checkbox.d.ts +2 -3
- package/dist/types/components/Input/Checkbox.d.ts.map +1 -1
- package/dist/types/components/Input/Input.d.ts +1 -1
- package/dist/types/components/LanguageBackground/index.d.ts.map +1 -1
- package/dist/types/components/Link/Link.d.ts +3 -4
- package/dist/types/components/Link/Link.d.ts.map +1 -1
- package/dist/types/components/Pagination/Pagination.d.ts +1 -1
- package/dist/types/components/Pagination/Pagination.d.ts.map +1 -1
- package/dist/types/components/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/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 +4 -1
- package/dist/types/routes.d.ts.map +1 -1
- package/package.json +28 -23
- package/tailwind.css +3 -24
- package/dist/esm/hooks/reactQuery.mjs +0 -1586
- 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 -236
- 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":"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,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { LanguageSection } from "./LanguageSection.mjs";
|
|
4
|
-
import { Suspense, lazy, useEffect, useState } 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
|
|
@@ -9,12 +9,14 @@ const LazyLanguageSection = lazy(() => import("./LanguageSection.mjs").then((m)
|
|
|
9
9
|
const LanguageBackground = ({ children }) => {
|
|
10
10
|
const [mounted, setMounted] = useState(false);
|
|
11
11
|
useEffect(() => {
|
|
12
|
-
|
|
12
|
+
startTransition(() => {
|
|
13
|
+
setMounted(true);
|
|
14
|
+
});
|
|
13
15
|
}, []);
|
|
14
|
-
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
|
|
15
|
-
className: "absolute top-0 left-0 z-
|
|
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",
|
|
16
18
|
children: mounted && /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(LazyLanguageSection, { className: "mt-[30%]" }) })
|
|
17
|
-
})
|
|
19
|
+
})] });
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
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 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 setMounted(true);\n }, []);\n\n return (\n <>\n <div className=\"absolute top-0 left-0 z-
|
|
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,11 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { usePersistedStore } from "../../hooks/usePersistedStore.mjs";
|
|
4
3
|
import { Container } from "../Container/index.mjs";
|
|
5
4
|
import { Button, ButtonColor, ButtonSize, ButtonTextAlign, ButtonVariant } from "../Button/Button.mjs";
|
|
6
5
|
import { DropDown } from "../DropDown/index.mjs";
|
|
7
6
|
import { Input } from "../Input/Input.mjs";
|
|
8
7
|
import { SwitchSelector, SwitchSelectorColor, SwitchSelectorSize } from "../SwitchSelector/SwitchSelector.mjs";
|
|
8
|
+
import { usePersistedStore } from "../../hooks/usePersistedStore.mjs";
|
|
9
9
|
import { useLocaleSwitcherContent } from "./LocaleSwitcherContentContext.mjs";
|
|
10
10
|
import { useMemo, useRef, useState } from "react";
|
|
11
11
|
import { Check, Globe, MoveVertical } from "lucide-react";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { cn } from "../../utils/cn.mjs";
|
|
4
|
-
import { useGetElementOrWindow } from "../../hooks/useGetElementOrWindow.mjs";
|
|
5
|
-
import { useScrollBlockage } from "../../hooks/useScrollBlockage/index.mjs";
|
|
6
4
|
import { Container } from "../Container/index.mjs";
|
|
7
5
|
import { Button, ButtonColor, ButtonSize, ButtonVariant } from "../Button/Button.mjs";
|
|
6
|
+
import { useGetElementOrWindow } from "../../hooks/useGetElementOrWindow.mjs";
|
|
7
|
+
import { useScrollBlockage } from "../../hooks/useScrollBlockage/index.mjs";
|
|
8
8
|
import { H3 } from "../Headers/index.mjs";
|
|
9
9
|
import { useEffect } from "react";
|
|
10
10
|
import { cva } from "class-variance-authority";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { cn } from "../../utils/cn.mjs";
|
|
4
|
+
import { MaxHeightSmoother } from "../MaxHeightSmoother/index.mjs";
|
|
4
5
|
import { useScrollBlockage } from "../../hooks/useScrollBlockage/index.mjs";
|
|
5
6
|
import { useScrollDetection } from "../../hooks/useScrollDetection.mjs";
|
|
6
|
-
import { MaxHeightSmoother } from "../MaxHeightSmoother/index.mjs";
|
|
7
7
|
import { Burger } from "./Burger.mjs";
|
|
8
8
|
import { useRef, useState } from "react";
|
|
9
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { cn } from "../../utils/cn.mjs";
|
|
4
|
-
import { useItemSelector } from "../../hooks/useItemSelector.mjs";
|
|
5
4
|
import { Button, ButtonColor, ButtonSize, ButtonVariant } from "../Button/Button.mjs";
|
|
5
|
+
import { useItemSelector } from "../../hooks/useItemSelector.mjs";
|
|
6
6
|
import { useEffect, useRef } from "react";
|
|
7
7
|
import { cva } from "class-variance-authority";
|
|
8
8
|
import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";
|
|
@@ -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":"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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useGetElementOrWindow } from "../../hooks/useGetElementOrWindow.mjs";
|
|
4
|
-
import { useDevice } from "../../hooks/useDevice.mjs";
|
|
5
|
-
import { useScrollBlockage } from "../../hooks/useScrollBlockage/index.mjs";
|
|
6
3
|
import { Container } from "../Container/index.mjs";
|
|
7
4
|
import { Button, ButtonColor, ButtonSize, ButtonVariant } from "../Button/Button.mjs";
|
|
5
|
+
import { useDevice } from "../../hooks/useDevice.mjs";
|
|
8
6
|
import { KeyboardShortcut } from "../KeyboardShortcut/KeyboardShortcut.mjs";
|
|
9
7
|
import { Popover } from "../Popover/dynamic.mjs";
|
|
8
|
+
import { useGetElementOrWindow } from "../../hooks/useGetElementOrWindow.mjs";
|
|
9
|
+
import { useScrollBlockage } from "../../hooks/useScrollBlockage/index.mjs";
|
|
10
10
|
import { MaxWidthSmoother } from "../MaxWidthSmoother/index.mjs";
|
|
11
11
|
import { isElementAtTopAndNotCovered } from "./isElementAtTopAndNotCovered.mjs";
|
|
12
12
|
import { useRightDrawer } from "./useRightDrawer.mjs";
|
|
@@ -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,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SwitchSelector.mjs","names":[],"sources":["../../../../src/components/SwitchSelector/SwitchSelector.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type { HTMLAttributes, ReactNode } from 'react';\nimport { useSwitchSelector } from './useSwitchSelector';\n\nexport type SwitchSelectorChoice<T = boolean> = {\n content: ReactNode;\n value: T;\n} & HTMLAttributes<HTMLButtonElement>;\nexport type SwitchSelectorChoices<T> = SwitchSelectorChoice<T>[];\n\nexport const defaultChoices: SwitchSelectorChoices<boolean> = [\n { content: 'Off', value: false },\n { content: 'On', value: true },\n];\n\nexport enum SwitchSelectorColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n
|
|
1
|
+
{"version":3,"file":"SwitchSelector.mjs","names":[],"sources":["../../../../src/components/SwitchSelector/SwitchSelector.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type { HTMLAttributes, ReactNode } from 'react';\nimport { useSwitchSelector } from './useSwitchSelector';\n\nexport type SwitchSelectorChoice<T = boolean> = {\n content: ReactNode;\n value: T;\n} & HTMLAttributes<HTMLButtonElement>;\nexport type SwitchSelectorChoices<T> = SwitchSelectorChoice<T>[];\n\nexport const defaultChoices: SwitchSelectorChoices<boolean> = [\n { content: 'Off', value: false },\n { content: 'On', value: true },\n];\n\nexport enum SwitchSelectorColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n NEUTRAL = 'neutral',\n LIGHT = 'light',\n DARK = 'dark',\n TEXT = 'text',\n}\n\nexport enum SwitchSelectorSize {\n XS = 'xs',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n}\n\nexport type SwitchSelectorBaseProps<T = boolean> = {\n choices?: SwitchSelectorChoices<T>;\n value?: T;\n defaultValue?: T;\n onChange?: (choice: T) => void;\n className?: string;\n itemClassName?: string;\n hoverable?: boolean;\n disabled?: boolean;\n [key: string]: any;\n};\n\nexport type SwitchSelectorProps<T = boolean> = SwitchSelectorBaseProps<T> &\n VariantProps<typeof switchSelectorVariant> &\n VariantProps<typeof choiceVariant>;\n\nexport const switchSelectorVariant = cva(\n 'flex h-fit w-fit cursor-pointer flex-row gap-2 rounded-full border-[1.3px] p-[1.5px]',\n {\n variants: {\n color: {\n [`${SwitchSelectorColor.PRIMARY}`]: 'border-primary text-primary',\n [`${SwitchSelectorColor.SECONDARY}`]: 'border-secondary text-secondary',\n [`${SwitchSelectorColor.NEUTRAL}`]: 'border-neutral text-neutral',\n [`${SwitchSelectorColor.LIGHT}`]: 'border-white text-white',\n [`${SwitchSelectorColor.DARK}`]: 'border-neutral-800 text-neutral-800',\n [`${SwitchSelectorColor.TEXT}`]: 'border-text text-text',\n },\n disabled: {\n true: 'cursor-not-allowed opacity-50',\n false: '',\n },\n },\n defaultVariants: {\n color: `${SwitchSelectorColor.TEXT}`,\n disabled: false,\n },\n }\n);\n\nexport const choiceVariant = cva(\n 'z-1 flex-1 cursor-pointer font-medium text-sm transition-all duration-300 ease-in-out aria-selected:cursor-default data-[indicator=true]:text-text-opposite motion-reduce:transition-none',\n {\n variants: {\n size: {\n [`${SwitchSelectorSize.XS}`]: 'px-2 py-0.5 text-xs',\n [`${SwitchSelectorSize.SM}`]: 'px-2 py-1 text-xs',\n [`${SwitchSelectorSize.MD}`]: 'p-2 text-sm',\n [`${SwitchSelectorSize.LG}`]: 'p-4 text-base',\n },\n },\n defaultVariants: {\n size: `${SwitchSelectorSize.MD}`,\n },\n }\n);\n\nexport const indicatorVariant = cva(\n 'absolute top-0 z-0 h-full w-auto rounded-full transition-all duration-300 ease-in-out motion-reduce:transition-none',\n {\n variants: {\n color: {\n [`${SwitchSelectorColor.PRIMARY}`]:\n 'bg-primary data-[indicator=true]:text-text',\n [`${SwitchSelectorColor.SECONDARY}`]:\n 'bg-secondary data-[indicator=true]:text-text',\n [`${SwitchSelectorColor.ERROR}`]:\n 'bg-error data-[indicator=true]:text-text',\n [`${SwitchSelectorColor.NEUTRAL}`]:\n 'bg-neutral data-[indicator=true]:text-white',\n [`${SwitchSelectorColor.LIGHT}`]:\n 'bg-white data-[indicator=true]:text-black',\n [`${SwitchSelectorColor.DARK}`]:\n 'bg-neutral-800 data-[indicator=true]:text-white',\n [`${SwitchSelectorColor.TEXT}`]:\n 'bg-text data-[indicator=true]:text-text-opposite',\n },\n },\n }\n);\n\n/**\n * Component that allows the user to select one of the provided choices.\n * This component is horizontal.\n */\nexport const SwitchSelector = <T,>(props: SwitchSelectorProps<T>) => {\n const {\n choices = defaultChoices as SwitchSelectorChoices<T>,\n color = SwitchSelectorColor.PRIMARY,\n size = SwitchSelectorSize.MD,\n className,\n itemClassName,\n } = props;\n\n const {\n selectedIndex,\n indicatorIndex,\n handleChange,\n optionsRefs,\n indicatorRef,\n choiceIndicatorPosition,\n setHoveredIndex,\n disabled,\n } = useSwitchSelector(\n {\n choices,\n value: props.value,\n defaultValue: props.defaultValue,\n onChange: props.onChange,\n hoverable: props.hoverable,\n disabled: props.disabled,\n },\n 'horizontal'\n );\n\n return (\n <div\n className={switchSelectorVariant({\n color,\n disabled,\n className,\n })}\n role=\"tablist\"\n aria-disabled={disabled ? 'true' : undefined}\n >\n <div className=\"relative flex h-full w-full flex-row items-center justify-center\">\n {choices.map((choice, index) => {\n const { content, value, ...buttonProps } = choice;\n\n const isKeyOfKey =\n typeof value === 'string' || typeof value === 'number';\n\n const isSelected = index === selectedIndex;\n const isIndicatorOwner = index === indicatorIndex;\n\n return (\n <button\n {...buttonProps}\n className={cn(\n choiceVariant({\n size,\n }),\n disabled && 'cursor-not-allowed',\n itemClassName\n )}\n key={isKeyOfKey ? value : index}\n role=\"tab\"\n onClick={() => handleChange(value)}\n aria-selected={isSelected ? 'true' : undefined}\n data-indicator={isIndicatorOwner ? 'true' : undefined}\n disabled={disabled}\n tabIndex={isSelected ? 0 : -1}\n ref={(el) => {\n optionsRefs.current[index] = el!;\n }}\n onMouseEnter={() => !disabled && setHoveredIndex(index)}\n onMouseLeave={() => !disabled && setHoveredIndex(null)}\n >\n {content}\n </button>\n );\n })}\n\n {choiceIndicatorPosition && (\n <div\n className={cn(\n indicatorVariant({\n color,\n })\n )}\n style={choiceIndicatorPosition}\n ref={indicatorRef}\n />\n )}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;AAaA,MAAa,iBAAiD,CAC5D;CAAE,SAAS;CAAO,OAAO;AAAM,GAC/B;CAAE,SAAS;CAAM,OAAO;AAAK,CAC/B;AAEA,IAAY,sBAAL;CACL;CACA;CACA;CACA;CACA;CACA;;AACF;AAEA,IAAY,qBAAL;CACL;CACA;CACA;CACA;;AACF;AAkBA,MAAa,wBAAwB,IACnC,wFACA;CACE,UAAU;EACR,OAAO;IACJ,YAAmC;IACnC,cAAqC;IACrC,YAAmC;IACnC,UAAiC;IACjC,SAAgC;IAChC,SAAgC;EACnC;EACA,UAAU;GACR,MAAM;GACN,OAAO;EACT;CACF;CACA,iBAAiB;EACf,OAAO;EACP,UAAU;CACZ;AACF,CACF;AAEA,MAAa,gBAAgB,IAC3B,6LACA;CACE,UAAU,EACR,MAAM;GACH,OAA6B;GAC7B,OAA6B;GAC7B,OAA6B;GAC7B,OAA6B;CAChC,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CACF;AAEA,MAAa,mBAAmB,IAC9B,uHACA,EACE,UAAU,EACR,OAAO;EACJ,YACC;EACD,cACC;EACD,GAAG,oBAAoB,UACtB;EACD,YACC;EACD,UACC;EACD,SACC;EACD,SACC;AACJ,EACF,EACF,CACF;;;;;AAMA,MAAa,kBAAsB,UAAkC;CACnE,MAAM,EACJ,UAAU,gBACV,mBACA,aACA,WACA,kBACE;CAEJ,MAAM,EACJ,eACA,gBACA,cACA,aACA,cACA,yBACA,iBACA,aACE,kBACF;EACE;EACA,OAAO,MAAM;EACb,cAAc,MAAM;EACpB,UAAU,MAAM;EAChB,WAAW,MAAM;EACjB,UAAU,MAAM;CAClB,GACA,YACF;CAEA,OACE,oBAAC,OAAD;EACE,WAAW,sBAAsB;GAC/B;GACA;GACA;EACF,CAAC;EACD,MAAK;EACL,iBAAe,WAAW,SAAS;YAEnC,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,QAAQ,KAAK,QAAQ,UAAU;IAC9B,MAAM,EAAE,SAAS,OAAO,GAAG,gBAAgB;IAE3C,MAAM,aACJ,OAAO,UAAU,YAAY,OAAO,UAAU;IAEhD,MAAM,aAAa,UAAU;IAC7B,MAAM,mBAAmB,UAAU;IAEnC,OACE,8BAAC,UAAD;KACE,GAAI;KACJ,WAAW,GACT,cAAc,EACZ,KACF,CAAC,GACD,YAAY,sBACZ,aACF;KACA,KAAK,aAAa,QAAQ;KAC1B,MAAK;KACL,eAAe,aAAa,KAAK;KACjC,iBAAe,aAAa,SAAS;KACrC,kBAAgB,mBAAmB,SAAS;KAClC;KACV,UAAU,aAAa,IAAI;KAC3B,MAAM,OAAO;MACX,YAAY,QAAQ,SAAS;KAC/B;KACA,oBAAoB,CAAC,YAAY,gBAAgB,KAAK;KACtD,oBAAoB,CAAC,YAAY,gBAAgB,IAAI;IAG/C,GADL,OACK;GAEZ,CAAC,GAEA,2BACC,oBAAC,OAAD;IACE,WAAW,GACT,iBAAiB,EACf,MACF,CAAC,CACH;IACA,OAAO;IACP,KAAK;GACN,EAEA;;CACF;AAET"}
|
|
@@ -13,7 +13,7 @@ const verticalSwitchSelectorVariant = cva("flex h-fit w-fit cursor-pointer flex-
|
|
|
13
13
|
color: {
|
|
14
14
|
[`${"primary"}`]: "border-primary text-primary",
|
|
15
15
|
[`${"secondary"}`]: "border-secondary text-secondary",
|
|
16
|
-
[`${
|
|
16
|
+
[`${SwitchSelectorColor.ERROR}`]: "border-error bg-error text-error",
|
|
17
17
|
[`${"neutral"}`]: "border-neutral text-neutral",
|
|
18
18
|
[`${"light"}`]: "border-white text-white",
|
|
19
19
|
[`${"dark"}`]: "border-neutral-800 text-neutral-800",
|
|
@@ -40,7 +40,7 @@ const verticalChoiceVariant = cva("z-1 w-full cursor-pointer font-medium text-sm
|
|
|
40
40
|
const verticalIndicatorVariant = cva("absolute left-0 z-0 h-auto w-full rounded-xl transition-all duration-300 ease-in-out motion-reduce:transition-none", { variants: { color: {
|
|
41
41
|
[`${"primary"}`]: "bg-primary data-[indicator=true]:text-text",
|
|
42
42
|
[`${"secondary"}`]: "bg-secondary data-[indicator=true]:text-text",
|
|
43
|
-
[`${
|
|
43
|
+
[`${SwitchSelectorColor.ERROR}`]: "bg-error data-[indicator=true]:text-text",
|
|
44
44
|
[`${"neutral"}`]: "bg-neutral data-[indicator=true]:text-white",
|
|
45
45
|
[`${"light"}`]: "bg-white data-[indicator=true]:text-black",
|
|
46
46
|
[`${"dark"}`]: "bg-neutral-800 data-[indicator=true]:text-white",
|
|
@@ -51,7 +51,7 @@ const verticalIndicatorVariant = cva("absolute left-0 z-0 h-auto w-full rounded-
|
|
|
51
51
|
* This component is vertical.
|
|
52
52
|
*/
|
|
53
53
|
const VerticalSwitchSelector = (props) => {
|
|
54
|
-
const { choices = defaultChoices, color = "primary", size = "md", className, itemClassName
|
|
54
|
+
const { choices = defaultChoices, color = "primary", size = "md", className, itemClassName } = props;
|
|
55
55
|
const { selectedIndex, indicatorIndex, handleChange, optionsRefs, indicatorRef, choiceIndicatorPosition, setHoveredIndex, disabled } = useSwitchSelector({
|
|
56
56
|
choices,
|
|
57
57
|
value: props.value,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VerticalSwitchSelector.mjs","names":[],"sources":["../../../../src/components/SwitchSelector/VerticalSwitchSelector.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n defaultChoices,\n type SwitchSelectorBaseProps,\n type SwitchSelectorChoices,\n SwitchSelectorColor,\n SwitchSelectorSize,\n} from './SwitchSelector';\nimport { useSwitchSelector } from './useSwitchSelector';\n\nconst verticalSwitchSelectorVariant = cva(\n 'flex h-fit w-fit cursor-pointer flex-col gap-2 rounded-2xl border-[1.3px] p-1',\n {\n variants: {\n color: {\n [`${SwitchSelectorColor.PRIMARY}`]: 'border-primary text-primary',\n [`${SwitchSelectorColor.SECONDARY}`]: 'border-secondary text-secondary',\n [`${SwitchSelectorColor.
|
|
1
|
+
{"version":3,"file":"VerticalSwitchSelector.mjs","names":[],"sources":["../../../../src/components/SwitchSelector/VerticalSwitchSelector.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n defaultChoices,\n type SwitchSelectorBaseProps,\n type SwitchSelectorChoices,\n SwitchSelectorColor,\n SwitchSelectorSize,\n} from './SwitchSelector';\nimport { useSwitchSelector } from './useSwitchSelector';\n\nconst verticalSwitchSelectorVariant = cva(\n 'flex h-fit w-fit cursor-pointer flex-col gap-2 rounded-2xl border-[1.3px] p-1',\n {\n variants: {\n color: {\n [`${SwitchSelectorColor.PRIMARY}`]: 'border-primary text-primary',\n [`${SwitchSelectorColor.SECONDARY}`]: 'border-secondary text-secondary',\n [`${SwitchSelectorColor.ERROR}`]: 'border-error bg-error text-error',\n [`${SwitchSelectorColor.NEUTRAL}`]: 'border-neutral text-neutral',\n [`${SwitchSelectorColor.LIGHT}`]: 'border-white text-white',\n [`${SwitchSelectorColor.DARK}`]: 'border-neutral-800 text-neutral-800',\n [`${SwitchSelectorColor.TEXT}`]: 'border-text text-text',\n },\n disabled: {\n true: 'cursor-not-allowed opacity-50',\n false: '',\n },\n },\n defaultVariants: {\n color: `${SwitchSelectorColor.PRIMARY}`,\n disabled: false,\n },\n }\n);\n\nconst verticalChoiceVariant = cva(\n 'z-1 w-full cursor-pointer font-medium text-sm transition-all duration-300 ease-in-out aria-selected:cursor-default data-[indicator=true]:text-text-opposite motion-reduce:transition-none',\n {\n variants: {\n size: {\n [`${SwitchSelectorSize.SM}`]: 'px-2 py-1 text-xs',\n [`${SwitchSelectorSize.MD}`]: 'p-2 text-sm',\n [`${SwitchSelectorSize.LG}`]: 'p-4 text-base',\n },\n },\n defaultVariants: {\n size: `${SwitchSelectorSize.MD}`,\n },\n }\n);\n\nconst verticalIndicatorVariant = cva(\n 'absolute left-0 z-0 h-auto w-full rounded-xl transition-all duration-300 ease-in-out motion-reduce:transition-none',\n {\n variants: {\n color: {\n [`${SwitchSelectorColor.PRIMARY}`]:\n 'bg-primary data-[indicator=true]:text-text',\n [`${SwitchSelectorColor.SECONDARY}`]:\n 'bg-secondary data-[indicator=true]:text-text',\n [`${SwitchSelectorColor.ERROR}`]:\n 'bg-error data-[indicator=true]:text-text',\n [`${SwitchSelectorColor.NEUTRAL}`]:\n 'bg-neutral data-[indicator=true]:text-white',\n [`${SwitchSelectorColor.LIGHT}`]:\n 'bg-white data-[indicator=true]:text-black',\n [`${SwitchSelectorColor.DARK}`]:\n 'bg-neutral-800 data-[indicator=true]:text-white',\n [`${SwitchSelectorColor.TEXT}`]:\n 'bg-text data-[indicator=true]:text-text-opposite',\n },\n },\n }\n);\n\nexport type VerticalSwitchSelectorProps<T = boolean> =\n SwitchSelectorBaseProps<T> &\n VariantProps<typeof verticalSwitchSelectorVariant> &\n VariantProps<typeof verticalChoiceVariant>;\n\n/**\n * Component that allows the user to select one of the provided choices.\n * This component is vertical.\n */\nexport const VerticalSwitchSelector = <T,>(\n props: VerticalSwitchSelectorProps<T>\n) => {\n const {\n choices = defaultChoices as SwitchSelectorChoices<T>,\n color = SwitchSelectorColor.PRIMARY,\n size = SwitchSelectorSize.MD,\n className,\n itemClassName,\n } = props;\n\n const {\n selectedIndex,\n indicatorIndex,\n handleChange,\n optionsRefs,\n indicatorRef,\n choiceIndicatorPosition,\n setHoveredIndex,\n disabled,\n } = useSwitchSelector(\n {\n choices,\n value: props.value,\n defaultValue: props.defaultValue,\n onChange: props.onChange,\n hoverable: props.hoverable,\n disabled: props.disabled,\n },\n 'vertical'\n );\n\n return (\n <div\n className={verticalSwitchSelectorVariant({\n color,\n disabled,\n className,\n })}\n role=\"tablist\"\n aria-disabled={disabled ? 'true' : undefined}\n >\n <div className=\"relative flex h-fit w-full flex-col items-center justify-center\">\n {choices.map((choice, index) => {\n const { content, value, ...buttonProps } = choice;\n\n const isKeyOfKey =\n typeof value === 'string' || typeof value === 'number';\n\n const isSelected = index === selectedIndex;\n const isIndicatorOwner = index === indicatorIndex;\n\n return (\n <button\n {...buttonProps}\n className={cn(\n verticalChoiceVariant({\n size,\n }),\n disabled && 'cursor-not-allowed',\n itemClassName\n )}\n key={isKeyOfKey ? value : index}\n role=\"tab\"\n onClick={() => handleChange(value)}\n aria-selected={isSelected ? 'true' : undefined}\n data-indicator={isIndicatorOwner ? 'true' : undefined}\n disabled={disabled || isSelected}\n tabIndex={isSelected ? 0 : -1}\n ref={(el) => {\n optionsRefs.current[index] = el!;\n }}\n onMouseEnter={() => !disabled && setHoveredIndex(index)}\n onMouseLeave={() => !disabled && setHoveredIndex(null)}\n >\n {content}\n </button>\n );\n })}\n\n {choiceIndicatorPosition && (\n <div\n className={cn(\n verticalIndicatorVariant({\n color,\n })\n )}\n style={choiceIndicatorPosition}\n ref={indicatorRef}\n />\n )}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;AAaA,MAAM,gCAAgC,IACpC,iFACA;CACE,UAAU;EACR,OAAO;IACJ,iBAAmC;IACnC,mBAAqC;IACrC,GAAG,oBAAoB,UAAU;IACjC,iBAAmC;IACnC,eAAiC;IACjC,cAAgC;IAChC,cAAgC;EACnC;EACA,UAAU;GACR,MAAM;GACN,OAAO;EACT;CACF;CACA,iBAAiB;EACf,OAAO;EACP,UAAU;CACZ;AACF,CACF;AAEA,MAAM,wBAAwB,IAC5B,6LACA;CACE,UAAU,EACR,MAAM;GACH,YAA6B;GAC7B,YAA6B;GAC7B,YAA6B;CAChC,EACF;CACA,iBAAiB,EACf,MAAM,UACR;AACF,CACF;AAEA,MAAM,2BAA2B,IAC/B,sHACA,EACE,UAAU,EACR,OAAO;EACJ,iBACC;EACD,mBACC;EACD,GAAG,oBAAoB,UACtB;EACD,iBACC;EACD,eACC;EACD,cACC;EACD,cACC;AACJ,EACF,EACF,CACF;;;;;AAWA,MAAa,0BACX,UACG;CACH,MAAM,EACJ,UAAU,gBACV,mBACA,aACA,WACA,kBACE;CAEJ,MAAM,EACJ,eACA,gBACA,cACA,aACA,cACA,yBACA,iBACA,aACE,kBACF;EACE;EACA,OAAO,MAAM;EACb,cAAc,MAAM;EACpB,UAAU,MAAM;EAChB,WAAW,MAAM;EACjB,UAAU,MAAM;CAClB,GACA,UACF;CAEA,OACE,oBAAC,OAAD;EACE,WAAW,8BAA8B;GACvC;GACA;GACA;EACF,CAAC;EACD,MAAK;EACL,iBAAe,WAAW,SAAS;YAEnC,qBAAC,OAAD;GAAK,WAAU;aAAf,CACG,QAAQ,KAAK,QAAQ,UAAU;IAC9B,MAAM,EAAE,SAAS,OAAO,GAAG,gBAAgB;IAE3C,MAAM,aACJ,OAAO,UAAU,YAAY,OAAO,UAAU;IAEhD,MAAM,aAAa,UAAU;IAC7B,MAAM,mBAAmB,UAAU;IAEnC,OACE,8BAAC,UAAD;KACE,GAAI;KACJ,WAAW,GACT,sBAAsB,EACpB,KACF,CAAC,GACD,YAAY,sBACZ,aACF;KACA,KAAK,aAAa,QAAQ;KAC1B,MAAK;KACL,eAAe,aAAa,KAAK;KACjC,iBAAe,aAAa,SAAS;KACrC,kBAAgB,mBAAmB,SAAS;KAC5C,UAAU,YAAY;KACtB,UAAU,aAAa,IAAI;KAC3B,MAAM,OAAO;MACX,YAAY,QAAQ,SAAS;KAC/B;KACA,oBAAoB,CAAC,YAAY,gBAAgB,KAAK;KACtD,oBAAoB,CAAC,YAAY,gBAAgB,IAAI;IAG/C,GADL,OACK;GAEZ,CAAC,GAEA,2BACC,oBAAC,OAAD;IACE,WAAW,GACT,yBAAyB,EACvB,MACF,CAAC,CACH;IACA,OAAO;IACP,KAAK;GACN,EAEA;;CACF;AAET"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { cn } from "../../utils/cn.mjs";
|
|
4
|
-
import { useHorizontalSwipe } from "../../hooks/useHorizontalSwipe.mjs";
|
|
5
4
|
import { TabSelector, TabSelectorColor } from "../TabSelector/TabSelector.mjs";
|
|
5
|
+
import { useHorizontalSwipe } from "../../hooks/useHorizontalSwipe.mjs";
|
|
6
6
|
import { useTabContext } from "./TabContext.mjs";
|
|
7
7
|
import { Children, createContext, isValidElement, useState } from "react";
|
|
8
8
|
import { cva } from "class-variance-authority";
|
|
@@ -10,7 +10,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
10
10
|
let TabSelectorColor = /* @__PURE__ */ function(TabSelectorColor) {
|
|
11
11
|
TabSelectorColor["PRIMARY"] = "primary";
|
|
12
12
|
TabSelectorColor["SECONDARY"] = "secondary";
|
|
13
|
-
TabSelectorColor["
|
|
13
|
+
TabSelectorColor["ERROR"] = "error";
|
|
14
14
|
TabSelectorColor["NEUTRAL"] = "neutral";
|
|
15
15
|
TabSelectorColor["LIGHT"] = "light";
|
|
16
16
|
TabSelectorColor["DARK"] = "dark";
|
|
@@ -21,7 +21,7 @@ const tabSelectorVariant = cva("relative z-0 flex size-full flex-row items-cente
|
|
|
21
21
|
variants: { color: {
|
|
22
22
|
primary: "border-primary text-primary",
|
|
23
23
|
secondary: "border-secondary text-secondary",
|
|
24
|
-
|
|
24
|
+
error: "border-error bg-error text-error",
|
|
25
25
|
neutral: "border-neutral text-neutral",
|
|
26
26
|
light: "border-white text-white",
|
|
27
27
|
dark: "border-neutral-800 text-neutral-800",
|
|
@@ -34,7 +34,7 @@ const indicatorVariant = cva("absolute -z-1 rounded-lg duration-300 ease-in-out
|
|
|
34
34
|
color: {
|
|
35
35
|
primary: "bg-primary/10 aria-selected:text-text",
|
|
36
36
|
secondary: "bg-secondary/10 aria-selected:text-text",
|
|
37
|
-
|
|
37
|
+
error: "bg-error/10 aria-selected:text-text",
|
|
38
38
|
neutral: "bg-neutral/10 aria-selected:text-white/10",
|
|
39
39
|
light: "bg-white/10 aria-selected:text-black",
|
|
40
40
|
dark: "bg-neutral-800/10 aria-selected:text-white",
|