@intlayer/design-system 8.9.6 → 8.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/esm/components/Avatar/index.mjs +1 -1
  2. package/dist/esm/components/Avatar/index.mjs.map +1 -1
  3. package/dist/esm/components/Container/index.mjs +1 -1
  4. package/dist/esm/components/Container/index.mjs.map +1 -1
  5. package/dist/esm/components/DictionaryFieldEditor/NavigationView/NavigationViewNode.mjs +1 -1
  6. package/dist/esm/components/Input/OTPInput.mjs +1 -1
  7. package/dist/esm/components/Input/OTPInput.mjs.map +1 -1
  8. package/dist/esm/components/Pagination/Pagination.mjs +8 -5
  9. package/dist/esm/components/Pagination/Pagination.mjs.map +1 -1
  10. package/dist/esm/components/TechLogo/logos/Atlassian.mjs +22 -0
  11. package/dist/esm/components/TechLogo/logos/Atlassian.mjs.map +1 -0
  12. package/dist/esm/components/TechLogo/logos/Microsoft.mjs +44 -0
  13. package/dist/esm/components/TechLogo/logos/Microsoft.mjs.map +1 -0
  14. package/dist/esm/components/TechLogo/techLogos.mjs +5 -1
  15. package/dist/esm/components/TechLogo/techLogos.mjs.map +1 -1
  16. package/dist/esm/components/Toaster/Toast.mjs +2 -2
  17. package/dist/esm/components/Toaster/Toast.mjs.map +1 -1
  18. package/dist/esm/components/Toaster/index.mjs +2 -2
  19. package/dist/esm/components/index.mjs +2 -2
  20. package/dist/esm/hooks/index.mjs +2 -2
  21. package/dist/esm/hooks/reactQuery.mjs +36 -7
  22. package/dist/esm/hooks/reactQuery.mjs.map +1 -1
  23. package/dist/esm/hooks/useAuth/useOAuth2.mjs +1 -1
  24. package/dist/esm/hooks/useAuth/useSession.mjs +1 -1
  25. package/dist/types/components/Avatar/index.d.ts +1 -1
  26. package/dist/types/components/Badge/index.d.ts +1 -1
  27. package/dist/types/components/Button/Button.d.ts +4 -4
  28. package/dist/types/components/CollapsibleTable/CollapsibleTable.d.ts +2 -2
  29. package/dist/types/components/Command/index.d.ts +2 -2
  30. package/dist/types/components/Container/index.d.ts +6 -6
  31. package/dist/types/components/Input/Checkbox.d.ts +1 -1
  32. package/dist/types/components/Link/Link.d.ts +3 -3
  33. package/dist/types/components/Pagination/Pagination.d.ts +1 -1
  34. package/dist/types/components/SwitchSelector/SwitchSelector.d.ts +2 -2
  35. package/dist/types/components/SwitchSelector/VerticalSwitchSelector.d.ts +1 -1
  36. package/dist/types/components/TabSelector/TabSelector.d.ts +1 -1
  37. package/dist/types/components/Tag/index.d.ts +2 -2
  38. package/dist/types/components/TechLogo/logos/Atlassian.d.ts +7 -0
  39. package/dist/types/components/TechLogo/logos/Atlassian.d.ts.map +1 -0
  40. package/dist/types/components/TechLogo/logos/Microsoft.d.ts +7 -0
  41. package/dist/types/components/TechLogo/logos/Microsoft.d.ts.map +1 -0
  42. package/dist/types/components/TechLogo/techLogos.d.ts +4 -2
  43. package/dist/types/components/Toaster/Toast.d.ts +1 -1
  44. package/dist/types/components/Toaster/Toast.d.ts.map +1 -1
  45. package/dist/types/components/Toaster/index.d.ts +2 -2
  46. package/dist/types/components/index.d.ts +2 -2
  47. package/dist/types/hooks/index.d.ts +2 -2
  48. package/dist/types/hooks/reactQuery.d.ts +4 -1
  49. package/dist/types/hooks/reactQuery.d.ts.map +1 -1
  50. package/package.json +15 -15
@@ -85,7 +85,7 @@ const Avatar = ({ fullname, className, isLoading = false, isLoggedIn = true, src
85
85
  ]);
86
86
  return /* @__PURE__ */ jsx(Container, {
87
87
  isClickable,
88
- className: cn(`rounded-full border-[1.3px] border-text p-[1.5px]`, size === "sm" && "size-7 border-[1px] p-[1px]", size === "md" && "size-9", size === "lg" && "size-12", size === "xl" && "size-16", isClickable && `cursor-pointer hover:opacity-80 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`, !isClickable && focusable && `focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`, displayLoader && "animate-pulse", className),
88
+ className: cn(`rounded-full border-[1.3px] border-text p-[1.5px]`, size === "sm" && "size-7 border-[1px] p-[1px]", size === "md" && "size-9", size === "lg" && "size-12", size === "xl" && "size-16", size === "2xl" && "size-24", isClickable && `cursor-pointer hover:opacity-80 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`, !isClickable && focusable && `focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`, displayLoader && "animate-pulse", className),
89
89
  onClick,
90
90
  ...accessibilityProps,
91
91
  ...props,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Avatar/index.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { User } from 'lucide-react';\nimport type { ComponentProps, FC, HTMLAttributes } from 'react';\nimport { useMemo } from 'react';\nimport { Loader } from '../Loader';\n\n/**\n * Props for the Avatar component\n */\nexport interface AvatarProps extends Omit<ComponentProps<'button'>, 'onClick'> {\n /** Image source URL for the avatar */\n src?: string;\n /** Full name used to generate initials and alt text */\n fullname?: string;\n /** Displays a loading spinner when true */\n isLoading?: boolean;\n /** Whether the user is authenticated */\n isLoggedIn?: boolean;\n /** Size variant of the avatar */\n size?: 'sm' | 'md' | 'lg' | 'xl';\n /** Click handler - when provided, makes the avatar clickable */\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n /** Alternative text for accessibility */\n alt?: string;\n /** Whether the avatar should be focusable when not clickable */\n focusable?: boolean;\n}\n\n/**\n * @description Gets the capital letters from a name.\n * @param name - The name to extract capitals from.\n * @param separator - The separator to split the name (default is an empty string, which splits by each character).\n * @returns {string[]} An array of capital letters from the name.\n */\nexport const getCapitals = (name: string, separator = ' '): string[] => {\n if (!name) return [];\n\n const parts =\n separator === ' '\n ? name.trim().split(/\\s+/) // handle multiple spaces\n : name.split(separator);\n\n return parts.filter(Boolean).map((word) => word.charAt(0).toUpperCase());\n};\n\n/**\n * Container component that renders either a button or div based on interactivity\n */\nconst Container: FC<\n HTMLAttributes<HTMLElement> & {\n isClickable: boolean;\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n }\n> = ({ isClickable, onClick, ...props }) => {\n if (isClickable && onClick) {\n return (\n <button\n {...(props as ComponentProps<'button'>)}\n onClick={onClick}\n type=\"button\"\n />\n );\n }\n\n return (\n <div\n {...(props as ComponentProps<'div'>)}\n role={\n props.tabIndex !== undefined || props['aria-label'] ? 'img' : undefined\n }\n />\n );\n};\n\n/**\n * Avatar component that displays user profile images, initials, or a default user icon.\n * Supports loading states, authentication states, and accessibility features.\n *\n * @example\n * ```tsx\n * // With image\n * <Avatar src=\"https://example.com/avatar.jpg\" fullname=\"John Doe\" />\n *\n * // With initials\n * <Avatar fullname=\"John Doe\" />\n *\n * // Clickable avatar\n * <Avatar\n * fullname=\"John Doe\"\n * onClick={(e) => console.log('Avatar clicked')}\n * />\n *\n * // Loading state\n * <Avatar isLoading fullname=\"John Doe\" />\n * ```\n */\nexport const Avatar: FC<AvatarProps> = ({\n fullname,\n className,\n isLoading = false,\n isLoggedIn = true,\n src,\n onClick,\n size = 'md',\n alt,\n focusable = false,\n ...props\n}) => {\n const isImageDefined = Boolean(src);\n const isNameDefined = Boolean((fullname ?? '').length > 0);\n const capitals = fullname ? getCapitals(fullname) : undefined;\n\n // Display logic\n const displayLoader = isLoading;\n const displayAvatar = isLoggedIn && !displayLoader && isImageDefined;\n const displayInitials =\n isLoggedIn && !displayLoader && !displayAvatar && isNameDefined;\n const displayUserIcon =\n isLoggedIn && !displayLoader && !displayAvatar && !displayInitials;\n\n const isClickable = onClick !== undefined;\n\n // Accessibility attributes\n const accessibilityProps = useMemo(() => {\n const baseProps: Record<string, any> = {};\n\n if (displayAvatar && alt) {\n baseProps['aria-label'] = alt;\n } else if (displayAvatar && fullname) {\n baseProps['aria-label'] = `Avatar of ${fullname}`;\n } else if (displayInitials && fullname) {\n baseProps['aria-label'] = `Avatar initials for ${fullname}`;\n } else if (displayUserIcon) {\n baseProps['aria-label'] = 'Default user avatar';\n } else if (displayLoader) {\n baseProps['aria-label'] = 'Loading avatar';\n baseProps['aria-busy'] = true;\n }\n\n if (!isClickable && focusable) {\n baseProps.tabIndex = 0;\n }\n\n if (isClickable) {\n baseProps['aria-describedby'] = 'avatar-description';\n }\n\n return baseProps;\n }, [\n displayAvatar,\n displayInitials,\n displayUserIcon,\n displayLoader,\n alt,\n fullname,\n isClickable,\n focusable,\n ]);\n\n return (\n <Container\n isClickable={isClickable}\n className={cn(\n `rounded-full border-[1.3px] border-text p-[1.5px]`,\n size === 'sm' && 'size-7 border-[1px] p-[1px]',\n size === 'md' && 'size-9',\n size === 'lg' && 'size-12',\n size === 'xl' && 'size-16',\n isClickable &&\n `cursor-pointer hover:opacity-80 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`,\n !isClickable &&\n focusable &&\n `focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`,\n displayLoader && 'animate-pulse',\n className\n )}\n onClick={onClick}\n {...accessibilityProps}\n {...props}\n >\n <div className=\"relative flex size-full flex-row items-center justify-center\">\n <div className=\"absolute top-0 left-0 flex size-full flex-col items-center justify-center rounded-full bg-text text-text-opposite\">\n {displayLoader && (\n <Loader className=\"w-3/4\" aria-label=\"Loading user avatar\" />\n )}\n\n {displayAvatar && (\n <img\n className=\"size-full rounded-full object-cover\"\n src={src}\n srcSet={src}\n alt={alt ?? `Avatar of ${fullname}`}\n width={59}\n height={59}\n loading=\"lazy\"\n draggable={false}\n />\n )}\n\n {displayInitials && (\n <div className=\"flex size-full items-center justify-center gap-[0.1rem] font-bold text-sm max-md:py-1\">\n {capitals?.map((capital, index) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: Capitals are primitives and order is fixed\n <span key={`${capital}-${index}`}>{capital}</span>\n ))}\n </div>\n )}\n\n {displayUserIcon && (\n <User\n size={cn(\n size === 'sm' && 14,\n size === 'md' && 25,\n size === 'lg' && 30,\n size === 'xl' && 40\n )}\n aria-label=\"Default user icon\"\n />\n )}\n </div>\n </div>\n </Container>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AAkCA,MAAa,eAAe,MAAc,YAAY,QAAkB;CACtE,IAAI,CAAC,MAAM,OAAO,EAAE;CAOpB,QAJE,cAAc,MACV,KAAK,MAAM,CAAC,MAAM,MAAM,GACxB,KAAK,MAAM,UAAU,EAEd,OAAO,QAAQ,CAAC,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,aAAa,CAAC;;;;;AAM1E,MAAM,aAKD,EAAE,aAAa,SAAS,GAAG,YAAY;CAC1C,IAAI,eAAe,SACjB,OACE,oBAAC,UAAD;EACE,GAAK;EACI;EACT,MAAK;EACL;CAIN,OACE,oBAAC,OAAD;EACE,GAAK;EACL,MACE,MAAM,aAAa,UAAa,MAAM,gBAAgB,QAAQ;EAEhE;;;;;;;;;;;;;;;;;;;;;;;;AA0BN,MAAa,UAA2B,EACtC,UACA,WACA,YAAY,OACZ,aAAa,MACb,KACA,SACA,OAAO,MACP,KACA,YAAY,OACZ,GAAG,YACC;CACJ,MAAM,iBAAiB,QAAQ,IAAI;CACnC,MAAM,gBAAgB,SAAS,YAAY,IAAI,SAAS,EAAE;CAC1D,MAAM,WAAW,WAAW,YAAY,SAAS,GAAG;CAGpD,MAAM,gBAAgB;CACtB,MAAM,gBAAgB,cAAc,CAAC,iBAAiB;CACtD,MAAM,kBACJ,cAAc,CAAC,iBAAiB,CAAC,iBAAiB;CACpD,MAAM,kBACJ,cAAc,CAAC,iBAAiB,CAAC,iBAAiB,CAAC;CAErD,MAAM,cAAc,YAAY;CAGhC,MAAM,qBAAqB,cAAc;EACvC,MAAM,YAAiC,EAAE;EAEzC,IAAI,iBAAiB,KACnB,UAAU,gBAAgB;OACrB,IAAI,iBAAiB,UAC1B,UAAU,gBAAgB,aAAa;OAClC,IAAI,mBAAmB,UAC5B,UAAU,gBAAgB,uBAAuB;OAC5C,IAAI,iBACT,UAAU,gBAAgB;OACrB,IAAI,eAAe;GACxB,UAAU,gBAAgB;GAC1B,UAAU,eAAe;;EAG3B,IAAI,CAAC,eAAe,WAClB,UAAU,WAAW;EAGvB,IAAI,aACF,UAAU,sBAAsB;EAGlC,OAAO;IACN;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,OACE,oBAAC,WAAD;EACe;EACb,WAAW,GACT,qDACA,SAAS,QAAQ,+BACjB,SAAS,QAAQ,UACjB,SAAS,QAAQ,WACjB,SAAS,QAAQ,WACjB,eACE,2GACF,CAAC,eACC,aACA,2EACF,iBAAiB,iBACjB,UACD;EACQ;EACT,GAAI;EACJ,GAAI;YAEJ,oBAAC,OAAD;GAAK,WAAU;aACb,qBAAC,OAAD;IAAK,WAAU;cAAf;KACG,iBACC,oBAAC,QAAD;MAAQ,WAAU;MAAQ,cAAW;MAAwB;KAG9D,iBACC,oBAAC,OAAD;MACE,WAAU;MACL;MACL,QAAQ;MACR,KAAK,OAAO,aAAa;MACzB,OAAO;MACP,QAAQ;MACR,SAAQ;MACR,WAAW;MACX;KAGH,mBACC,oBAAC,OAAD;MAAK,WAAU;gBACZ,UAAU,KAAK,SAAS,UAEvB,oBAAC,QAAD,YAAmC,SAAe,EAAvC,GAAG,QAAQ,GAAG,QAAyB,CAClD;MACE;KAGP,mBACC,oBAAC,MAAD;MACE,MAAM,GACJ,SAAS,QAAQ,IACjB,SAAS,QAAQ,IACjB,SAAS,QAAQ,IACjB,SAAS,QAAQ,GAClB;MACD,cAAW;MACX;KAEA;;GACF;EACI"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Avatar/index.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { User } from 'lucide-react';\nimport type { ComponentProps, FC, HTMLAttributes } from 'react';\nimport { useMemo } from 'react';\nimport { Loader } from '../Loader';\n\n/**\n * Props for the Avatar component\n */\nexport interface AvatarProps extends Omit<ComponentProps<'button'>, 'onClick'> {\n /** Image source URL for the avatar */\n src?: string;\n /** Full name used to generate initials and alt text */\n fullname?: string;\n /** Displays a loading spinner when true */\n isLoading?: boolean;\n /** Whether the user is authenticated */\n isLoggedIn?: boolean;\n /** Size variant of the avatar */\n size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl';\n /** Click handler - when provided, makes the avatar clickable */\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n /** Alternative text for accessibility */\n alt?: string;\n /** Whether the avatar should be focusable when not clickable */\n focusable?: boolean;\n}\n\n/**\n * @description Gets the capital letters from a name.\n * @param name - The name to extract capitals from.\n * @param separator - The separator to split the name (default is an empty string, which splits by each character).\n * @returns {string[]} An array of capital letters from the name.\n */\nexport const getCapitals = (name: string, separator = ' '): string[] => {\n if (!name) return [];\n\n const parts =\n separator === ' '\n ? name.trim().split(/\\s+/) // handle multiple spaces\n : name.split(separator);\n\n return parts.filter(Boolean).map((word) => word.charAt(0).toUpperCase());\n};\n\n/**\n * Container component that renders either a button or div based on interactivity\n */\nconst Container: FC<\n HTMLAttributes<HTMLElement> & {\n isClickable: boolean;\n onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n }\n> = ({ isClickable, onClick, ...props }) => {\n if (isClickable && onClick) {\n return (\n <button\n {...(props as ComponentProps<'button'>)}\n onClick={onClick}\n type=\"button\"\n />\n );\n }\n\n return (\n <div\n {...(props as ComponentProps<'div'>)}\n role={\n props.tabIndex !== undefined || props['aria-label'] ? 'img' : undefined\n }\n />\n );\n};\n\n/**\n * Avatar component that displays user profile images, initials, or a default user icon.\n * Supports loading states, authentication states, and accessibility features.\n *\n * @example\n * ```tsx\n * // With image\n * <Avatar src=\"https://example.com/avatar.jpg\" fullname=\"John Doe\" />\n *\n * // With initials\n * <Avatar fullname=\"John Doe\" />\n *\n * // Clickable avatar\n * <Avatar\n * fullname=\"John Doe\"\n * onClick={(e) => console.log('Avatar clicked')}\n * />\n *\n * // Loading state\n * <Avatar isLoading fullname=\"John Doe\" />\n * ```\n */\nexport const Avatar: FC<AvatarProps> = ({\n fullname,\n className,\n isLoading = false,\n isLoggedIn = true,\n src,\n onClick,\n size = 'md',\n alt,\n focusable = false,\n ...props\n}) => {\n const isImageDefined = Boolean(src);\n const isNameDefined = Boolean((fullname ?? '').length > 0);\n const capitals = fullname ? getCapitals(fullname) : undefined;\n\n // Display logic\n const displayLoader = isLoading;\n const displayAvatar = isLoggedIn && !displayLoader && isImageDefined;\n const displayInitials =\n isLoggedIn && !displayLoader && !displayAvatar && isNameDefined;\n const displayUserIcon =\n isLoggedIn && !displayLoader && !displayAvatar && !displayInitials;\n\n const isClickable = onClick !== undefined;\n\n // Accessibility attributes\n const accessibilityProps = useMemo(() => {\n const baseProps: Record<string, any> = {};\n\n if (displayAvatar && alt) {\n baseProps['aria-label'] = alt;\n } else if (displayAvatar && fullname) {\n baseProps['aria-label'] = `Avatar of ${fullname}`;\n } else if (displayInitials && fullname) {\n baseProps['aria-label'] = `Avatar initials for ${fullname}`;\n } else if (displayUserIcon) {\n baseProps['aria-label'] = 'Default user avatar';\n } else if (displayLoader) {\n baseProps['aria-label'] = 'Loading avatar';\n baseProps['aria-busy'] = true;\n }\n\n if (!isClickable && focusable) {\n baseProps.tabIndex = 0;\n }\n\n if (isClickable) {\n baseProps['aria-describedby'] = 'avatar-description';\n }\n\n return baseProps;\n }, [\n displayAvatar,\n displayInitials,\n displayUserIcon,\n displayLoader,\n alt,\n fullname,\n isClickable,\n focusable,\n ]);\n\n return (\n <Container\n isClickable={isClickable}\n className={cn(\n `rounded-full border-[1.3px] border-text p-[1.5px]`,\n size === 'sm' && 'size-7 border-[1px] p-[1px]',\n size === 'md' && 'size-9',\n size === 'lg' && 'size-12',\n size === 'xl' && 'size-16',\n size === '2xl' && 'size-24',\n isClickable &&\n `cursor-pointer hover:opacity-80 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`,\n !isClickable &&\n focusable &&\n `focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2`,\n displayLoader && 'animate-pulse',\n className\n )}\n onClick={onClick}\n {...accessibilityProps}\n {...props}\n >\n <div className=\"relative flex size-full flex-row items-center justify-center\">\n <div className=\"absolute top-0 left-0 flex size-full flex-col items-center justify-center rounded-full bg-text text-text-opposite\">\n {displayLoader && (\n <Loader className=\"w-3/4\" aria-label=\"Loading user avatar\" />\n )}\n\n {displayAvatar && (\n <img\n className=\"size-full rounded-full object-cover\"\n src={src}\n srcSet={src}\n alt={alt ?? `Avatar of ${fullname}`}\n width={59}\n height={59}\n loading=\"lazy\"\n draggable={false}\n />\n )}\n\n {displayInitials && (\n <div className=\"flex size-full items-center justify-center gap-[0.1rem] font-bold text-sm max-md:py-1\">\n {capitals?.map((capital, index) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: Capitals are primitives and order is fixed\n <span key={`${capital}-${index}`}>{capital}</span>\n ))}\n </div>\n )}\n\n {displayUserIcon && (\n <User\n size={cn(\n size === 'sm' && 14,\n size === 'md' && 25,\n size === 'lg' && 30,\n size === 'xl' && 40\n )}\n aria-label=\"Default user icon\"\n />\n )}\n </div>\n </div>\n </Container>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AAkCA,MAAa,eAAe,MAAc,YAAY,QAAkB;CACtE,IAAI,CAAC,MAAM,OAAO,EAAE;CAOpB,QAJE,cAAc,MACV,KAAK,MAAM,CAAC,MAAM,MAAM,GACxB,KAAK,MAAM,UAAU,EAEd,OAAO,QAAQ,CAAC,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,aAAa,CAAC;;;;;AAM1E,MAAM,aAKD,EAAE,aAAa,SAAS,GAAG,YAAY;CAC1C,IAAI,eAAe,SACjB,OACE,oBAAC,UAAD;EACE,GAAK;EACI;EACT,MAAK;EACL;CAIN,OACE,oBAAC,OAAD;EACE,GAAK;EACL,MACE,MAAM,aAAa,UAAa,MAAM,gBAAgB,QAAQ;EAEhE;;;;;;;;;;;;;;;;;;;;;;;;AA0BN,MAAa,UAA2B,EACtC,UACA,WACA,YAAY,OACZ,aAAa,MACb,KACA,SACA,OAAO,MACP,KACA,YAAY,OACZ,GAAG,YACC;CACJ,MAAM,iBAAiB,QAAQ,IAAI;CACnC,MAAM,gBAAgB,SAAS,YAAY,IAAI,SAAS,EAAE;CAC1D,MAAM,WAAW,WAAW,YAAY,SAAS,GAAG;CAGpD,MAAM,gBAAgB;CACtB,MAAM,gBAAgB,cAAc,CAAC,iBAAiB;CACtD,MAAM,kBACJ,cAAc,CAAC,iBAAiB,CAAC,iBAAiB;CACpD,MAAM,kBACJ,cAAc,CAAC,iBAAiB,CAAC,iBAAiB,CAAC;CAErD,MAAM,cAAc,YAAY;CAGhC,MAAM,qBAAqB,cAAc;EACvC,MAAM,YAAiC,EAAE;EAEzC,IAAI,iBAAiB,KACnB,UAAU,gBAAgB;OACrB,IAAI,iBAAiB,UAC1B,UAAU,gBAAgB,aAAa;OAClC,IAAI,mBAAmB,UAC5B,UAAU,gBAAgB,uBAAuB;OAC5C,IAAI,iBACT,UAAU,gBAAgB;OACrB,IAAI,eAAe;GACxB,UAAU,gBAAgB;GAC1B,UAAU,eAAe;;EAG3B,IAAI,CAAC,eAAe,WAClB,UAAU,WAAW;EAGvB,IAAI,aACF,UAAU,sBAAsB;EAGlC,OAAO;IACN;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,OACE,oBAAC,WAAD;EACe;EACb,WAAW,GACT,qDACA,SAAS,QAAQ,+BACjB,SAAS,QAAQ,UACjB,SAAS,QAAQ,WACjB,SAAS,QAAQ,WACjB,SAAS,SAAS,WAClB,eACE,2GACF,CAAC,eACC,aACA,2EACF,iBAAiB,iBACjB,UACD;EACQ;EACT,GAAI;EACJ,GAAI;YAEJ,oBAAC,OAAD;GAAK,WAAU;aACb,qBAAC,OAAD;IAAK,WAAU;cAAf;KACG,iBACC,oBAAC,QAAD;MAAQ,WAAU;MAAQ,cAAW;MAAwB;KAG9D,iBACC,oBAAC,OAAD;MACE,WAAU;MACL;MACL,QAAQ;MACR,KAAK,OAAO,aAAa;MACzB,OAAO;MACP,QAAQ;MACR,SAAQ;MACR,WAAW;MACX;KAGH,mBACC,oBAAC,OAAD;MAAK,WAAU;gBACZ,UAAU,KAAK,SAAS,UAEvB,oBAAC,QAAD,YAAmC,SAAe,EAAvC,GAAG,QAAQ,GAAG,QAAyB,CAClD;MACE;KAGP,mBACC,oBAAC,MAAD;MACE,MAAM,GACJ,SAAS,QAAQ,IACjB,SAAS,QAAQ,IACjB,SAAS,QAAQ,IACjB,SAAS,QAAQ,GAClB;MACD,cAAW;MACX;KAEA;;GACF;EACI"}
@@ -58,7 +58,7 @@ const containerVariants = cva("flex flex-col text-text backdrop-blur", {
58
58
  success: "border-success"
59
59
  },
60
60
  background: {
61
- none: "",
61
+ none: "backdrop-blur-none",
62
62
  hoverable: "bg-opacity-5! backdrop-blur-0 hover:bg-opacity-10! hover:backdrop-blur focus:bg-opacity-10! focus:backdrop-blur aria-selected:bg-opacity-15! aria-selected:backdrop-blur",
63
63
  with: ""
64
64
  },
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Container/index.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type {\n DetailedHTMLProps,\n FC,\n HTMLAttributes,\n PropsWithChildren,\n} from 'react';\n\n/**\n * Container component variants using class-variance-authority\n * Provides flexible styling options for background, padding, borders, and layout\n */\nexport const containerVariants = cva('flex flex-col text-text backdrop-blur', {\n variants: {\n roundedSize: {\n none: 'rounded-none',\n sm: 'rounded-sm [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-md',\n md: 'rounded-md [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-lg',\n lg: 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n xl: 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n '2xl':\n 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n '3xl':\n 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n '4xl':\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n full: 'rounded-full',\n },\n transparency: {\n none: 'bg-card',\n xs: 'bg-card/95',\n sm: 'bg-card/90',\n md: 'bg-card/70',\n lg: 'bg-card/40',\n xl: 'bg-card/20',\n full: '',\n },\n padding: {\n none: 'p-0',\n sm: 'px-3 py-2',\n md: 'px-4 py-3',\n lg: 'px-6 py-4',\n xl: 'px-8 py-6',\n '2xl': 'px-10 py-8',\n },\n separator: {\n without: '',\n x: 'divide-x divide-dashed divide-text/20',\n y: 'divide-y divide-dashed divide-text/20',\n both: 'divide-x divide-y divide-dashed divide-text/20',\n },\n border: {\n none: '',\n with: 'border-[1.3px]',\n },\n borderColor: {\n primary: 'border-primary',\n secondary: 'border-secondary',\n neutral: 'border-neutral',\n card: 'border-card',\n text: 'border-text',\n error: 'border-error',\n warning: 'border-warning',\n success: 'border-success',\n },\n background: {\n none: '',\n hoverable:\n 'bg-opacity-5! backdrop-blur-0 hover:bg-opacity-10! hover:backdrop-blur focus:bg-opacity-10! focus:backdrop-blur aria-selected:bg-opacity-15! aria-selected:backdrop-blur',\n with: '',\n },\n gap: {\n none: 'gap-0',\n sm: 'gap-1',\n md: 'gap-3',\n lg: 'gap-5',\n xl: 'gap-8',\n '2xl': 'gap-10',\n },\n },\n defaultVariants: {\n roundedSize: 'lg',\n border: 'none',\n borderColor: 'text',\n transparency: 'md',\n padding: 'none',\n separator: 'without',\n gap: 'none',\n },\n compoundVariants: [\n {\n background: 'none',\n class: 'bg-transparent',\n },\n ],\n});\n\n/** Available rounded corner sizes for the container */\nexport enum ContainerRoundedSize {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n '2xl' = '2xl',\n '3xl' = '3xl',\n '4xl' = '4xl',\n '5xl' = '5xl',\n FULL = 'full',\n}\n\n/** Background transparency levels for the container */\nexport enum ContainerTransparency {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n FULL = 'full',\n}\n\n/** Padding sizes for container content */\nexport enum ContainerPadding {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n}\n\n/** Separator options for dividing container children */\nexport enum ContainerSeparator {\n WITHOUT = 'without',\n X = 'x',\n Y = 'y',\n BOTH = 'both',\n}\n\n/** Border color options for the container */\nexport enum ContainerBorderColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n NEUTRAL = 'neutral',\n CARD = 'card',\n TEXT = 'text',\n ERROR = 'error',\n WARNING = 'warning',\n SUCCESS = 'success',\n}\n\n/** Background interaction states for the container */\nexport enum ContainerBackground {\n NONE = 'none',\n HOVERABLE = 'hoverable',\n WITH = 'with',\n}\n\n/** Gap sizes between container children */\nexport enum ContainerGap {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n '2xl' = '2xl',\n}\n\n/** Container component props extending HTML div attributes */\nexport type ContainerProps = PropsWithChildren<\n Omit<VariantProps<typeof containerVariants>, 'border'>\n> &\n DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {\n /** Whether to show a border around the container */\n border?: boolean;\n };\n\n/**\n * Container Component\n *\n * A flexible container component for organizing content with customizable styling options.\n * Supports various visual states, layouts, and accessibility features.\n *\n * ## Features\n * - **Flexible Layout**: Supports different padding, gap, and separator options\n * - **Visual Variants**: Multiple background transparency levels and border styles\n * - **Responsive Design**: Configurable rounded corners and spacing\n * - **Semantic HTML**: Proper div element with extensible attributes\n *\n * ## Accessibility\n * - Inherits all standard div accessibility features\n * - Supports ARIA attributes through spread props\n * - Maintains proper semantic structure for screen readers\n *\n * @param children - The content to display inside the container\n * @param roundedSize - Border radius size (default: 'md')\n * @param transparency - Background transparency level (default: 'md')\n * @param padding - Internal padding size (default: 'none')\n * @param separator - Divider lines between children (default: 'without')\n * @param border - Whether to show border (default: false)\n * @param borderColor - Color of the border (default: 'text')\n * @param background - Background interaction behavior (default: 'none')\n * @param gap - Space between child elements (default: 'none')\n * @param className - Additional CSS classes\n * @param props - Additional HTML div attributes including ARIA attributes\n */\nexport const Container: FC<ContainerProps> = ({\n children,\n roundedSize,\n padding,\n transparency,\n separator,\n className,\n border,\n borderColor,\n background,\n gap,\n ...props\n}) => (\n <div\n className={cn(\n containerVariants({\n roundedSize,\n transparency,\n padding,\n separator,\n border:\n typeof border === 'boolean' ? (border ? 'with' : 'none') : undefined,\n background,\n borderColor,\n gap,\n }),\n className\n )}\n {...props}\n >\n {children}\n </div>\n);\n"],"mappings":";;;;;;;;;AAaA,MAAa,oBAAoB,IAAI,yCAAyC;CAC5E,UAAU;EACR,aAAa;GACX,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OACE;GACF,OACE;GACF,OACE;GACF,MAAM;GACP;EACD,cAAc;GACZ,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,MAAM;GACP;EACD,SAAS;GACP,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OAAO;GACR;EACD,WAAW;GACT,SAAS;GACT,GAAG;GACH,GAAG;GACH,MAAM;GACP;EACD,QAAQ;GACN,MAAM;GACN,MAAM;GACP;EACD,aAAa;GACX,SAAS;GACT,WAAW;GACX,SAAS;GACT,MAAM;GACN,MAAM;GACN,OAAO;GACP,SAAS;GACT,SAAS;GACV;EACD,YAAY;GACV,MAAM;GACN,WACE;GACF,MAAM;GACP;EACD,KAAK;GACH,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OAAO;GACR;EACF;CACD,iBAAiB;EACf,aAAa;EACb,QAAQ;EACR,aAAa;EACb,cAAc;EACd,SAAS;EACT,WAAW;EACX,KAAK;EACN;CACD,kBAAkB,CAChB;EACE,YAAY;EACZ,OAAO;EACR,CACF;CACF,CAAC;;AAGF,IAAY,uBAAL;CACL;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;;KACD;;AAGD,IAAY,wBAAL;CACL;CACA;CACA;CACA;CACA;CACA;;KACD;;AAGD,IAAY,mBAAL;CACL;CACA;CACA;CACA;CACA;;KACD;;AAGD,IAAY,qBAAL;CACL;CACA;CACA;CACA;;KACD;;AAGD,IAAY,uBAAL;CACL;CACA;CACA;CACA;CACA;CACA;CACA;CACA;;KACD;;AAGD,IAAY,sBAAL;CACL;CACA;CACA;;KACD;;AAGD,IAAY,eAAL;CACL;CACA;CACA;CACA;CACA;CACA;;KACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCD,MAAa,aAAiC,EAC5C,UACA,aACA,SACA,cACA,WACA,WACA,QACA,aACA,YACA,KACA,GAAG,YAEH,oBAAC,OAAD;CACE,WAAW,GACT,kBAAkB;EAChB;EACA;EACA;EACA;EACA,QACE,OAAO,WAAW,YAAa,SAAS,SAAS,SAAU;EAC7D;EACA;EACA;EACD,CAAC,EACF,UACD;CACD,GAAI;CAEH;CACG"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Container/index.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type {\n DetailedHTMLProps,\n FC,\n HTMLAttributes,\n PropsWithChildren,\n} from 'react';\n\n/**\n * Container component variants using class-variance-authority\n * Provides flexible styling options for background, padding, borders, and layout\n */\nexport const containerVariants = cva('flex flex-col text-text backdrop-blur', {\n variants: {\n roundedSize: {\n none: 'rounded-none',\n sm: 'rounded-sm [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-md',\n md: 'rounded-md [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-lg',\n lg: 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n xl: 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n '2xl':\n 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n '3xl':\n 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n '4xl':\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n full: 'rounded-full',\n },\n transparency: {\n none: 'bg-card',\n xs: 'bg-card/95',\n sm: 'bg-card/90',\n md: 'bg-card/70',\n lg: 'bg-card/40',\n xl: 'bg-card/20',\n full: '',\n },\n padding: {\n none: 'p-0',\n sm: 'px-3 py-2',\n md: 'px-4 py-3',\n lg: 'px-6 py-4',\n xl: 'px-8 py-6',\n '2xl': 'px-10 py-8',\n },\n separator: {\n without: '',\n x: 'divide-x divide-dashed divide-text/20',\n y: 'divide-y divide-dashed divide-text/20',\n both: 'divide-x divide-y divide-dashed divide-text/20',\n },\n border: {\n none: '',\n with: 'border-[1.3px]',\n },\n borderColor: {\n primary: 'border-primary',\n secondary: 'border-secondary',\n neutral: 'border-neutral',\n card: 'border-card',\n text: 'border-text',\n error: 'border-error',\n warning: 'border-warning',\n success: 'border-success',\n },\n background: {\n none: 'backdrop-blur-none',\n hoverable:\n 'bg-opacity-5! backdrop-blur-0 hover:bg-opacity-10! hover:backdrop-blur focus:bg-opacity-10! focus:backdrop-blur aria-selected:bg-opacity-15! aria-selected:backdrop-blur',\n with: '',\n },\n gap: {\n none: 'gap-0',\n sm: 'gap-1',\n md: 'gap-3',\n lg: 'gap-5',\n xl: 'gap-8',\n '2xl': 'gap-10',\n },\n },\n defaultVariants: {\n roundedSize: 'lg',\n border: 'none',\n borderColor: 'text',\n transparency: 'md',\n padding: 'none',\n separator: 'without',\n gap: 'none',\n },\n compoundVariants: [\n {\n background: 'none',\n class: 'bg-transparent',\n },\n ],\n});\n\n/** Available rounded corner sizes for the container */\nexport enum ContainerRoundedSize {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n '2xl' = '2xl',\n '3xl' = '3xl',\n '4xl' = '4xl',\n '5xl' = '5xl',\n FULL = 'full',\n}\n\n/** Background transparency levels for the container */\nexport enum ContainerTransparency {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n FULL = 'full',\n}\n\n/** Padding sizes for container content */\nexport enum ContainerPadding {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n}\n\n/** Separator options for dividing container children */\nexport enum ContainerSeparator {\n WITHOUT = 'without',\n X = 'x',\n Y = 'y',\n BOTH = 'both',\n}\n\n/** Border color options for the container */\nexport enum ContainerBorderColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n NEUTRAL = 'neutral',\n CARD = 'card',\n TEXT = 'text',\n ERROR = 'error',\n WARNING = 'warning',\n SUCCESS = 'success',\n}\n\n/** Background interaction states for the container */\nexport enum ContainerBackground {\n NONE = 'none',\n HOVERABLE = 'hoverable',\n WITH = 'with',\n}\n\n/** Gap sizes between container children */\nexport enum ContainerGap {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n '2xl' = '2xl',\n}\n\n/** Container component props extending HTML div attributes */\nexport type ContainerProps = PropsWithChildren<\n Omit<VariantProps<typeof containerVariants>, 'border'>\n> &\n DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {\n /** Whether to show a border around the container */\n border?: boolean;\n };\n\n/**\n * Container Component\n *\n * A flexible container component for organizing content with customizable styling options.\n * Supports various visual states, layouts, and accessibility features.\n *\n * ## Features\n * - **Flexible Layout**: Supports different padding, gap, and separator options\n * - **Visual Variants**: Multiple background transparency levels and border styles\n * - **Responsive Design**: Configurable rounded corners and spacing\n * - **Semantic HTML**: Proper div element with extensible attributes\n *\n * ## Accessibility\n * - Inherits all standard div accessibility features\n * - Supports ARIA attributes through spread props\n * - Maintains proper semantic structure for screen readers\n *\n * @param children - The content to display inside the container\n * @param roundedSize - Border radius size (default: 'md')\n * @param transparency - Background transparency level (default: 'md')\n * @param padding - Internal padding size (default: 'none')\n * @param separator - Divider lines between children (default: 'without')\n * @param border - Whether to show border (default: false)\n * @param borderColor - Color of the border (default: 'text')\n * @param background - Background interaction behavior (default: 'none')\n * @param gap - Space between child elements (default: 'none')\n * @param className - Additional CSS classes\n * @param props - Additional HTML div attributes including ARIA attributes\n */\nexport const Container: FC<ContainerProps> = ({\n children,\n roundedSize,\n padding,\n transparency,\n separator,\n className,\n border,\n borderColor,\n background,\n gap,\n ...props\n}) => (\n <div\n className={cn(\n containerVariants({\n roundedSize,\n transparency,\n padding,\n separator,\n border:\n typeof border === 'boolean' ? (border ? 'with' : 'none') : undefined,\n background,\n borderColor,\n gap,\n }),\n className\n )}\n {...props}\n >\n {children}\n </div>\n);\n"],"mappings":";;;;;;;;;AAaA,MAAa,oBAAoB,IAAI,yCAAyC;CAC5E,UAAU;EACR,aAAa;GACX,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OACE;GACF,OACE;GACF,OACE;GACF,MAAM;GACP;EACD,cAAc;GACZ,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,MAAM;GACP;EACD,SAAS;GACP,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OAAO;GACR;EACD,WAAW;GACT,SAAS;GACT,GAAG;GACH,GAAG;GACH,MAAM;GACP;EACD,QAAQ;GACN,MAAM;GACN,MAAM;GACP;EACD,aAAa;GACX,SAAS;GACT,WAAW;GACX,SAAS;GACT,MAAM;GACN,MAAM;GACN,OAAO;GACP,SAAS;GACT,SAAS;GACV;EACD,YAAY;GACV,MAAM;GACN,WACE;GACF,MAAM;GACP;EACD,KAAK;GACH,MAAM;GACN,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,OAAO;GACR;EACF;CACD,iBAAiB;EACf,aAAa;EACb,QAAQ;EACR,aAAa;EACb,cAAc;EACd,SAAS;EACT,WAAW;EACX,KAAK;EACN;CACD,kBAAkB,CAChB;EACE,YAAY;EACZ,OAAO;EACR,CACF;CACF,CAAC;;AAGF,IAAY,uBAAL;CACL;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;;KACD;;AAGD,IAAY,wBAAL;CACL;CACA;CACA;CACA;CACA;CACA;;KACD;;AAGD,IAAY,mBAAL;CACL;CACA;CACA;CACA;CACA;;KACD;;AAGD,IAAY,qBAAL;CACL;CACA;CACA;CACA;;KACD;;AAGD,IAAY,uBAAL;CACL;CACA;CACA;CACA;CACA;CACA;CACA;CACA;;KACD;;AAGD,IAAY,sBAAL;CACL;CACA;CACA;;KACD;;AAGD,IAAY,eAAL;CACL;CACA;CACA;CACA;CACA;CACA;;KACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCD,MAAa,aAAiC,EAC5C,UACA,aACA,SACA,cACA,WACA,WACA,QACA,aACA,YACA,KACA,GAAG,YAEH,oBAAC,OAAD;CACE,WAAW,GACT,kBAAkB;EAChB;EACA;EACA;EACA;EACA,QACE,OAAO,WAAW,YAAa,SAAS,SAAS,SAAU;EAC7D;EACA;EACA;EACD,CAAC,EACF,UACD;CACD,GAAI;CAEH;CACG"}
@@ -1,10 +1,10 @@
1
1
  import { Button, ButtonColor, ButtonTextAlign, ButtonVariant } from "../../Button/Button.mjs";
2
2
  import { Accordion } from "../../Accordion/Accordion.mjs";
3
3
  import { getIsEditableSection } from "../getIsEditableSection.mjs";
4
- import { internationalization } from "@intlayer/config/built";
5
4
  import { useState } from "react";
6
5
  import { ChevronRight, Plus } from "lucide-react";
7
6
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
+ import { internationalization } from "@intlayer/config/built";
8
8
  import { useIntlayer } from "react-intlayer";
9
9
  import { useEditedContentActions, useEditorLocale, useFocusUnmergedDictionary } from "@intlayer/editor-react";
10
10
  import { getContentNodeByKeyPath, getEmptyNode, getNodeType } from "@intlayer/core/dictionaryManipulator";
@@ -478,7 +478,7 @@ const InputOTPSlot = ({ index, className, onClick, onKeyDown, ...props }) => {
478
478
  };
479
479
  const InputOTPSeparator = (props) => /* @__PURE__ */ jsx("div", {
480
480
  "aria-hidden": true,
481
- className: "z-0 table h-0.5 w-3 rounded-full bg-border text-text/50",
481
+ className: "z-0 table h-0.5 w-3 rounded-full text-text/50",
482
482
  ...props,
483
483
  children: /* @__PURE__ */ jsx(MinusIcon, {})
484
484
  });
@@ -1 +1 @@
1
- {"version":3,"file":"OTPInput.mjs","names":[],"sources":["../../../../src/components/Input/OTPInput.tsx"],"sourcesContent":["'use client';\n\n/**\n * This component is a fork of https://github.com/guilhermerodz/input-otp\n */\n\nimport { cn } from '@utils/cn';\nimport { cva } from 'class-variance-authority';\nimport { MinusIcon } from 'lucide-react';\nimport {\n type ChangeEvent,\n type ClipboardEvent,\n type ComponentProps,\n type CSSProperties,\n createContext,\n type FC,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type RefObject,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { Button, type ButtonProps } from '../Button';\n\n// ---------------- Utilities ----------------\n\nconst syncTimeouts = (cb: (...args: any[]) => unknown): number[] => {\n const t1 = setTimeout(cb, 0); // For faster machines\n const t2 = setTimeout(cb, 1_0);\n const t3 = setTimeout(cb, 5_0);\n return [t1, t2, t3];\n};\n\nconst safeInsertRule = (sheet: CSSStyleSheet, rule: string) => {\n try {\n sheet.insertRule(rule);\n } catch {\n console.error('input-otp could not insert CSS rule:', rule);\n }\n};\n\n// Decided to go with <noscript>\n// instead of `scripting` CSS media query\n// because it's a fallback for initial page load\n// and the <script> tag won't be loaded\n// unless the user has JS disabled.\nconst NOSCRIPT_CSS_FALLBACK = `\n[data-input-otp] {\n --nojs-bg: white !important;\n --nojs-fg: black !important;\n\n background-color: var(--nojs-bg) !important;\n color: var(--nojs-fg) !important;\n caret-color: var(--nojs-fg) !important;\n letter-spacing: .25em !important;\n text-align: center !important;\n border: 1px solid var(--nojs-fg) !important;\n border-radius: 4px !important;\n width: 100% !important;\n}\n@media (prefers-color-scheme: dark) {\n [data-input-otp] {\n --nojs-bg: black !important;\n --nojs-fg: white !important;\n }\n}`;\n\n// ---------------- Constants ----------------\n\nconst PWM_BADGE_MARGIN_RIGHT = 18;\nconst PWM_BADGE_SPACE_WIDTH_PX = 40;\nconst PWM_BADGE_SPACE_WIDTH = `${PWM_BADGE_SPACE_WIDTH_PX}px` as const;\n\nconst PASSWORD_MANAGERS_SELECTORS = [\n '[data-lastpass-icon-root]', // LastPass\n 'com-1password-button', // 1Password\n '[data-dashlanecreated]', // Dashlane\n '[style$=\"2147483647 !important;\"]', // Bitwarden\n].join(',');\n\n// ---------------- Types ----------------\n\nexport type SlotProps = {\n isActive: boolean;\n char: string | null;\n placeholderChar: string | null;\n hasFakeCaret: boolean;\n};\n\nexport type RenderProps = {\n slots: SlotProps[];\n isFocused: boolean;\n isHovering: boolean;\n setSelection: (index: number) => void;\n};\n\ntype OverrideProps<T, R> = Omit<T, keyof R> & R;\n\ntype OTPInputBaseProps = OverrideProps<\n InputHTMLAttributes<HTMLInputElement>,\n {\n value?: string;\n onChange?: (newValue: string) => unknown;\n\n maxLength: number;\n\n onComplete?: (...args: any[]) => unknown;\n onActiveSlotChange?: (activeSlotIndex: number | null) => unknown;\n pushPasswordManagerStrategy?: 'increase-width' | 'none';\n pasteTransformer?: (pasted: string) => string;\n\n containerClassName?: string;\n\n noScriptCSSFallback?: string | null;\n }\n>;\n\ntype InputOTPRenderFn = (props: RenderProps) => ReactNode;\n\nexport type OTPInputProps = OTPInputBaseProps &\n (\n | {\n render: InputOTPRenderFn;\n children?: never;\n }\n | {\n render?: never;\n children: ReactNode;\n }\n );\n\n// ---------------- Hooks ----------------\n\nexport const usePasswordManagerBadge = ({\n containerRef,\n inputRef,\n pushPasswordManagerStrategy,\n isFocused,\n}: {\n containerRef: RefObject<HTMLDivElement | null>;\n inputRef: RefObject<HTMLInputElement | null>;\n pushPasswordManagerStrategy: OTPInputProps['pushPasswordManagerStrategy'];\n isFocused: boolean;\n}) => {\n /** Password managers have a badge\n * and I'll use this state to push them\n * outside the input */\n const [hasPWMBadge, setHasPWMBadge] = useState(false);\n const [hasPWMBadgeSpace, setHasPWMBadgeSpace] = useState(false);\n const [done, setDone] = useState(false);\n\n const willPushPWMBadge =\n pushPasswordManagerStrategy === 'none'\n ? false\n : (pushPasswordManagerStrategy === 'increase-width' ||\n // TODO: remove 'experimental-no-flickering' support in 2.0.0\n pushPasswordManagerStrategy === 'experimental-no-flickering') &&\n hasPWMBadge &&\n hasPWMBadgeSpace;\n\n const trackPWMBadge = () => {\n const container = containerRef.current;\n const input = inputRef.current;\n if (\n !container ||\n !input ||\n done ||\n pushPasswordManagerStrategy === 'none'\n ) {\n return;\n }\n\n const elementToCompare = container;\n\n // Get the top right-center point of the container.\n // That is usually where most password managers place their badge.\n const rightCornerX =\n elementToCompare.getBoundingClientRect().left +\n elementToCompare.offsetWidth;\n const centereredY =\n elementToCompare.getBoundingClientRect().top +\n elementToCompare.offsetHeight / 2;\n const x = rightCornerX - PWM_BADGE_MARGIN_RIGHT;\n const y = centereredY;\n\n // Do an extra search to check for famous password managers\n const pmws = document.querySelectorAll(PASSWORD_MANAGERS_SELECTORS);\n\n // If no password manager is automatically detect,\n // we'll try to dispatch document.elementFromPoint\n // to identify badges\n if (pmws.length === 0) {\n const maybeBadgeEl = document.elementFromPoint(x, y);\n\n // If the found element is the input itself,\n // then we assume it's not a password manager badge.\n // We are not sure. Most times that means there isn't a badge.\n if (maybeBadgeEl === container) {\n return;\n }\n }\n\n setHasPWMBadge(true);\n setDone(true);\n };\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container || pushPasswordManagerStrategy === 'none') {\n return;\n }\n\n // Check if the PWM area is 100% visible\n const checkHasSpace = () => {\n const viewportWidth = window.innerWidth;\n const distanceToRightEdge =\n viewportWidth - container.getBoundingClientRect().right;\n setHasPWMBadgeSpace(distanceToRightEdge >= PWM_BADGE_SPACE_WIDTH_PX);\n };\n\n checkHasSpace();\n const interval = setInterval(checkHasSpace, 1000);\n\n return () => {\n clearInterval(interval);\n };\n }, [containerRef, pushPasswordManagerStrategy]);\n\n useEffect(() => {\n const _isFocused = isFocused || document.activeElement === inputRef.current;\n\n if (pushPasswordManagerStrategy === 'none' || !_isFocused) {\n return;\n }\n const t1 = setTimeout(trackPWMBadge, 0);\n const t2 = setTimeout(trackPWMBadge, 2000);\n const t3 = setTimeout(trackPWMBadge, 5000);\n const t4 = setTimeout(() => {\n setDone(true);\n }, 6000);\n return () => {\n clearTimeout(t1);\n clearTimeout(t2);\n clearTimeout(t3);\n clearTimeout(t4);\n };\n }, [inputRef, isFocused, pushPasswordManagerStrategy]);\n\n return { hasPWMBadge, willPushPWMBadge, PWM_BADGE_SPACE_WIDTH };\n};\n\nexport const usePrevious = <T,>(value: T): T | undefined => {\n const ref = useRef<T | undefined>(undefined);\n useEffect(() => {\n ref.current = value;\n });\n return ref.current;\n};\n\n// ---------------- Context ----------------\n\nexport const OTPInputContext = createContext<RenderProps>({} as RenderProps);\n\n// ---------------- Core Component ----------------\n\nexport const OTPInput: FC<OTPInputProps> = ({\n value: uncheckedValue,\n onChange: uncheckedOnChange,\n maxLength,\n pattern,\n placeholder,\n inputMode = 'numeric',\n onComplete,\n onActiveSlotChange,\n pushPasswordManagerStrategy = 'increase-width',\n pasteTransformer,\n containerClassName,\n noScriptCSSFallback = NOSCRIPT_CSS_FALLBACK,\n render,\n children,\n ...props\n}) => {\n // Only used when `value` state is not provided\n const [internalValue, setInternalValue] = useState(\n typeof props.defaultValue === 'string' ? props.defaultValue : ''\n );\n\n // Definitions\n const value = uncheckedValue ?? internalValue;\n const previousValue = usePrevious(value);\n const onChange = (newValue: string) => {\n uncheckedOnChange?.(newValue);\n setInternalValue(newValue);\n };\n const regexp =\n pattern !== undefined\n ? typeof pattern === 'string'\n ? new RegExp(pattern)\n : pattern\n : null;\n\n /** useRef */\n const inputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const initialLoadRef = useRef({\n value,\n onChange,\n isIOS:\n typeof window !== 'undefined' &&\n window?.CSS?.supports?.('-webkit-touch-callout', 'none'),\n });\n const inputMetadataRef = useRef<{\n prev: [number | null, number | null, 'none' | 'forward' | 'backward'];\n }>({\n prev: [\n inputRef.current?.selectionStart ?? null,\n inputRef.current?.selectionEnd ?? null,\n inputRef.current?.selectionDirection ?? 'none',\n ],\n });\n useEffect(() => {\n const input = inputRef.current;\n const container = containerRef.current;\n\n if (!input || !container) {\n return;\n }\n\n // Sync input value\n if (initialLoadRef.current.value !== input.value) {\n initialLoadRef.current.onChange(input.value);\n }\n\n // Previous selection\n inputMetadataRef.current.prev = [\n input.selectionStart,\n input.selectionEnd,\n input.selectionDirection ?? 'none',\n ];\n const onDocumentSelectionChange = () => {\n if (document.activeElement !== input) {\n setMirrorSelectionStart(null);\n setMirrorSelectionEnd(null);\n setActualCaretPosition(null);\n return;\n }\n\n const selectionStart = input.selectionStart;\n const selectionEnd = input.selectionEnd;\n const selectionDirection = input.selectionDirection;\n const maxLength = input.maxLength;\n const value = input.value;\n const previousSelection = inputMetadataRef.current.prev;\n\n let calculatedStart = -1;\n let calculatedEnd = -1;\n let calculatedDirection: 'forward' | 'backward' | 'none' =\n selectionDirection ?? 'none';\n\n if (\n value.length !== 0 &&\n selectionStart !== null &&\n selectionEnd !== null\n ) {\n const isSingleCaret = selectionStart === selectionEnd;\n const isInsertMode =\n selectionStart === value.length && value.length < maxLength;\n\n if (isSingleCaret && !isInsertMode) {\n const caretPosition = selectionStart;\n if (caretPosition === 0) {\n calculatedStart = 0;\n calculatedEnd = 1;\n calculatedDirection = 'forward';\n } else if (caretPosition === maxLength) {\n calculatedStart = caretPosition - 1;\n calculatedEnd = caretPosition;\n calculatedDirection = 'backward';\n } else if (maxLength > 1 && value.length > 1) {\n let offset = 0;\n if (\n previousSelection[0] !== null &&\n previousSelection[1] !== null\n ) {\n calculatedDirection =\n caretPosition < previousSelection[1] ? 'backward' : 'forward';\n const wasPreviouslyInserting =\n previousSelection[0] === previousSelection[1] &&\n previousSelection[0] < maxLength;\n if (\n calculatedDirection === 'backward' &&\n !wasPreviouslyInserting\n ) {\n offset = -1;\n }\n }\n\n calculatedStart = offset + caretPosition;\n calculatedEnd = offset + caretPosition + 1;\n }\n }\n\n if (\n calculatedStart !== -1 &&\n calculatedEnd !== -1 &&\n calculatedStart !== calculatedEnd\n ) {\n inputRef.current?.setSelectionRange(\n calculatedStart,\n calculatedEnd,\n calculatedDirection\n );\n }\n }\n\n const finalSelectionStart =\n calculatedStart !== -1 ? calculatedStart : selectionStart;\n const finalSelectionEnd =\n calculatedEnd !== -1 ? calculatedEnd : selectionEnd;\n const finalDirection = calculatedDirection;\n\n // Track actual caret position (before expansion) for active slot detection\n if (selectionStart !== null && selectionEnd !== null) {\n const isSingleCaret = selectionStart === selectionEnd;\n if (isSingleCaret) {\n setActualCaretPosition(selectionStart);\n } else {\n // When selection is expanded, use the start position as the caret\n setActualCaretPosition(finalSelectionStart);\n }\n } else {\n setActualCaretPosition(null);\n }\n\n setMirrorSelectionStart(finalSelectionStart);\n setMirrorSelectionEnd(finalSelectionEnd);\n inputMetadataRef.current.prev = [\n finalSelectionStart,\n finalSelectionEnd,\n finalDirection,\n ];\n };\n document.addEventListener('selectionchange', onDocumentSelectionChange, {\n capture: true,\n });\n\n // Set initial mirror state\n onDocumentSelectionChange();\n if (document.activeElement === input) {\n setIsFocused(true);\n }\n\n // Apply needed styles\n if (!document.getElementById('input-otp-style')) {\n const styleEl = document.createElement('style');\n styleEl.id = 'input-otp-style';\n document.head.appendChild(styleEl);\n\n if (styleEl.sheet) {\n const autofillStyles =\n 'background: transparent !important; color: transparent !important; border-color: transparent !important; opacity: 0 !important; box-shadow: none !important; -webkit-box-shadow: none !important; -webkit-text-fill-color: transparent !important;';\n\n safeInsertRule(\n styleEl.sheet,\n '[data-input-otp]::selection { background: transparent !important; color: transparent !important; }'\n );\n safeInsertRule(\n styleEl.sheet,\n `[data-input-otp]:autofill { ${autofillStyles} }`\n );\n safeInsertRule(\n styleEl.sheet,\n `[data-input-otp]:-webkit-autofill { ${autofillStyles} }`\n );\n // iOS\n safeInsertRule(\n styleEl.sheet,\n `@supports (-webkit-touch-callout: none) { [data-input-otp] { letter-spacing: -.6em !important; font-weight: 100 !important; font-stretch: ultra-condensed; font-optical-sizing: none !important; left: -1px !important; right: 1px !important; } }`\n );\n // PWM badges\n safeInsertRule(\n styleEl.sheet,\n `[data-input-otp] + * { pointer-events: all !important; }`\n );\n }\n }\n // Track root height\n const updateRootHeight = () => {\n if (container) {\n container.style.setProperty('--root-height', `${input.clientHeight}px`);\n }\n };\n updateRootHeight();\n const resizeObserver = new ResizeObserver(updateRootHeight);\n resizeObserver.observe(input);\n\n return () => {\n document.removeEventListener(\n 'selectionchange',\n onDocumentSelectionChange,\n { capture: true }\n );\n resizeObserver.disconnect();\n };\n }, []);\n\n /** Mirrors for UI rendering purpose only */\n const [isHoveringInput, setIsHoveringInput] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [mirrorSelectionStart, setMirrorSelectionStart] = useState<\n number | null\n >(null);\n const [mirrorSelectionEnd, setMirrorSelectionEnd] = useState<number | null>(\n null\n );\n const [actualCaretPosition, setActualCaretPosition] = useState<number | null>(\n null\n );\n\n /** Effects */\n useEffect(() => {\n syncTimeouts(() => {\n // Forcefully remove :autofill state\n inputRef.current?.dispatchEvent(new Event('input'));\n\n // Update the selection state\n const s = inputRef.current?.selectionStart ?? null;\n const e = inputRef.current?.selectionEnd ?? null;\n const dir = inputRef.current?.selectionDirection ?? 'none';\n if (s !== null && e !== null) {\n setMirrorSelectionStart(s);\n setMirrorSelectionEnd(e);\n // Track actual caret position (use start position as caret)\n setActualCaretPosition(s);\n inputMetadataRef.current.prev = [s, e, dir];\n }\n });\n }, [value, isFocused]);\n\n useEffect(() => {\n if (previousValue === undefined) {\n return;\n }\n\n if (\n value !== previousValue &&\n previousValue.length < maxLength &&\n value.length === maxLength\n ) {\n onComplete?.(value);\n }\n }, [maxLength, onComplete, previousValue, value]);\n\n // Track active slot changes\n const previousActiveSlot = useRef<number | null>(null);\n useEffect(() => {\n const activeSlotIndex =\n isFocused && actualCaretPosition !== null ? actualCaretPosition : null;\n\n if (activeSlotIndex !== previousActiveSlot.current) {\n previousActiveSlot.current = activeSlotIndex;\n onActiveSlotChange?.(activeSlotIndex);\n }\n }, [isFocused, actualCaretPosition, onActiveSlotChange]);\n\n const pwmb = usePasswordManagerBadge({\n containerRef,\n inputRef,\n pushPasswordManagerStrategy,\n isFocused,\n });\n\n /** Event handlers */\n const _changeListener = (e: ChangeEvent<HTMLInputElement>) => {\n const newValue = e.currentTarget.value.slice(0, maxLength);\n if (newValue.length > 0 && regexp && !regexp.test(newValue)) {\n e.preventDefault();\n return;\n }\n const maybeHasDeleted =\n typeof previousValue === 'string' &&\n newValue.length < previousValue.length;\n if (maybeHasDeleted) {\n // Since cutting/deleting text doesn't trigger\n // selectionchange event, we'll have to dispatch it manually.\n // NOTE: The following line also triggers when cmd+A then pasting\n // a value with smaller length, which is not ideal for performance.\n document.dispatchEvent(new Event('selectionchange'));\n }\n onChange(newValue);\n };\n const _focusListener = () => {\n if (inputRef.current) {\n const start = Math.min(inputRef.current.value.length, maxLength - 1);\n const end = inputRef.current.value.length;\n inputRef.current?.setSelectionRange(start, end);\n setMirrorSelectionStart(start);\n setMirrorSelectionEnd(end);\n }\n setIsFocused(true);\n };\n // Fix iOS pasting\n const _pasteListener = (e: ClipboardEvent<HTMLInputElement>) => {\n const input = inputRef.current;\n if (\n !pasteTransformer &&\n (!initialLoadRef.current.isIOS || !e.clipboardData || !input)\n ) {\n return;\n }\n\n const _content = e.clipboardData.getData('text/plain');\n const content = pasteTransformer ? pasteTransformer(_content) : _content;\n e.preventDefault();\n\n const start = inputRef.current?.selectionStart;\n const end = inputRef.current?.selectionEnd;\n\n const isReplacing = start !== end;\n\n const newValueUncapped = isReplacing\n ? value.slice(0, start ?? 0) + content + value.slice(end ?? 0) // Replacing\n : value.slice(0, start ?? 0) + content + value.slice(start ?? 0); // Inserting\n const newValue = newValueUncapped.slice(0, maxLength);\n\n if (newValue.length > 0 && regexp && !regexp.test(newValue)) {\n return;\n }\n\n if (input) {\n input.value = newValue;\n onChange(newValue);\n\n const _start = Math.min(newValue.length, maxLength - 1);\n const _end = newValue.length;\n\n input.setSelectionRange(_start, _end);\n setMirrorSelectionStart(_start);\n setMirrorSelectionEnd(_end);\n }\n };\n\n /** Styles - dynamic styles that can't be converted to Tailwind */\n const dynamicInputStyle: CSSProperties = {\n width: pwmb.willPushPWMBadge\n ? `calc(100% + ${pwmb.PWM_BADGE_SPACE_WIDTH})`\n : '100%',\n clipPath: pwmb.willPushPWMBadge\n ? `inset(0 ${pwmb.PWM_BADGE_SPACE_WIDTH} 0 0)`\n : undefined,\n fontSize: 'var(--root-height)',\n };\n\n /** Rendering */\n const renderedInput = (\n <input\n autoComplete={props.autoComplete || 'one-time-code'}\n {...props}\n data-input-otp\n data-input-otp-placeholder-shown={value.length === 0 || undefined}\n data-input-otp-mss={mirrorSelectionStart}\n data-input-otp-mse={mirrorSelectionEnd}\n inputMode={inputMode}\n pattern={regexp?.source}\n aria-placeholder={placeholder}\n className=\"pointer-events-auto absolute inset-0 -z-10 flex h-full border-0 border-transparent bg-transparent text-center font-mono text-transparent tabular-nums leading-none tracking-[-.5em] caret-transparent opacity-100 shadow-none outline-none\"\n style={dynamicInputStyle}\n maxLength={maxLength}\n value={value}\n ref={inputRef}\n onPaste={(e) => {\n _pasteListener(e);\n props.onPaste?.(e);\n }}\n onChange={_changeListener}\n onMouseOver={(e) => {\n setIsHoveringInput(true);\n props.onMouseOver?.(e);\n }}\n onMouseLeave={(e) => {\n setIsHoveringInput(false);\n props.onMouseLeave?.(e);\n }}\n onKeyDown={(e) => {\n // Track arrow key navigation to ensure active slot updates correctly\n if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {\n // Use requestAnimationFrame to check selection after browser has processed the key\n requestAnimationFrame(() => {\n const input = inputRef.current;\n if (input && document.activeElement === input) {\n const s = input.selectionStart;\n const end = input.selectionEnd;\n if (s !== null && end !== null) {\n // Update actual caret position - use start position as caret\n setActualCaretPosition(s);\n }\n }\n });\n }\n props.onKeyDown?.(e);\n }}\n onFocus={(e) => {\n _focusListener();\n props.onFocus?.(e);\n }}\n onBlur={(e) => {\n setIsFocused(false);\n props.onBlur?.(e);\n }}\n />\n );\n\n const setSelection = (index: number) => {\n const input = inputRef.current;\n if (!input || props.disabled) {\n return;\n }\n\n // Clamp index to valid range\n const clampedIndex = Math.max(0, Math.min(index, maxLength - 1));\n\n // Focus the input if not already focused\n if (document.activeElement !== input) {\n input.focus();\n }\n\n // Set selection to the clicked slot\n // If there's a character at that position, select it; otherwise just position the caret\n const hasChar = value[clampedIndex] !== undefined;\n const start = clampedIndex;\n const end = hasChar ? clampedIndex + 1 : clampedIndex;\n\n input.setSelectionRange(start, end);\n setMirrorSelectionStart(start);\n setMirrorSelectionEnd(end);\n setIsFocused(true);\n };\n\n const contextValue: RenderProps = {\n slots: Array.from({ length: maxLength }).map((_, slotIdx) => {\n const isActive =\n isFocused &&\n mirrorSelectionStart !== null &&\n mirrorSelectionEnd !== null &&\n ((mirrorSelectionStart === mirrorSelectionEnd &&\n slotIdx === mirrorSelectionStart) ||\n (slotIdx >= mirrorSelectionStart && slotIdx < mirrorSelectionEnd));\n\n const char = value[slotIdx] !== undefined ? value[slotIdx] : null;\n const placeholderChar =\n value[0] !== undefined ? null : (placeholder?.[slotIdx] ?? null);\n\n return {\n char,\n placeholderChar,\n isActive,\n hasFakeCaret: isActive && char === null,\n };\n }),\n isFocused,\n isHovering: !props.disabled && isHoveringInput,\n setSelection,\n };\n\n const renderedChildren =\n render !== undefined ? (\n render(contextValue)\n ) : (\n <OTPInputContext.Provider value={contextValue}>\n {children}\n </OTPInputContext.Provider>\n );\n\n return (\n <>\n {noScriptCSSFallback !== null && (\n <noscript>\n <style>{noScriptCSSFallback}</style>\n </noscript>\n )}\n\n <div\n ref={containerRef}\n className={cn(\n 'relative',\n props.disabled ? 'cursor-default' : 'cursor-text',\n containerClassName\n )}\n >\n {renderedChildren}\n\n <div className=\"absolute inset-0\">{renderedInput}</div>\n </div>\n </>\n );\n};\n\n// ---------------- Root ----------------\n\ntype InputOTPProps = Omit<ComponentProps<typeof OTPInput>, 'children'>;\n\nexport const inputSlotVariants = cva('block text-center', {\n variants: {\n size: {\n sm: 'h-4 w-3 text-sm',\n md: 'h-5 w-4 text-base',\n lg: 'h-6 w-5 text-lg',\n xl: 'h-7 w-6 text-xl',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\nexport const InputOTP: FC<InputOTPProps> = ({\n className,\n render,\n ...props\n}) => (\n <OTPInput\n containerClassName=\"relative flex items-center gap-2 has-disabled:opacity-50\"\n className={cn('disabled:cursor-not-allowed', className)}\n render={render!}\n {...props}\n />\n);\n\n// ---------------- Group ----------------\n\nexport const InputOTPGroup = ({\n className,\n ...props\n}: ComponentProps<'div'>) => (\n <div className={cn('z-10 flex items-center gap-3', className)} {...props} />\n);\n\n// ---------------- Slot ----------------\n\ntype InputOTPSlotProps = Omit<ButtonProps, 'variant' | 'label'> & {\n index: number;\n};\n\nexport const InputOTPSlot: FC<InputOTPSlotProps> = ({\n index,\n className,\n onClick,\n onKeyDown,\n ...props\n}) => {\n const inputOTPContext = useContext(OTPInputContext);\n const { char, isActive } = inputOTPContext?.slots[index] ?? {};\n const { setSelection } = inputOTPContext ?? {};\n\n const handleClick = (e: MouseEvent<HTMLButtonElement>) => {\n setSelection?.(index);\n onClick?.(e);\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setSelection?.(index);\n }\n onKeyDown?.(e);\n };\n\n return (\n <Button\n isSelected={isActive}\n variant=\"input\"\n color=\"custom\"\n tabIndex={-1}\n className={cn('relative z-10 px-2!', isActive && 'ring-4!', className)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n label={null}\n {...props}\n >\n {/* value */}\n <span className=\"relative z-10 flex h-6 w-4 items-center justify-center\">\n {char}\n </span>\n </Button>\n );\n};\n\n// ---------------- Separator ----------------\n\nexport const InputOTPSeparator: FC<ComponentProps<'div'>> = (props) => (\n <div\n aria-hidden\n className=\"z-0 table h-0.5 w-3 rounded-full bg-border text-text/50\"\n {...props}\n >\n <MinusIcon />\n </div>\n);\n\nexport const InputIndicator: FC<ComponentProps<'div'>> = (props) => (\n <div\n data-indicator\n className=\"absolute top-0 z-0 h-full w-auto rounded-xl bg-text/20 ring-4 ring-text/20 transition-[left,width] duration-300 ease-in-out [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl motion-reduce:transition-none\"\n {...props}\n />\n);\n"],"mappings":";;;;;;;;;;;;;AA8BA,MAAM,gBAAgB,OAA8C;CAIlE,OAAO;EAHI,WAAW,IAAI,EAGhB;EAFC,WAAW,IAAI,GAEZ;EADH,WAAW,IAAI,GACR;EAAC;;AAGrB,MAAM,kBAAkB,OAAsB,SAAiB;CAC7D,IAAI;EACF,MAAM,WAAW,KAAK;SAChB;EACN,QAAQ,MAAM,wCAAwC,KAAK;;;AAS/D,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;AAuB9B,MAAM,yBAAyB;AAC/B,MAAM,2BAA2B;AACjC,MAAM,wBAAwB,GAAG,yBAAyB;AAE1D,MAAM,8BAA8B;CAClC;CACA;CACA;CACA;CACD,CAAC,KAAK,IAAI;AAuDX,MAAa,2BAA2B,EACtC,cACA,UACA,6BACA,gBAMI;;;;CAIJ,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;CACrD,MAAM,CAAC,kBAAkB,uBAAuB,SAAS,MAAM;CAC/D,MAAM,CAAC,MAAM,WAAW,SAAS,MAAM;CAEvC,MAAM,mBACJ,gCAAgC,SAC5B,SACC,gCAAgC,oBAE/B,gCAAgC,iCAClC,eACA;CAEN,MAAM,sBAAsB;EAC1B,MAAM,YAAY,aAAa;EAC/B,MAAM,QAAQ,SAAS;EACvB,IACE,CAAC,aACD,CAAC,SACD,QACA,gCAAgC,QAEhC;EAGF,MAAM,mBAAmB;EAIzB,MAAM,eACJ,iBAAiB,uBAAuB,CAAC,OACzC,iBAAiB;EACnB,MAAM,cACJ,iBAAiB,uBAAuB,CAAC,MACzC,iBAAiB,eAAe;EAClC,MAAM,IAAI,eAAe;EACzB,MAAM,IAAI;EAQV,IALa,SAAS,iBAAiB,4BAK/B,CAAC,WAAW,GAMlB;OALqB,SAAS,iBAAiB,GAAG,EAKlC,KAAK,WACnB;;EAIJ,eAAe,KAAK;EACpB,QAAQ,KAAK;;CAGf,gBAAgB;EACd,MAAM,YAAY,aAAa;EAC/B,IAAI,CAAC,aAAa,gCAAgC,QAChD;EAIF,MAAM,sBAAsB;GAI1B,oBAHsB,OAAO,aAEX,UAAU,uBAAuB,CAAC,SACT,yBAAyB;;EAGtE,eAAe;EACf,MAAM,WAAW,YAAY,eAAe,IAAK;EAEjD,aAAa;GACX,cAAc,SAAS;;IAExB,CAAC,cAAc,4BAA4B,CAAC;CAE/C,gBAAgB;EACd,MAAM,aAAa,aAAa,SAAS,kBAAkB,SAAS;EAEpE,IAAI,gCAAgC,UAAU,CAAC,YAC7C;EAEF,MAAM,KAAK,WAAW,eAAe,EAAE;EACvC,MAAM,KAAK,WAAW,eAAe,IAAK;EAC1C,MAAM,KAAK,WAAW,eAAe,IAAK;EAC1C,MAAM,KAAK,iBAAiB;GAC1B,QAAQ,KAAK;KACZ,IAAK;EACR,aAAa;GACX,aAAa,GAAG;GAChB,aAAa,GAAG;GAChB,aAAa,GAAG;GAChB,aAAa,GAAG;;IAEjB;EAAC;EAAU;EAAW;EAA4B,CAAC;CAEtD,OAAO;EAAE;EAAa;EAAkB;EAAuB;;AAGjE,MAAa,eAAmB,UAA4B;CAC1D,MAAM,MAAM,OAAsB,OAAU;CAC5C,gBAAgB;EACd,IAAI,UAAU;GACd;CACF,OAAO,IAAI;;AAKb,MAAa,kBAAkB,cAA2B,EAAE,CAAgB;AAI5E,MAAa,YAA+B,EAC1C,OAAO,gBACP,UAAU,mBACV,WACA,SACA,aACA,YAAY,WACZ,YACA,oBACA,8BAA8B,kBAC9B,kBACA,oBACA,sBAAsB,uBACtB,QACA,UACA,GAAG,YACC;CAEJ,MAAM,CAAC,eAAe,oBAAoB,SACxC,OAAO,MAAM,iBAAiB,WAAW,MAAM,eAAe,GAC/D;CAGD,MAAM,QAAQ,kBAAkB;CAChC,MAAM,gBAAgB,YAAY,MAAM;CACxC,MAAM,YAAY,aAAqB;EACrC,oBAAoB,SAAS;EAC7B,iBAAiB,SAAS;;CAE5B,MAAM,SACJ,YAAY,SACR,OAAO,YAAY,WACjB,IAAI,OAAO,QAAQ,GACnB,UACF;;CAGN,MAAM,WAAW,OAAyB,KAAK;CAC/C,MAAM,eAAe,OAAuB,KAAK;CACjD,MAAM,iBAAiB,OAAO;EAC5B;EACA;EACA,OACE,OAAO,WAAW,eAClB,QAAQ,KAAK,WAAW,yBAAyB,OAAO;EAC3D,CAAC;CACF,MAAM,mBAAmB,OAEtB,EACD,MAAM;EACJ,SAAS,SAAS,kBAAkB;EACpC,SAAS,SAAS,gBAAgB;EAClC,SAAS,SAAS,sBAAsB;EACzC,EACF,CAAC;CACF,gBAAgB;EACd,MAAM,QAAQ,SAAS;EACvB,MAAM,YAAY,aAAa;EAE/B,IAAI,CAAC,SAAS,CAAC,WACb;EAIF,IAAI,eAAe,QAAQ,UAAU,MAAM,OACzC,eAAe,QAAQ,SAAS,MAAM,MAAM;EAI9C,iBAAiB,QAAQ,OAAO;GAC9B,MAAM;GACN,MAAM;GACN,MAAM,sBAAsB;GAC7B;EACD,MAAM,kCAAkC;GACtC,IAAI,SAAS,kBAAkB,OAAO;IACpC,wBAAwB,KAAK;IAC7B,sBAAsB,KAAK;IAC3B,uBAAuB,KAAK;IAC5B;;GAGF,MAAM,iBAAiB,MAAM;GAC7B,MAAM,eAAe,MAAM;GAC3B,MAAM,qBAAqB,MAAM;GACjC,MAAM,YAAY,MAAM;GACxB,MAAM,QAAQ,MAAM;GACpB,MAAM,oBAAoB,iBAAiB,QAAQ;GAEnD,IAAI,kBAAkB;GACtB,IAAI,gBAAgB;GACpB,IAAI,sBACF,sBAAsB;GAExB,IACE,MAAM,WAAW,KACjB,mBAAmB,QACnB,iBAAiB,MACjB;IACA,MAAM,gBAAgB,mBAAmB;IACzC,MAAM,eACJ,mBAAmB,MAAM,UAAU,MAAM,SAAS;IAEpD,IAAI,iBAAiB,CAAC,cAAc;KAClC,MAAM,gBAAgB;KACtB,IAAI,kBAAkB,GAAG;MACvB,kBAAkB;MAClB,gBAAgB;MAChB,sBAAsB;YACjB,IAAI,kBAAkB,WAAW;MACtC,kBAAkB,gBAAgB;MAClC,gBAAgB;MAChB,sBAAsB;YACjB,IAAI,YAAY,KAAK,MAAM,SAAS,GAAG;MAC5C,IAAI,SAAS;MACb,IACE,kBAAkB,OAAO,QACzB,kBAAkB,OAAO,MACzB;OACA,sBACE,gBAAgB,kBAAkB,KAAK,aAAa;OACtD,MAAM,yBACJ,kBAAkB,OAAO,kBAAkB,MAC3C,kBAAkB,KAAK;OACzB,IACE,wBAAwB,cACxB,CAAC,wBAED,SAAS;;MAIb,kBAAkB,SAAS;MAC3B,gBAAgB,SAAS,gBAAgB;;;IAI7C,IACE,oBAAoB,MACpB,kBAAkB,MAClB,oBAAoB,eAEpB,SAAS,SAAS,kBAChB,iBACA,eACA,oBACD;;GAIL,MAAM,sBACJ,oBAAoB,KAAK,kBAAkB;GAC7C,MAAM,oBACJ,kBAAkB,KAAK,gBAAgB;GACzC,MAAM,iBAAiB;GAGvB,IAAI,mBAAmB,QAAQ,iBAAiB,MAE9C,IADsB,mBAAmB,cAEvC,uBAAuB,eAAe;QAGtC,uBAAuB,oBAAoB;QAG7C,uBAAuB,KAAK;GAG9B,wBAAwB,oBAAoB;GAC5C,sBAAsB,kBAAkB;GACxC,iBAAiB,QAAQ,OAAO;IAC9B;IACA;IACA;IACD;;EAEH,SAAS,iBAAiB,mBAAmB,2BAA2B,EACtE,SAAS,MACV,CAAC;EAGF,2BAA2B;EAC3B,IAAI,SAAS,kBAAkB,OAC7B,aAAa,KAAK;EAIpB,IAAI,CAAC,SAAS,eAAe,kBAAkB,EAAE;GAC/C,MAAM,UAAU,SAAS,cAAc,QAAQ;GAC/C,QAAQ,KAAK;GACb,SAAS,KAAK,YAAY,QAAQ;GAElC,IAAI,QAAQ,OAAO;IACjB,MAAM,iBACJ;IAEF,eACE,QAAQ,OACR,qGACD;IACD,eACE,QAAQ,OACR,+BAA+B,eAAe,IAC/C;IACD,eACE,QAAQ,OACR,uCAAuC,eAAe,IACvD;IAED,eACE,QAAQ,OACR,qPACD;IAED,eACE,QAAQ,OACR,2DACD;;;EAIL,MAAM,yBAAyB;GAC7B,IAAI,WACF,UAAU,MAAM,YAAY,iBAAiB,GAAG,MAAM,aAAa,IAAI;;EAG3E,kBAAkB;EAClB,MAAM,iBAAiB,IAAI,eAAe,iBAAiB;EAC3D,eAAe,QAAQ,MAAM;EAE7B,aAAa;GACX,SAAS,oBACP,mBACA,2BACA,EAAE,SAAS,MAAM,CAClB;GACD,eAAe,YAAY;;IAE5B,EAAE,CAAC;;CAGN,MAAM,CAAC,iBAAiB,sBAAsB,SAAS,MAAM;CAC7D,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;CACjD,MAAM,CAAC,sBAAsB,2BAA2B,SAEtD,KAAK;CACP,MAAM,CAAC,oBAAoB,yBAAyB,SAClD,KACD;CACD,MAAM,CAAC,qBAAqB,0BAA0B,SACpD,KACD;;CAGD,gBAAgB;EACd,mBAAmB;GAEjB,SAAS,SAAS,cAAc,IAAI,MAAM,QAAQ,CAAC;GAGnD,MAAM,IAAI,SAAS,SAAS,kBAAkB;GAC9C,MAAM,IAAI,SAAS,SAAS,gBAAgB;GAC5C,MAAM,MAAM,SAAS,SAAS,sBAAsB;GACpD,IAAI,MAAM,QAAQ,MAAM,MAAM;IAC5B,wBAAwB,EAAE;IAC1B,sBAAsB,EAAE;IAExB,uBAAuB,EAAE;IACzB,iBAAiB,QAAQ,OAAO;KAAC;KAAG;KAAG;KAAI;;IAE7C;IACD,CAAC,OAAO,UAAU,CAAC;CAEtB,gBAAgB;EACd,IAAI,kBAAkB,QACpB;EAGF,IACE,UAAU,iBACV,cAAc,SAAS,aACvB,MAAM,WAAW,WAEjB,aAAa,MAAM;IAEpB;EAAC;EAAW;EAAY;EAAe;EAAM,CAAC;CAGjD,MAAM,qBAAqB,OAAsB,KAAK;CACtD,gBAAgB;EACd,MAAM,kBACJ,aAAa,wBAAwB,OAAO,sBAAsB;EAEpE,IAAI,oBAAoB,mBAAmB,SAAS;GAClD,mBAAmB,UAAU;GAC7B,qBAAqB,gBAAgB;;IAEtC;EAAC;EAAW;EAAqB;EAAmB,CAAC;CAExD,MAAM,OAAO,wBAAwB;EACnC;EACA;EACA;EACA;EACD,CAAC;;CAGF,MAAM,mBAAmB,MAAqC;EAC5D,MAAM,WAAW,EAAE,cAAc,MAAM,MAAM,GAAG,UAAU;EAC1D,IAAI,SAAS,SAAS,KAAK,UAAU,CAAC,OAAO,KAAK,SAAS,EAAE;GAC3D,EAAE,gBAAgB;GAClB;;EAKF,IAFE,OAAO,kBAAkB,YACzB,SAAS,SAAS,cAAc,QAMhC,SAAS,cAAc,IAAI,MAAM,kBAAkB,CAAC;EAEtD,SAAS,SAAS;;CAEpB,MAAM,uBAAuB;EAC3B,IAAI,SAAS,SAAS;GACpB,MAAM,QAAQ,KAAK,IAAI,SAAS,QAAQ,MAAM,QAAQ,YAAY,EAAE;GACpE,MAAM,MAAM,SAAS,QAAQ,MAAM;GACnC,SAAS,SAAS,kBAAkB,OAAO,IAAI;GAC/C,wBAAwB,MAAM;GAC9B,sBAAsB,IAAI;;EAE5B,aAAa,KAAK;;CAGpB,MAAM,kBAAkB,MAAwC;EAC9D,MAAM,QAAQ,SAAS;EACvB,IACE,CAAC,qBACA,CAAC,eAAe,QAAQ,SAAS,CAAC,EAAE,iBAAiB,CAAC,QAEvD;EAGF,MAAM,WAAW,EAAE,cAAc,QAAQ,aAAa;EACtD,MAAM,UAAU,mBAAmB,iBAAiB,SAAS,GAAG;EAChE,EAAE,gBAAgB;EAElB,MAAM,QAAQ,SAAS,SAAS;EAChC,MAAM,MAAM,SAAS,SAAS;EAO9B,MAAM,YALc,UAAU,MAG1B,MAAM,MAAM,GAAG,SAAS,EAAE,GAAG,UAAU,MAAM,MAAM,OAAO,EAAE,GAC5D,MAAM,MAAM,GAAG,SAAS,EAAE,GAAG,UAAU,MAAM,MAAM,SAAS,EAAE,EAChC,MAAM,GAAG,UAAU;EAErD,IAAI,SAAS,SAAS,KAAK,UAAU,CAAC,OAAO,KAAK,SAAS,EACzD;EAGF,IAAI,OAAO;GACT,MAAM,QAAQ;GACd,SAAS,SAAS;GAElB,MAAM,SAAS,KAAK,IAAI,SAAS,QAAQ,YAAY,EAAE;GACvD,MAAM,OAAO,SAAS;GAEtB,MAAM,kBAAkB,QAAQ,KAAK;GACrC,wBAAwB,OAAO;GAC/B,sBAAsB,KAAK;;;;CAK/B,MAAM,oBAAmC;EACvC,OAAO,KAAK,mBACR,eAAe,KAAK,sBAAsB,KAC1C;EACJ,UAAU,KAAK,mBACX,WAAW,KAAK,sBAAsB,SACtC;EACJ,UAAU;EACX;;CAGD,MAAM,gBACJ,oBAAC,SAAD;EACE,cAAc,MAAM,gBAAgB;EACpC,GAAI;EACJ;EACA,oCAAkC,MAAM,WAAW,KAAK;EACxD,sBAAoB;EACpB,sBAAoB;EACT;EACX,SAAS,QAAQ;EACjB,oBAAkB;EAClB,WAAU;EACV,OAAO;EACI;EACJ;EACP,KAAK;EACL,UAAU,MAAM;GACd,eAAe,EAAE;GACjB,MAAM,UAAU,EAAE;;EAEpB,UAAU;EACV,cAAc,MAAM;GAClB,mBAAmB,KAAK;GACxB,MAAM,cAAc,EAAE;;EAExB,eAAe,MAAM;GACnB,mBAAmB,MAAM;GACzB,MAAM,eAAe,EAAE;;EAEzB,YAAY,MAAM;GAEhB,IAAI,EAAE,QAAQ,eAAe,EAAE,QAAQ,cAErC,4BAA4B;IAC1B,MAAM,QAAQ,SAAS;IACvB,IAAI,SAAS,SAAS,kBAAkB,OAAO;KAC7C,MAAM,IAAI,MAAM;KAChB,MAAM,MAAM,MAAM;KAClB,IAAI,MAAM,QAAQ,QAAQ,MAExB,uBAAuB,EAAE;;KAG7B;GAEJ,MAAM,YAAY,EAAE;;EAEtB,UAAU,MAAM;GACd,gBAAgB;GAChB,MAAM,UAAU,EAAE;;EAEpB,SAAS,MAAM;GACb,aAAa,MAAM;GACnB,MAAM,SAAS,EAAE;;EAEnB;CAGJ,MAAM,gBAAgB,UAAkB;EACtC,MAAM,QAAQ,SAAS;EACvB,IAAI,CAAC,SAAS,MAAM,UAClB;EAIF,MAAM,eAAe,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,YAAY,EAAE,CAAC;EAGhE,IAAI,SAAS,kBAAkB,OAC7B,MAAM,OAAO;EAKf,MAAM,UAAU,MAAM,kBAAkB;EACxC,MAAM,QAAQ;EACd,MAAM,MAAM,UAAU,eAAe,IAAI;EAEzC,MAAM,kBAAkB,OAAO,IAAI;EACnC,wBAAwB,MAAM;EAC9B,sBAAsB,IAAI;EAC1B,aAAa,KAAK;;CAGpB,MAAM,eAA4B;EAChC,OAAO,MAAM,KAAK,EAAE,QAAQ,WAAW,CAAC,CAAC,KAAK,GAAG,YAAY;GAC3D,MAAM,WACJ,aACA,yBAAyB,QACzB,uBAAuB,SACrB,yBAAyB,sBACzB,YAAY,wBACX,WAAW,wBAAwB,UAAU;GAElD,MAAM,OAAO,MAAM,aAAa,SAAY,MAAM,WAAW;GAI7D,OAAO;IACL;IACA,iBAJA,MAAM,OAAO,SAAY,OAAQ,cAAc,YAAY;IAK3D;IACA,cAAc,YAAY,SAAS;IACpC;IACD;EACF;EACA,YAAY,CAAC,MAAM,YAAY;EAC/B;EACD;CAED,MAAM,mBACJ,WAAW,SACT,OAAO,aAAa,GAEpB,oBAAC,gBAAgB,UAAjB;EAA0B,OAAO;EAC9B;EACwB;CAG/B,OACE,8CACG,wBAAwB,QACvB,oBAAC,YAAD,YACE,oBAAC,SAAD,YAAQ,qBAA4B,GAC3B,GAGb,qBAAC,OAAD;EACE,KAAK;EACL,WAAW,GACT,YACA,MAAM,WAAW,mBAAmB,eACpC,mBACD;YANH,CAQG,kBAED,oBAAC,OAAD;GAAK,WAAU;aAAoB;GAAoB,EACnD;IACL;;AAQP,MAAa,oBAAoB,IAAI,qBAAqB;CACxD,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACL,EACF;CACD,iBAAiB,EACf,MAAM,MACP;CACF,CAAC;AAEF,MAAa,YAA+B,EAC1C,WACA,QACA,GAAG,YAEH,oBAAC,UAAD;CACE,oBAAmB;CACnB,WAAW,GAAG,+BAA+B,UAAU;CAC/C;CACR,GAAI;CACJ;AAKJ,MAAa,iBAAiB,EAC5B,WACA,GAAG,YAEH,oBAAC,OAAD;CAAK,WAAW,GAAG,gCAAgC,UAAU;CAAE,GAAI;CAAS;AAS9E,MAAa,gBAAuC,EAClD,OACA,WACA,SACA,WACA,GAAG,YACC;CACJ,MAAM,kBAAkB,WAAW,gBAAgB;CACnD,MAAM,EAAE,MAAM,aAAa,iBAAiB,MAAM,UAAU,EAAE;CAC9D,MAAM,EAAE,iBAAiB,mBAAmB,EAAE;CAE9C,MAAM,eAAe,MAAqC;EACxD,eAAe,MAAM;EACrB,UAAU,EAAE;;CAGd,MAAM,iBAAiB,MAAwC;EAC7D,IAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;GACtC,EAAE,gBAAgB;GAClB,eAAe,MAAM;;EAEvB,YAAY,EAAE;;CAGhB,OACE,oBAAC,QAAD;EACE,YAAY;EACZ,SAAQ;EACR,OAAM;EACN,UAAU;EACV,WAAW,GAAG,uBAAuB,YAAY,WAAW,UAAU;EACtE,SAAS;EACT,WAAW;EACX,OAAO;EACP,GAAI;YAGJ,oBAAC,QAAD;GAAM,WAAU;aACb;GACI;EACA;;AAMb,MAAa,qBAAgD,UAC3D,oBAAC,OAAD;CACE;CACA,WAAU;CACV,GAAI;WAEJ,oBAAC,WAAD,EAAa;CACT;AAGR,MAAa,kBAA6C,UACxD,oBAAC,OAAD;CACE;CACA,WAAU;CACV,GAAI;CACJ"}
1
+ {"version":3,"file":"OTPInput.mjs","names":[],"sources":["../../../../src/components/Input/OTPInput.tsx"],"sourcesContent":["'use client';\n\n/**\n * This component is a fork of https://github.com/guilhermerodz/input-otp\n */\n\nimport { cn } from '@utils/cn';\nimport { cva } from 'class-variance-authority';\nimport { MinusIcon } from 'lucide-react';\nimport {\n type ChangeEvent,\n type ClipboardEvent,\n type ComponentProps,\n type CSSProperties,\n createContext,\n type FC,\n type InputHTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type RefObject,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { Button, type ButtonProps } from '../Button';\n\n// ---------------- Utilities ----------------\n\nconst syncTimeouts = (cb: (...args: any[]) => unknown): number[] => {\n const t1 = setTimeout(cb, 0); // For faster machines\n const t2 = setTimeout(cb, 1_0);\n const t3 = setTimeout(cb, 5_0);\n return [t1, t2, t3];\n};\n\nconst safeInsertRule = (sheet: CSSStyleSheet, rule: string) => {\n try {\n sheet.insertRule(rule);\n } catch {\n console.error('input-otp could not insert CSS rule:', rule);\n }\n};\n\n// Decided to go with <noscript>\n// instead of `scripting` CSS media query\n// because it's a fallback for initial page load\n// and the <script> tag won't be loaded\n// unless the user has JS disabled.\nconst NOSCRIPT_CSS_FALLBACK = `\n[data-input-otp] {\n --nojs-bg: white !important;\n --nojs-fg: black !important;\n\n background-color: var(--nojs-bg) !important;\n color: var(--nojs-fg) !important;\n caret-color: var(--nojs-fg) !important;\n letter-spacing: .25em !important;\n text-align: center !important;\n border: 1px solid var(--nojs-fg) !important;\n border-radius: 4px !important;\n width: 100% !important;\n}\n@media (prefers-color-scheme: dark) {\n [data-input-otp] {\n --nojs-bg: black !important;\n --nojs-fg: white !important;\n }\n}`;\n\n// ---------------- Constants ----------------\n\nconst PWM_BADGE_MARGIN_RIGHT = 18;\nconst PWM_BADGE_SPACE_WIDTH_PX = 40;\nconst PWM_BADGE_SPACE_WIDTH = `${PWM_BADGE_SPACE_WIDTH_PX}px` as const;\n\nconst PASSWORD_MANAGERS_SELECTORS = [\n '[data-lastpass-icon-root]', // LastPass\n 'com-1password-button', // 1Password\n '[data-dashlanecreated]', // Dashlane\n '[style$=\"2147483647 !important;\"]', // Bitwarden\n].join(',');\n\n// ---------------- Types ----------------\n\nexport type SlotProps = {\n isActive: boolean;\n char: string | null;\n placeholderChar: string | null;\n hasFakeCaret: boolean;\n};\n\nexport type RenderProps = {\n slots: SlotProps[];\n isFocused: boolean;\n isHovering: boolean;\n setSelection: (index: number) => void;\n};\n\ntype OverrideProps<T, R> = Omit<T, keyof R> & R;\n\ntype OTPInputBaseProps = OverrideProps<\n InputHTMLAttributes<HTMLInputElement>,\n {\n value?: string;\n onChange?: (newValue: string) => unknown;\n\n maxLength: number;\n\n onComplete?: (...args: any[]) => unknown;\n onActiveSlotChange?: (activeSlotIndex: number | null) => unknown;\n pushPasswordManagerStrategy?: 'increase-width' | 'none';\n pasteTransformer?: (pasted: string) => string;\n\n containerClassName?: string;\n\n noScriptCSSFallback?: string | null;\n }\n>;\n\ntype InputOTPRenderFn = (props: RenderProps) => ReactNode;\n\nexport type OTPInputProps = OTPInputBaseProps &\n (\n | {\n render: InputOTPRenderFn;\n children?: never;\n }\n | {\n render?: never;\n children: ReactNode;\n }\n );\n\n// ---------------- Hooks ----------------\n\nexport const usePasswordManagerBadge = ({\n containerRef,\n inputRef,\n pushPasswordManagerStrategy,\n isFocused,\n}: {\n containerRef: RefObject<HTMLDivElement | null>;\n inputRef: RefObject<HTMLInputElement | null>;\n pushPasswordManagerStrategy: OTPInputProps['pushPasswordManagerStrategy'];\n isFocused: boolean;\n}) => {\n /** Password managers have a badge\n * and I'll use this state to push them\n * outside the input */\n const [hasPWMBadge, setHasPWMBadge] = useState(false);\n const [hasPWMBadgeSpace, setHasPWMBadgeSpace] = useState(false);\n const [done, setDone] = useState(false);\n\n const willPushPWMBadge =\n pushPasswordManagerStrategy === 'none'\n ? false\n : (pushPasswordManagerStrategy === 'increase-width' ||\n // TODO: remove 'experimental-no-flickering' support in 2.0.0\n pushPasswordManagerStrategy === 'experimental-no-flickering') &&\n hasPWMBadge &&\n hasPWMBadgeSpace;\n\n const trackPWMBadge = () => {\n const container = containerRef.current;\n const input = inputRef.current;\n if (\n !container ||\n !input ||\n done ||\n pushPasswordManagerStrategy === 'none'\n ) {\n return;\n }\n\n const elementToCompare = container;\n\n // Get the top right-center point of the container.\n // That is usually where most password managers place their badge.\n const rightCornerX =\n elementToCompare.getBoundingClientRect().left +\n elementToCompare.offsetWidth;\n const centereredY =\n elementToCompare.getBoundingClientRect().top +\n elementToCompare.offsetHeight / 2;\n const x = rightCornerX - PWM_BADGE_MARGIN_RIGHT;\n const y = centereredY;\n\n // Do an extra search to check for famous password managers\n const pmws = document.querySelectorAll(PASSWORD_MANAGERS_SELECTORS);\n\n // If no password manager is automatically detect,\n // we'll try to dispatch document.elementFromPoint\n // to identify badges\n if (pmws.length === 0) {\n const maybeBadgeEl = document.elementFromPoint(x, y);\n\n // If the found element is the input itself,\n // then we assume it's not a password manager badge.\n // We are not sure. Most times that means there isn't a badge.\n if (maybeBadgeEl === container) {\n return;\n }\n }\n\n setHasPWMBadge(true);\n setDone(true);\n };\n\n useEffect(() => {\n const container = containerRef.current;\n if (!container || pushPasswordManagerStrategy === 'none') {\n return;\n }\n\n // Check if the PWM area is 100% visible\n const checkHasSpace = () => {\n const viewportWidth = window.innerWidth;\n const distanceToRightEdge =\n viewportWidth - container.getBoundingClientRect().right;\n setHasPWMBadgeSpace(distanceToRightEdge >= PWM_BADGE_SPACE_WIDTH_PX);\n };\n\n checkHasSpace();\n const interval = setInterval(checkHasSpace, 1000);\n\n return () => {\n clearInterval(interval);\n };\n }, [containerRef, pushPasswordManagerStrategy]);\n\n useEffect(() => {\n const _isFocused = isFocused || document.activeElement === inputRef.current;\n\n if (pushPasswordManagerStrategy === 'none' || !_isFocused) {\n return;\n }\n const t1 = setTimeout(trackPWMBadge, 0);\n const t2 = setTimeout(trackPWMBadge, 2000);\n const t3 = setTimeout(trackPWMBadge, 5000);\n const t4 = setTimeout(() => {\n setDone(true);\n }, 6000);\n return () => {\n clearTimeout(t1);\n clearTimeout(t2);\n clearTimeout(t3);\n clearTimeout(t4);\n };\n }, [inputRef, isFocused, pushPasswordManagerStrategy]);\n\n return { hasPWMBadge, willPushPWMBadge, PWM_BADGE_SPACE_WIDTH };\n};\n\nexport const usePrevious = <T,>(value: T): T | undefined => {\n const ref = useRef<T | undefined>(undefined);\n useEffect(() => {\n ref.current = value;\n });\n return ref.current;\n};\n\n// ---------------- Context ----------------\n\nexport const OTPInputContext = createContext<RenderProps>({} as RenderProps);\n\n// ---------------- Core Component ----------------\n\nexport const OTPInput: FC<OTPInputProps> = ({\n value: uncheckedValue,\n onChange: uncheckedOnChange,\n maxLength,\n pattern,\n placeholder,\n inputMode = 'numeric',\n onComplete,\n onActiveSlotChange,\n pushPasswordManagerStrategy = 'increase-width',\n pasteTransformer,\n containerClassName,\n noScriptCSSFallback = NOSCRIPT_CSS_FALLBACK,\n render,\n children,\n ...props\n}) => {\n // Only used when `value` state is not provided\n const [internalValue, setInternalValue] = useState(\n typeof props.defaultValue === 'string' ? props.defaultValue : ''\n );\n\n // Definitions\n const value = uncheckedValue ?? internalValue;\n const previousValue = usePrevious(value);\n const onChange = (newValue: string) => {\n uncheckedOnChange?.(newValue);\n setInternalValue(newValue);\n };\n const regexp =\n pattern !== undefined\n ? typeof pattern === 'string'\n ? new RegExp(pattern)\n : pattern\n : null;\n\n /** useRef */\n const inputRef = useRef<HTMLInputElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const initialLoadRef = useRef({\n value,\n onChange,\n isIOS:\n typeof window !== 'undefined' &&\n window?.CSS?.supports?.('-webkit-touch-callout', 'none'),\n });\n const inputMetadataRef = useRef<{\n prev: [number | null, number | null, 'none' | 'forward' | 'backward'];\n }>({\n prev: [\n inputRef.current?.selectionStart ?? null,\n inputRef.current?.selectionEnd ?? null,\n inputRef.current?.selectionDirection ?? 'none',\n ],\n });\n useEffect(() => {\n const input = inputRef.current;\n const container = containerRef.current;\n\n if (!input || !container) {\n return;\n }\n\n // Sync input value\n if (initialLoadRef.current.value !== input.value) {\n initialLoadRef.current.onChange(input.value);\n }\n\n // Previous selection\n inputMetadataRef.current.prev = [\n input.selectionStart,\n input.selectionEnd,\n input.selectionDirection ?? 'none',\n ];\n const onDocumentSelectionChange = () => {\n if (document.activeElement !== input) {\n setMirrorSelectionStart(null);\n setMirrorSelectionEnd(null);\n setActualCaretPosition(null);\n return;\n }\n\n const selectionStart = input.selectionStart;\n const selectionEnd = input.selectionEnd;\n const selectionDirection = input.selectionDirection;\n const maxLength = input.maxLength;\n const value = input.value;\n const previousSelection = inputMetadataRef.current.prev;\n\n let calculatedStart = -1;\n let calculatedEnd = -1;\n let calculatedDirection: 'forward' | 'backward' | 'none' =\n selectionDirection ?? 'none';\n\n if (\n value.length !== 0 &&\n selectionStart !== null &&\n selectionEnd !== null\n ) {\n const isSingleCaret = selectionStart === selectionEnd;\n const isInsertMode =\n selectionStart === value.length && value.length < maxLength;\n\n if (isSingleCaret && !isInsertMode) {\n const caretPosition = selectionStart;\n if (caretPosition === 0) {\n calculatedStart = 0;\n calculatedEnd = 1;\n calculatedDirection = 'forward';\n } else if (caretPosition === maxLength) {\n calculatedStart = caretPosition - 1;\n calculatedEnd = caretPosition;\n calculatedDirection = 'backward';\n } else if (maxLength > 1 && value.length > 1) {\n let offset = 0;\n if (\n previousSelection[0] !== null &&\n previousSelection[1] !== null\n ) {\n calculatedDirection =\n caretPosition < previousSelection[1] ? 'backward' : 'forward';\n const wasPreviouslyInserting =\n previousSelection[0] === previousSelection[1] &&\n previousSelection[0] < maxLength;\n if (\n calculatedDirection === 'backward' &&\n !wasPreviouslyInserting\n ) {\n offset = -1;\n }\n }\n\n calculatedStart = offset + caretPosition;\n calculatedEnd = offset + caretPosition + 1;\n }\n }\n\n if (\n calculatedStart !== -1 &&\n calculatedEnd !== -1 &&\n calculatedStart !== calculatedEnd\n ) {\n inputRef.current?.setSelectionRange(\n calculatedStart,\n calculatedEnd,\n calculatedDirection\n );\n }\n }\n\n const finalSelectionStart =\n calculatedStart !== -1 ? calculatedStart : selectionStart;\n const finalSelectionEnd =\n calculatedEnd !== -1 ? calculatedEnd : selectionEnd;\n const finalDirection = calculatedDirection;\n\n // Track actual caret position (before expansion) for active slot detection\n if (selectionStart !== null && selectionEnd !== null) {\n const isSingleCaret = selectionStart === selectionEnd;\n if (isSingleCaret) {\n setActualCaretPosition(selectionStart);\n } else {\n // When selection is expanded, use the start position as the caret\n setActualCaretPosition(finalSelectionStart);\n }\n } else {\n setActualCaretPosition(null);\n }\n\n setMirrorSelectionStart(finalSelectionStart);\n setMirrorSelectionEnd(finalSelectionEnd);\n inputMetadataRef.current.prev = [\n finalSelectionStart,\n finalSelectionEnd,\n finalDirection,\n ];\n };\n document.addEventListener('selectionchange', onDocumentSelectionChange, {\n capture: true,\n });\n\n // Set initial mirror state\n onDocumentSelectionChange();\n if (document.activeElement === input) {\n setIsFocused(true);\n }\n\n // Apply needed styles\n if (!document.getElementById('input-otp-style')) {\n const styleEl = document.createElement('style');\n styleEl.id = 'input-otp-style';\n document.head.appendChild(styleEl);\n\n if (styleEl.sheet) {\n const autofillStyles =\n 'background: transparent !important; color: transparent !important; border-color: transparent !important; opacity: 0 !important; box-shadow: none !important; -webkit-box-shadow: none !important; -webkit-text-fill-color: transparent !important;';\n\n safeInsertRule(\n styleEl.sheet,\n '[data-input-otp]::selection { background: transparent !important; color: transparent !important; }'\n );\n safeInsertRule(\n styleEl.sheet,\n `[data-input-otp]:autofill { ${autofillStyles} }`\n );\n safeInsertRule(\n styleEl.sheet,\n `[data-input-otp]:-webkit-autofill { ${autofillStyles} }`\n );\n // iOS\n safeInsertRule(\n styleEl.sheet,\n `@supports (-webkit-touch-callout: none) { [data-input-otp] { letter-spacing: -.6em !important; font-weight: 100 !important; font-stretch: ultra-condensed; font-optical-sizing: none !important; left: -1px !important; right: 1px !important; } }`\n );\n // PWM badges\n safeInsertRule(\n styleEl.sheet,\n `[data-input-otp] + * { pointer-events: all !important; }`\n );\n }\n }\n // Track root height\n const updateRootHeight = () => {\n if (container) {\n container.style.setProperty('--root-height', `${input.clientHeight}px`);\n }\n };\n updateRootHeight();\n const resizeObserver = new ResizeObserver(updateRootHeight);\n resizeObserver.observe(input);\n\n return () => {\n document.removeEventListener(\n 'selectionchange',\n onDocumentSelectionChange,\n { capture: true }\n );\n resizeObserver.disconnect();\n };\n }, []);\n\n /** Mirrors for UI rendering purpose only */\n const [isHoveringInput, setIsHoveringInput] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [mirrorSelectionStart, setMirrorSelectionStart] = useState<\n number | null\n >(null);\n const [mirrorSelectionEnd, setMirrorSelectionEnd] = useState<number | null>(\n null\n );\n const [actualCaretPosition, setActualCaretPosition] = useState<number | null>(\n null\n );\n\n /** Effects */\n useEffect(() => {\n syncTimeouts(() => {\n // Forcefully remove :autofill state\n inputRef.current?.dispatchEvent(new Event('input'));\n\n // Update the selection state\n const s = inputRef.current?.selectionStart ?? null;\n const e = inputRef.current?.selectionEnd ?? null;\n const dir = inputRef.current?.selectionDirection ?? 'none';\n if (s !== null && e !== null) {\n setMirrorSelectionStart(s);\n setMirrorSelectionEnd(e);\n // Track actual caret position (use start position as caret)\n setActualCaretPosition(s);\n inputMetadataRef.current.prev = [s, e, dir];\n }\n });\n }, [value, isFocused]);\n\n useEffect(() => {\n if (previousValue === undefined) {\n return;\n }\n\n if (\n value !== previousValue &&\n previousValue.length < maxLength &&\n value.length === maxLength\n ) {\n onComplete?.(value);\n }\n }, [maxLength, onComplete, previousValue, value]);\n\n // Track active slot changes\n const previousActiveSlot = useRef<number | null>(null);\n useEffect(() => {\n const activeSlotIndex =\n isFocused && actualCaretPosition !== null ? actualCaretPosition : null;\n\n if (activeSlotIndex !== previousActiveSlot.current) {\n previousActiveSlot.current = activeSlotIndex;\n onActiveSlotChange?.(activeSlotIndex);\n }\n }, [isFocused, actualCaretPosition, onActiveSlotChange]);\n\n const pwmb = usePasswordManagerBadge({\n containerRef,\n inputRef,\n pushPasswordManagerStrategy,\n isFocused,\n });\n\n /** Event handlers */\n const _changeListener = (e: ChangeEvent<HTMLInputElement>) => {\n const newValue = e.currentTarget.value.slice(0, maxLength);\n if (newValue.length > 0 && regexp && !regexp.test(newValue)) {\n e.preventDefault();\n return;\n }\n const maybeHasDeleted =\n typeof previousValue === 'string' &&\n newValue.length < previousValue.length;\n if (maybeHasDeleted) {\n // Since cutting/deleting text doesn't trigger\n // selectionchange event, we'll have to dispatch it manually.\n // NOTE: The following line also triggers when cmd+A then pasting\n // a value with smaller length, which is not ideal for performance.\n document.dispatchEvent(new Event('selectionchange'));\n }\n onChange(newValue);\n };\n const _focusListener = () => {\n if (inputRef.current) {\n const start = Math.min(inputRef.current.value.length, maxLength - 1);\n const end = inputRef.current.value.length;\n inputRef.current?.setSelectionRange(start, end);\n setMirrorSelectionStart(start);\n setMirrorSelectionEnd(end);\n }\n setIsFocused(true);\n };\n // Fix iOS pasting\n const _pasteListener = (e: ClipboardEvent<HTMLInputElement>) => {\n const input = inputRef.current;\n if (\n !pasteTransformer &&\n (!initialLoadRef.current.isIOS || !e.clipboardData || !input)\n ) {\n return;\n }\n\n const _content = e.clipboardData.getData('text/plain');\n const content = pasteTransformer ? pasteTransformer(_content) : _content;\n e.preventDefault();\n\n const start = inputRef.current?.selectionStart;\n const end = inputRef.current?.selectionEnd;\n\n const isReplacing = start !== end;\n\n const newValueUncapped = isReplacing\n ? value.slice(0, start ?? 0) + content + value.slice(end ?? 0) // Replacing\n : value.slice(0, start ?? 0) + content + value.slice(start ?? 0); // Inserting\n const newValue = newValueUncapped.slice(0, maxLength);\n\n if (newValue.length > 0 && regexp && !regexp.test(newValue)) {\n return;\n }\n\n if (input) {\n input.value = newValue;\n onChange(newValue);\n\n const _start = Math.min(newValue.length, maxLength - 1);\n const _end = newValue.length;\n\n input.setSelectionRange(_start, _end);\n setMirrorSelectionStart(_start);\n setMirrorSelectionEnd(_end);\n }\n };\n\n /** Styles - dynamic styles that can't be converted to Tailwind */\n const dynamicInputStyle: CSSProperties = {\n width: pwmb.willPushPWMBadge\n ? `calc(100% + ${pwmb.PWM_BADGE_SPACE_WIDTH})`\n : '100%',\n clipPath: pwmb.willPushPWMBadge\n ? `inset(0 ${pwmb.PWM_BADGE_SPACE_WIDTH} 0 0)`\n : undefined,\n fontSize: 'var(--root-height)',\n };\n\n /** Rendering */\n const renderedInput = (\n <input\n autoComplete={props.autoComplete || 'one-time-code'}\n {...props}\n data-input-otp\n data-input-otp-placeholder-shown={value.length === 0 || undefined}\n data-input-otp-mss={mirrorSelectionStart}\n data-input-otp-mse={mirrorSelectionEnd}\n inputMode={inputMode}\n pattern={regexp?.source}\n aria-placeholder={placeholder}\n className=\"pointer-events-auto absolute inset-0 -z-10 flex h-full border-0 border-transparent bg-transparent text-center font-mono text-transparent tabular-nums leading-none tracking-[-.5em] caret-transparent opacity-100 shadow-none outline-none\"\n style={dynamicInputStyle}\n maxLength={maxLength}\n value={value}\n ref={inputRef}\n onPaste={(e) => {\n _pasteListener(e);\n props.onPaste?.(e);\n }}\n onChange={_changeListener}\n onMouseOver={(e) => {\n setIsHoveringInput(true);\n props.onMouseOver?.(e);\n }}\n onMouseLeave={(e) => {\n setIsHoveringInput(false);\n props.onMouseLeave?.(e);\n }}\n onKeyDown={(e) => {\n // Track arrow key navigation to ensure active slot updates correctly\n if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {\n // Use requestAnimationFrame to check selection after browser has processed the key\n requestAnimationFrame(() => {\n const input = inputRef.current;\n if (input && document.activeElement === input) {\n const s = input.selectionStart;\n const end = input.selectionEnd;\n if (s !== null && end !== null) {\n // Update actual caret position - use start position as caret\n setActualCaretPosition(s);\n }\n }\n });\n }\n props.onKeyDown?.(e);\n }}\n onFocus={(e) => {\n _focusListener();\n props.onFocus?.(e);\n }}\n onBlur={(e) => {\n setIsFocused(false);\n props.onBlur?.(e);\n }}\n />\n );\n\n const setSelection = (index: number) => {\n const input = inputRef.current;\n if (!input || props.disabled) {\n return;\n }\n\n // Clamp index to valid range\n const clampedIndex = Math.max(0, Math.min(index, maxLength - 1));\n\n // Focus the input if not already focused\n if (document.activeElement !== input) {\n input.focus();\n }\n\n // Set selection to the clicked slot\n // If there's a character at that position, select it; otherwise just position the caret\n const hasChar = value[clampedIndex] !== undefined;\n const start = clampedIndex;\n const end = hasChar ? clampedIndex + 1 : clampedIndex;\n\n input.setSelectionRange(start, end);\n setMirrorSelectionStart(start);\n setMirrorSelectionEnd(end);\n setIsFocused(true);\n };\n\n const contextValue: RenderProps = {\n slots: Array.from({ length: maxLength }).map((_, slotIdx) => {\n const isActive =\n isFocused &&\n mirrorSelectionStart !== null &&\n mirrorSelectionEnd !== null &&\n ((mirrorSelectionStart === mirrorSelectionEnd &&\n slotIdx === mirrorSelectionStart) ||\n (slotIdx >= mirrorSelectionStart && slotIdx < mirrorSelectionEnd));\n\n const char = value[slotIdx] !== undefined ? value[slotIdx] : null;\n const placeholderChar =\n value[0] !== undefined ? null : (placeholder?.[slotIdx] ?? null);\n\n return {\n char,\n placeholderChar,\n isActive,\n hasFakeCaret: isActive && char === null,\n };\n }),\n isFocused,\n isHovering: !props.disabled && isHoveringInput,\n setSelection,\n };\n\n const renderedChildren =\n render !== undefined ? (\n render(contextValue)\n ) : (\n <OTPInputContext.Provider value={contextValue}>\n {children}\n </OTPInputContext.Provider>\n );\n\n return (\n <>\n {noScriptCSSFallback !== null && (\n <noscript>\n <style>{noScriptCSSFallback}</style>\n </noscript>\n )}\n\n <div\n ref={containerRef}\n className={cn(\n 'relative',\n props.disabled ? 'cursor-default' : 'cursor-text',\n containerClassName\n )}\n >\n {renderedChildren}\n\n <div className=\"absolute inset-0\">{renderedInput}</div>\n </div>\n </>\n );\n};\n\n// ---------------- Root ----------------\n\ntype InputOTPProps = Omit<ComponentProps<typeof OTPInput>, 'children'>;\n\nexport const inputSlotVariants = cva('block text-center', {\n variants: {\n size: {\n sm: 'h-4 w-3 text-sm',\n md: 'h-5 w-4 text-base',\n lg: 'h-6 w-5 text-lg',\n xl: 'h-7 w-6 text-xl',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\nexport const InputOTP: FC<InputOTPProps> = ({\n className,\n render,\n ...props\n}) => (\n <OTPInput\n containerClassName=\"relative flex items-center gap-2 has-disabled:opacity-50\"\n className={cn('disabled:cursor-not-allowed', className)}\n render={render!}\n {...props}\n />\n);\n\n// ---------------- Group ----------------\n\nexport const InputOTPGroup = ({\n className,\n ...props\n}: ComponentProps<'div'>) => (\n <div className={cn('z-10 flex items-center gap-3', className)} {...props} />\n);\n\n// ---------------- Slot ----------------\n\ntype InputOTPSlotProps = Omit<ButtonProps, 'variant' | 'label'> & {\n index: number;\n};\n\nexport const InputOTPSlot: FC<InputOTPSlotProps> = ({\n index,\n className,\n onClick,\n onKeyDown,\n ...props\n}) => {\n const inputOTPContext = useContext(OTPInputContext);\n const { char, isActive } = inputOTPContext?.slots[index] ?? {};\n const { setSelection } = inputOTPContext ?? {};\n\n const handleClick = (e: MouseEvent<HTMLButtonElement>) => {\n setSelection?.(index);\n onClick?.(e);\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLButtonElement>) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setSelection?.(index);\n }\n onKeyDown?.(e);\n };\n\n return (\n <Button\n isSelected={isActive}\n variant=\"input\"\n color=\"custom\"\n tabIndex={-1}\n className={cn('relative z-10 px-2!', isActive && 'ring-4!', className)}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n label={null}\n {...props}\n >\n {/* value */}\n <span className=\"relative z-10 flex h-6 w-4 items-center justify-center\">\n {char}\n </span>\n </Button>\n );\n};\n\n// ---------------- Separator ----------------\n\nexport const InputOTPSeparator: FC<ComponentProps<'div'>> = (props) => (\n <div\n aria-hidden\n className=\"z-0 table h-0.5 w-3 rounded-full text-text/50\"\n {...props}\n >\n <MinusIcon />\n </div>\n);\n\nexport const InputIndicator: FC<ComponentProps<'div'>> = (props) => (\n <div\n data-indicator\n className=\"absolute top-0 z-0 h-full w-auto rounded-xl bg-text/20 ring-4 ring-text/20 transition-[left,width] duration-300 ease-in-out [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl motion-reduce:transition-none\"\n {...props}\n />\n);\n"],"mappings":"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"}
@@ -130,10 +130,13 @@ const Pagination = ({ currentPage, totalPages, onPageChange, showFirstLast = fal
130
130
  /* @__PURE__ */ jsx("div", {
131
131
  className: "flex items-center gap-1 max-md:gap-0.5",
132
132
  children: pageNumbers.map((page, index) => {
133
- if (page === "ellipsis") return /* @__PURE__ */ jsx("div", {
134
- className: "flex h-8 min-w-8 items-center justify-center px-1",
135
- children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4 text-muted-foreground" })
136
- }, `ellipsis-${page}-${index}`);
133
+ if (page === "ellipsis") {
134
+ const ellipsisKey = index === pageNumbers.indexOf("ellipsis") ? "ellipsis-start" : "ellipsis-end";
135
+ return /* @__PURE__ */ jsx("div", {
136
+ className: "flex h-8 min-w-8 items-center justify-center px-1",
137
+ children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-4 w-4 text-muted-foreground" })
138
+ }, ellipsisKey);
139
+ }
137
140
  const isActive = page === currentPage;
138
141
  const refIndex = (showPrevNext ? 1 : 0) + pageNumbers.slice(0, index).filter((p) => p !== "ellipsis").length;
139
142
  return /* @__PURE__ */ jsx(Button, {
@@ -147,7 +150,7 @@ const Pagination = ({ currentPage, totalPages, onPageChange, showFirstLast = fal
147
150
  ref: (el) => {
148
151
  if (el) optionsRefs.current[refIndex] = el;
149
152
  },
150
- className: cn("flex aspect-square h-8 w-8 min-w-0 items-center justify-center p-0 text-sm", size === "sm" && "h-6 w-6 text-xs", size === "lg" && "h-10 w-10 text-base", isActive && "font-semibold"),
153
+ className: cn("flex aspect-square h-8 w-8 min-w-0 items-center justify-center p-0 text-sm", size === "sm" && "h-6 w-6 text-xs", size === "lg" && "size-10 text-base", isActive && "font-semibold"),
151
154
  children: page
152
155
  }, page);
153
156
  })
@@ -1 +1 @@
1
- {"version":3,"file":"Pagination.mjs","names":[],"sources":["../../../../src/components/Pagination/Pagination.tsx"],"sourcesContent":["'use client';\n\nimport { useItemSelector } from '@hooks/useItemSelector';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react';\nimport {\n type ComponentProps,\n type FC,\n type HTMLAttributes,\n useEffect,\n useRef,\n} from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { Button, ButtonColor, ButtonSize, ButtonVariant } from '../Button';\n\nexport const paginationVariants = cva(\n 'flex items-center justify-center gap-1',\n {\n variants: {\n size: {\n sm: 'gap-1',\n md: 'gap-2',\n lg: 'gap-3',\n },\n color: {\n text: 'background-text',\n primary: 'background-primary',\n secondary: 'background-secondary',\n neutral: 'background-neutral',\n destructive: 'background-destructive',\n },\n variant: {\n default: '',\n bordered: 'rounded-lg border border-border p-2',\n ghost: 'bg-transparent',\n },\n },\n defaultVariants: {\n size: 'md',\n variant: 'default',\n },\n }\n);\n\nexport enum PaginationSize {\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n}\n\nexport enum PaginationVariant {\n DEFAULT = 'default',\n BORDERED = 'bordered',\n GHOST = 'ghost',\n}\n\nexport type PaginationProps = HTMLAttributes<HTMLDivElement> &\n VariantProps<typeof paginationVariants> & {\n currentPage: number;\n totalPages: number;\n onPageChange: (page: number) => void;\n showFirstLast?: boolean;\n showPrevNext?: boolean;\n maxVisiblePages?: number;\n disabled?: boolean;\n };\n\nconst generatePageNumbers = (\n currentPage: number,\n totalPages: number,\n maxVisiblePages: number\n): (number | 'ellipsis')[] => {\n if (totalPages <= maxVisiblePages) {\n return Array.from({ length: totalPages }, (_, i) => i + 1);\n }\n\n const pages: (number | 'ellipsis')[] = [];\n const halfVisible = Math.floor(maxVisiblePages / 2);\n\n pages.push(1);\n\n if (currentPage <= halfVisible + 2) {\n for (let i = 2; i <= Math.min(maxVisiblePages - 1, totalPages - 1); i++) {\n pages.push(i);\n }\n if (totalPages > maxVisiblePages) {\n pages.push('ellipsis');\n }\n if (totalPages > 1) {\n pages.push(totalPages);\n }\n } else if (currentPage >= totalPages - halfVisible - 1) {\n if (totalPages > maxVisiblePages) {\n pages.push('ellipsis');\n }\n for (\n let i = Math.max(2, totalPages - maxVisiblePages + 2);\n i <= totalPages;\n i++\n ) {\n pages.push(i);\n }\n } else {\n pages.push('ellipsis');\n const start = currentPage - halfVisible;\n const end = currentPage + halfVisible;\n for (let i = start; i <= end; i++) {\n pages.push(i);\n }\n pages.push('ellipsis');\n pages.push(totalPages);\n }\n\n return pages;\n};\n\nconst selector = (option: HTMLElement) =>\n option?.getAttribute('aria-current') === 'true';\n\nconst getButtonSize = (size?: PaginationSize | `${PaginationSize}` | null) => {\n if (size === PaginationSize.SM) {\n return ButtonSize.ICON_SM;\n } else if (size === PaginationSize.LG) {\n return ButtonSize.ICON_LG;\n } else {\n return ButtonSize.ICON_MD;\n }\n};\n\nconst InputIndicator: FC<ComponentProps<'div'>> = (props) => (\n <div\n className=\"absolute top-0 z-0 h-full w-auto rounded-xl bg-text/20 ring-4 ring-text/10 transition-[left,width] duration-300 ease-in-out [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl motion-reduce:transition-none\"\n {...props}\n />\n);\n\nexport const Pagination: FC<PaginationProps> = ({\n currentPage,\n totalPages,\n onPageChange,\n showFirstLast = false,\n showPrevNext = true,\n maxVisiblePages = 5,\n disabled = false,\n size = PaginationSize.MD,\n variant = PaginationVariant.DEFAULT,\n color = ButtonColor.TEXT,\n className,\n ...props\n}) => {\n const { goToNextPage, goToPreviousPage } = useIntlayer('pagination');\n\n const pageNumbers = generatePageNumbers(\n currentPage,\n totalPages,\n maxVisiblePages\n );\n\n const buttonSize = getButtonSize(size);\n const isFirstPage = currentPage === 1;\n const isLastPage = currentPage === totalPages;\n\n const optionsRefs = useRef<HTMLElement[]>([]);\n const indicatorRef = useRef<HTMLDivElement | null>(null);\n const { choiceIndicatorPosition, calculatePosition } = useItemSelector(\n optionsRefs,\n {\n selector,\n isHoverable: true,\n }\n );\n\n useEffect(() => {\n const timer = setTimeout(() => {\n calculatePosition();\n }, 300);\n\n return () => clearTimeout(timer);\n }, [currentPage, calculatePosition]);\n\n if (totalPages <= 1) return null;\n\n const handlePageChange = (page: number) => {\n if (!disabled && page >= 1 && page <= totalPages && page !== currentPage) {\n onPageChange(page);\n }\n };\n\n return (\n <div\n className={cn(paginationVariants({ size, variant }), className)}\n {...props}\n >\n <div className=\"relative flex items-center gap-1\">\n {choiceIndicatorPosition && (\n <InputIndicator style={choiceIndicatorPosition} ref={indicatorRef} />\n )}\n\n {showPrevNext && (\n <Button\n variant={ButtonVariant.OUTLINE}\n size={buttonSize}\n color={ButtonColor.TEXT}\n onClick={() => handlePageChange(currentPage - 1)}\n disabled={disabled || isFirstPage}\n label={goToPreviousPage.value}\n Icon={ChevronLeft}\n ref={(el) => {\n if (el) optionsRefs.current[0] = el;\n }}\n className=\"min-w-0 px-2\"\n />\n )}\n\n <div className=\"flex items-center gap-1 max-md:gap-0.5\">\n {pageNumbers.map((page, index) => {\n if (page === 'ellipsis') {\n return (\n <div\n key={`ellipsis-${page}-${index}`}\n className=\"flex h-8 min-w-8 items-center justify-center px-1\"\n >\n <MoreHorizontal className=\"h-4 w-4 text-muted-foreground\" />\n </div>\n );\n }\n\n const isActive = page === currentPage;\n // Calculate ref index: offset by 1 if showPrevNext, then count only non-ellipsis items\n const refIndex =\n (showPrevNext ? 1 : 0) +\n pageNumbers.slice(0, index).filter((p) => p !== 'ellipsis')\n .length;\n\n return (\n <Button\n key={page}\n variant={\n isActive ? ButtonVariant.DEFAULT : ButtonVariant.OUTLINE\n }\n size={buttonSize}\n color={ButtonColor.TEXT}\n onClick={() => handlePageChange(page)}\n disabled={disabled}\n label={`Go to page ${page}`}\n aria-current={isActive ? 'true' : 'false'}\n ref={(el) => {\n if (el) optionsRefs.current[refIndex] = el;\n }}\n className={cn(\n 'flex aspect-square h-8 w-8 min-w-0 items-center justify-center p-0 text-sm',\n size === 'sm' && 'h-6 w-6 text-xs',\n size === 'lg' && 'h-10 w-10 text-base',\n isActive && 'font-semibold'\n )}\n >\n {page}\n </Button>\n );\n })}\n </div>\n\n {showPrevNext && (\n <Button\n variant={ButtonVariant.OUTLINE}\n size={buttonSize}\n color={ButtonColor.TEXT}\n onClick={() => handlePageChange(currentPage + 1)}\n disabled={disabled || isLastPage}\n label={goToNextPage.value}\n Icon={ChevronRight}\n ref={(el) => {\n const lastRefIndex =\n (showPrevNext ? 1 : 0) +\n pageNumbers.filter((p) => p !== 'ellipsis').length;\n if (el) optionsRefs.current[lastRefIndex] = el;\n }}\n className=\"min-w-0 px-2\"\n />\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"Pagination.mjs","names":[],"sources":["../../../../src/components/Pagination/Pagination.tsx"],"sourcesContent":["'use client';\n\nimport { useItemSelector } from '@hooks/useItemSelector';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react';\nimport {\n type ComponentProps,\n type FC,\n type HTMLAttributes,\n useEffect,\n useRef,\n} from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { Button, ButtonColor, ButtonSize, ButtonVariant } from '../Button';\n\nexport const paginationVariants = cva(\n 'flex items-center justify-center gap-1',\n {\n variants: {\n size: {\n sm: 'gap-1',\n md: 'gap-2',\n lg: 'gap-3',\n },\n color: {\n text: 'background-text',\n primary: 'background-primary',\n secondary: 'background-secondary',\n neutral: 'background-neutral',\n destructive: 'background-destructive',\n },\n variant: {\n default: '',\n bordered: 'rounded-lg border border-border p-2',\n ghost: 'bg-transparent',\n },\n },\n defaultVariants: {\n size: 'md',\n variant: 'default',\n },\n }\n);\n\nexport enum PaginationSize {\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n}\n\nexport enum PaginationVariant {\n DEFAULT = 'default',\n BORDERED = 'bordered',\n GHOST = 'ghost',\n}\n\nexport type PaginationProps = HTMLAttributes<HTMLDivElement> &\n VariantProps<typeof paginationVariants> & {\n currentPage: number;\n totalPages: number;\n onPageChange: (page: number) => void;\n showFirstLast?: boolean;\n showPrevNext?: boolean;\n maxVisiblePages?: number;\n disabled?: boolean;\n };\n\nconst generatePageNumbers = (\n currentPage: number,\n totalPages: number,\n maxVisiblePages: number\n): (number | 'ellipsis')[] => {\n if (totalPages <= maxVisiblePages) {\n return Array.from({ length: totalPages }, (_, i) => i + 1);\n }\n\n const pages: (number | 'ellipsis')[] = [];\n const halfVisible = Math.floor(maxVisiblePages / 2);\n\n pages.push(1);\n\n if (currentPage <= halfVisible + 2) {\n for (let i = 2; i <= Math.min(maxVisiblePages - 1, totalPages - 1); i++) {\n pages.push(i);\n }\n if (totalPages > maxVisiblePages) {\n pages.push('ellipsis');\n }\n if (totalPages > 1) {\n pages.push(totalPages);\n }\n } else if (currentPage >= totalPages - halfVisible - 1) {\n if (totalPages > maxVisiblePages) {\n pages.push('ellipsis');\n }\n for (\n let i = Math.max(2, totalPages - maxVisiblePages + 2);\n i <= totalPages;\n i++\n ) {\n pages.push(i);\n }\n } else {\n pages.push('ellipsis');\n const start = currentPage - halfVisible;\n const end = currentPage + halfVisible;\n for (let i = start; i <= end; i++) {\n pages.push(i);\n }\n pages.push('ellipsis');\n pages.push(totalPages);\n }\n\n return pages;\n};\n\nconst selector = (option: HTMLElement) =>\n option?.getAttribute('aria-current') === 'true';\n\nconst getButtonSize = (size?: PaginationSize | `${PaginationSize}` | null) => {\n if (size === PaginationSize.SM) {\n return ButtonSize.ICON_SM;\n } else if (size === PaginationSize.LG) {\n return ButtonSize.ICON_LG;\n } else {\n return ButtonSize.ICON_MD;\n }\n};\n\nconst InputIndicator: FC<ComponentProps<'div'>> = (props) => (\n <div\n className=\"absolute top-0 z-0 h-full w-auto rounded-xl bg-text/20 ring-4 ring-text/10 transition-[left,width] duration-300 ease-in-out [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl motion-reduce:transition-none\"\n {...props}\n />\n);\n\nexport const Pagination: FC<PaginationProps> = ({\n currentPage,\n totalPages,\n onPageChange,\n showFirstLast = false,\n showPrevNext = true,\n maxVisiblePages = 5,\n disabled = false,\n size = PaginationSize.MD,\n variant = PaginationVariant.DEFAULT,\n color = ButtonColor.TEXT,\n className,\n ...props\n}) => {\n const { goToNextPage, goToPreviousPage } = useIntlayer('pagination');\n\n const pageNumbers = generatePageNumbers(\n currentPage,\n totalPages,\n maxVisiblePages\n );\n\n const buttonSize = getButtonSize(size);\n const isFirstPage = currentPage === 1;\n const isLastPage = currentPage === totalPages;\n\n const optionsRefs = useRef<HTMLElement[]>([]);\n const indicatorRef = useRef<HTMLDivElement | null>(null);\n const { choiceIndicatorPosition, calculatePosition } = useItemSelector(\n optionsRefs,\n {\n selector,\n isHoverable: true,\n }\n );\n\n useEffect(() => {\n const timer = setTimeout(() => {\n calculatePosition();\n }, 300);\n\n return () => clearTimeout(timer);\n }, [currentPage, calculatePosition]);\n\n if (totalPages <= 1) return null;\n\n const handlePageChange = (page: number) => {\n if (!disabled && page >= 1 && page <= totalPages && page !== currentPage) {\n onPageChange(page);\n }\n };\n\n return (\n <div\n className={cn(paginationVariants({ size, variant }), className)}\n {...props}\n >\n <div className=\"relative flex items-center gap-1\">\n {choiceIndicatorPosition && (\n <InputIndicator style={choiceIndicatorPosition} ref={indicatorRef} />\n )}\n\n {showPrevNext && (\n <Button\n variant={ButtonVariant.OUTLINE}\n size={buttonSize}\n color={ButtonColor.TEXT}\n onClick={() => handlePageChange(currentPage - 1)}\n disabled={disabled || isFirstPage}\n label={goToPreviousPage.value}\n Icon={ChevronLeft}\n ref={(el) => {\n if (el) optionsRefs.current[0] = el;\n }}\n className=\"min-w-0 px-2\"\n />\n )}\n\n <div className=\"flex items-center gap-1 max-md:gap-0.5\">\n {pageNumbers.map((page, index) => {\n if (page === 'ellipsis') {\n const isFirstEllipsis = index === pageNumbers.indexOf('ellipsis');\n const ellipsisKey = isFirstEllipsis\n ? 'ellipsis-start'\n : 'ellipsis-end';\n return (\n <div\n key={ellipsisKey}\n className=\"flex h-8 min-w-8 items-center justify-center px-1\"\n >\n <MoreHorizontal className=\"h-4 w-4 text-muted-foreground\" />\n </div>\n );\n }\n\n const isActive = page === currentPage;\n // Calculate ref index: offset by 1 if showPrevNext, then count only non-ellipsis items\n const refIndex =\n (showPrevNext ? 1 : 0) +\n pageNumbers.slice(0, index).filter((p) => p !== 'ellipsis')\n .length;\n\n return (\n <Button\n key={page}\n variant={\n isActive ? ButtonVariant.DEFAULT : ButtonVariant.OUTLINE\n }\n size={buttonSize}\n color={ButtonColor.TEXT}\n onClick={() => handlePageChange(page)}\n disabled={disabled}\n label={`Go to page ${page}`}\n aria-current={isActive ? 'true' : 'false'}\n ref={(el) => {\n if (el) optionsRefs.current[refIndex] = el;\n }}\n className={cn(\n 'flex aspect-square h-8 w-8 min-w-0 items-center justify-center p-0 text-sm',\n size === 'sm' && 'h-6 w-6 text-xs',\n size === 'lg' && 'size-10 text-base',\n isActive && 'font-semibold'\n )}\n >\n {page}\n </Button>\n );\n })}\n </div>\n\n {showPrevNext && (\n <Button\n variant={ButtonVariant.OUTLINE}\n size={buttonSize}\n color={ButtonColor.TEXT}\n onClick={() => handlePageChange(currentPage + 1)}\n disabled={disabled || isLastPage}\n label={goToNextPage.value}\n Icon={ChevronRight}\n ref={(el) => {\n const lastRefIndex =\n (showPrevNext ? 1 : 0) +\n pageNumbers.filter((p) => p !== 'ellipsis').length;\n if (el) optionsRefs.current[lastRefIndex] = el;\n }}\n className=\"min-w-0 px-2\"\n />\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+
3
+ //#region src/components/TechLogo/logos/Atlassian.tsx
4
+ const AtlassianLogo = (props) => /* @__PURE__ */ jsxs("svg", {
5
+ role: "img",
6
+ "aria-label": "Atlassian logo",
7
+ viewBox: "0 0 32 32",
8
+ fill: "none",
9
+ xmlns: "http://www.w3.org/2000/svg",
10
+ ...props,
11
+ children: [/* @__PURE__ */ jsx("path", {
12
+ d: "M11.11 14.918c-.274-.34-.762-.29-.99.096L5.03 24.108a.584.584 0 00.514.862h7.29a.587.587 0 00.527-.329c1.587-3.33.693-7.513-2.252-9.723z",
13
+ fill: "#2684FF"
14
+ }), /* @__PURE__ */ jsx("path", {
15
+ d: "M15.763 5.125a13.27 13.27 0 00-.17 13.83l3.515 6.688a.586.586 0 00.527.327h7.29a.584.584 0 00.515-.862L16.753 5.22a.585.585 0 00-1.023-.032l.033-.063z",
16
+ fill: "#2684FF"
17
+ })]
18
+ });
19
+
20
+ //#endregion
21
+ export { AtlassianLogo };
22
+ //# sourceMappingURL=Atlassian.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Atlassian.mjs","names":[],"sources":["../../../../../src/components/TechLogo/logos/Atlassian.tsx"],"sourcesContent":["import type { FC, SVGProps } from 'react';\n\nexport const AtlassianLogo: FC<SVGProps<SVGSVGElement>> = (props) => (\n <svg\n role=\"img\"\n aria-label=\"Atlassian logo\"\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M11.11 14.918c-.274-.34-.762-.29-.99.096L5.03 24.108a.584.584 0 00.514.862h7.29a.587.587 0 00.527-.329c1.587-3.33.693-7.513-2.252-9.723z\"\n fill=\"#2684FF\"\n />\n <path\n d=\"M15.763 5.125a13.27 13.27 0 00-.17 13.83l3.515 6.688a.586.586 0 00.527.327h7.29a.584.584 0 00.515-.862L16.753 5.22a.585.585 0 00-1.023-.032l.033-.063z\"\n fill=\"#2684FF\"\n />\n </svg>\n);\n"],"mappings":";;;AAEA,MAAa,iBAA8C,UACzD,qBAAC,OAAD;CACE,MAAK;CACL,cAAW;CACX,SAAQ;CACR,MAAK;CACL,OAAM;CACN,GAAI;WANN,CAQE,oBAAC,QAAD;EACE,GAAE;EACF,MAAK;EACL,GACF,oBAAC,QAAD;EACE,GAAE;EACF,MAAK;EACL,EACE"}
@@ -0,0 +1,44 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+
3
+ //#region src/components/TechLogo/logos/Microsoft.tsx
4
+ const MicrosoftLogo = (props) => /* @__PURE__ */ jsxs("svg", {
5
+ role: "img",
6
+ "aria-label": "Microsoft logo",
7
+ viewBox: "0 0 21 21",
8
+ xmlns: "http://www.w3.org/2000/svg",
9
+ ...props,
10
+ children: [
11
+ /* @__PURE__ */ jsx("rect", {
12
+ x: "0",
13
+ y: "0",
14
+ width: "10",
15
+ height: "10",
16
+ fill: "#F25022"
17
+ }),
18
+ /* @__PURE__ */ jsx("rect", {
19
+ x: "11",
20
+ y: "0",
21
+ width: "10",
22
+ height: "10",
23
+ fill: "#7FBA00"
24
+ }),
25
+ /* @__PURE__ */ jsx("rect", {
26
+ x: "0",
27
+ y: "11",
28
+ width: "10",
29
+ height: "10",
30
+ fill: "#00A4EF"
31
+ }),
32
+ /* @__PURE__ */ jsx("rect", {
33
+ x: "11",
34
+ y: "11",
35
+ width: "10",
36
+ height: "10",
37
+ fill: "#FFB900"
38
+ })
39
+ ]
40
+ });
41
+
42
+ //#endregion
43
+ export { MicrosoftLogo };
44
+ //# sourceMappingURL=Microsoft.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Microsoft.mjs","names":[],"sources":["../../../../../src/components/TechLogo/logos/Microsoft.tsx"],"sourcesContent":["import type { FC, SVGProps } from 'react';\n\nexport const MicrosoftLogo: FC<SVGProps<SVGSVGElement>> = (props) => (\n <svg\n role=\"img\"\n aria-label=\"Microsoft logo\"\n viewBox=\"0 0 21 21\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <rect x=\"0\" y=\"0\" width=\"10\" height=\"10\" fill=\"#F25022\" />\n <rect x=\"11\" y=\"0\" width=\"10\" height=\"10\" fill=\"#7FBA00\" />\n <rect x=\"0\" y=\"11\" width=\"10\" height=\"10\" fill=\"#00A4EF\" />\n <rect x=\"11\" y=\"11\" width=\"10\" height=\"10\" fill=\"#FFB900\" />\n </svg>\n);\n"],"mappings":";;;AAEA,MAAa,iBAA8C,UACzD,qBAAC,OAAD;CACE,MAAK;CACL,cAAW;CACX,SAAQ;CACR,OAAM;CACN,GAAI;WALN;EAOE,oBAAC,QAAD;GAAM,GAAE;GAAI,GAAE;GAAI,OAAM;GAAK,QAAO;GAAK,MAAK;GAAY;EAC1D,oBAAC,QAAD;GAAM,GAAE;GAAK,GAAE;GAAI,OAAM;GAAK,QAAO;GAAK,MAAK;GAAY;EAC3D,oBAAC,QAAD;GAAM,GAAE;GAAI,GAAE;GAAK,OAAM;GAAK,QAAO;GAAK,MAAK;GAAY;EAC3D,oBAAC,QAAD;GAAM,GAAE;GAAK,GAAE;GAAK,OAAM;GAAK,QAAO;GAAK,MAAK;GAAY;EACxD"}
@@ -8,6 +8,7 @@ import { AdonisLogo } from "./logos/Adonis.mjs";
8
8
  import { AngularLogo } from "./logos/Angular.mjs";
9
9
  import { AnthropicLogo } from "./logos/Anthropic.mjs";
10
10
  import { AstroLogo } from "./logos/Astro.mjs";
11
+ import { AtlassianLogo } from "./logos/Atlassian.mjs";
11
12
  import { ChatGPTLogo } from "./logos/ChatGPT.mjs";
12
13
  import { ClaudeLogo } from "./logos/Claude.mjs";
13
14
  import { DeepSeekLogo } from "./logos/DeepSeek.mjs";
@@ -19,6 +20,7 @@ import { GrokLogo } from "./logos/Grok.mjs";
19
20
  import { HonoLogo } from "./logos/Hono.mjs";
20
21
  import { LitLogo } from "./logos/Lit.mjs";
21
22
  import { LynxLogo } from "./logos/Lynx.mjs";
23
+ import { MicrosoftLogo } from "./logos/Microsoft.mjs";
22
24
  import { MistralLogo } from "./logos/Mistral.mjs";
23
25
  import { NestJSLogo } from "./logos/NestJS.mjs";
24
26
  import { NextJSLogo } from "./logos/Nextjs.mjs";
@@ -42,6 +44,7 @@ var techLogos_exports = /* @__PURE__ */ __exportAll({
42
44
  ANGULAR: () => AngularLogo,
43
45
  ANTHROPIC: () => AnthropicLogo,
44
46
  ASTRO: () => AstroLogo,
47
+ ATLASSIAN: () => AtlassianLogo,
45
48
  BITBUCKET: () => BitbucketLogo,
46
49
  CHATGPT: () => ChatGPTLogo,
47
50
  CLAUDE: () => ClaudeLogo,
@@ -58,6 +61,7 @@ var techLogos_exports = /* @__PURE__ */ __exportAll({
58
61
  LINKEDIN: () => LinkedInLogo,
59
62
  LIT: () => LitLogo,
60
63
  LYNX: () => LynxLogo,
64
+ MICROSOFT: () => MicrosoftLogo,
61
65
  MISTRAL: () => MistralLogo,
62
66
  NESTJS: () => NestJSLogo,
63
67
  NEXTJS: () => NextJSLogo,
@@ -77,5 +81,5 @@ var techLogos_exports = /* @__PURE__ */ __exportAll({
77
81
  });
78
82
 
79
83
  //#endregion
80
- export { AdonisLogo as ADONIS, AngularLogo as ANGULAR, AnthropicLogo as ANTHROPIC, AstroLogo as ASTRO, BitbucketLogo as BITBUCKET, ChatGPTLogo as CHATGPT, ClaudeLogo as CLAUDE, DeepSeekLogo as DEEPSEEK, ExpressLogo as EXPRESS, FastifyLogo as FASTIFY, GeminiLogo as GEMINI, GitHubLogo as GITHUB, GitLabLogo as GITLAB, GoogleLogo as GOOGLE, GoogleAILogo as GOOGLE_AI, GrokLogo as GROK, HonoLogo as HONO, LinkedInLogo as LINKEDIN, LitLogo as LIT, LynxLogo as LYNX, MistralLogo as MISTRAL, NestJSLogo as NESTJS, NextJSLogo as NEXTJS, NodejsLogo as NODE, NuxtLogo as NUXT, OllamaLogo as OLLAMA, OpenAILogo as OPENAI, PerplexityLogo as PERPLEXITY, PreactLogo as PREACT, ReactLogo as REACT, SolidLogo as SOLID, SvelteLogo as SVELTE, TanstackLogo as TANSTACK, JavaScriptLogo as VANILLA, ViteLogo as VITE, VuejsLogo as VUE, techLogos_exports };
84
+ export { AdonisLogo as ADONIS, AngularLogo as ANGULAR, AnthropicLogo as ANTHROPIC, AstroLogo as ASTRO, AtlassianLogo as ATLASSIAN, BitbucketLogo as BITBUCKET, ChatGPTLogo as CHATGPT, ClaudeLogo as CLAUDE, DeepSeekLogo as DEEPSEEK, ExpressLogo as EXPRESS, FastifyLogo as FASTIFY, GeminiLogo as GEMINI, GitHubLogo as GITHUB, GitLabLogo as GITLAB, GoogleLogo as GOOGLE, GoogleAILogo as GOOGLE_AI, GrokLogo as GROK, HonoLogo as HONO, LinkedInLogo as LINKEDIN, LitLogo as LIT, LynxLogo as LYNX, MicrosoftLogo as MICROSOFT, MistralLogo as MISTRAL, NestJSLogo as NESTJS, NextJSLogo as NEXTJS, NodejsLogo as NODE, NuxtLogo as NUXT, OllamaLogo as OLLAMA, OpenAILogo as OPENAI, PerplexityLogo as PERPLEXITY, PreactLogo as PREACT, ReactLogo as REACT, SolidLogo as SOLID, SvelteLogo as SVELTE, TanstackLogo as TANSTACK, JavaScriptLogo as VANILLA, ViteLogo as VITE, VuejsLogo as VUE, techLogos_exports };
81
85
  //# sourceMappingURL=techLogos.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"techLogos.mjs","names":[],"sources":["../../../../src/components/TechLogo/techLogos.ts"],"sourcesContent":["export { AdonisLogo as ADONIS } from './logos/Adonis';\nexport { AngularLogo as ANGULAR } from './logos/Angular';\nexport { AnthropicLogo as ANTHROPIC } from './logos/Anthropic';\nexport { AstroLogo as ASTRO } from './logos/Astro';\nexport { BitbucketLogo as BITBUCKET } from './logos/Bitbucket';\nexport { ChatGPTLogo as CHATGPT } from './logos/ChatGPT';\nexport { ClaudeLogo as CLAUDE } from './logos/Claude';\nexport { DeepSeekLogo as DEEPSEEK } from './logos/DeepSeek';\nexport { ExpressLogo as EXPRESS } from './logos/Express';\nexport { FastifyLogo as FASTIFY } from './logos/Fastify';\nexport { GeminiLogo as GEMINI } from './logos/Gemini';\nexport { GitHubLogo as GITHUB } from './logos/GitHub';\nexport { GitLabLogo as GITLAB } from './logos/GitLab';\nexport { GoogleLogo as GOOGLE } from './logos/Google';\nexport { GoogleAILogo as GOOGLE_AI } from './logos/GoogleAI';\nexport { GrokLogo as GROK } from './logos/Grok';\nexport { HonoLogo as HONO } from './logos/Hono';\nexport { LinkedInLogo as LINKEDIN } from './logos/LinkedIn';\nexport { LitLogo as LIT } from './logos/Lit';\nexport { LynxLogo as LYNX } from './logos/Lynx';\nexport { MistralLogo as MISTRAL } from './logos/Mistral';\nexport { NestJSLogo as NESTJS } from './logos/NestJS';\nexport { NextJSLogo as NEXTJS } from './logos/Nextjs';\nexport { NodejsLogo as NODE } from './logos/Node';\nexport { NuxtLogo as NUXT } from './logos/Nuxt';\nexport { OllamaLogo as OLLAMA } from './logos/Ollama';\nexport { OpenAILogo as OPENAI } from './logos/OpenAI';\nexport { PerplexityLogo as PERPLEXITY } from './logos/Perplexity';\nexport { PreactLogo as PREACT } from './logos/Preact';\nexport { ReactLogo as REACT } from './logos/Reactjs';\nexport { SolidLogo as SOLID } from './logos/Solid';\nexport { SvelteLogo as SVELTE } from './logos/Svelte';\nexport { TanstackLogo as TANSTACK } from './logos/Tanstack';\nexport { JavaScriptLogo as VANILLA } from './logos/Vanilla';\nexport { ViteLogo as VITE } from './logos/Vitejs';\nexport { VuejsLogo as VUE } from './logos/Vuejs';\n"],"mappings":""}
1
+ {"version":3,"file":"techLogos.mjs","names":[],"sources":["../../../../src/components/TechLogo/techLogos.ts"],"sourcesContent":["export { AdonisLogo as ADONIS } from './logos/Adonis';\nexport { AngularLogo as ANGULAR } from './logos/Angular';\nexport { AnthropicLogo as ANTHROPIC } from './logos/Anthropic';\nexport { AstroLogo as ASTRO } from './logos/Astro';\nexport { AtlassianLogo as ATLASSIAN } from './logos/Atlassian';\nexport { BitbucketLogo as BITBUCKET } from './logos/Bitbucket';\nexport { ChatGPTLogo as CHATGPT } from './logos/ChatGPT';\nexport { ClaudeLogo as CLAUDE } from './logos/Claude';\nexport { DeepSeekLogo as DEEPSEEK } from './logos/DeepSeek';\nexport { ExpressLogo as EXPRESS } from './logos/Express';\nexport { FastifyLogo as FASTIFY } from './logos/Fastify';\nexport { GeminiLogo as GEMINI } from './logos/Gemini';\nexport { GitHubLogo as GITHUB } from './logos/GitHub';\nexport { GitLabLogo as GITLAB } from './logos/GitLab';\nexport { GoogleLogo as GOOGLE } from './logos/Google';\nexport { GoogleAILogo as GOOGLE_AI } from './logos/GoogleAI';\nexport { GrokLogo as GROK } from './logos/Grok';\nexport { HonoLogo as HONO } from './logos/Hono';\nexport { LinkedInLogo as LINKEDIN } from './logos/LinkedIn';\nexport { LitLogo as LIT } from './logos/Lit';\nexport { LynxLogo as LYNX } from './logos/Lynx';\nexport { MicrosoftLogo as MICROSOFT } from './logos/Microsoft';\nexport { MistralLogo as MISTRAL } from './logos/Mistral';\nexport { NestJSLogo as NESTJS } from './logos/NestJS';\nexport { NextJSLogo as NEXTJS } from './logos/Nextjs';\nexport { NodejsLogo as NODE } from './logos/Node';\nexport { NuxtLogo as NUXT } from './logos/Nuxt';\nexport { OllamaLogo as OLLAMA } from './logos/Ollama';\nexport { OpenAILogo as OPENAI } from './logos/OpenAI';\nexport { PerplexityLogo as PERPLEXITY } from './logos/Perplexity';\nexport { PreactLogo as PREACT } from './logos/Preact';\nexport { ReactLogo as REACT } from './logos/Reactjs';\nexport { SolidLogo as SOLID } from './logos/Solid';\nexport { SvelteLogo as SVELTE } from './logos/Svelte';\nexport { TanstackLogo as TANSTACK } from './logos/Tanstack';\nexport { JavaScriptLogo as VANILLA } from './logos/Vanilla';\nexport { ViteLogo as VITE } from './logos/Vitejs';\nexport { VuejsLogo as VUE } from './logos/Vuejs';\n"],"mappings":""}
@@ -30,7 +30,7 @@ const ToastViewport = ({ className, ...props }) => /* @__PURE__ */ jsx(ToastPrim
30
30
  * <Toast variant="default">Info message</Toast>
31
31
  * ```
32
32
  */
33
- const toastVariants = cva("group data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md p-4 pr-6 shadow-[0_0_10px_-15px_rgba(0,0,0,0.3)] backdrop-blur transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[state=closed]:animate-out data-[state=open]:animate-in data-[swipe=end]:animate-out data-[swipe=move]:transition-none", {
33
+ const toastVariants = cva("group data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-xl p-4 pr-6 shadow-[0_0_10px_-15px_rgba(0,0,0,0.3)] backdrop-blur transition-all [corner-shape:squircle] data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[state=closed]:animate-out data-[state=open]:animate-in data-[swipe=end]:animate-out data-[swipe=move]:transition-none supports-[corner-shape:squircle]:rounded-3xl", {
34
34
  variants: {
35
35
  /** Toast visual variants for different message types */
36
36
  variant: {
@@ -189,5 +189,5 @@ const ToastDescription = ({ className, ...props }) => /* @__PURE__ */ jsx(ToastP
189
189
  });
190
190
 
191
191
  //#endregion
192
- export { Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport };
192
+ export { Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, toastVariants };
193
193
  //# sourceMappingURL=Toast.mjs.map