@intlayer/design-system 9.4.4 → 9.5.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/README.md +0 -2
- package/dist/esm/components/Badge/index.mjs +2 -4
- package/dist/esm/components/Badge/index.mjs.map +1 -1
- package/dist/esm/components/Breadcrumb/index.mjs +0 -4
- package/dist/esm/components/Breadcrumb/index.mjs.map +1 -1
- package/dist/esm/components/Button/Button.mjs +2 -7
- package/dist/esm/components/Button/Button.mjs.map +1 -1
- package/dist/esm/components/Container/index.mjs +0 -2
- package/dist/esm/components/Container/index.mjs.map +1 -1
- package/dist/esm/components/CopyButton/index.mjs +1 -1
- package/dist/esm/components/CopyButton/index.mjs.map +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/Input/Radio.mjs +0 -2
- package/dist/esm/components/Input/Radio.mjs.map +1 -1
- package/dist/esm/components/Link/Link.mjs +4 -28
- 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/DesktopNavbar.mjs +1 -1
- package/dist/esm/components/Navbar/DesktopNavbar.mjs.map +1 -1
- package/dist/esm/components/Navbar/MobileNavbar.mjs +1 -1
- package/dist/esm/components/Pagination/Pagination.mjs +1 -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 +1 -5
- package/dist/esm/components/SwitchSelector/SwitchSelector.mjs.map +1 -1
- package/dist/esm/components/SwitchSelector/VerticalSwitchSelector.mjs +2 -6
- 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 +2 -6
- package/dist/esm/components/TabSelector/TabSelector.mjs.map +1 -1
- package/dist/esm/components/Table/Table.mjs +1 -1
- package/dist/esm/components/Table/Table.mjs.map +1 -1
- package/dist/esm/components/Tag/index.mjs +0 -1
- package/dist/esm/components/Tag/index.mjs.map +1 -1
- package/dist/esm/hooks/index.mjs +9 -8
- package/dist/esm/hooks/useListKeyboardNavigation.mjs +73 -0
- package/dist/esm/hooks/useListKeyboardNavigation.mjs.map +1 -0
- package/dist/esm/routes.mjs +125 -122
- package/dist/esm/routes.mjs.map +1 -1
- package/dist/types/components/Badge/index.d.ts +2 -2
- 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 +2 -2
- package/dist/types/components/Button/Button.d.ts.map +1 -1
- package/dist/types/components/Container/index.d.ts +2 -2
- package/dist/types/components/Container/index.d.ts.map +1 -1
- package/dist/types/components/CopyButton/index.d.ts +1 -1
- package/dist/types/components/Input/Checkbox.d.ts +2 -2
- package/dist/types/components/Input/Checkbox.d.ts.map +1 -1
- package/dist/types/components/Input/Radio.d.ts +2 -2
- package/dist/types/components/Input/Radio.d.ts.map +1 -1
- package/dist/types/components/Link/Link.d.ts +2 -2
- 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 +3 -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/Tag/index.d.ts.map +1 -1
- package/dist/types/hooks/index.d.ts +2 -1
- package/dist/types/hooks/useListKeyboardNavigation.d.ts +31 -0
- package/dist/types/hooks/useListKeyboardNavigation.d.ts.map +1 -0
- package/dist/types/routes.d.ts +7 -4
- package/dist/types/routes.d.ts.map +1 -1
- package/package.json +41 -41
- package/styles/globals.css +11 -3
|
@@ -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\nexport type LinkVariant =\n | 'default'\n | 'invisible-link'\n | 'button'\n | 'button-outlined'\n | 'hoverable';\n\n/**\n * Color theme variants for Link component\n */\nexport type LinkColor =\n | 'primary'\n | 'secondary'\n | 'neutral'\n | 'light'\n | 'dark'\n | 'text'\n | 'text-inverse'\n | 'error'\n | 'success'\n | 'custom';\n\nexport type LinkRoundedSize =\n | 'none'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | 'full';\n\nexport type LinkSize = 'sm' | 'md' | 'lg' | 'xl' | 'custom';\n\nexport type LinkUnderlined = 'default' | 'true' | 'false';\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 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 'invisible-link':\n 'h-auto justify-start border-inherit bg-current/0 px-1',\n\n button:\n 'relative inline-flex min-h-8 cursor-pointer flex-row items-center justify-center gap-2 rounded-full bg-current px-6 text-center font-medium text-sm text-text ring-0 *:text-text-opposite hover:bg-current/90 hover:ring-5 aria-selected:ring-5 aria-[current]:ring-5 max-md:py-2',\n\n 'button-outlined':\n 'relative inline-flex min-h-8 cursor-pointer flex-row items-center justify-center gap-2 rounded-full border-[1.3px] border-current px-6 text-center font-medium text-sm text-text ring-0 *:text-text hover:bg-current/20 hover:ring-5 aria-selected:ring-5 aria-[current]:ring-5 max-md:py-2',\n\n hoverable:\n 'rounded-lg border-none bg-current/0 transition *:text-current! hover:bg-current/10 aria-[current]:bg-current/5',\n },\n roundedSize: {\n none: 'rounded-none',\n sm: 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n md: 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n lg: 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n xl: 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n '2xl':\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n '3xl':\n 'rounded-[2.5rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[3rem]',\n full: 'rounded-full',\n },\n color: {\n primary: 'text-primary',\n secondary: 'text-secondary',\n neutral: 'text-neutral',\n light: 'text-white',\n dark: 'text-neutral-800',\n text: 'text-text',\n 'text-inverse': 'text-text-opposite',\n error: 'text-error',\n success: 'text-success',\n custom: '',\n },\n size: {\n sm: 'text-sm',\n md: 'text-base',\n lg: 'text-lg',\n xl: 'text-xl',\n custom: '',\n },\n underlined: {\n default: '',\n true: 'underline',\n 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: 'button',\n color: '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: 'button-outlined',\n color: 'text-inverse',\n class: 'text-text-opposite *:text-text-opposite',\n },\n\n // Min height and padding for button variants\n {\n variant: ['button', 'button-outlined'],\n size: 'sm',\n class: 'min-h-7 px-3 text-xs max-md:py-1',\n },\n {\n variant: ['button', 'button-outlined'],\n size: 'md',\n class: 'min-h-8 px-6 text-sm max-md:py-2',\n },\n {\n variant: ['button', 'button-outlined'],\n size: 'lg',\n class: 'min-h-10 px-8 text-lg max-md:py-3',\n },\n {\n variant: ['button', 'button-outlined'],\n size: 'xl',\n class: 'min-h-11 px-10 text-xl max-md:py-4',\n },\n // Ring color variants\n {\n variant: ['button', 'button-outlined'],\n color: 'primary',\n class: 'ring-primary/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'secondary',\n class: 'ring-secondary/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'neutral',\n class: 'ring-neutral/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'light',\n class: 'ring-white/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'dark',\n class: 'ring-neutral-800/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'text',\n class: 'ring-text/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'text-inverse',\n class: 'ring-text-opposite/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'error',\n class: 'ring-error/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'success',\n class: 'ring-success/20',\n },\n ],\n\n defaultVariants: {\n variant: 'default',\n roundedSize: 'md',\n underlined: 'default',\n size: 'custom',\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 {\n href,\n isExternalLink: isExternalLinkProp,\n }: Pick<LinkProps, 'href' | 'isExternalLink'>,\n url?: string\n): boolean => {\n // Explicit prop override takes precedence\n if (typeof isExternalLinkProp === 'boolean') {\n return isExternalLinkProp;\n }\n\n const isValidHref = typeof href === 'string' && href.trim() !== '';\n\n if (!isValidHref) return false;\n\n // Relative URLs (e.g., '/about') are always internal\n if (!/^https?:\\/\\//.test(href)) {\n return false;\n }\n\n // Compare base domains\n if (url) {\n try {\n const hrefHost = new URL(href).hostname;\n // Ensure the reference url has a protocol so URL() can parse it correctly\n const currentHost = new URL(\n url.startsWith('http') ? url : `https://${url}`\n ).hostname;\n\n // Extract the root domain (e.g., 'app.intlayer.org' -> 'intlayer.org')\n const getBaseDomain = (host: string) =>\n host.split('.').slice(-2).join('.');\n\n return getBaseDomain(hrefHost) !== getBaseDomain(currentHost);\n } catch {\n // If URL parsing fails for any reason, default to treating it as external\n return true;\n }\n }\n\n // Absolute URL with no comparison URL provided\n return true;\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 = 'default',\n color = 'custom',\n roundedSize,\n children,\n label,\n className,\n isActive,\n underlined,\n locale,\n size: sizeProp,\n isExternalLink: isExternalLinkProp,\n isPageSection: isPageSectionProp,\n href: hrefProp,\n rel: relProp,\n target: targetProp,\n ...otherProps\n } = props;\n\n const isButton = variant === 'button' || variant === 'button-outlined';\n const size = sizeProp ?? (isButton ? 'md' : 'custom');\n\n const isExternalLink = isExternalLinkProp ?? checkIsExternalLink(props);\n const isPageSection = isPageSectionProp ?? hrefProp?.startsWith('#') ?? false;\n\n const isChildrenString = isTextChildren(children);\n\n /**\n * External links always carry the full safety/SEO `rel`, so a caller cannot\n * accidentally strip `nofollow`. Internal links keep whatever the caller asked for.\n */\n const rel = isExternalLink ? 'noopener noreferrer nofollow' : relProp;\n\n const target = isExternalLink ? '_blank' : (targetProp ?? '_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 {...otherProps}\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 >\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":"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"}
|
|
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\nexport type LinkVariant =\n | 'default'\n | 'invisible-link'\n | 'button'\n | 'button-outlined'\n | 'hoverable';\n\n/**\n * Color theme variants for Link component\n */\nexport type LinkColor =\n | 'neutral'\n | 'text'\n | 'error'\n | 'success'\n | 'custom'\n | 'text-inverse';\n\nexport type LinkRoundedSize =\n | 'none'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | 'full';\n\nexport type LinkSize = 'sm' | 'md' | 'lg' | 'xl' | 'custom';\n\nexport type LinkUnderlined = 'default' | 'true' | 'false';\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 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:underline hover:underline-offset-6 hover:opacity-80',\n 'invisible-link':\n 'h-auto justify-start border-inherit bg-current/0 px-1',\n\n button:\n 'relative inline-flex min-h-8 cursor-pointer flex-row items-center justify-center gap-2 rounded-full bg-current px-6 text-center font-medium text-sm text-text ring-0 *:text-text-opposite hover:bg-current/90 hover:ring-5 aria-selected:ring-5 aria-[current]:ring-5 max-md:py-2',\n\n 'button-outlined':\n 'relative inline-flex min-h-8 cursor-pointer flex-row items-center justify-center gap-2 rounded-full border-[1.3px] border-current! px-6 text-center font-medium text-sm text-text ring-0 *:text-text hover:bg-current/30! hover:ring-5 aria-selected:ring-5 aria-[current]:ring-5 max-md:py-2',\n\n hoverable:\n 'block rounded-lg border-none bg-current/0 transition *:text-current! hover:bg-current/10 aria-[current]:bg-current/5',\n },\n roundedSize: {\n none: 'rounded-none',\n sm: 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n md: 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n lg: 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n xl: 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n '2xl':\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n '3xl':\n 'rounded-[2.5rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[3rem]',\n full: 'rounded-full',\n },\n color: {\n neutral: 'text-neutral',\n text: 'text-text',\n error: 'text-error',\n success: 'text-success',\n 'text-inverse': 'text-text-opposite',\n custom: '',\n },\n size: {\n sm: 'text-sm',\n md: 'text-base',\n lg: 'text-lg',\n xl: 'text-xl',\n custom: '',\n },\n underlined: {\n default: '',\n true: 'underline',\n 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: 'button',\n color: '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: 'button-outlined',\n color: 'text-inverse',\n class: 'text-text-opposite *:text-text-opposite',\n },\n // Min height and padding for button variants\n {\n variant: ['button', 'button-outlined'],\n size: 'sm',\n class: 'min-h-7 px-3 text-xs max-md:py-1',\n },\n {\n variant: ['button', 'button-outlined'],\n size: 'md',\n class: 'min-h-8 px-6 text-sm max-md:py-2',\n },\n {\n variant: ['button', 'button-outlined'],\n size: 'lg',\n class: 'min-h-10 px-8 text-lg max-md:py-3',\n },\n {\n variant: ['button', 'button-outlined'],\n size: 'xl',\n class: 'min-h-11 px-10 text-xl max-md:py-4',\n },\n // Ring color variants\n\n {\n variant: ['button', 'button-outlined'],\n color: 'neutral',\n class: 'ring-neutral/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'text',\n class: 'ring-text/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'text-inverse',\n class: 'ring-text-opposite/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'error',\n class: 'ring-error/20',\n },\n {\n variant: ['button', 'button-outlined'],\n color: 'success',\n class: 'ring-success/20',\n },\n ],\n\n defaultVariants: {\n variant: 'default',\n roundedSize: 'md',\n underlined: 'default',\n size: 'custom',\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 {\n href,\n isExternalLink: isExternalLinkProp,\n }: Pick<LinkProps, 'href' | 'isExternalLink'>,\n url?: string\n): boolean => {\n // Explicit prop override takes precedence\n if (typeof isExternalLinkProp === 'boolean') {\n return isExternalLinkProp;\n }\n\n const isValidHref = typeof href === 'string' && href.trim() !== '';\n\n if (!isValidHref) return false;\n\n // Relative URLs (e.g., '/about') are always internal\n if (!/^https?:\\/\\//.test(href)) {\n return false;\n }\n\n // Compare base domains\n if (url) {\n try {\n const hrefHost = new URL(href).hostname;\n // Ensure the reference url has a protocol so URL() can parse it correctly\n const currentHost = new URL(\n url.startsWith('http') ? url : `https://${url}`\n ).hostname;\n\n // Extract the root domain (e.g., 'app.intlayer.org' -> 'intlayer.org')\n const getBaseDomain = (host: string) =>\n host.split('.').slice(-2).join('.');\n\n return getBaseDomain(hrefHost) !== getBaseDomain(currentHost);\n } catch {\n // If URL parsing fails for any reason, default to treating it as external\n return true;\n }\n }\n\n // Absolute URL with no comparison URL provided\n return true;\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 = 'default',\n color = 'custom',\n roundedSize,\n children,\n label,\n className,\n isActive,\n underlined,\n locale,\n size: sizeProp,\n isExternalLink: isExternalLinkProp,\n isPageSection: isPageSectionProp,\n href: hrefProp,\n rel: relProp,\n target: targetProp,\n ...otherProps\n } = props;\n\n const isButton = variant === 'button' || variant === 'button-outlined';\n const size = sizeProp ?? (isButton ? 'md' : 'custom');\n\n const isExternalLink = isExternalLinkProp ?? checkIsExternalLink(props);\n const isPageSection = isPageSectionProp ?? hrefProp?.startsWith('#') ?? false;\n\n const isChildrenString = isTextChildren(children);\n\n /**\n * External links always carry the full safety/SEO `rel`, so a caller cannot\n * accidentally strip `nofollow`. Internal links keep whatever the caller asked for.\n */\n const rel = isExternalLink ? 'noopener noreferrer nofollow' : relProp;\n\n const target = isExternalLink ? '_blank' : (targetProp ?? '_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 {...otherProps}\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 >\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":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { usePersistedStore } from "../../hooks/usePersistedStore.mjs";
|
|
3
4
|
import { Button } from "../Button/Button.mjs";
|
|
4
5
|
import { Container } from "../Container/index.mjs";
|
|
5
6
|
import { DropDown } from "../DropDown/index.mjs";
|
|
6
7
|
import { Input } from "../Input/Input.mjs";
|
|
7
8
|
import { SwitchSelector } 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 { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { cn } from "../../utils/cn.mjs";
|
|
4
|
-
import { Button } from "../Button/Button.mjs";
|
|
5
|
-
import { Container } from "../Container/index.mjs";
|
|
6
4
|
import { useGetElementOrWindow } from "../../hooks/useGetElementOrWindow.mjs";
|
|
7
5
|
import { useScrollBlockage } from "../../hooks/useScrollBlockage/index.mjs";
|
|
6
|
+
import { Button } from "../Button/Button.mjs";
|
|
7
|
+
import { Container } from "../Container/index.mjs";
|
|
8
8
|
import { H3 } from "../Headers/index.mjs";
|
|
9
9
|
import { useEffect } from "react";
|
|
10
10
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -83,7 +83,7 @@ const DesktopNavbar = ({ logo, sections, rightItems, selectedChoice }) => /* @__
|
|
|
83
83
|
className: "ml-[2vw] h-auto gap-3 overflow-x-auto text-muted-foreground tracking-wide lg:ml-[5vw] lg:gap-3 xl:ml-[10vw] xl:gap-6",
|
|
84
84
|
tabs: sections,
|
|
85
85
|
hoverable: true,
|
|
86
|
-
color: "
|
|
86
|
+
color: "text"
|
|
87
87
|
}),
|
|
88
88
|
/* @__PURE__ */ jsx("div", {
|
|
89
89
|
className: "mr-4 flex items-center justify-end gap-2 md:gap-4",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DesktopNavbar.mjs","names":[],"sources":["../../../../src/components/Navbar/DesktopNavbar.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement, ReactNode } from 'react';\nimport { TabSelector, type TabSelectorItemProps } from '../TabSelector';\n\n/**\n * Props for the DesktopNavbar component\n * @template T - The tab props type extending TabProps\n */\ntype DesktopNavbarProps<T extends TabSelectorItemProps> = {\n /** Logo component or element displayed on the left side */\n logo: ReactNode;\n /** Array of navigation sections as tab elements */\n sections: ReactElement<T>[];\n /** Right-aligned items (e.g., user menu, search, settings) */\n rightItems?: ReactNode;\n /** Currently selected tab key for highlighting active state */\n selectedChoice: T['key'];\n};\n\n/**\n * Desktop Navigation Bar Component\n *\n * A horizontal navigation bar optimized for desktop and tablet viewports.\n * Features a sticky header with backdrop blur, left-aligned logo, center navigation tabs,\n * and right-aligned utility items.\n *\n * Features:\n * - Sticky positioning with z-index layering (z-50)\n * - Semi-transparent backdrop with blur effect for modern glass-morphism design\n * - Responsive spacing that adapts across screen sizes\n * - Horizontal scrollable tabs for overflow content\n * - Left-to-right layout: Logo → Navigation → Utility Items\n * - Integrated with TabSelector for consistent tab behavior\n *\n * Layout Structure:\n * ```\n * [Logo] -------- [Nav Tab 1] [Nav Tab 2] [Nav Tab 3] -------- [Right Items]\n * ```\n *\n * Responsive Behavior:\n * - Base: 2vw margin-left, 3-unit gap between tabs\n * - Large (≥1024px): 5vw margin-left, 3-unit gap between tabs\n * - Extra Large (≥1280px): 10vw margin-left, 6-unit gap between tabs\n * - Right items: 2-unit gap on mobile, 4-unit gap on medium screens\n *\n * Styling Features:\n * - Semi-transparent card background (`bg-card/80`)\n * - Subtle shadow with controlled blur (`shadow-[0_0_10px_-15px_rgba(0,0,0,0.3)]`)\n * - Backdrop blur effect for content behind navbar\n * - Horizontal overflow scrolling for tab content\n *\n * @example\n * Basic usage:\n * ```tsx\n * const navigationTabs = [\n * { key: 'home', label: 'Home', href: '/' },\n * { key: 'products', label: 'Products', href: '/products' },\n * { key: 'about', label: 'About', href: '/about' }\n * ];\n *\n * <DesktopNavbar\n * logo={<CompanyLogo />}\n * sections={navigationTabs}\n * selectedChoice=\"home\"\n * rightItems={<UserProfileMenu />}\n * />\n * ```\n *\n * @example\n * With multiple right items:\n * ```tsx\n * <DesktopNavbar\n * logo={<Logo />}\n * sections={navSections}\n * selectedChoice={currentPage}\n * rightItems={\n * <>\n * <SearchButton />\n * <NotificationBell />\n * <UserMenu />\n * </>\n * }\n * />\n * ```\n *\n * @template T - Tab properties type extending TabProps for type safety\n * @param props - DesktopNavbar component props\n * @returns Horizontal desktop navigation JSX element\n */\nexport const DesktopNavbar = <T extends TabSelectorItemProps>({\n logo,\n sections,\n rightItems,\n selectedChoice,\n}: DesktopNavbarProps<T>) => (\n <nav className=\"sticky top-0 z-50 flex w-full items-center border-neutral border-b px-4 py-3 shadow-[0_0_10px_-15px_rgba(0,0,0,0.3)] backdrop-blur-2xl\">\n {logo}\n\n <TabSelector\n selectedChoice={selectedChoice}\n className=\"ml-[2vw] h-auto gap-3 overflow-x-auto text-muted-foreground tracking-wide lg:ml-[5vw] lg:gap-3 xl:ml-[10vw] xl:gap-6\"\n tabs={sections}\n hoverable\n color=\"
|
|
1
|
+
{"version":3,"file":"DesktopNavbar.mjs","names":[],"sources":["../../../../src/components/Navbar/DesktopNavbar.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement, ReactNode } from 'react';\nimport { TabSelector, type TabSelectorItemProps } from '../TabSelector';\n\n/**\n * Props for the DesktopNavbar component\n * @template T - The tab props type extending TabProps\n */\ntype DesktopNavbarProps<T extends TabSelectorItemProps> = {\n /** Logo component or element displayed on the left side */\n logo: ReactNode;\n /** Array of navigation sections as tab elements */\n sections: ReactElement<T>[];\n /** Right-aligned items (e.g., user menu, search, settings) */\n rightItems?: ReactNode;\n /** Currently selected tab key for highlighting active state */\n selectedChoice: T['key'];\n};\n\n/**\n * Desktop Navigation Bar Component\n *\n * A horizontal navigation bar optimized for desktop and tablet viewports.\n * Features a sticky header with backdrop blur, left-aligned logo, center navigation tabs,\n * and right-aligned utility items.\n *\n * Features:\n * - Sticky positioning with z-index layering (z-50)\n * - Semi-transparent backdrop with blur effect for modern glass-morphism design\n * - Responsive spacing that adapts across screen sizes\n * - Horizontal scrollable tabs for overflow content\n * - Left-to-right layout: Logo → Navigation → Utility Items\n * - Integrated with TabSelector for consistent tab behavior\n *\n * Layout Structure:\n * ```\n * [Logo] -------- [Nav Tab 1] [Nav Tab 2] [Nav Tab 3] -------- [Right Items]\n * ```\n *\n * Responsive Behavior:\n * - Base: 2vw margin-left, 3-unit gap between tabs\n * - Large (≥1024px): 5vw margin-left, 3-unit gap between tabs\n * - Extra Large (≥1280px): 10vw margin-left, 6-unit gap between tabs\n * - Right items: 2-unit gap on mobile, 4-unit gap on medium screens\n *\n * Styling Features:\n * - Semi-transparent card background (`bg-card/80`)\n * - Subtle shadow with controlled blur (`shadow-[0_0_10px_-15px_rgba(0,0,0,0.3)]`)\n * - Backdrop blur effect for content behind navbar\n * - Horizontal overflow scrolling for tab content\n *\n * @example\n * Basic usage:\n * ```tsx\n * const navigationTabs = [\n * { key: 'home', label: 'Home', href: '/' },\n * { key: 'products', label: 'Products', href: '/products' },\n * { key: 'about', label: 'About', href: '/about' }\n * ];\n *\n * <DesktopNavbar\n * logo={<CompanyLogo />}\n * sections={navigationTabs}\n * selectedChoice=\"home\"\n * rightItems={<UserProfileMenu />}\n * />\n * ```\n *\n * @example\n * With multiple right items:\n * ```tsx\n * <DesktopNavbar\n * logo={<Logo />}\n * sections={navSections}\n * selectedChoice={currentPage}\n * rightItems={\n * <>\n * <SearchButton />\n * <NotificationBell />\n * <UserMenu />\n * </>\n * }\n * />\n * ```\n *\n * @template T - Tab properties type extending TabProps for type safety\n * @param props - DesktopNavbar component props\n * @returns Horizontal desktop navigation JSX element\n */\nexport const DesktopNavbar = <T extends TabSelectorItemProps>({\n logo,\n sections,\n rightItems,\n selectedChoice,\n}: DesktopNavbarProps<T>) => (\n <nav className=\"sticky top-0 z-50 flex w-full items-center border-neutral border-b px-4 py-3 shadow-[0_0_10px_-15px_rgba(0,0,0,0.3)] backdrop-blur-2xl\">\n {logo}\n\n <TabSelector\n selectedChoice={selectedChoice}\n className=\"ml-[2vw] h-auto gap-3 overflow-x-auto text-muted-foreground tracking-wide lg:ml-[5vw] lg:gap-3 xl:ml-[10vw] xl:gap-6\"\n tabs={sections}\n hoverable\n color=\"text\"\n />\n\n <div className=\"mr-4 flex items-center justify-end gap-2 md:gap-4\">\n {rightItems}\n </div>\n </nav>\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0FA,MAAa,iBAAiD,EAC5D,MACA,UACA,YACA,qBAEA,qBAAC,OAAD;CAAK,WAAU;WAAf;EACG;EAED,oBAAC,aAAD;GACkB;GAChB,WAAU;GACV,MAAM;GACN;GACA,OAAM;EACP;EAED,oBAAC,OAAD;GAAK,WAAU;aACZ;EACE;CACF"}
|
|
@@ -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";
|
|
5
4
|
import { useScrollBlockage } from "../../hooks/useScrollBlockage/index.mjs";
|
|
6
5
|
import { useScrollDetection } from "../../hooks/useScrollDetection.mjs";
|
|
6
|
+
import { MaxHeightSmoother } from "../MaxHeightSmoother/index.mjs";
|
|
7
7
|
import { Burger } from "./Burger.mjs";
|
|
8
8
|
import { useEffect, 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 { Button } from "../Button/Button.mjs";
|
|
5
4
|
import { useItemSelector } from "../../hooks/useItemSelector.mjs";
|
|
5
|
+
import { Button } from "../Button/Button.mjs";
|
|
6
6
|
import { useEffect, useRef } from "react";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { cva } from "class-variance-authority";
|
|
@@ -19,8 +19,6 @@ const paginationVariants = cva("flex items-center justify-center gap-1", {
|
|
|
19
19
|
},
|
|
20
20
|
color: {
|
|
21
21
|
text: "background-text",
|
|
22
|
-
primary: "background-primary",
|
|
23
|
-
secondary: "background-secondary",
|
|
24
22
|
neutral: "background-neutral"
|
|
25
23
|
},
|
|
26
24
|
variant: {
|
|
@@ -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 } 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 type PaginationSize = 'sm' | 'md' | 'lg';\n\nexport type PaginationVariant = 'default' | 'bordered' | 'ghost';\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 === 'sm') {\n return 'icon-sm';\n } else if (size === 'lg') {\n return 'icon-lg';\n } else {\n return '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 = 'md',\n variant = 'default',\n color = '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, scheduleMeasurement } = useItemSelector(\n optionsRefs,\n {\n selector,\n isHoverable: true,\n }\n );\n\n useEffect(() => {\n const timer = setTimeout(() => {\n scheduleMeasurement();\n }, 300);\n\n return () => clearTimeout(timer);\n }, [currentPage, scheduleMeasurement]);\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=\"outline\"\n size={buttonSize}\n color=\"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={isActive ? 'default' : 'outline'}\n size={buttonSize}\n color=\"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=\"outline\"\n size={buttonSize}\n color=\"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 } 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 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 type PaginationSize = 'sm' | 'md' | 'lg';\n\nexport type PaginationVariant = 'default' | 'bordered' | 'ghost';\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 === 'sm') {\n return 'icon-sm';\n } else if (size === 'lg') {\n return 'icon-lg';\n } else {\n return '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 = 'md',\n variant = 'default',\n color = '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, scheduleMeasurement } = useItemSelector(\n optionsRefs,\n {\n selector,\n isHoverable: true,\n }\n );\n\n useEffect(() => {\n const timer = setTimeout(() => {\n scheduleMeasurement();\n }, 300);\n\n return () => clearTimeout(timer);\n }, [currentPage, scheduleMeasurement]);\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=\"outline\"\n size={buttonSize}\n color=\"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={isActive ? 'default' : 'outline'}\n size={buttonSize}\n color=\"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=\"outline\"\n size={buttonSize}\n color=\"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";
|
|
3
6
|
import { Button } from "../Button/Button.mjs";
|
|
4
7
|
import { Container } from "../Container/index.mjs";
|
|
5
|
-
import { useDevice } from "../../hooks/useDevice.mjs";
|
|
6
8
|
import { KeyboardShortcut } from "../KeyboardShortcut/KeyboardShortcut.mjs";
|
|
7
9
|
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 { useIsRightDrawerOpen, useRightDrawerActions } from "./useRightDrawer.mjs";
|
|
@@ -17,8 +17,6 @@ const defaultChoices = [{
|
|
|
17
17
|
const switchSelectorVariant = cva("flex h-fit w-fit cursor-pointer flex-row gap-2 rounded-full border-[1.3px] p-0.38", {
|
|
18
18
|
variants: {
|
|
19
19
|
color: {
|
|
20
|
-
primary: "border-primary text-primary",
|
|
21
|
-
secondary: "border-secondary text-secondary",
|
|
22
20
|
neutral: "border-neutral text-neutral",
|
|
23
21
|
white: "border-white text-white",
|
|
24
22
|
black: "border-black text-black",
|
|
@@ -45,8 +43,6 @@ const choiceVariant = cva("z-1 flex-1 cursor-pointer font-medium text-sm transit
|
|
|
45
43
|
defaultVariants: { size: "md" }
|
|
46
44
|
});
|
|
47
45
|
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: {
|
|
48
|
-
primary: "bg-primary data-[indicator=true]:text-primary-foreground",
|
|
49
|
-
secondary: "bg-secondary data-[indicator=true]:text-secondary-foreground",
|
|
50
46
|
neutral: "bg-neutral data-[indicator=true]:text-white",
|
|
51
47
|
white: "bg-white data-[indicator=true]:text-black",
|
|
52
48
|
black: "bg-black data-[indicator=true]:text-white",
|
|
@@ -58,7 +54,7 @@ const indicatorVariant = cva("absolute top-0 z-0 h-full w-auto rounded-full tran
|
|
|
58
54
|
* This component is horizontal.
|
|
59
55
|
*/
|
|
60
56
|
const SwitchSelector = (props) => {
|
|
61
|
-
const { choices = defaultChoices, color = "
|
|
57
|
+
const { choices = defaultChoices, color = "text", size = "md", className, itemClassName } = props;
|
|
62
58
|
const { selectedIndex, indicatorIndex, handleChange, optionsRefs, indicatorRef, choiceIndicatorPosition, setHoveredIndex, disabled } = useSwitchSelector({
|
|
63
59
|
choices,
|
|
64
60
|
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 type SwitchSelectorColor =\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 type SwitchSelectorColor =\n | 'neutral'\n | 'white'\n | 'black'\n | 'text'\n | 'error';\n\nexport type SwitchSelectorSize = 'xs' | 'sm' | 'md' | 'lg';\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-0.38',\n {\n variants: {\n color: {\n neutral: 'border-neutral text-neutral',\n white: 'border-white text-white',\n black: 'border-black text-black',\n text: 'border-foreground text-foreground',\n error: 'border-error text-error',\n },\n disabled: {\n true: 'cursor-not-allowed opacity-50',\n false: '',\n },\n },\n defaultVariants: {\n color: '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-background motion-reduce:transition-none',\n {\n variants: {\n size: {\n xs: 'px-2 py-0.5 text-xs',\n sm: 'px-2 py-1 text-xs',\n md: 'p-2 text-sm',\n lg: 'p-4 text-base',\n },\n },\n defaultVariants: {\n size: '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 neutral: 'bg-neutral data-[indicator=true]:text-white',\n white: 'bg-white data-[indicator=true]:text-black',\n black: 'bg-black data-[indicator=true]:text-white',\n text: 'bg-foreground data-[indicator=true]:text-background',\n error: 'bg-error data-[indicator=true]:text-white',\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 = 'text',\n size = '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 size-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 type=\"button\"\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;AA2BA,MAAa,wBAAwB,IACnC,qFACA;CACE,UAAU;EACR,OAAO;GACL,SAAS;GACT,OAAO;GACP,OAAO;GACP,MAAM;GACN,OAAO;EACT;EACA,UAAU;GACR,MAAM;GACN,OAAO;EACT;CACF;CACA,iBAAiB;EACf,OAAO;EACP,UAAU;CACZ;AACF,CACF;AAEA,MAAa,gBAAgB,IAC3B,0LACA;CACE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CACF;AAEA,MAAa,mBAAmB,IAC9B,uHACA,EACE,UAAU,EACR,OAAO;CACL,SAAS;CACT,OAAO;CACP,OAAO;CACP,MAAM;CACN,OAAO;AACT,EACF,EACF,CACF;;;;;AAKA,MAAa,kBAAsB,UAAkC;CACnE,MAAM,EACJ,UAAU,gBACV,QAAQ,QACR,OAAO,MACP,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,MAAK;KACL,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"}
|
|
@@ -11,8 +11,6 @@ import { cva } from "class-variance-authority";
|
|
|
11
11
|
const verticalSwitchSelectorVariant = cva("flex h-fit w-fit cursor-pointer flex-col gap-2 rounded-2xl border-[1.3px] p-1", {
|
|
12
12
|
variants: {
|
|
13
13
|
color: {
|
|
14
|
-
primary: "border-primary text-primary",
|
|
15
|
-
secondary: "border-secondary text-secondary",
|
|
16
14
|
[`error`]: "border-error bg-error text-error",
|
|
17
15
|
neutral: "border-neutral text-neutral",
|
|
18
16
|
light: "border-white text-white",
|
|
@@ -25,7 +23,7 @@ const verticalSwitchSelectorVariant = cva("flex h-fit w-fit cursor-pointer flex-
|
|
|
25
23
|
}
|
|
26
24
|
},
|
|
27
25
|
defaultVariants: {
|
|
28
|
-
color: `
|
|
26
|
+
color: `text`,
|
|
29
27
|
disabled: false
|
|
30
28
|
}
|
|
31
29
|
});
|
|
@@ -38,8 +36,6 @@ const verticalChoiceVariant = cva("z-1 w-full cursor-pointer font-medium text-sm
|
|
|
38
36
|
defaultVariants: { size: `md` }
|
|
39
37
|
});
|
|
40
38
|
const verticalIndicatorVariant = cva("absolute left-0 z-0 h-auto w-full rounded-xl transition-all duration-300 ease-in-out motion-reduce:transition-none", { variants: { color: {
|
|
41
|
-
primary: "bg-primary data-[indicator=true]:text-foreground",
|
|
42
|
-
secondary: "bg-secondary data-[indicator=true]:text-foreground",
|
|
43
39
|
[`error`]: "bg-error data-[indicator=true]:text-foreground",
|
|
44
40
|
neutral: "bg-neutral data-[indicator=true]:text-white",
|
|
45
41
|
light: "bg-white data-[indicator=true]:text-black",
|
|
@@ -51,7 +47,7 @@ const verticalIndicatorVariant = cva("absolute left-0 z-0 h-auto w-full rounded-
|
|
|
51
47
|
* This component is vertical.
|
|
52
48
|
*/
|
|
53
49
|
const VerticalSwitchSelector = (props) => {
|
|
54
|
-
const { choices = defaultChoices, color = "
|
|
50
|
+
const { choices = defaultChoices, color = "text", size = "md", className, itemClassName } = props;
|
|
55
51
|
const { selectedIndex, indicatorIndex, handleChange, optionsRefs, indicatorRef, choiceIndicatorPosition, setHoveredIndex, disabled } = useSwitchSelector({
|
|
56
52
|
choices,
|
|
57
53
|
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} 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
|
|
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} 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 [`${'error'}`]: 'border-error bg-error text-error',\n neutral: 'border-neutral text-neutral',\n light: 'border-white text-white',\n dark: 'border-neutral-800 text-neutral-800',\n text: 'border-text text-foreground',\n },\n disabled: {\n true: 'cursor-not-allowed opacity-50',\n false: '',\n },\n },\n defaultVariants: {\n color: `${'text'}`,\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-foreground-opposite motion-reduce:transition-none',\n {\n variants: {\n size: {\n sm: 'px-2 py-1 text-xs',\n md: 'p-2 text-sm',\n lg: 'p-4 text-base',\n },\n },\n defaultVariants: {\n size: `${'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 [`${'error'}`]: 'bg-error data-[indicator=true]:text-foreground',\n neutral: 'bg-neutral data-[indicator=true]:text-white',\n light: 'bg-white data-[indicator=true]:text-black',\n dark: 'bg-neutral-800 data-[indicator=true]:text-white',\n text: 'bg-text data-[indicator=true]:text-foreground-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 = 'text',\n size = '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":";;;;;;;;;;AAWA,MAAM,gCAAgC,IACpC,iFACA;CACE,UAAU;EACR,OAAO;IACJ,UAAe;GAChB,SAAS;GACT,OAAO;GACP,MAAM;GACN,MAAM;EACR;EACA,UAAU;GACR,MAAM;GACN,OAAO;EACT;CACF;CACA,iBAAiB;EACf,OAAO;EACP,UAAU;CACZ;AACF,CACF;AAEA,MAAM,wBAAwB,IAC5B,mMACA;CACE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CACF;AAEA,MAAM,2BAA2B,IAC/B,sHACA,EACE,UAAU,EACR,OAAO;EACJ,UAAe;CAChB,SAAS;CACT,OAAO;CACP,MAAM;CACN,MAAM;AACR,EACF,EACF,CACF;;;;;AAWA,MAAa,0BACX,UACG;CACH,MAAM,EACJ,UAAU,gBACV,QAAQ,QACR,OAAO,MACP,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 { TabSelector } from "../TabSelector/TabSelector.mjs";
|
|
5
4
|
import { useHorizontalSwipe } from "../../hooks/useHorizontalSwipe.mjs";
|
|
5
|
+
import { TabSelector } from "../TabSelector/TabSelector.mjs";
|
|
6
6
|
import { useTabContext } from "./TabContext.mjs";
|
|
7
7
|
import { Children, createContext, isValidElement, useState } from "react";
|
|
8
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -9,21 +9,17 @@ import { cva } from "class-variance-authority";
|
|
|
9
9
|
//#region src/components/TabSelector/TabSelector.tsx
|
|
10
10
|
const tabSelectorVariant = cva("relative z-0 flex size-full flex-row items-center gap-2", {
|
|
11
11
|
variants: { color: {
|
|
12
|
-
primary: "border-primary text-primary",
|
|
13
|
-
secondary: "border-secondary text-secondary",
|
|
14
12
|
error: "border-error bg-error text-error",
|
|
15
13
|
neutral: "border-neutral text-neutral",
|
|
16
14
|
light: "border-white text-white",
|
|
17
15
|
dark: "border-neutral-800 text-neutral-800",
|
|
18
16
|
text: "border-text text-foreground"
|
|
19
17
|
} },
|
|
20
|
-
defaultVariants: { color: "
|
|
18
|
+
defaultVariants: { color: "text" }
|
|
21
19
|
});
|
|
22
20
|
const indicatorVariant = cva("absolute -z-1 rounded-lg duration-300 ease-in-out motion-reduce:transition-none", {
|
|
23
21
|
variants: {
|
|
24
22
|
color: {
|
|
25
|
-
primary: "bg-primary/10 aria-selected:text-foreground",
|
|
26
|
-
secondary: "bg-secondary/10 aria-selected:text-foreground",
|
|
27
23
|
error: "bg-error/10 aria-selected:text-foreground",
|
|
28
24
|
neutral: "bg-neutral/10 aria-selected:text-white/10",
|
|
29
25
|
light: "bg-white/10 aria-selected:text-black",
|
|
@@ -54,7 +50,7 @@ const indicatorVariant = cva("absolute -z-1 rounded-lg duration-300 ease-in-out
|
|
|
54
50
|
* </TabSelector>
|
|
55
51
|
* ```
|
|
56
52
|
*/
|
|
57
|
-
const TabSelector = ({ tabs, selectedChoice, onTabClick, color = "
|
|
53
|
+
const TabSelector = ({ tabs, selectedChoice, onTabClick, color = "text", hoverable = false, orientation = "horizontal", className }) => {
|
|
58
54
|
const optionsRefs = useRef([]);
|
|
59
55
|
const indicatorRef = useRef(null);
|
|
60
56
|
const { choiceIndicatorPosition, scheduleMeasurement } = useItemSelector(optionsRefs, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabSelector.mjs","names":[],"sources":["../../../../src/components/TabSelector/TabSelector.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ItemSelectorOrientation,\n useItemSelector,\n} from '@hooks/useItemSelector';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n cloneElement,\n type HTMLAttributes,\n type MouseEvent,\n type ReactElement,\n useEffect,\n useRef,\n} from 'react';\n\nexport type TabSelectorColor
|
|
1
|
+
{"version":3,"file":"TabSelector.mjs","names":[],"sources":["../../../../src/components/TabSelector/TabSelector.tsx"],"sourcesContent":["'use client';\n\nimport {\n type ItemSelectorOrientation,\n useItemSelector,\n} from '@hooks/useItemSelector';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport {\n cloneElement,\n type HTMLAttributes,\n type MouseEvent,\n type ReactElement,\n useEffect,\n useRef,\n} from 'react';\n\nexport type TabSelectorColor = 'error' | 'neutral' | 'light' | 'dark' | 'text';\n\nconst tabSelectorVariant = cva(\n 'relative z-0 flex size-full flex-row items-center gap-2',\n {\n variants: {\n color: {\n error: 'border-error bg-error text-error',\n neutral: 'border-neutral text-neutral',\n light: 'border-white text-white',\n dark: 'border-neutral-800 text-neutral-800',\n text: 'border-text text-foreground',\n },\n },\n defaultVariants: {\n color: 'text',\n },\n }\n);\n\nconst indicatorVariant = cva(\n 'absolute -z-1 rounded-lg duration-300 ease-in-out motion-reduce:transition-none',\n {\n variants: {\n color: {\n error: 'bg-error/10 aria-selected:text-foreground',\n neutral: 'bg-neutral/10 aria-selected:text-white/10',\n light: 'bg-white/10 aria-selected:text-black',\n dark: 'bg-neutral-800/10 aria-selected:text-white',\n text: 'bg-text/10 aria-selected:text-foreground-opposite',\n },\n orientation: {\n horizontal: 'top-0 h-full w-auto transition-[left,width]',\n vertical: 'left-0 h-auto w-full transition-[top,height]',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n }\n);\n\nexport type TabSelectorItemProps = HTMLAttributes<HTMLElement> & {\n key: string | number;\n};\n\nexport type TabSelectorProps<T extends TabSelectorItemProps> = {\n tabs: ReactElement<T>[];\n selectedChoice: T['key'];\n onTabClick?: (choice: T['key']) => void;\n hoverable?: boolean;\n orientation?: ItemSelectorOrientation;\n} & HTMLAttributes<HTMLElement> &\n Omit<VariantProps<typeof tabSelectorVariant>, 'color'> & {\n color?: TabSelectorColor | `${TabSelectorColor}`;\n };\n\n/**\n *\n * Component that allows the user to select one of the provided choices.\n *\n * Example:\n * ```jsx\n * <TabSelector\n * selectedChoice=\"option1\"\n * onTabClick={(choice) => console.log(choice)}\n * hoverable={true}\n * >\n * <Button key=\"option1\"/>\n * <Button key=\"option2\"/>\n * <Button key=\"option3\"/>\n * </TabSelector>\n * ```\n */\nexport const TabSelector = <T extends TabSelectorItemProps>({\n tabs,\n selectedChoice,\n onTabClick,\n color = 'text',\n hoverable = false,\n orientation = 'horizontal',\n className,\n}: TabSelectorProps<T>) => {\n const optionsRefs = useRef<HTMLElement[]>([]);\n const indicatorRef = useRef<HTMLDivElement | null>(null);\n const { choiceIndicatorPosition, scheduleMeasurement } = useItemSelector(\n optionsRefs,\n { isHoverable: hoverable, orientation }\n );\n\n useEffect(() => {\n scheduleMeasurement();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [selectedChoice]);\n\n return (\n <div\n className={cn(\n tabSelectorVariant({\n color,\n }),\n className\n )}\n aria-orientation={orientation}\n aria-multiselectable=\"false\"\n role=\"tablist\"\n >\n {tabs.map((Tab, index) => {\n const key = Tab.key!;\n\n const isSelected = selectedChoice === key;\n\n return cloneElement(Tab, {\n key: key ?? index,\n role: 'tab',\n onClick: (e: MouseEvent<HTMLElement>) => {\n Tab.props?.onClick?.(e);\n onTabClick?.(key);\n },\n 'aria-selected': isSelected,\n 'data-active': isSelected as unknown as string,\n tabIndex: isSelected ? 0 : -1,\n ref: (el: HTMLElement) => {\n optionsRefs.current[index] = el!;\n },\n } as unknown as T);\n })}\n {choiceIndicatorPosition && (\n <div\n className={cn(\n indicatorVariant({\n color,\n orientation,\n })\n )}\n style={choiceIndicatorPosition}\n ref={indicatorRef}\n key={`${selectedChoice}${JSON.stringify(tabs.map((tab) => tab.key))}`}\n />\n )}\n </div>\n );\n};\n"],"mappings":";;;;;;;;;AAmBA,MAAM,qBAAqB,IACzB,2DACA;CACE,UAAU,EACR,OAAO;EACL,OAAO;EACP,SAAS;EACT,OAAO;EACP,MAAM;EACN,MAAM;CACR,EACF;CACA,iBAAiB,EACf,OAAO,OACT;AACF,CACF;AAEA,MAAM,mBAAmB,IACvB,mFACA;CACE,UAAU;EACR,OAAO;GACL,OAAO;GACP,SAAS;GACT,OAAO;GACP,MAAM;GACN,MAAM;EACR;EACA,aAAa;GACX,YAAY;GACZ,UAAU;EACZ;CACF;CACA,iBAAiB,EACf,aAAa,aACf;AACF,CACF;;;;;;;;;;;;;;;;;;AAkCA,MAAa,eAA+C,EAC1D,MACA,gBACA,YACA,QAAQ,QACR,YAAY,OACZ,cAAc,cACd,gBACyB;CACzB,MAAM,cAAc,OAAsB,CAAC,CAAC;CAC5C,MAAM,eAAe,OAA8B,IAAI;CACvD,MAAM,EAAE,yBAAyB,wBAAwB,gBACvD,aACA;EAAE,aAAa;EAAW;CAAY,CACxC;CAEA,gBAAgB;EACd,oBAAoB;CAEtB,GAAG,CAAC,cAAc,CAAC;CAEnB,OACE,qBAAC,OAAD;EACE,WAAW,GACT,mBAAmB,EACjB,MACF,CAAC,GACD,SACF;EACA,oBAAkB;EAClB,wBAAqB;EACrB,MAAK;YATP,CAWG,KAAK,KAAK,KAAK,UAAU;GACxB,MAAM,MAAM,IAAI;GAEhB,MAAM,aAAa,mBAAmB;GAEtC,OAAO,aAAa,KAAK;IACvB,KAAK,OAAO;IACZ,MAAM;IACN,UAAU,MAA+B;KACvC,IAAI,OAAO,UAAU,CAAC;KACtB,aAAa,GAAG;IAClB;IACA,iBAAiB;IACjB,eAAe;IACf,UAAU,aAAa,IAAI;IAC3B,MAAM,OAAoB;KACxB,YAAY,QAAQ,SAAS;IAC/B;GACF,CAAiB;EACnB,CAAC,GACA,2BACC,oBAAC,OAAD;GACE,WAAW,GACT,iBAAiB;IACf;IACA;GACF,CAAC,CACH;GACA,OAAO;GACP,KAAK;EAEN,GADM,GAAG,iBAAiB,KAAK,UAAU,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,GACnE,CAEA;;AAET"}
|
|
@@ -5,7 +5,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
5
5
|
//#region src/components/Table/Table.tsx
|
|
6
6
|
const Table = forwardRef(({ className, isInteractive, ...props }, ref) => /* @__PURE__ */ jsx("table", {
|
|
7
7
|
ref,
|
|
8
|
-
className: cn("w-full table-auto border-separate border-spacing-0 overflow-hidden rounded-2xl text-left text-sm", "[&_thead_tr:first-child_th:first-child]:rounded-tl-2xl", "[&_thead_tr:first-child_th:last-child]:rounded-tr-2xl", "[&_tbody_tr:last-child_td:first-child]:rounded-bl-2xl", "[&_tbody_tr:last-child_td:last-child]:rounded-br-2xl", "supports-[corner-shape:squircle]:rounded-3xl", "supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:first-child]:rounded-tl-3xl", "supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:last-child]:rounded-tr-3xl", "supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:first-child]:rounded-bl-3xl", "supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:last-child]:rounded-br-3xl", isInteractive && "[&_tbody_tr:hover]:bg-neutral/40 [&_tbody_tr
|
|
8
|
+
className: cn("w-full table-auto border-separate border-spacing-0 overflow-hidden rounded-2xl text-left text-sm", "[&_thead_tr:first-child_th:first-child]:rounded-tl-2xl", "[&_thead_tr:first-child_th:last-child]:rounded-tr-2xl", "[&_tbody_tr:last-child_td:first-child]:rounded-bl-2xl", "[&_tbody_tr:last-child_td:last-child]:rounded-br-2xl", "supports-[corner-shape:squircle]:rounded-3xl", "supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:first-child]:rounded-tl-3xl", "supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:last-child]:rounded-tr-3xl", "supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:first-child]:rounded-bl-3xl", "supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:last-child]:rounded-br-3xl", isInteractive && "[&_tbody_tr:hover]:bg-neutral/40 [&_tbody_tr]:cursor-pointer [&_tbody_tr]:transition-colors", className),
|
|
9
9
|
...props
|
|
10
10
|
}));
|
|
11
11
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.mjs","names":[],"sources":["../../../../src/components/Table/Table.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { forwardRef, type HTMLAttributes } from 'react';\n\nexport interface TableProps extends HTMLAttributes<HTMLTableElement> {\n /** Enables hover states and cursor changes for interactive rows */\n isInteractive?: boolean;\n}\n\nexport const Table = forwardRef<HTMLTableElement, TableProps>(\n ({ className, isInteractive, ...props }, ref) => (\n <table\n ref={ref}\n className={cn(\n 'w-full table-auto border-separate border-spacing-0 overflow-hidden rounded-2xl text-left text-sm',\n '[&_thead_tr:first-child_th:first-child]:rounded-tl-2xl',\n '[&_thead_tr:first-child_th:last-child]:rounded-tr-2xl',\n '[&_tbody_tr:last-child_td:first-child]:rounded-bl-2xl',\n '[&_tbody_tr:last-child_td:last-child]:rounded-br-2xl',\n 'supports-[corner-shape:squircle]:rounded-3xl',\n 'supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:first-child]:rounded-tl-3xl',\n 'supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:last-child]:rounded-tr-3xl',\n 'supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:first-child]:rounded-bl-3xl',\n 'supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:last-child]:rounded-br-3xl',\n isInteractive &&\n '[&_tbody_tr:hover]:bg-neutral/40 [&_tbody_tr
|
|
1
|
+
{"version":3,"file":"Table.mjs","names":[],"sources":["../../../../src/components/Table/Table.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { forwardRef, type HTMLAttributes } from 'react';\n\nexport interface TableProps extends HTMLAttributes<HTMLTableElement> {\n /** Enables hover states and cursor changes for interactive rows */\n isInteractive?: boolean;\n}\n\nexport const Table = forwardRef<HTMLTableElement, TableProps>(\n ({ className, isInteractive, ...props }, ref) => (\n <table\n ref={ref}\n className={cn(\n 'w-full table-auto border-separate border-spacing-0 overflow-hidden rounded-2xl text-left text-sm',\n '[&_thead_tr:first-child_th:first-child]:rounded-tl-2xl',\n '[&_thead_tr:first-child_th:last-child]:rounded-tr-2xl',\n '[&_tbody_tr:last-child_td:first-child]:rounded-bl-2xl',\n '[&_tbody_tr:last-child_td:last-child]:rounded-br-2xl',\n 'supports-[corner-shape:squircle]:rounded-3xl',\n 'supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:first-child]:rounded-tl-3xl',\n 'supports-[corner-shape:squircle]:[&_thead_tr:first-child_th:last-child]:rounded-tr-3xl',\n 'supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:first-child]:rounded-bl-3xl',\n 'supports-[corner-shape:squircle]:[&_tbody_tr:last-child_td:last-child]:rounded-br-3xl',\n isInteractive &&\n '[&_tbody_tr:hover]:bg-neutral/40 [&_tbody_tr]:cursor-pointer [&_tbody_tr]:transition-colors',\n className\n )}\n {...props}\n />\n )\n);\n"],"mappings":";;;;;AAQA,MAAa,QAAQ,YAClB,EAAE,WAAW,eAAe,GAAG,SAAS,QACvC,oBAAC,SAAD;CACO;CACL,WAAW,GACT,oGACA,0DACA,yDACA,yDACA,wDACA,gDACA,2FACA,0FACA,0FACA,yFACA,iBACE,+FACF,SACF;CACA,GAAI;AACL,EAEL"}
|
|
@@ -15,7 +15,6 @@ const containerVariants = cva("w-fit backdrop-blur", {
|
|
|
15
15
|
full: "rounded-full"
|
|
16
16
|
},
|
|
17
17
|
color: {
|
|
18
|
-
primary: "border-primary bg-primary/10 text-primary",
|
|
19
18
|
success: "border-success bg-success/10 text-success",
|
|
20
19
|
error: "border-error bg-error/10 text-error",
|
|
21
20
|
warning: "border-warning bg-warning/10 text-warning",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Tag/index.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type { FC, HTMLAttributes, PropsWithChildren } from 'react';\n\n/**\n * Properties for the Tag component extending HTML div attributes and variant options\n *\n * @interface TagProps\n * @extends {PropsWithChildren<VariantProps<typeof containerVariants>>}\n * @extends {HTMLAttributes<HTMLDivElement>}\n *\n * @property {ReactNode} children - The content to display inside the tag\n * @property {TagColor} [color] - Color theme variant of the tag\n * @property {TagRoundedSize} [roundedSize] - Border radius size of the tag\n * @property {TagSize} [size] - Size variant affecting padding and font size\n * @property {TagBorder} [border] - Whether to show a border around the tag\n * @property {TagBackground} [background] - Background visibility option\n * @property [className] - Additional CSS classes for custom styling\n *\n * @example\n * ```tsx\n * // Basic tag\n * <Tag>Default Tag</Tag>\n *\n * // Success tag with border\n * <Tag color=\"success\" border=\"with\">\n * Success Status\n * </Tag>\n *\n * // Large warning tag\n * <Tag color=\"warning\" size=\"lg\">\n * Important Warning\n * </Tag>\n * ```\n */\ntype TagProps = PropsWithChildren<VariantProps<typeof containerVariants>> &\n HTMLAttributes<HTMLDivElement>;\n\n/**\n * Enumeration for tag border radius sizes\n *\n * Controls the roundedness of tag corners, from sharp edges to fully rounded pills.\n *\n * @enum TagRoundedSize\n * @property NONE - 'none' - No border radius (sharp corners)\n * @property SM - 'sm' - Small border radius (2px)\n * @property MD - 'md' - Medium border radius (6px)\n * @property LG - 'lg' - Large border radius (8px)\n * @property XL - 'xl' - Extra large border radius (12px)\n * @property XXL - '2xl' - 2x large border radius (16px)\n * @property XXXL - '3xl' - 3x large border radius (24px)\n * @property FULL - 'full' - Fully rounded (50% border radius, pill shape)\n *\n * @example\n * ```tsx\n * // Sharp corners\n * <Tag roundedSize=\"none\">Sharp Tag</Tag>\n *\n * // Pill-shaped tag\n * <Tag roundedSize=\"full\">Pill Tag</Tag>\n *\n * // Medium rounded corners\n * <Tag roundedSize=\"md\">Rounded Tag</Tag>\n * ```\n */\nexport type TagRoundedSize =\n | 'none'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | 'full';\n\n/**\n * Enumeration for tag color themes\n *\n * Provides semantic color options for different tag purposes and meanings.\n * Each color includes background, border, and text color variations.\n *\n * @enum TagColor\n * @property SUCCESS - 'success' - Green theme for positive states, success messages, or completed items\n * @property ERROR - 'error' - Red theme for error states, warnings, or failed operations\n * @property WARNING - 'warning' - Yellow/orange theme for caution, pending states, or important notices\n * @property NEUTRAL - 'neutral' - Gray theme for neutral information or secondary content\n * @property TEXT - 'text' - Default text color theme for general purpose tags\n *\n * @example\n * ```tsx\n * // Status indicators\n * <Tag color=\"success\">Completed</Tag>\n * <Tag color=\"error\">Failed</Tag>\n * <Tag color=\"warning\">Pending</Tag>\n *\n * // Category tags\n * <Tag color=\"neutral\">Category</Tag>\n * <Tag color=\"text\">General</Tag>\n * ```\n */\nexport type TagColor =\n | 'primary'\n | 'success'\n | 'error'\n | 'warning'\n | 'neutral'\n | 'text'\n | 'blue'\n | 'yellow'\n | 'green'\n | 'red'\n | 'orange'\n | 'purple'\n | 'pink'\n | 'brown'\n | 'gray'\n | 'black'\n | 'white';\n\n/**\n * Enumeration for tag size variants\n *\n * Controls the overall size of tags including padding, font size, and border thickness.\n * Sizes are designed to maintain visual hierarchy and readability.\n *\n * @enum TagSize\n * @property XS - 'xs' - Extra small (0.5rem padding, text-xs, 1.2px border)\n * @property SM - 'sm' - Small (0.5rem padding, text-sm, 1.5px border)\n * @property MD - 'md' - Medium (1rem padding, text-base, 2px border) - Default size\n * @property LG - 'lg' - Large (2rem padding, text-lg, 2px border)\n * @property XL - 'xl' - Extra large (4rem padding, text-xl, 2px border)\n *\n * @example\n * ```tsx\n * // Different sizes for hierarchy\n * <Tag size=\"xs\">Small detail</Tag>\n * <Tag size=\"sm\">Minor category</Tag>\n * <Tag size=\"md\">Standard tag</Tag>\n * <Tag size=\"lg\">Important label</Tag>\n * <Tag size=\"xl\">Hero tag</Tag>\n * ```\n */\nexport type TagSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\n/**\n * Enumeration for tag border visibility\n *\n * Controls whether a border is displayed around the tag.\n *\n * @enum TagBorder\n * @property NONE - 'none' - No border (default)\n * @property WITH - 'with' - Show border with 1.5px thickness\n *\n * @example\n * ```tsx\n * <Tag border=\"none\">Borderless</Tag>\n * <Tag border=\"with\">With Border</Tag>\n * ```\n */\nexport type TagBorder = 'none' | 'with';\n\n/**\n * Enumeration for tag background visibility\n *\n * Controls the background styling of the tag.\n *\n * @enum TagBackground\n * @property NONE - 'none' - No background styling\n * @property WITH - 'with' - Apply background styling\n *\n * @example\n * ```tsx\n * <Tag background=\"none\">No Background</Tag>\n * <Tag background=\"with\">With Background</Tag>\n * ```\n */\nexport type TagBackground = 'none' | 'with';\n\nconst containerVariants = cva('w-fit backdrop-blur', {\n variants: {\n roundedSize: {\n none: 'rounded-none',\n sm: 'rounded-sm',\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n [`${'xxl'}`]: 'rounded-2xl',\n [`${'xxxl'}`]: 'rounded-3xl',\n full: 'rounded-full',\n },\n color: {\n primary: 'border-primary bg-primary/10 text-primary',\n success: 'border-success bg-success/10 text-success',\n error: 'border-error bg-error/10 text-error',\n warning: 'border-warning bg-warning/10 text-warning',\n neutral: '/10 border-neutral bg-neutral/10 text-neutral',\n text: 'border-text bg-text/10 text-foreground',\n black: 'border-black bg-black/10 text-black',\n white: 'border-white bg-white/10 text-white',\n },\n size: {\n xs: 'border-[1.2px] px-2 py-0.5 text-xs',\n sm: 'border-[1.3px] px-2 py-0.5 text-sm',\n md: 'border-2 px-2 py-1 text-base',\n lg: 'border-2 px-3 py-2 text-lg',\n xl: 'border-2 px-3 py-2 text-xl',\n },\n border: {\n none: 'border-none',\n with: 'border-[1.3px] border-text',\n },\n background: {\n none: 'bg-none',\n with: '',\n },\n },\n\n defaultVariants: {\n roundedSize: 'full',\n border: 'none',\n color: 'text',\n size: 'md',\n },\n});\n\n/**\n * Tag component for displaying labels, categories, status indicators, and badges\n *\n * The Tag component is a versatile labeling element that supports multiple visual variants\n * for different use cases. It provides semantic color options, flexible sizing, and\n * customizable styling options for borders and backgrounds.\n *\n * ## Features\n * - **Semantic Colors**: Success, error, warning, neutral, and text color themes\n * - **Flexible Sizing**: Five size variants from extra small to extra large\n * - **Border Radius Options**: Eight rounding options from none to fully rounded\n * - **Border Control**: Optional borders for enhanced visual separation\n * - **Background Control**: Configurable background styling\n * - **Accessibility**: Proper HTML semantics and keyboard navigation support\n *\n * ## Use Cases\n * - **Status Indicators**: Show completion, error, or pending states\n * - **Category Labels**: Organize and categorize content\n * - **Badges**: Display counts, notifications, or achievements\n * - **Keywords**: Tag content with relevant keywords or topics\n * - **Metadata**: Show additional information like dates, authors, or types\n *\n * ## Design Principles\n * - Maintains readability across all size and color combinations\n * - Uses backdrop blur effect for subtle transparency\n * - Follows consistent spacing and typography scales\n * - Provides sufficient color contrast for accessibility\n *\n * @param {TagProps} props - The properties for the Tag component\n * @returns {JSX.Element} The rendered tag element\n *\n * @example\n * ```tsx\n * // Basic status tags\n * <Tag color=\"success\">Completed</Tag>\n * <Tag color=\"error\">Failed</Tag>\n * <Tag color=\"warning\">In Progress</Tag>\n *\n * // Category tags with borders\n * <Tag color=\"neutral\" border=\"with\">\n * Technology\n * </Tag>\n * <Tag color=\"text\" border=\"with\">\n * Design\n * </Tag>\n *\n * // Size variations for hierarchy\n * <div className=\"flex items-center gap-2\">\n * <Tag size=\"xs\" color=\"neutral\">Minor</Tag>\n * <Tag size=\"sm\" color=\"text\">Standard</Tag>\n * <Tag size=\"lg\" color=\"success\">Important</Tag>\n * </div>\n *\n * // Rounded variations\n * <div className=\"flex gap-2\">\n * <Tag roundedSize=\"none\">Sharp</Tag>\n * <Tag roundedSize=\"md\">Rounded</Tag>\n * <Tag roundedSize=\"full\">Pill</Tag>\n * </div>\n *\n * // Custom styled tag\n * <Tag\n * color=\"warning\"\n * size=\"lg\"\n * border=\"with\"\n * roundedSize=\"lg\"\n * className=\"font-bold uppercase tracking-wide\"\n * >\n * Custom Style\n * </Tag>\n *\n * // Interactive tags with click handlers\n * <Tag\n * color=\"success\"\n * onClick={() => console.log('Tag clicked')}\n * className=\"cursor-pointer hover:opacity-80 transition-opacity\"\n * >\n * Clickable Tag\n * </Tag>\n * ```\n *\n * @see {@link TagColor} - Available color theme options\n * @see {@link TagSize} - Available size variants\n * @see {@link TagRoundedSize} - Available border radius options\n * @see {@link TagBorder} - Border visibility options\n * @see {@link TagBackground} - Background styling options\n */\nexport const Tag: FC<TagProps> = ({\n children,\n color,\n roundedSize,\n size,\n border,\n background,\n className,\n ...props\n}) => {\n return (\n <div\n className={containerVariants({\n color,\n roundedSize,\n size,\n border,\n background,\n className,\n })}\n {...props}\n >\n {children}\n </div>\n );\n};\n"],"mappings":";;;;AAiLA,MAAM,oBAAoB,IAAI,uBAAuB;CACnD,UAAU;EACR,aAAa;GACX,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;IACH,QAAa;IACb,SAAc;GACf,MAAM;EACR;EACA,OAAO;GACL,SAAS;GACT,SAAS;GACT,OAAO;GACP,SAAS;GACT,SAAS;GACT,MAAM;GACN,OAAO;GACP,OAAO;EACT;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;EACA,QAAQ;GACN,MAAM;GACN,MAAM;EACR;EACA,YAAY;GACV,MAAM;GACN,MAAM;EACR;CACF;CAEA,iBAAiB;EACf,aAAa;EACb,QAAQ;EACR,OAAO;EACP,MAAM;CACR;AACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyFD,MAAa,OAAqB,EAChC,UACA,OACA,aACA,MACA,QACA,YACA,WACA,GAAG,YACC;CACJ,OACE,oBAAC,OAAD;EACE,WAAW,kBAAkB;GAC3B;GACA;GACA;GACA;GACA;GACA;EACF,CAAC;EACD,GAAI;EAEH;CACE;AAET"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Tag/index.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type { FC, HTMLAttributes, PropsWithChildren } from 'react';\n\n/**\n * Properties for the Tag component extending HTML div attributes and variant options\n *\n * @interface TagProps\n * @extends {PropsWithChildren<VariantProps<typeof containerVariants>>}\n * @extends {HTMLAttributes<HTMLDivElement>}\n *\n * @property {ReactNode} children - The content to display inside the tag\n * @property {TagColor} [color] - Color theme variant of the tag\n * @property {TagRoundedSize} [roundedSize] - Border radius size of the tag\n * @property {TagSize} [size] - Size variant affecting padding and font size\n * @property {TagBorder} [border] - Whether to show a border around the tag\n * @property {TagBackground} [background] - Background visibility option\n * @property [className] - Additional CSS classes for custom styling\n *\n * @example\n * ```tsx\n * // Basic tag\n * <Tag>Default Tag</Tag>\n *\n * // Success tag with border\n * <Tag color=\"success\" border=\"with\">\n * Success Status\n * </Tag>\n *\n * // Large warning tag\n * <Tag color=\"warning\" size=\"lg\">\n * Important Warning\n * </Tag>\n * ```\n */\ntype TagProps = PropsWithChildren<VariantProps<typeof containerVariants>> &\n HTMLAttributes<HTMLDivElement>;\n\n/**\n * Enumeration for tag border radius sizes\n *\n * Controls the roundedness of tag corners, from sharp edges to fully rounded pills.\n *\n * @enum TagRoundedSize\n * @property NONE - 'none' - No border radius (sharp corners)\n * @property SM - 'sm' - Small border radius (2px)\n * @property MD - 'md' - Medium border radius (6px)\n * @property LG - 'lg' - Large border radius (8px)\n * @property XL - 'xl' - Extra large border radius (12px)\n * @property XXL - '2xl' - 2x large border radius (16px)\n * @property XXXL - '3xl' - 3x large border radius (24px)\n * @property FULL - 'full' - Fully rounded (50% border radius, pill shape)\n *\n * @example\n * ```tsx\n * // Sharp corners\n * <Tag roundedSize=\"none\">Sharp Tag</Tag>\n *\n * // Pill-shaped tag\n * <Tag roundedSize=\"full\">Pill Tag</Tag>\n *\n * // Medium rounded corners\n * <Tag roundedSize=\"md\">Rounded Tag</Tag>\n * ```\n */\nexport type TagRoundedSize =\n | 'none'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | 'full';\n\n/**\n * Enumeration for tag color themes\n *\n * Provides semantic color options for different tag purposes and meanings.\n * Each color includes background, border, and text color variations.\n *\n * @enum TagColor\n * @property SUCCESS - 'success' - Green theme for positive states, success messages, or completed items\n * @property ERROR - 'error' - Red theme for error states, warnings, or failed operations\n * @property WARNING - 'warning' - Yellow/orange theme for caution, pending states, or important notices\n * @property NEUTRAL - 'neutral' - Gray theme for neutral information or secondary content\n * @property TEXT - 'text' - Default text color theme for general purpose tags\n *\n * @example\n * ```tsx\n * // Status indicators\n * <Tag color=\"success\">Completed</Tag>\n * <Tag color=\"error\">Failed</Tag>\n * <Tag color=\"warning\">Pending</Tag>\n *\n * // Category tags\n * <Tag color=\"neutral\">Category</Tag>\n * <Tag color=\"text\">General</Tag>\n * ```\n */\nexport type TagColor =\n | 'success'\n | 'error'\n | 'warning'\n | 'neutral'\n | 'text'\n | 'blue'\n | 'yellow'\n | 'green'\n | 'red'\n | 'orange'\n | 'purple'\n | 'pink'\n | 'brown'\n | 'gray'\n | 'black'\n | 'white';\n\n/**\n * Enumeration for tag size variants\n *\n * Controls the overall size of tags including padding, font size, and border thickness.\n * Sizes are designed to maintain visual hierarchy and readability.\n *\n * @enum TagSize\n * @property XS - 'xs' - Extra small (0.5rem padding, text-xs, 1.2px border)\n * @property SM - 'sm' - Small (0.5rem padding, text-sm, 1.5px border)\n * @property MD - 'md' - Medium (1rem padding, text-base, 2px border) - Default size\n * @property LG - 'lg' - Large (2rem padding, text-lg, 2px border)\n * @property XL - 'xl' - Extra large (4rem padding, text-xl, 2px border)\n *\n * @example\n * ```tsx\n * // Different sizes for hierarchy\n * <Tag size=\"xs\">Small detail</Tag>\n * <Tag size=\"sm\">Minor category</Tag>\n * <Tag size=\"md\">Standard tag</Tag>\n * <Tag size=\"lg\">Important label</Tag>\n * <Tag size=\"xl\">Hero tag</Tag>\n * ```\n */\nexport type TagSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\n/**\n * Enumeration for tag border visibility\n *\n * Controls whether a border is displayed around the tag.\n *\n * @enum TagBorder\n * @property NONE - 'none' - No border (default)\n * @property WITH - 'with' - Show border with 1.5px thickness\n *\n * @example\n * ```tsx\n * <Tag border=\"none\">Borderless</Tag>\n * <Tag border=\"with\">With Border</Tag>\n * ```\n */\nexport type TagBorder = 'none' | 'with';\n\n/**\n * Enumeration for tag background visibility\n *\n * Controls the background styling of the tag.\n *\n * @enum TagBackground\n * @property NONE - 'none' - No background styling\n * @property WITH - 'with' - Apply background styling\n *\n * @example\n * ```tsx\n * <Tag background=\"none\">No Background</Tag>\n * <Tag background=\"with\">With Background</Tag>\n * ```\n */\nexport type TagBackground = 'none' | 'with';\n\nconst containerVariants = cva('w-fit backdrop-blur', {\n variants: {\n roundedSize: {\n none: 'rounded-none',\n sm: 'rounded-sm',\n md: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n [`${'xxl'}`]: 'rounded-2xl',\n [`${'xxxl'}`]: 'rounded-3xl',\n full: 'rounded-full',\n },\n color: {\n success: 'border-success bg-success/10 text-success',\n error: 'border-error bg-error/10 text-error',\n warning: 'border-warning bg-warning/10 text-warning',\n neutral: '/10 border-neutral bg-neutral/10 text-neutral',\n text: 'border-text bg-text/10 text-foreground',\n black: 'border-black bg-black/10 text-black',\n white: 'border-white bg-white/10 text-white',\n },\n size: {\n xs: 'border-[1.2px] px-2 py-0.5 text-xs',\n sm: 'border-[1.3px] px-2 py-0.5 text-sm',\n md: 'border-2 px-2 py-1 text-base',\n lg: 'border-2 px-3 py-2 text-lg',\n xl: 'border-2 px-3 py-2 text-xl',\n },\n border: {\n none: 'border-none',\n with: 'border-[1.3px] border-text',\n },\n background: {\n none: 'bg-none',\n with: '',\n },\n },\n\n defaultVariants: {\n roundedSize: 'full',\n border: 'none',\n color: 'text',\n size: 'md',\n },\n});\n\n/**\n * Tag component for displaying labels, categories, status indicators, and badges\n *\n * The Tag component is a versatile labeling element that supports multiple visual variants\n * for different use cases. It provides semantic color options, flexible sizing, and\n * customizable styling options for borders and backgrounds.\n *\n * ## Features\n * - **Semantic Colors**: Success, error, warning, neutral, and text color themes\n * - **Flexible Sizing**: Five size variants from extra small to extra large\n * - **Border Radius Options**: Eight rounding options from none to fully rounded\n * - **Border Control**: Optional borders for enhanced visual separation\n * - **Background Control**: Configurable background styling\n * - **Accessibility**: Proper HTML semantics and keyboard navigation support\n *\n * ## Use Cases\n * - **Status Indicators**: Show completion, error, or pending states\n * - **Category Labels**: Organize and categorize content\n * - **Badges**: Display counts, notifications, or achievements\n * - **Keywords**: Tag content with relevant keywords or topics\n * - **Metadata**: Show additional information like dates, authors, or types\n *\n * ## Design Principles\n * - Maintains readability across all size and color combinations\n * - Uses backdrop blur effect for subtle transparency\n * - Follows consistent spacing and typography scales\n * - Provides sufficient color contrast for accessibility\n *\n * @param {TagProps} props - The properties for the Tag component\n * @returns {JSX.Element} The rendered tag element\n *\n * @example\n * ```tsx\n * // Basic status tags\n * <Tag color=\"success\">Completed</Tag>\n * <Tag color=\"error\">Failed</Tag>\n * <Tag color=\"warning\">In Progress</Tag>\n *\n * // Category tags with borders\n * <Tag color=\"neutral\" border=\"with\">\n * Technology\n * </Tag>\n * <Tag color=\"text\" border=\"with\">\n * Design\n * </Tag>\n *\n * // Size variations for hierarchy\n * <div className=\"flex items-center gap-2\">\n * <Tag size=\"xs\" color=\"neutral\">Minor</Tag>\n * <Tag size=\"sm\" color=\"text\">Standard</Tag>\n * <Tag size=\"lg\" color=\"success\">Important</Tag>\n * </div>\n *\n * // Rounded variations\n * <div className=\"flex gap-2\">\n * <Tag roundedSize=\"none\">Sharp</Tag>\n * <Tag roundedSize=\"md\">Rounded</Tag>\n * <Tag roundedSize=\"full\">Pill</Tag>\n * </div>\n *\n * // Custom styled tag\n * <Tag\n * color=\"warning\"\n * size=\"lg\"\n * border=\"with\"\n * roundedSize=\"lg\"\n * className=\"font-bold uppercase tracking-wide\"\n * >\n * Custom Style\n * </Tag>\n *\n * // Interactive tags with click handlers\n * <Tag\n * color=\"success\"\n * onClick={() => console.log('Tag clicked')}\n * className=\"cursor-pointer hover:opacity-80 transition-opacity\"\n * >\n * Clickable Tag\n * </Tag>\n * ```\n *\n * @see {@link TagColor} - Available color theme options\n * @see {@link TagSize} - Available size variants\n * @see {@link TagRoundedSize} - Available border radius options\n * @see {@link TagBorder} - Border visibility options\n * @see {@link TagBackground} - Background styling options\n */\nexport const Tag: FC<TagProps> = ({\n children,\n color,\n roundedSize,\n size,\n border,\n background,\n className,\n ...props\n}) => {\n return (\n <div\n className={containerVariants({\n color,\n roundedSize,\n size,\n border,\n background,\n className,\n })}\n {...props}\n >\n {children}\n </div>\n );\n};\n"],"mappings":";;;;AAgLA,MAAM,oBAAoB,IAAI,uBAAuB;CACnD,UAAU;EACR,aAAa;GACX,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;IACH,QAAa;IACb,SAAc;GACf,MAAM;EACR;EACA,OAAO;GACL,SAAS;GACT,OAAO;GACP,SAAS;GACT,SAAS;GACT,MAAM;GACN,OAAO;GACP,OAAO;EACT;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;EACN;EACA,QAAQ;GACN,MAAM;GACN,MAAM;EACR;EACA,YAAY;GACV,MAAM;GACN,MAAM;EACR;CACF;CAEA,iBAAiB;EACf,aAAa;EACb,QAAQ;EACR,OAAO;EACP,MAAM;CACR;AACF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyFD,MAAa,OAAqB,EAChC,UACA,OACA,aACA,MACA,QACA,YACA,WACA,GAAG,YACC;CACJ,OACE,oBAAC,OAAD;EACE,WAAW,kBAAkB;GAC3B;GACA;GACA;GACA;GACA;GACA;EACF,CAAC;EACD,GAAI;EAEH;CACE;AAET"}
|
package/dist/esm/hooks/index.mjs
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useItemSelector } from "./useItemSelector.mjs";
|
|
3
|
-
import { usePersistedStore } from "./usePersistedStore.mjs";
|
|
4
|
-
import { useGetElementById } from "./useGetElementById.mjs";
|
|
1
|
+
import { useKeyboardDetector } from "./useKeyboardDetector.mjs";
|
|
5
2
|
import { useGetElementOrWindow } from "./useGetElementOrWindow.mjs";
|
|
3
|
+
import { useScrollY } from "./useScrollY.mjs";
|
|
4
|
+
import { usePersistedStore } from "./usePersistedStore.mjs";
|
|
6
5
|
import { useHorizontalSwipe } from "./useHorizontalSwipe.mjs";
|
|
6
|
+
import { useItemSelector } from "./useItemSelector.mjs";
|
|
7
|
+
import { NO_HIGHLIGHTED_INDEX, useListKeyboardNavigation } from "./useListKeyboardNavigation.mjs";
|
|
8
|
+
import { calculateIsMobile, checkIsIOS, checkIsIphoneOrSafariDevice, checkIsMac, checkIsMobileScreen, checkIsMobileUserAgent, getBreakpointFromSize, useDevice } from "./useDevice.mjs";
|
|
9
|
+
import { useSearch } from "./useSearch.mjs";
|
|
7
10
|
import { useIsMounted } from "./useIsMounted.mjs";
|
|
8
|
-
import {
|
|
11
|
+
import { useGetElementById } from "./useGetElementById.mjs";
|
|
9
12
|
import { useScreenWidth } from "./useScreenWidth.mjs";
|
|
10
13
|
import { useScrollBlockage } from "./useScrollBlockage/index.mjs";
|
|
11
14
|
import { useScrollDetection } from "./useScrollDetection.mjs";
|
|
12
|
-
import { useScrollY } from "./useScrollY.mjs";
|
|
13
|
-
import { useSearch } from "./useSearch.mjs";
|
|
14
15
|
import { useStickToBottom } from "./useStickToBottom.mjs";
|
|
15
16
|
|
|
16
|
-
export { calculateIsMobile, checkIsIOS, checkIsIphoneOrSafariDevice, checkIsMac, checkIsMobileScreen, checkIsMobileUserAgent, getBreakpointFromSize, useDevice, useGetElementById, useGetElementOrWindow, useHorizontalSwipe, useIsMounted, useItemSelector, useKeyboardDetector, usePersistedStore, useScreenWidth, useScrollBlockage, useScrollDetection, useScrollY, useSearch, useStickToBottom };
|
|
17
|
+
export { NO_HIGHLIGHTED_INDEX, calculateIsMobile, checkIsIOS, checkIsIphoneOrSafariDevice, checkIsMac, checkIsMobileScreen, checkIsMobileUserAgent, getBreakpointFromSize, useDevice, useGetElementById, useGetElementOrWindow, useHorizontalSwipe, useIsMounted, useItemSelector, useKeyboardDetector, useListKeyboardNavigation, usePersistedStore, useScreenWidth, useScrollBlockage, useScrollDetection, useScrollY, useSearch, useStickToBottom };
|