@intlayer/design-system 8.1.7 → 8.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/components/Badge/index.mjs +1 -1
- package/dist/esm/components/Badge/index.mjs.map +1 -1
- package/dist/esm/components/Carousel/index.mjs +1 -1
- package/dist/esm/components/Carousel/index.mjs.map +1 -1
- package/dist/esm/components/IDE/CodeBlockShiki.mjs +1 -1
- package/dist/esm/components/IDE/CodeBlockShiki.mjs.map +1 -1
- package/dist/esm/components/Link/Link.mjs +1 -1
- package/dist/esm/components/Link/Link.mjs.map +1 -1
- package/dist/esm/components/MarkDownRender/MarkDownRender.mjs +1 -1
- package/dist/esm/components/MarkDownRender/MarkDownRender.mjs.map +1 -1
- package/dist/esm/components/Pagination/NumberItemsSelector.mjs +1 -1
- package/dist/esm/components/Pagination/NumberItemsSelector.mjs.map +1 -1
- package/dist/types/components/Badge/index.d.ts +15 -26
- package/dist/types/components/Badge/index.d.ts.map +1 -1
- package/dist/types/components/Breadcrumb/breadcrumb.content.d.ts +1 -1
- package/dist/types/components/Browser/Browser.content.d.ts +8 -8
- package/dist/types/components/Button/Button.d.ts +3 -3
- package/dist/types/components/Carousel/index.content.d.ts +3 -3
- package/dist/types/components/Carousel/index.d.ts.map +1 -1
- package/dist/types/components/CollapsibleTable/CollapsibleTable.d.ts +2 -2
- package/dist/types/components/Command/index.d.ts +1 -1
- package/dist/types/components/Container/index.d.ts +6 -6
- package/dist/types/components/CopyButton/CopyButton.content.d.ts +1 -1
- package/dist/types/components/DictionaryFieldEditor/DictionaryCreationForm/dictionaryCreationForm.content.d.ts +12 -12
- package/dist/types/components/DictionaryFieldEditor/DictionaryCreationForm/useDictionaryFormSchema.content.d.ts +4 -4
- package/dist/types/components/DictionaryFieldEditor/DictionaryDetails/dictionaryDetails.content.d.ts +27 -27
- package/dist/types/components/DictionaryFieldEditor/DictionaryDetails/useDictionaryDetailsSchema.content.d.ts +16 -16
- package/dist/types/components/DictionaryFieldEditor/NavigationView/navigationViewNode.content.d.ts +12 -12
- package/dist/types/components/DictionaryFieldEditor/SaveForm/saveForm.content.d.ts +16 -16
- package/dist/types/components/DictionaryFieldEditor/StructureView/structureView.content.d.ts +4 -4
- package/dist/types/components/DictionaryFieldEditor/VersionSwitcherDropDown/versionSwitcherDropDown.content.d.ts +3 -3
- package/dist/types/components/DictionaryFieldEditor/dictionaryFieldEditor.content.d.ts +2 -2
- package/dist/types/components/DictionaryFieldEditor/nodeTypeSelector.content.d.ts +15 -15
- package/dist/types/components/ExpandCollapse/expandCollapse.content.d.ts +1 -1
- package/dist/types/components/IDE/CodeBlockShiki.d.ts.map +1 -1
- package/dist/types/components/IDE/code.content.d.ts +2 -2
- package/dist/types/components/IDE/copyCode.content.d.ts +2 -2
- package/dist/types/components/IDE/selectors.content.d.ts +6 -6
- package/dist/types/components/Input/Checkbox.d.ts +1 -1
- package/dist/types/components/Link/Link.d.ts +1 -1
- package/dist/types/components/Link/Link.d.ts.map +1 -1
- package/dist/types/components/Loader/index.content.d.ts +1 -1
- package/dist/types/components/LocaleSwitcherContentDropDown/localeSwitcher.content.d.ts +8 -8
- package/dist/types/components/LocaleSwitcherDropDown/localeSwitcher.content.d.ts +6 -6
- package/dist/types/components/MarkDownRender/MarkDownRender.d.ts.map +1 -1
- package/dist/types/components/Pagination/NumberItemsSelector.d.ts +1 -1
- package/dist/types/components/Pagination/Pagination.d.ts +2 -2
- package/dist/types/components/Pagination/pagination.content.d.ts +5 -5
- package/dist/types/components/RightDrawer/rightDrawer.content.d.ts +2 -2
- package/dist/types/components/Tab/Tab.d.ts +1 -1
- package/dist/types/components/TabSelector/TabSelector.d.ts +1 -1
- package/dist/types/components/Table/table.content.d.ts +1 -1
- package/dist/types/components/Tag/index.d.ts +1 -1
- package/dist/types/components/Terminal/terminal.content.d.ts +2 -2
- package/dist/types/components/Toaster/Toast.d.ts +1 -1
- package/package.json +15 -16
- package/tw-source.css +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{cn as e}from"../../utils/cn.mjs";import{cva as t}from"class-variance-authority";import{jsx as n,jsxs as r}from"react/jsx-runtime";let i=function(e){return e.PRIMARY=`primary`,e.SECONDARY=`secondary`,e.DESTRUCTIVE=`destructive`,e.SUCCESS=`success`,e.ERROR=`error`,e.NEUTRAL=`neutral`,e.LIGHT=`light`,e.DARK=`dark`,e.TEXT=`text`,e.CUSTOM=`custom`,e}({}),a=function(e){return e.DEFAULT=`default`,e.NONE=`none`,e.OUTLINE=`outline`,e.HOVERABLE=`hoverable`,e}({}),o=function(e){return e.SMALL=`sm`,e.MEDIUM=`md`,e.LARGE=`lg`,e}({});const s=t(`inline-flex items-center rounded-md border px-2.5 py-0.5 font-semibold text-xs transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2`,{variants:{color:{[i.PRIMARY]:`border-primary bg-primary text-primary hover:bg-primary-500`,[i.SECONDARY]:`border-secondary bg-secondary text-secondary hover:bg-secondary-300`,[i.DESTRUCTIVE]:`border-destructive bg-destructive text-destructive hover:bg-destructive-500`,[i.SUCCESS]:`border-success bg-success text-success hover:bg-success-500`,[i.ERROR]:`border-error bg-error text-error hover:bg-error-500`,[i.NEUTRAL]:`border-neutral bg-neutral text-neutral hover:bg-neutral-600`,[i.LIGHT]:`border-white bg-white text-white hover:bg-neutral-500`,[i.DARK]:`border-neutral-800 bg-neutral-800 text-neutral-800 hover:bg-neutral-900`,[i.TEXT]:`border-text bg-text text-text hover:opacity-80`,[i.CUSTOM]:``},variant:{[a.DEFAULT]:`rounded-lg text-text-opposite`,[a.NONE]:`border-none bg-opacity-0 text-inherit hover:bg-opacity-0`,[a.OUTLINE]:`rounded-lg border-[1.3px] bg-opacity-0 hover:bg-opacity-30`,[a.HOVERABLE]:`rounded-lg border-none bg-opacity-0 transition hover:bg-opacity-10`},size:{[o.SMALL]:`px-2 py-0.5 text-xs`,[o.MEDIUM]:`px-2.5 py-0.5 text-xs`,[o.LARGE]:`px-3 py-1 text-sm`}},defaultVariants:{variant:a.DEFAULT,color:i.PRIMARY,size:o.MEDIUM}}),c=({className:t,variant:c=a.DEFAULT,color:l=i.PRIMARY,size:u=o.MEDIUM,children:d,clickable:f=!1,dismissible:p=!1,onClick:m,onDismiss:h,role:g,tabIndex:_,"aria-label":v,...y})=>{let b=f?`button`:`span`,x=e=>{f&&m&&(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),m(e))},S=e=>{e.stopPropagation(),h?.()};return r(b,{className:e(s({variant:c,color:l,size:u}),f&&`cursor-pointer hover:opacity-80 focus-visible:ring-2 focus-visible:ring-offset-2`,p&&`pr-1`,t),onClick:f?m:void 0,onKeyDown:f?x:void 0,role:g||(f?`button`:`status`),tabIndex:f?_??0:_,"aria-label":v||(f?`${d} button`:void 0),...y,children:[d,p&&n(`button`,{type:`button`,className:`ml-1 inline-flex h-4 w-4 items-center justify-center rounded-full hover:bg-black/10 focus:outline-none focus:ring-1 focus:ring-offset-1`,onClick:S,"aria-label":`Remove ${d} badge`,children:r(`svg`,{className:`size-3`,viewBox:`0 0 20 20`,fill:`currentColor`,"aria-label":`Remove badge`,children:[n(`title`,{children:`Remove badge`}),n(`path`,{fillRule:`evenodd`,d:`M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z`,clipRule:`evenodd`})]})})]})};export{c as Badge,i as BadgeColor,o as BadgeSize,a as BadgeVariant,s as badgeVariants};
|
|
1
|
+
import{cn as e}from"../../utils/cn.mjs";import{cva as t}from"class-variance-authority";import{jsx as n,jsxs as r}from"react/jsx-runtime";let i=function(e){return e.PRIMARY=`primary`,e.SECONDARY=`secondary`,e.DESTRUCTIVE=`destructive`,e.SUCCESS=`success`,e.ERROR=`error`,e.NEUTRAL=`neutral`,e.LIGHT=`light`,e.DARK=`dark`,e.TEXT=`text`,e.CUSTOM=`custom`,e}({}),a=function(e){return e.DEFAULT=`default`,e.NONE=`none`,e.OUTLINE=`outline`,e.HOVERABLE=`hoverable`,e}({}),o=function(e){return e.SMALL=`sm`,e.MEDIUM=`md`,e.LARGE=`lg`,e}({});const s=t(`inline-flex items-center rounded-md border px-2.5 py-0.5 font-semibold text-xs transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2`,{variants:{color:{[`${i.PRIMARY}`]:`border-primary bg-primary text-primary hover:bg-primary-500`,[`${i.SECONDARY}`]:`border-secondary bg-secondary text-secondary hover:bg-secondary-300`,[`${i.DESTRUCTIVE}`]:`border-destructive bg-destructive text-destructive hover:bg-destructive-500`,[`${i.SUCCESS}`]:`border-success bg-success text-success hover:bg-success-500`,[`${i.ERROR}`]:`border-error bg-error text-error hover:bg-error-500`,[`${i.NEUTRAL}`]:`border-neutral bg-neutral text-neutral hover:bg-neutral-600`,[`${i.LIGHT}`]:`border-white bg-white text-white hover:bg-neutral-500`,[`${i.DARK}`]:`border-neutral-800 bg-neutral-800 text-neutral-800 hover:bg-neutral-900`,[`${i.TEXT}`]:`border-text bg-text text-text hover:opacity-80`,[`${i.CUSTOM}`]:``},variant:{[`${a.DEFAULT}`]:`rounded-lg text-text-opposite`,[`${a.NONE}`]:`border-none bg-opacity-0 text-inherit hover:bg-opacity-0`,[`${a.OUTLINE}`]:`rounded-lg border-[1.3px] bg-opacity-0 hover:bg-opacity-30`,[`${a.HOVERABLE}`]:`rounded-lg border-none bg-opacity-0 transition hover:bg-opacity-10`},size:{[`${o.SMALL}`]:`px-2 py-0.5 text-xs`,[`${o.MEDIUM}`]:`px-2.5 py-0.5 text-xs`,[`${o.LARGE}`]:`px-3 py-1 text-sm`}},defaultVariants:{variant:a.DEFAULT,color:i.PRIMARY,size:o.MEDIUM}}),c=({className:t,variant:c=a.DEFAULT,color:l=i.PRIMARY,size:u=o.MEDIUM,children:d,clickable:f=!1,dismissible:p=!1,onClick:m,onDismiss:h,role:g,tabIndex:_,"aria-label":v,...y})=>{let b=f?`button`:`span`,x=e=>{f&&m&&(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),m(e))},S=e=>{e.stopPropagation(),h?.()};return r(b,{className:e(s({variant:c,color:l,size:u}),f&&`cursor-pointer hover:opacity-80 focus-visible:ring-2 focus-visible:ring-offset-2`,p&&`pr-1`,t),onClick:f?m:void 0,onKeyDown:f?x:void 0,role:g||(f?`button`:`status`),tabIndex:f?_??0:_,"aria-label":v||(f?`${d} button`:void 0),...y,children:[d,p&&n(`button`,{type:`button`,className:`ml-1 inline-flex h-4 w-4 items-center justify-center rounded-full hover:bg-black/10 focus:outline-none focus:ring-1 focus:ring-offset-1`,onClick:S,"aria-label":`Remove ${d} badge`,children:r(`svg`,{className:`size-3`,viewBox:`0 0 20 20`,fill:`currentColor`,"aria-label":`Remove badge`,children:[n(`title`,{children:`Remove badge`}),n(`path`,{fillRule:`evenodd`,d:`M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z`,clipRule:`evenodd`})]})})]})};export{c as Badge,i as BadgeColor,o as BadgeSize,a as BadgeVariant,s as badgeVariants};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Badge/index.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type { HTMLAttributes } from 'react';\n\n/**\n * Badge color variants enum\n * @description Defines the available color themes for the badge component\n */\nexport enum BadgeColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n DESTRUCTIVE = 'destructive',\n SUCCESS = 'success',\n ERROR = 'error',\n NEUTRAL = 'neutral',\n LIGHT = 'light',\n DARK = 'dark',\n TEXT = 'text',\n CUSTOM = 'custom',\n}\n\n/**\n * Badge visual variants enum\n * @description Defines the available visual styles for the badge component\n */\nexport enum BadgeVariant {\n DEFAULT = 'default',\n NONE = 'none',\n OUTLINE = 'outline',\n HOVERABLE = 'hoverable',\n}\n\n/**\n * Badge size variants enum\n * @description Defines the available sizes for the badge component\n */\nexport enum BadgeSize {\n SMALL = 'sm',\n MEDIUM = 'md',\n LARGE = 'lg',\n}\n\n/**\n * Badge component variants using class-variance-authority\n * @description Defines the styling variants for different badge combinations\n */\nexport const badgeVariants = cva(\n 'inline-flex items-center rounded-md border px-2.5 py-0.5 font-semibold text-xs transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2',\n {\n variants: {\n color: {\n [BadgeColor.PRIMARY]:\n 'border-primary bg-primary text-primary hover:bg-primary-500',\n [BadgeColor.SECONDARY]:\n 'border-secondary bg-secondary text-secondary hover:bg-secondary-300',\n [BadgeColor.DESTRUCTIVE]:\n 'border-destructive bg-destructive text-destructive hover:bg-destructive-500',\n [BadgeColor.SUCCESS]:\n 'border-success bg-success text-success hover:bg-success-500',\n [BadgeColor.ERROR]:\n 'border-error bg-error text-error hover:bg-error-500',\n [BadgeColor.NEUTRAL]:\n 'border-neutral bg-neutral text-neutral hover:bg-neutral-600',\n [BadgeColor.LIGHT]:\n 'border-white bg-white text-white hover:bg-neutral-500',\n [BadgeColor.DARK]:\n 'border-neutral-800 bg-neutral-800 text-neutral-800 hover:bg-neutral-900',\n [BadgeColor.TEXT]
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Badge/index.tsx"],"sourcesContent":["import { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport type { HTMLAttributes } from 'react';\n\n/**\n * Badge color variants enum\n * @description Defines the available color themes for the badge component\n */\nexport enum BadgeColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n DESTRUCTIVE = 'destructive',\n SUCCESS = 'success',\n ERROR = 'error',\n NEUTRAL = 'neutral',\n LIGHT = 'light',\n DARK = 'dark',\n TEXT = 'text',\n CUSTOM = 'custom',\n}\n\n/**\n * Badge visual variants enum\n * @description Defines the available visual styles for the badge component\n */\nexport enum BadgeVariant {\n DEFAULT = 'default',\n NONE = 'none',\n OUTLINE = 'outline',\n HOVERABLE = 'hoverable',\n}\n\n/**\n * Badge size variants enum\n * @description Defines the available sizes for the badge component\n */\nexport enum BadgeSize {\n SMALL = 'sm',\n MEDIUM = 'md',\n LARGE = 'lg',\n}\n\n/**\n * Badge component variants using class-variance-authority\n * @description Defines the styling variants for different badge combinations\n */\nexport const badgeVariants = cva(\n 'inline-flex items-center rounded-md border px-2.5 py-0.5 font-semibold text-xs transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2',\n {\n variants: {\n color: {\n [`${BadgeColor.PRIMARY}`]:\n 'border-primary bg-primary text-primary hover:bg-primary-500',\n [`${BadgeColor.SECONDARY}`]:\n 'border-secondary bg-secondary text-secondary hover:bg-secondary-300',\n [`${BadgeColor.DESTRUCTIVE}`]:\n 'border-destructive bg-destructive text-destructive hover:bg-destructive-500',\n [`${BadgeColor.SUCCESS}`]:\n 'border-success bg-success text-success hover:bg-success-500',\n [`${BadgeColor.ERROR}`]:\n 'border-error bg-error text-error hover:bg-error-500',\n [`${BadgeColor.NEUTRAL}`]:\n 'border-neutral bg-neutral text-neutral hover:bg-neutral-600',\n [`${BadgeColor.LIGHT}`]:\n 'border-white bg-white text-white hover:bg-neutral-500',\n [`${BadgeColor.DARK}`]:\n 'border-neutral-800 bg-neutral-800 text-neutral-800 hover:bg-neutral-900',\n [`${BadgeColor.TEXT}`]:\n 'border-text bg-text text-text hover:opacity-80',\n [`${BadgeColor.CUSTOM}`]: '',\n },\n variant: {\n [`${BadgeVariant.DEFAULT}`]: 'rounded-lg text-text-opposite',\n [`${BadgeVariant.NONE}`]:\n 'border-none bg-opacity-0 text-inherit hover:bg-opacity-0',\n [`${BadgeVariant.OUTLINE}`]:\n 'rounded-lg border-[1.3px] bg-opacity-0 hover:bg-opacity-30',\n [`${BadgeVariant.HOVERABLE}`]:\n 'rounded-lg border-none bg-opacity-0 transition hover:bg-opacity-10',\n },\n size: {\n [`${BadgeSize.SMALL}`]: 'px-2 py-0.5 text-xs',\n [`${BadgeSize.MEDIUM}`]: 'px-2.5 py-0.5 text-xs',\n [`${BadgeSize.LARGE}`]: 'px-3 py-1 text-sm',\n },\n },\n defaultVariants: {\n variant: BadgeVariant.DEFAULT,\n color: BadgeColor.PRIMARY,\n size: BadgeSize.MEDIUM,\n },\n }\n);\n\n/**\n * Badge component props interface\n * @description Comprehensive props for the Badge component with accessibility and interactive features\n */\nexport type BadgeProps = HTMLAttributes<HTMLElement> & {\n /** The content to display inside the badge */\n children?: React.ReactNode;\n /** Color theme variant */\n color?: BadgeColor | `${BadgeColor}`;\n /** Visual style variant */\n variant?: BadgeVariant | `${BadgeVariant}`;\n /** Size of the badge */\n size?: BadgeSize | `${BadgeSize}`;\n /** Whether the badge is clickable */\n clickable?: boolean;\n /** Whether the badge is dismissible (shows close button) */\n dismissible?: boolean;\n /** Click handler for the badge */\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n /** Click handler for the dismiss button */\n onDismiss?: () => void;\n /** ARIA label for accessibility */\n 'aria-label'?: string;\n /** Badge role for accessibility (default: 'status') */\n role?: 'status' | 'button' | 'generic';\n /** Whether badge should be focusable */\n tabIndex?: number;\n};\n\n/**\n * Utility type for badge variant props\n */\nexport type BadgeVariantProps = VariantProps<typeof badgeVariants>;\n\n/**\n * Badge component for displaying status indicators, labels, and notifications\n *\n * @description A flexible badge component that supports multiple visual styles, colors, and interactive features.\n * It maintains accessibility standards and provides comprehensive customization options.\n *\n * @example\n * ```tsx\n * // Basic badge\n * <Badge>New</Badge>\n *\n * // Colored badge\n * <Badge color={BadgeColor.DESTRUCTIVE}>Error</Badge>\n *\n * // Clickable badge\n * <Badge clickable onClick={() => console.log('clicked')}>\n * Clickable\n * </Badge>\n *\n * // Dismissible badge\n * <Badge dismissible onDismiss={() => console.log('dismissed')}>\n * Dismissible\n * </Badge>\n * ```\n */\nexport const Badge: React.FC<BadgeProps> = ({\n className,\n variant = BadgeVariant.DEFAULT,\n color = BadgeColor.PRIMARY,\n size = BadgeSize.MEDIUM,\n children,\n clickable = false,\n dismissible = false,\n onClick,\n onDismiss,\n role,\n tabIndex,\n 'aria-label': ariaLabel,\n ...props\n}) => {\n const Component = clickable ? 'button' : 'span';\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLElement>) => {\n if (clickable && onClick && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n onClick(event as any);\n }\n };\n\n const handleDismiss = (event: React.MouseEvent) => {\n event.stopPropagation();\n onDismiss?.();\n };\n\n return (\n <Component\n className={cn(\n badgeVariants({ variant, color, size }),\n clickable &&\n 'cursor-pointer hover:opacity-80 focus-visible:ring-2 focus-visible:ring-offset-2',\n dismissible && 'pr-1',\n className\n )}\n onClick={clickable ? onClick : undefined}\n onKeyDown={clickable ? handleKeyDown : undefined}\n role={role || (clickable ? 'button' : 'status')}\n tabIndex={clickable ? (tabIndex ?? 0) : tabIndex}\n aria-label={ariaLabel || (clickable ? `${children} button` : undefined)}\n {...props}\n >\n {children}\n {dismissible && (\n <button\n type=\"button\"\n className=\"ml-1 inline-flex h-4 w-4 items-center justify-center rounded-full hover:bg-black/10 focus:outline-none focus:ring-1 focus:ring-offset-1\"\n onClick={handleDismiss}\n aria-label={`Remove ${children} badge`}\n >\n <svg\n className=\"size-3\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n aria-label=\"Remove badge\"\n >\n <title>Remove badge</title>\n <path\n fillRule=\"evenodd\"\n d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\"\n clipRule=\"evenodd\"\n />\n </svg>\n </button>\n )}\n </Component>\n );\n};\n"],"mappings":"yIAQA,IAAY,EAAA,SAAA,EAAL,OACL,GAAA,QAAA,UACA,EAAA,UAAA,YACA,EAAA,YAAA,cACA,EAAA,QAAA,UACA,EAAA,MAAA,QACA,EAAA,QAAA,UACA,EAAA,MAAA,QACA,EAAA,KAAA,OACA,EAAA,KAAA,OACA,EAAA,OAAA,gBAOU,EAAA,SAAA,EAAL,OACL,GAAA,QAAA,UACA,EAAA,KAAA,OACA,EAAA,QAAA,UACA,EAAA,UAAA,mBAOU,EAAA,SAAA,EAAL,OACL,GAAA,MAAA,KACA,EAAA,OAAA,KACA,EAAA,MAAA,YAOF,MAAa,EAAgB,EAC3B,yKACA,CACE,SAAU,CACR,MAAO,EACJ,GAAG,EAAW,WACb,+DACD,GAAG,EAAW,aACb,uEACD,GAAG,EAAW,eACb,+EACD,GAAG,EAAW,WACb,+DACD,GAAG,EAAW,SACb,uDACD,GAAG,EAAW,WACb,+DACD,GAAG,EAAW,SACb,yDACD,GAAG,EAAW,QACb,2EACD,GAAG,EAAW,QACb,kDACD,GAAG,EAAW,UAAW,GAC3B,CACD,QAAS,EACN,GAAG,EAAa,WAAY,iCAC5B,GAAG,EAAa,QACf,4DACD,GAAG,EAAa,WACf,8DACD,GAAG,EAAa,aACf,qEACH,CACD,KAAM,EACH,GAAG,EAAU,SAAU,uBACvB,GAAG,EAAU,UAAW,yBACxB,GAAG,EAAU,SAAU,oBACzB,CACF,CACD,gBAAiB,CACf,QAAS,EAAa,QACtB,MAAO,EAAW,QAClB,KAAM,EAAU,OACjB,CACF,CACF,CA6DY,GAA+B,CAC1C,YACA,UAAU,EAAa,QACvB,QAAQ,EAAW,QACnB,OAAO,EAAU,OACjB,WACA,YAAY,GACZ,cAAc,GACd,UACA,YACA,OACA,WACA,aAAc,EACd,GAAG,KACC,CACJ,IAAM,EAAY,EAAY,SAAW,OAEnC,EAAiB,GAA4C,CAC7D,GAAa,IAAY,EAAM,MAAQ,SAAW,EAAM,MAAQ,OAClE,EAAM,gBAAgB,CACtB,EAAQ,EAAa,GAInB,EAAiB,GAA4B,CACjD,EAAM,iBAAiB,CACvB,KAAa,EAGf,OACE,EAAC,EAAA,CACC,UAAW,EACT,EAAc,CAAE,UAAS,QAAO,OAAM,CAAC,CACvC,GACE,mFACF,GAAe,OACf,EACD,CACD,QAAS,EAAY,EAAU,IAAA,GAC/B,UAAW,EAAY,EAAgB,IAAA,GACvC,KAAM,IAAS,EAAY,SAAW,UACtC,SAAU,EAAa,GAAY,EAAK,EACxC,aAAY,IAAc,EAAY,GAAG,EAAS,SAAW,IAAA,IAC7D,GAAI,YAEH,EACA,GACC,EAAC,SAAA,CACC,KAAK,SACL,UAAU,0IACV,QAAS,EACT,aAAY,UAAU,EAAS,iBAE/B,EAAC,MAAA,CACC,UAAU,SACV,QAAQ,YACR,KAAK,eACL,aAAW,yBAEX,EAAC,QAAA,CAAA,SAAM,eAAA,CAAoB,CAC3B,EAAC,OAAA,CACC,SAAS,UACT,EAAE,qMACF,SAAS,WACT,CAAA,EACE,EACC,CAAA,EAED"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use client";import{cn as e}from"../../utils/cn.mjs";import{Button as t,ButtonColor as n,ButtonSize as r,ButtonVariant as i}from"../Button/Button.mjs";import{KeyboardShortcut as a}from"../KeyboardShortcut/KeyboardShortcut.mjs";import{Popover as o}from"../Popover/dynamic.mjs";import{ChevronLeft as s,ChevronRight as c}from"lucide-react";import{Children as l,createContext as u,isValidElement as d,useContext as f,useEffect as p,useRef as m,useState as h}from"react";import{jsx as g,jsxs as _}from"react/jsx-runtime";import{useIntlayer as v}from"react-intlayer";const y=u(null),b=()=>{let e=f(y);if(!e)throw Error(`useCarousel must be used within a Carousel`);return e},x=(e,t)=>{switch(Math.abs(e-t)){case 0:return`opacity-100 z-40`;case 1:return`opacity-75 z-30 cursor-pointer`;case 2:return`opacity-50 z-20 pointer-events-none`;default:return`opacity-0 z-10 pointer-events-none`}},S=(e,t)=>{switch(Math.abs(e-t)){case 0:return 1;case 1:return .9;case 2:return .8;default:return .7}},C=(e,t)
|
|
1
|
+
"use client";import{cn as e}from"../../utils/cn.mjs";import{Button as t,ButtonColor as n,ButtonSize as r,ButtonVariant as i}from"../Button/Button.mjs";import{KeyboardShortcut as a}from"../KeyboardShortcut/KeyboardShortcut.mjs";import{Popover as o}from"../Popover/dynamic.mjs";import{ChevronLeft as s,ChevronRight as c}from"lucide-react";import{Children as l,createContext as u,isValidElement as d,useContext as f,useEffect as p,useRef as m,useState as h}from"react";import{jsx as g,jsxs as _}from"react/jsx-runtime";import{useIntlayer as v}from"react-intlayer";const y=u(null),b=()=>{let e=f(y);if(!e)throw Error(`useCarousel must be used within a Carousel`);return e},x=(e,t)=>{switch(Math.abs(e-t)){case 0:return`opacity-100 z-40`;case 1:return`opacity-75 z-30 cursor-pointer`;case 2:return`opacity-50 z-20 pointer-events-none`;default:return`opacity-0 z-10 pointer-events-none`}},S=(e,t)=>{switch(Math.abs(e-t)){case 0:return 1;case 1:return .9;case 2:return .8;default:return .7}},C=(e,t)=>`calc(${e-t} * min(30vw, 300px))`,w=({children:t,className:n,...r})=>g(`div`,{className:e(`h-full w-full`,n),...r,children:t}),T=({className:l,disableKeyboardShortcuts:u=!1,...d})=>{let{selectedIndex:f,setSelectedIndex:p,totalItems:m,handlePrev:h,handleNext:y}=b(),{goToSlide:x,previousSlide:S,nextSlide:C}=v(`carousel`);return m<=1?null:_(`div`,{className:e(`absolute bottom-4 left-1/2 z-50 flex -translate-x-1/2 flex-row items-center gap-2`,l),...d,children:[_(o,{identifier:`carousel-prev`,children:[g(t,{variant:i.HOVERABLE,color:n.NEUTRAL,label:S.value,roundedSize:`full`,onClick:e=>{e.stopPropagation(),h()},Icon:s,size:r.ICON_MD,disabled:f===0}),g(o.Detail,{identifier:`carousel-prev`,children:_(`div`,{className:`flex items-center gap-2 p-2`,children:[g(`span`,{className:`whitespace-nowrap text-neutral text-xs`,children:S.value}),g(a,{shortcut:`ArrowLeft`,disabled:u,size:`sm`,onTriggered:h})]})})]}),Array.from({length:m}).map((t,n)=>{let r=n===f;return g(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),p(n)},"aria-label":x({index:n+1}).value,className:e(`h-2.5 w-2.5 rounded-full transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-neutral-400 focus:ring-offset-2`,r?`scale-110 bg-text`:`bg-text/20 hover:bg-text/40`)},n)}),_(o,{identifier:`carousel-next`,children:[g(t,{variant:i.HOVERABLE,color:n.NEUTRAL,roundedSize:`full`,label:C.value,onClick:e=>{e.stopPropagation(),y()},Icon:c,size:r.ICON_MD,disabled:f===m-1}),g(o.Detail,{identifier:`carousel-next`,children:_(`div`,{className:`flex items-center gap-2 p-2`,children:[g(`span`,{className:`whitespace-nowrap text-neutral text-xs`,children:C.value}),g(a,{shortcut:`ArrowRight`,size:`sm`,onTriggered:y,disabled:u})]})})]})]})},E=e=>{let t=[],n=[];return e.forEach(e=>{d(e)&&e.type===w?t.push(e):n.push(e)}),[t,n]},D=Object.assign(({children:t,className:n,initialIndex:r=0,onIndexChange:i,...a})=>{let[o,s]=E(l.toArray(t)),c=o.length,[u,d]=h(r),[f,v]=h(r),[b,w]=h(0),[T,D]=h(0),[O,k]=h(!1),A=m(null),j=m([]),M=e=>{if(typeof window>`u`)return;let t=window.innerWidth/5,n=Math.round(e/t);if(Math.abs(n)>=1){let t=f-n,r=Math.max(0,Math.min(t,c-1));r!==u&&(d(r),D(t=>t+e))}},N=()=>{d(e=>Math.min(e+1,c-1))},P=()=>{d(e=>Math.max(e-1,0))},F=e=>{k(!0),D(e.clientX)},I=e=>{O&&M(e.clientX-T)},L=()=>k(!1);return p(()=>{u&&i?.(u)},[u,i]),p(()=>{let e;return u!==f&&(e=setInterval(()=>{v(t=>t===u?(clearInterval(e),t):t<u?t+1:t-1)},50)),()=>clearInterval(e)},[u,f]),p(()=>{let e=()=>{let e=j.current.map(e=>e?.offsetHeight||0),t=Math.max(0,...e);t>0&&w(t+40)};e();let t=new ResizeObserver(()=>{e()});return j.current.forEach(e=>{e&&t.observe(e)}),()=>t.disconnect()},[c]),g(y.Provider,{value:{selectedIndex:u,setSelectedIndex:d,totalItems:c,handlePrev:P,handleNext:N},children:_(`div`,{ref:A,className:e(`relative w-full cursor-grab select-none overflow-hidden outline-none transition-[height] duration-300 ease-in-out focus:outline-none focus:outline-none focus:ring-0 active:cursor-grabbing`,`max-w-[1400px]`,n),style:{height:b>0?b:`auto`,minHeight:`400px`},onMouseDown:F,onMouseMove:I,onMouseUp:L,onMouseLeave:L,onTouchStart:e=>{k(!0),D(e.touches[0].clientX)},onTouchMove:e=>{O&&M(e.touches[0].clientX-T)},onTouchEnd:L,role:`region`,"aria-label":`Carousel`,...a,children:[o.map((t,n)=>g(`div`,{role:`button`,tabIndex:0,ref:e=>{j.current[n]=e},className:e(`absolute left-1/2 -translate-x-1/2 transition-all duration-300 ease-in-out`,`outline-none ring-0 focus:outline-none focus:ring-0 focus:ring-offset-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0`,x(n,f)),onClick:e=>{e.stopPropagation(),d(n)},onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&d(n)},style:{transform:`
|
|
2
2
|
translateX(${C(n,f)})
|
|
3
3
|
scale(${S(n,f)})
|
|
4
4
|
`},children:t},n)),s]})})},{Item:w,Indicators:T});export{D as Carousel};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Carousel/index.tsx"],"sourcesContent":["'use client';\n\nimport {\n Button,\n ButtonColor,\n ButtonSize,\n ButtonVariant,\n} from '@components/Button';\nimport { KeyboardShortcut } from '@components/KeyboardShortcut';\nimport { Popover } from '@components/Popover';\n// Removed useIsMounted as it is no longer needed for positioning\nimport { cn } from '@utils/cn';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport {\n Children,\n createContext,\n type FC,\n type HTMLAttributes,\n isValidElement,\n type MouseEventHandler,\n type ReactElement,\n type ReactNode,\n type TouchEventHandler,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { useIntlayer } from 'react-intlayer';\n\n// ------------------------------------------------------------------\n// Configuration\n// ------------------------------------------------------------------\nconst SWIPE_THRESHOLD_DIVISOR = 5;\nconst TRANSITION_DELAY_MS = 50;\n\n// ------------------------------------------------------------------\n// Context Definition\n// ------------------------------------------------------------------\ntype CarouselContextValue = {\n selectedIndex: number;\n setSelectedIndex: (index: number) => void;\n totalItems: number;\n handlePrev: () => void;\n handleNext: () => void;\n};\n\nconst CarouselContext = createContext<CarouselContextValue | null>(null);\n\nconst useCarousel = () => {\n const context = useContext(CarouselContext);\n if (!context) {\n throw new Error('useCarousel must be used within a Carousel');\n }\n return context;\n};\n\n// ------------------------------------------------------------------\n// Helper Functions\n// ------------------------------------------------------------------\nconst getCardStyle = (index: number, displayedIndex: number) => {\n const diff = Math.abs(index - displayedIndex);\n switch (diff) {\n case 0:\n return 'opacity-100 z-40';\n case 1:\n return 'opacity-75 z-30 cursor-pointer';\n case 2:\n return 'opacity-50 z-20 pointer-events-none';\n default:\n return 'opacity-0 z-10 pointer-events-none';\n }\n};\n\nconst getCardScale = (index: number, displayedIndex: number) => {\n const diff = Math.abs(index - displayedIndex);\n switch (diff) {\n case 0:\n return 1;\n case 1:\n return 0.9;\n case 2:\n return 0.8;\n default:\n return 0.7;\n }\n};\n\n// FIX 1: Use CSS units (vw) instead of window.innerWidth (pixels)\n// This allows the calculation to work on SSR without hydration mismatch.\n// Your original logic: (3 * screenWidth) / 10 === 30% of viewport width\nconst getCardPositionX = (index: number, displayedIndex: number) => {\n const diff = index - displayedIndex;\n return `${diff * 30}vw`;\n};\n\n// ------------------------------------------------------------------\n// Sub-Component: Item\n// ------------------------------------------------------------------\ntype CarouselItemProps = HTMLAttributes<HTMLDivElement> & {\n children: ReactNode;\n};\n\nconst CarouselItem: FC<CarouselItemProps> = ({\n children,\n className,\n ...props\n}) => {\n return (\n <div className={cn('h-full w-full', className)} {...props}>\n {children}\n </div>\n );\n};\n\n// ------------------------------------------------------------------\n// Sub-Component: Indicators (Controller)\n// ------------------------------------------------------------------\ntype CarouselIndicatorsProps = HTMLAttributes<HTMLDivElement> & {\n disableKeyboardShortcuts?: boolean;\n};\n\nconst CarouselIndicators: FC<CarouselIndicatorsProps> = ({\n className,\n disableKeyboardShortcuts = false,\n ...props\n}) => {\n const {\n selectedIndex,\n setSelectedIndex,\n totalItems,\n handlePrev,\n handleNext,\n } = useCarousel();\n const { goToSlide, previousSlide, nextSlide } = useIntlayer('carousel');\n\n if (totalItems <= 1) return null;\n\n return (\n <div\n className={cn(\n 'absolute bottom-4 left-1/2 z-50 flex -translate-x-1/2 flex-row items-center gap-2',\n className\n )}\n {...props}\n >\n <Popover identifier=\"carousel-prev\">\n <Button\n variant={ButtonVariant.HOVERABLE}\n color={ButtonColor.NEUTRAL}\n label={previousSlide.value}\n roundedSize=\"full\"\n onClick={(e) => {\n e.stopPropagation();\n handlePrev();\n }}\n Icon={ChevronLeft}\n size={ButtonSize.ICON_MD}\n disabled={selectedIndex === 0}\n />\n\n <Popover.Detail identifier=\"carousel-prev\">\n <div className=\"flex items-center gap-2 p-2\">\n <span className=\"whitespace-nowrap text-neutral text-xs\">\n {previousSlide.value}\n </span>\n <KeyboardShortcut\n shortcut=\"ArrowLeft\"\n disabled={disableKeyboardShortcuts}\n size=\"sm\"\n onTriggered={handlePrev}\n />\n </div>\n </Popover.Detail>\n </Popover>\n\n {Array.from({ length: totalItems }).map((_, index) => {\n const isActive = index === selectedIndex;\n return (\n <button\n key={index}\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n setSelectedIndex(index);\n }}\n aria-label={goToSlide({ index: index + 1 }).value}\n className={cn(\n 'h-2.5 w-2.5 rounded-full transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-neutral-400 focus:ring-offset-2',\n isActive ? 'scale-110 bg-text' : 'bg-text/20 hover:bg-text/40'\n )}\n />\n );\n })}\n\n <Popover identifier=\"carousel-next\">\n <Button\n variant={ButtonVariant.HOVERABLE}\n color={ButtonColor.NEUTRAL}\n roundedSize=\"full\"\n label={nextSlide.value}\n onClick={(e) => {\n e.stopPropagation();\n handleNext();\n }}\n Icon={ChevronRight}\n size={ButtonSize.ICON_MD}\n disabled={selectedIndex === totalItems - 1}\n />\n\n <Popover.Detail identifier=\"carousel-next\">\n <div className=\"flex items-center gap-2 p-2\">\n <span className=\"whitespace-nowrap text-neutral text-xs\">\n {nextSlide.value}\n </span>\n <KeyboardShortcut\n shortcut=\"ArrowRight\"\n size=\"sm\"\n onTriggered={handleNext}\n disabled={disableKeyboardShortcuts}\n />\n </div>\n </Popover.Detail>\n </Popover>\n </div>\n );\n};\n\n// ------------------------------------------------------------------\n// Main Component: Carousel Root\n// ------------------------------------------------------------------\ntype CarouselProps = HTMLAttributes<HTMLDivElement> & {\n children: ReactNode;\n initialIndex?: number;\n onIndexChange?: (index: number) => void;\n};\n\nconst partitionCarouselChildren = (\n children: ReactNode[]\n): [ReactElement[], ReactNode[]] => {\n const slides: ReactElement[] = [];\n const others: ReactNode[] = [];\n\n children.forEach((child) => {\n if (isValidElement(child) && child.type === CarouselItem) {\n slides.push(child);\n } else {\n others.push(child);\n }\n });\n\n return [slides, others];\n};\n\nconst CarouselRoot: FC<CarouselProps> = ({\n children,\n className,\n initialIndex = 0,\n onIndexChange,\n ...props\n}) => {\n const allChildren = Children.toArray(children);\n const [slides, others] = partitionCarouselChildren(allChildren);\n const totalItems = slides.length;\n\n // State Management\n const [selectedIndex, setSelectedIndex] = useState<number>(initialIndex);\n const [displayedIndex, setDisplayedIndex] = useState<number>(initialIndex);\n const [containerHeight, setContainerHeight] = useState<number>(0);\n\n // Drag State\n const [startX, setStartX] = useState(0);\n const [isDragging, setIsDragging] = useState(false);\n\n // Refs\n const containerRef = useRef<HTMLDivElement>(null);\n const itemsRef = useRef<(HTMLDivElement | null)[]>([]);\n\n // Navigation Logic\n const handleSwitchItem = (diff: number) => {\n if (typeof window === 'undefined') return;\n\n const screenWidth = window.innerWidth;\n const swipeStep = screenWidth / SWIPE_THRESHOLD_DIVISOR;\n const numSwipe = Math.round(diff / swipeStep);\n\n if (Math.abs(numSwipe) >= 1) {\n const newIndex = displayedIndex - numSwipe;\n const clampedIndex = Math.max(0, Math.min(newIndex, totalItems - 1));\n\n if (clampedIndex !== selectedIndex) {\n setSelectedIndex(clampedIndex);\n setStartX((prev) => prev + diff);\n }\n }\n };\n\n const handleNext = () => {\n setSelectedIndex((prev) => Math.min(prev + 1, totalItems - 1));\n };\n\n const handlePrev = () => {\n setSelectedIndex((prev) => Math.max(prev - 1, 0));\n };\n\n // Input Handlers\n const handleMouseDown: MouseEventHandler<HTMLDivElement> = (e) => {\n setIsDragging(true);\n setStartX(e.clientX);\n };\n const handleMouseMove: MouseEventHandler<HTMLDivElement> = (e) => {\n if (isDragging) handleSwitchItem(e.clientX - startX);\n };\n const handleDragEnd = () => setIsDragging(false);\n const handleTouchStart: TouchEventHandler<HTMLDivElement> = (e) => {\n setIsDragging(true);\n setStartX(e.touches[0].clientX);\n };\n const handleTouchMove: TouchEventHandler<HTMLDivElement> = (e) => {\n if (isDragging) handleSwitchItem(e.touches[0].clientX - startX);\n };\n\n // Effects\n useEffect(() => {\n if (selectedIndex) onIndexChange?.(selectedIndex);\n }, [selectedIndex, onIndexChange]);\n\n useEffect(() => {\n let interval: NodeJS.Timeout;\n\n if (selectedIndex !== displayedIndex) {\n interval = setInterval(() => {\n setDisplayedIndex((prev) => {\n if (prev === selectedIndex) {\n clearInterval(interval);\n return prev;\n }\n return prev < selectedIndex ? prev + 1 : prev - 1;\n });\n }, TRANSITION_DELAY_MS);\n }\n return () => clearInterval(interval);\n }, [selectedIndex, displayedIndex]);\n\n // Calculate height based on the MAX height of ALL items\n useEffect(() => {\n const calculateMaxHeight = () => {\n const heights = itemsRef.current.map((item) => item?.offsetHeight || 0);\n const maxHeight = Math.max(0, ...heights);\n\n if (maxHeight > 0) {\n setContainerHeight(maxHeight + 40);\n }\n };\n\n calculateMaxHeight();\n\n const observer = new ResizeObserver(() => {\n calculateMaxHeight();\n });\n\n itemsRef.current.forEach((item) => {\n if (item) observer.observe(item);\n });\n\n return () => observer.disconnect();\n }, [totalItems]); // Removed isMounted dependency\n\n return (\n <CarouselContext.Provider\n value={{\n selectedIndex,\n setSelectedIndex,\n totalItems,\n handlePrev,\n handleNext,\n }}\n >\n <div\n ref={containerRef}\n className={cn(\n 'relative w-full cursor-grab select-none overflow-hidden outline-none transition-[height] duration-300 ease-in-out focus:outline-none focus:outline-none focus:ring-0 active:cursor-grabbing',\n className\n )}\n style={{\n height: containerHeight > 0 ? containerHeight : 'auto',\n minHeight: '400px',\n }}\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleDragEnd}\n onMouseLeave={handleDragEnd}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleDragEnd}\n role=\"region\"\n aria-label=\"Carousel\"\n {...props}\n >\n {slides.map((child, index) => {\n return (\n <div\n key={index}\n role=\"button\"\n tabIndex={0}\n ref={(el) => {\n itemsRef.current[index] = el;\n }}\n // FIX 2: Removed isMounted checks and invisible classes.\n // CSS units allow correct SSR rendering.\n className={cn(\n 'absolute left-1/2 -translate-x-1/2 transition-all duration-300 ease-in-out',\n 'outline-none ring-0 focus:outline-none focus:ring-0 focus:ring-offset-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0',\n getCardStyle(index, displayedIndex)\n )}\n onClick={(e) => {\n e.stopPropagation();\n setSelectedIndex(index);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') setSelectedIndex(index);\n }}\n style={{\n // FIX 3: getCardPositionX now returns '30vw', so no 'px' suffix needed here\n transform: `\n translateX(${getCardPositionX(index, displayedIndex)}) \n scale(${getCardScale(index, displayedIndex)})\n `,\n }}\n >\n {child}\n </div>\n );\n })}\n\n {others}\n </div>\n </CarouselContext.Provider>\n );\n};\n\nexport const Carousel = Object.assign(CarouselRoot, {\n Item: CarouselItem,\n Indicators: CarouselIndicators,\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/components/Carousel/index.tsx"],"sourcesContent":["'use client';\n\nimport {\n Button,\n ButtonColor,\n ButtonSize,\n ButtonVariant,\n} from '@components/Button';\nimport { KeyboardShortcut } from '@components/KeyboardShortcut';\nimport { Popover } from '@components/Popover';\nimport { cn } from '@utils/cn';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport {\n Children,\n createContext,\n type FC,\n type HTMLAttributes,\n isValidElement,\n type MouseEventHandler,\n type ReactElement,\n type ReactNode,\n type TouchEventHandler,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { useIntlayer } from 'react-intlayer';\n\n// ------------------------------------------------------------------\n// Configuration\n// ------------------------------------------------------------------\nconst SWIPE_THRESHOLD_DIVISOR = 5;\nconst TRANSITION_DELAY_MS = 50;\n\n// ------------------------------------------------------------------\n// Context Definition\n// ------------------------------------------------------------------\ntype CarouselContextValue = {\n selectedIndex: number;\n setSelectedIndex: (index: number) => void;\n totalItems: number;\n handlePrev: () => void;\n handleNext: () => void;\n};\n\nconst CarouselContext = createContext<CarouselContextValue | null>(null);\n\nconst useCarousel = () => {\n const context = useContext(CarouselContext);\n if (!context) {\n throw new Error('useCarousel must be used within a Carousel');\n }\n return context;\n};\n\n// ------------------------------------------------------------------\n// Helper Functions\n// ------------------------------------------------------------------\nconst getCardStyle = (index: number, displayedIndex: number) => {\n const diff = Math.abs(index - displayedIndex);\n switch (diff) {\n case 0:\n return 'opacity-100 z-40';\n case 1:\n return 'opacity-75 z-30 cursor-pointer';\n case 2:\n return 'opacity-50 z-20 pointer-events-none';\n default:\n return 'opacity-0 z-10 pointer-events-none';\n }\n};\n\nconst getCardScale = (index: number, displayedIndex: number) => {\n const diff = Math.abs(index - displayedIndex);\n switch (diff) {\n case 0:\n return 1;\n case 1:\n return 0.9;\n case 2:\n return 0.8;\n default:\n return 0.7;\n }\n};\n\n// FIX 1: Use CSS units (vw) instead of window.innerWidth (pixels)\n// This allows the calculation to work on SSR without hydration mismatch.\n// Your original logic: (3 * screenWidth) / 10 === 30% of viewport width\nconst getCardPositionX = (index: number, displayedIndex: number) => {\n const diff = index - displayedIndex;\n return `calc(${diff} * min(30vw, 300px))`;\n};\n\n// ------------------------------------------------------------------\n// Sub-Component: Item\n// ------------------------------------------------------------------\ntype CarouselItemProps = HTMLAttributes<HTMLDivElement> & {\n children: ReactNode;\n};\n\nconst CarouselItem: FC<CarouselItemProps> = ({\n children,\n className,\n ...props\n}) => {\n return (\n <div className={cn('h-full w-full', className)} {...props}>\n {children}\n </div>\n );\n};\n\n// ------------------------------------------------------------------\n// Sub-Component: Indicators (Controller)\n// ------------------------------------------------------------------\ntype CarouselIndicatorsProps = HTMLAttributes<HTMLDivElement> & {\n disableKeyboardShortcuts?: boolean;\n};\n\nconst CarouselIndicators: FC<CarouselIndicatorsProps> = ({\n className,\n disableKeyboardShortcuts = false,\n ...props\n}) => {\n const {\n selectedIndex,\n setSelectedIndex,\n totalItems,\n handlePrev,\n handleNext,\n } = useCarousel();\n const { goToSlide, previousSlide, nextSlide } = useIntlayer('carousel');\n\n if (totalItems <= 1) return null;\n\n return (\n <div\n className={cn(\n 'absolute bottom-4 left-1/2 z-50 flex -translate-x-1/2 flex-row items-center gap-2',\n className\n )}\n {...props}\n >\n <Popover identifier=\"carousel-prev\">\n <Button\n variant={ButtonVariant.HOVERABLE}\n color={ButtonColor.NEUTRAL}\n label={previousSlide.value}\n roundedSize=\"full\"\n onClick={(e) => {\n e.stopPropagation();\n handlePrev();\n }}\n Icon={ChevronLeft}\n size={ButtonSize.ICON_MD}\n disabled={selectedIndex === 0}\n />\n\n <Popover.Detail identifier=\"carousel-prev\">\n <div className=\"flex items-center gap-2 p-2\">\n <span className=\"whitespace-nowrap text-neutral text-xs\">\n {previousSlide.value}\n </span>\n <KeyboardShortcut\n shortcut=\"ArrowLeft\"\n disabled={disableKeyboardShortcuts}\n size=\"sm\"\n onTriggered={handlePrev}\n />\n </div>\n </Popover.Detail>\n </Popover>\n\n {Array.from({ length: totalItems }).map((_, index) => {\n const isActive = index === selectedIndex;\n return (\n <button\n key={index}\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n setSelectedIndex(index);\n }}\n aria-label={goToSlide({ index: index + 1 }).value}\n className={cn(\n 'h-2.5 w-2.5 rounded-full transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-neutral-400 focus:ring-offset-2',\n isActive ? 'scale-110 bg-text' : 'bg-text/20 hover:bg-text/40'\n )}\n />\n );\n })}\n\n <Popover identifier=\"carousel-next\">\n <Button\n variant={ButtonVariant.HOVERABLE}\n color={ButtonColor.NEUTRAL}\n roundedSize=\"full\"\n label={nextSlide.value}\n onClick={(e) => {\n e.stopPropagation();\n handleNext();\n }}\n Icon={ChevronRight}\n size={ButtonSize.ICON_MD}\n disabled={selectedIndex === totalItems - 1}\n />\n\n <Popover.Detail identifier=\"carousel-next\">\n <div className=\"flex items-center gap-2 p-2\">\n <span className=\"whitespace-nowrap text-neutral text-xs\">\n {nextSlide.value}\n </span>\n <KeyboardShortcut\n shortcut=\"ArrowRight\"\n size=\"sm\"\n onTriggered={handleNext}\n disabled={disableKeyboardShortcuts}\n />\n </div>\n </Popover.Detail>\n </Popover>\n </div>\n );\n};\n\n// ------------------------------------------------------------------\n// Main Component: Carousel Root\n// ------------------------------------------------------------------\ntype CarouselProps = HTMLAttributes<HTMLDivElement> & {\n children: ReactNode;\n initialIndex?: number;\n onIndexChange?: (index: number) => void;\n};\n\nconst partitionCarouselChildren = (\n children: ReactNode[]\n): [ReactElement[], ReactNode[]] => {\n const slides: ReactElement[] = [];\n const others: ReactNode[] = [];\n\n children.forEach((child) => {\n if (isValidElement(child) && child.type === CarouselItem) {\n slides.push(child);\n } else {\n others.push(child);\n }\n });\n\n return [slides, others];\n};\n\nconst CarouselRoot: FC<CarouselProps> = ({\n children,\n className,\n initialIndex = 0,\n onIndexChange,\n ...props\n}) => {\n const allChildren = Children.toArray(children);\n const [slides, others] = partitionCarouselChildren(allChildren);\n const totalItems = slides.length;\n\n // State Management\n const [selectedIndex, setSelectedIndex] = useState<number>(initialIndex);\n const [displayedIndex, setDisplayedIndex] = useState<number>(initialIndex);\n const [containerHeight, setContainerHeight] = useState<number>(0);\n\n // Drag State\n const [startX, setStartX] = useState(0);\n const [isDragging, setIsDragging] = useState(false);\n\n // Refs\n const containerRef = useRef<HTMLDivElement>(null);\n const itemsRef = useRef<(HTMLDivElement | null)[]>([]);\n\n // Navigation Logic\n const handleSwitchItem = (diff: number) => {\n if (typeof window === 'undefined') return;\n\n const screenWidth = window.innerWidth;\n const swipeStep = screenWidth / SWIPE_THRESHOLD_DIVISOR;\n const numSwipe = Math.round(diff / swipeStep);\n\n if (Math.abs(numSwipe) >= 1) {\n const newIndex = displayedIndex - numSwipe;\n const clampedIndex = Math.max(0, Math.min(newIndex, totalItems - 1));\n\n if (clampedIndex !== selectedIndex) {\n setSelectedIndex(clampedIndex);\n setStartX((prev) => prev + diff);\n }\n }\n };\n\n const handleNext = () => {\n setSelectedIndex((prev) => Math.min(prev + 1, totalItems - 1));\n };\n\n const handlePrev = () => {\n setSelectedIndex((prev) => Math.max(prev - 1, 0));\n };\n\n // Input Handlers\n const handleMouseDown: MouseEventHandler<HTMLDivElement> = (e) => {\n setIsDragging(true);\n setStartX(e.clientX);\n };\n const handleMouseMove: MouseEventHandler<HTMLDivElement> = (e) => {\n if (isDragging) handleSwitchItem(e.clientX - startX);\n };\n const handleDragEnd = () => setIsDragging(false);\n const handleTouchStart: TouchEventHandler<HTMLDivElement> = (e) => {\n setIsDragging(true);\n setStartX(e.touches[0].clientX);\n };\n const handleTouchMove: TouchEventHandler<HTMLDivElement> = (e) => {\n if (isDragging) handleSwitchItem(e.touches[0].clientX - startX);\n };\n\n // Effects\n useEffect(() => {\n if (selectedIndex) onIndexChange?.(selectedIndex);\n }, [selectedIndex, onIndexChange]);\n\n useEffect(() => {\n let interval: NodeJS.Timeout;\n\n if (selectedIndex !== displayedIndex) {\n interval = setInterval(() => {\n setDisplayedIndex((prev) => {\n if (prev === selectedIndex) {\n clearInterval(interval);\n return prev;\n }\n return prev < selectedIndex ? prev + 1 : prev - 1;\n });\n }, TRANSITION_DELAY_MS);\n }\n return () => clearInterval(interval);\n }, [selectedIndex, displayedIndex]);\n\n // Calculate height based on the MAX height of ALL items\n useEffect(() => {\n const calculateMaxHeight = () => {\n const heights = itemsRef.current.map((item) => item?.offsetHeight || 0);\n const maxHeight = Math.max(0, ...heights);\n\n if (maxHeight > 0) {\n setContainerHeight(maxHeight + 40);\n }\n };\n\n calculateMaxHeight();\n\n const observer = new ResizeObserver(() => {\n calculateMaxHeight();\n });\n\n itemsRef.current.forEach((item) => {\n if (item) observer.observe(item);\n });\n\n return () => observer.disconnect();\n }, [totalItems]); // Removed isMounted dependency\n\n return (\n <CarouselContext.Provider\n value={{\n selectedIndex,\n setSelectedIndex,\n totalItems,\n handlePrev,\n handleNext,\n }}\n >\n <div\n ref={containerRef}\n className={cn(\n 'relative w-full cursor-grab select-none overflow-hidden outline-none transition-[height] duration-300 ease-in-out focus:outline-none focus:outline-none focus:ring-0 active:cursor-grabbing',\n 'max-w-[1400px]',\n className\n )}\n style={{\n height: containerHeight > 0 ? containerHeight : 'auto',\n minHeight: '400px',\n }}\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleDragEnd}\n onMouseLeave={handleDragEnd}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleDragEnd}\n role=\"region\"\n aria-label=\"Carousel\"\n {...props}\n >\n {slides.map((child, index) => {\n return (\n <div\n key={index}\n role=\"button\"\n tabIndex={0}\n ref={(el) => {\n itemsRef.current[index] = el;\n }}\n // FIX 2: Removed isMounted checks and invisible classes.\n // CSS units allow correct SSR rendering.\n className={cn(\n 'absolute left-1/2 -translate-x-1/2 transition-all duration-300 ease-in-out',\n 'outline-none ring-0 focus:outline-none focus:ring-0 focus:ring-offset-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0',\n getCardStyle(index, displayedIndex)\n )}\n onClick={(e) => {\n e.stopPropagation();\n setSelectedIndex(index);\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') setSelectedIndex(index);\n }}\n style={{\n // FIX 3: getCardPositionX now returns '30vw', so no 'px' suffix needed here\n transform: `\n translateX(${getCardPositionX(index, displayedIndex)}) \n scale(${getCardScale(index, displayedIndex)})\n `,\n }}\n >\n {child}\n </div>\n );\n })}\n\n {others}\n </div>\n </CarouselContext.Provider>\n );\n};\n\nexport const Carousel = Object.assign(CarouselRoot, {\n Item: CarouselItem,\n Indicators: CarouselIndicators,\n});\n"],"mappings":"ijBAgCA,MAcM,EAAkB,EAA2C,KAAK,CAElE,MAAoB,CACxB,IAAM,EAAU,EAAW,EAAgB,CAC3C,GAAI,CAAC,EACH,MAAU,MAAM,6CAA6C,CAE/D,OAAO,GAMH,GAAgB,EAAe,IAA2B,CAE9D,OADa,KAAK,IAAI,EAAQ,EAAe,CAC7C,CACE,IAAK,GACH,MAAO,mBACT,IAAK,GACH,MAAO,iCACT,IAAK,GACH,MAAO,sCACT,QACE,MAAO,uCAIP,GAAgB,EAAe,IAA2B,CAE9D,OADa,KAAK,IAAI,EAAQ,EAAe,CAC7C,CACE,IAAK,GACH,MAAO,GACT,IAAK,GACH,MAAO,IACT,IAAK,GACH,MAAO,IACT,QACE,MAAO,MAOP,GAAoB,EAAe,IAEhC,QADM,EAAQ,EACD,sBAUhB,GAAuC,CAC3C,WACA,YACA,GAAG,KAGD,EAAC,MAAA,CAAI,UAAW,EAAG,gBAAiB,EAAU,CAAE,GAAI,EACjD,YACG,CAWJ,GAAmD,CACvD,YACA,2BAA2B,GAC3B,GAAG,KACC,CACJ,GAAM,CACJ,gBACA,mBACA,aACA,aACA,cACE,GAAa,CACX,CAAE,YAAW,gBAAe,aAAc,EAAY,WAAW,CAIvE,OAFI,GAAc,EAAU,KAG1B,EAAC,MAAA,CACC,UAAW,EACT,oFACA,EACD,CACD,GAAI,YAEJ,EAAC,EAAA,CAAQ,WAAW,0BAClB,EAAC,EAAA,CACC,QAAS,EAAc,UACvB,MAAO,EAAY,QACnB,MAAO,EAAc,MACrB,YAAY,OACZ,QAAU,GAAM,CACd,EAAE,iBAAiB,CACnB,GAAY,EAEd,KAAM,EACN,KAAM,EAAW,QACjB,SAAU,IAAkB,GAC5B,CAEF,EAAC,EAAQ,OAAA,CAAO,WAAW,yBACzB,EAAC,MAAA,CAAI,UAAU,wCACb,EAAC,OAAA,CAAK,UAAU,kDACb,EAAc,OACV,CACP,EAAC,EAAA,CACC,SAAS,YACT,SAAU,EACV,KAAK,KACL,YAAa,GACb,CAAA,EACE,EACS,CAAA,EACT,CAET,MAAM,KAAK,CAAE,OAAQ,EAAY,CAAC,CAAC,KAAK,EAAG,IAAU,CACpD,IAAM,EAAW,IAAU,EAC3B,OACE,EAAC,SAAA,CAEC,KAAK,SACL,QAAU,GAAM,CACd,EAAE,iBAAiB,CACnB,EAAiB,EAAM,EAEzB,aAAY,EAAU,CAAE,MAAO,EAAQ,EAAG,CAAC,CAAC,MAC5C,UAAW,EACT,kIACA,EAAW,oBAAsB,8BAClC,EAVI,EAWL,EAEJ,CAEF,EAAC,EAAA,CAAQ,WAAW,0BAClB,EAAC,EAAA,CACC,QAAS,EAAc,UACvB,MAAO,EAAY,QACnB,YAAY,OACZ,MAAO,EAAU,MACjB,QAAU,GAAM,CACd,EAAE,iBAAiB,CACnB,GAAY,EAEd,KAAM,EACN,KAAM,EAAW,QACjB,SAAU,IAAkB,EAAa,GACzC,CAEF,EAAC,EAAQ,OAAA,CAAO,WAAW,yBACzB,EAAC,MAAA,CAAI,UAAU,wCACb,EAAC,OAAA,CAAK,UAAU,kDACb,EAAU,OACN,CACP,EAAC,EAAA,CACC,SAAS,aACT,KAAK,KACL,YAAa,EACb,SAAU,GACV,CAAA,EACE,EACS,CAAA,EACT,GACN,EAaJ,EACJ,GACkC,CAClC,IAAM,EAAyB,EAAE,CAC3B,EAAsB,EAAE,CAU9B,OARA,EAAS,QAAS,GAAU,CACtB,EAAe,EAAM,EAAI,EAAM,OAAS,EAC1C,EAAO,KAAK,EAAM,CAElB,EAAO,KAAK,EAAM,EAEpB,CAEK,CAAC,EAAQ,EAAO,EA+LZ,EAAW,OAAO,QA5LU,CACvC,WACA,YACA,eAAe,EACf,gBACA,GAAG,KACC,CAEJ,GAAM,CAAC,EAAQ,GAAU,EADL,EAAS,QAAQ,EAAS,CACiB,CACzD,EAAa,EAAO,OAGpB,CAAC,EAAe,GAAoB,EAAiB,EAAa,CAClE,CAAC,EAAgB,GAAqB,EAAiB,EAAa,CACpE,CAAC,EAAiB,GAAsB,EAAiB,EAAE,CAG3D,CAAC,EAAQ,GAAa,EAAS,EAAE,CACjC,CAAC,EAAY,GAAiB,EAAS,GAAM,CAG7C,EAAe,EAAuB,KAAK,CAC3C,EAAW,EAAkC,EAAE,CAAC,CAGhD,EAAoB,GAAiB,CACzC,GAAI,OAAO,OAAW,IAAa,OAGnC,IAAM,EADc,OAAO,WACK,EAC1B,EAAW,KAAK,MAAM,EAAO,EAAU,CAE7C,GAAI,KAAK,IAAI,EAAS,EAAI,EAAG,CAC3B,IAAM,EAAW,EAAiB,EAC5B,EAAe,KAAK,IAAI,EAAG,KAAK,IAAI,EAAU,EAAa,EAAE,CAAC,CAEhE,IAAiB,IACnB,EAAiB,EAAa,CAC9B,EAAW,GAAS,EAAO,EAAK,IAKhC,MAAmB,CACvB,EAAkB,GAAS,KAAK,IAAI,EAAO,EAAG,EAAa,EAAE,CAAC,EAG1D,MAAmB,CACvB,EAAkB,GAAS,KAAK,IAAI,EAAO,EAAG,EAAE,CAAC,EAI7C,EAAsD,GAAM,CAChE,EAAc,GAAK,CACnB,EAAU,EAAE,QAAQ,EAEhB,EAAsD,GAAM,CAC5D,GAAY,EAAiB,EAAE,QAAU,EAAO,EAEhD,MAAsB,EAAc,GAAM,CAuDhD,OA7CA,MAAgB,CACV,GAAe,IAAgB,EAAc,EAChD,CAAC,EAAe,EAAc,CAAC,CAElC,MAAgB,CACd,IAAI,EAaJ,OAXI,IAAkB,IACpB,EAAW,gBAAkB,CAC3B,EAAmB,GACb,IAAS,GACX,cAAc,EAAS,CAChB,GAEF,EAAO,EAAgB,EAAO,EAAI,EAAO,EAChD,EACD,GAAoB,MAEZ,cAAc,EAAS,EACnC,CAAC,EAAe,EAAe,CAAC,CAGnC,MAAgB,CACd,IAAM,MAA2B,CAC/B,IAAM,EAAU,EAAS,QAAQ,IAAK,GAAS,GAAM,cAAgB,EAAE,CACjE,EAAY,KAAK,IAAI,EAAG,GAAG,EAAQ,CAErC,EAAY,GACd,EAAmB,EAAY,GAAG,EAItC,GAAoB,CAEpB,IAAM,EAAW,IAAI,mBAAqB,CACxC,GAAoB,EACpB,CAMF,OAJA,EAAS,QAAQ,QAAS,GAAS,CAC7B,GAAM,EAAS,QAAQ,EAAK,EAChC,KAEW,EAAS,YAAY,EACjC,CAAC,EAAW,CAAC,CAGd,EAAC,EAAgB,SAAA,CACf,MAAO,CACL,gBACA,mBACA,aACA,aACA,aACD,UAED,EAAC,MAAA,CACC,IAAK,EACL,UAAW,EACT,8LACA,iBACA,EACD,CACD,MAAO,CACL,OAAQ,EAAkB,EAAI,EAAkB,OAChD,UAAW,QACZ,CACD,YAAa,EACb,YAAa,EACb,UAAW,EACX,aAAc,EACd,aA/EuD,GAAM,CACjE,EAAc,GAAK,CACnB,EAAU,EAAE,QAAQ,GAAG,QAAQ,EA8E3B,YA5EsD,GAAM,CAC5D,GAAY,EAAiB,EAAE,QAAQ,GAAG,QAAU,EAAO,EA4E3D,WAAY,EACZ,KAAK,SACL,aAAW,WACX,GAAI,YAEH,EAAO,KAAK,EAAO,IAEhB,EAAC,MAAA,CAEC,KAAK,SACL,SAAU,EACV,IAAM,GAAO,CACX,EAAS,QAAQ,GAAS,GAI5B,UAAW,EACT,6EACA,sJACA,EAAa,EAAO,EAAe,CACpC,CACD,QAAU,GAAM,CACd,EAAE,iBAAiB,CACnB,EAAiB,EAAM,EAEzB,UAAY,GAAM,EACZ,EAAE,MAAQ,SAAW,EAAE,MAAQ,MAAK,EAAiB,EAAM,EAEjE,MAAO,CAEL,UAAW;+BACI,EAAiB,EAAO,EAAe,CAAC;0BAC7C,EAAa,EAAO,EAAe,CAAC;kBAE/C,UAEA,GA5BI,EA6BD,CAER,CAED,EAAA,EACG,EACmB,EAIqB,CAClD,KAAM,EACN,WAAY,EACb,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{CodeDefault as e}from"./CodeBlockClient.mjs";import{useEffect as t,useState as n}from"react";import{jsx as r}from"react/jsx-runtime";const i=new Map,a=new Map,o=async e=>{if(i.has(e))return i.get(e);let t;switch(e){case`typescript`:case`ts`:t=await import(`shiki/langs/typescript.mjs`);break;case`javascript`:case`js`:t=await import(`shiki/langs/javascript.mjs`);break;case`bash`:case`sh`:case`shell`:t=await import(`shiki/langs/bash.mjs`);break;case`json`:t=await import(`shiki/langs/json.mjs`);break;case`tsx`:t=await import(`shiki/langs/tsx.mjs`);break;case`vue`:t=await import(`shiki/langs/vue.mjs`);break;case`html`:t=await import(`shiki/langs/html.mjs`);break;default:t=await import(`shiki/langs/typescript.mjs`);break}let n=t.default;return i.set(e,n),n},s=async e=>{if(a.has(e))return a.get(e);let t;switch(e){case`github-dark`:t=await import(`shiki/themes/github-dark.mjs`);break;
|
|
1
|
+
"use client";import{CodeDefault as e}from"./CodeBlockClient.mjs";import{useEffect as t,useState as n}from"react";import{jsx as r}from"react/jsx-runtime";const i=new Map,a=new Map,o=async e=>{if(i.has(e))return i.get(e);let t;switch(e){case`typescript`:case`ts`:t=await import(`shiki/langs/typescript.mjs`);break;case`javascript`:case`js`:t=await import(`shiki/langs/javascript.mjs`);break;case`bash`:case`sh`:case`shell`:t=await import(`shiki/langs/bash.mjs`);break;case`json`:t=await import(`shiki/langs/json.mjs`);break;case`tsx`:t=await import(`shiki/langs/tsx.mjs`);break;case`vue`:t=await import(`shiki/langs/vue.mjs`);break;case`html`:t=await import(`shiki/langs/html.mjs`);break;default:t=await import(`shiki/langs/typescript.mjs`);break}let n=t.default;return i.set(e,n),n},s=async e=>{if(a.has(e))return a.get(e);let t;switch(e){case`github-dark`:t=await import(`shiki/themes/github-dark.mjs`);break;default:t=await import(`shiki/themes/github-light.mjs`);break}let n=t.default;return a.set(e,n),n};let c=null;const l=async()=>(c||=import(`shiki/bundle/web`).then(({createHighlighter:e})=>e({langs:[],themes:[]})),c),u=async(e,t,n)=>{let r=n?`github-dark`:`github-light`,[i,a,c]=await Promise.all([l(),o(t),s(r)]);return i.getLoadedLanguages().includes(t)||await i.loadLanguage(a),i.getLoadedThemes().includes(r)||await i.loadTheme(c),i.codeToHtml(e,{lang:t,theme:r})},d=({children:i,lang:a,isDarkMode:o})=>{let[s,c]=n(null);return t(()=>{let e=!1;return u(i,a,o).then(t=>{e||c(t)}).catch(t=>{console.error(`Failed to highlight code:`,t),!e&&s===null&&c(``)}),()=>{e=!0}},[i,a,o]),r(`div`,{className:`min-w-0 max-w-full overflow-auto bg-transparent [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden [&_pre::-webkit-scrollbar]:hidden [&_pre]:[-ms-overflow-style:none] [&_pre]:[scrollbar-width:none]`,children:s?r(`div`,{dangerouslySetInnerHTML:{__html:s}}):r(e,{children:i})})};export{d as CodeBlockShiki};
|
|
2
2
|
//# sourceMappingURL=CodeBlockShiki.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlockShiki.mjs","names":[],"sources":["../../../../src/components/IDE/CodeBlockShiki.tsx"],"sourcesContent":["'use client';\n\nimport { type FC, useEffect, useState } from 'react';\nimport type {\n BundledLanguage,\n BundledTheme,\n
|
|
1
|
+
{"version":3,"file":"CodeBlockShiki.mjs","names":[],"sources":["../../../../src/components/IDE/CodeBlockShiki.tsx"],"sourcesContent":["'use client';\n\nimport { type FC, useEffect, useState } from 'react';\nimport type {\n BundledLanguage,\n BundledTheme,\n HighlighterGeneric,\n} from 'shiki/bundle/web';\nimport { CodeDefault } from './CodeBlockClient';\n\n// Map of loaded modules to avoid re-importing\nconst languageCache = new Map<BundledLanguage, any>();\nconst themeCache = new Map<BundledTheme, any>();\n\n// Lazy load language modules\nconst loadLanguage = async (lang: BundledLanguage): Promise<any> => {\n if (languageCache.has(lang)) return languageCache.get(lang);\n\n let languageModule: any;\n switch (lang) {\n case 'typescript':\n case 'ts':\n languageModule = await import('shiki/langs/typescript.mjs');\n break;\n case 'javascript':\n case 'js':\n languageModule = await import('shiki/langs/javascript.mjs');\n break;\n case 'bash':\n case 'sh':\n case 'shell':\n languageModule = await import('shiki/langs/bash.mjs');\n break;\n case 'json':\n languageModule = await import('shiki/langs/json.mjs');\n break;\n case 'tsx':\n languageModule = await import('shiki/langs/tsx.mjs');\n break;\n case 'vue':\n languageModule = await import('shiki/langs/vue.mjs');\n break;\n case 'html':\n languageModule = await import('shiki/langs/html.mjs');\n break;\n default:\n languageModule = await import('shiki/langs/typescript.mjs');\n break;\n }\n\n const language = languageModule.default;\n languageCache.set(lang, language);\n return language;\n};\n\n// Lazy load theme modules\nconst loadTheme = async (themeName: BundledTheme): Promise<any> => {\n if (themeCache.has(themeName)) return themeCache.get(themeName);\n\n let themeModule: any;\n switch (themeName) {\n case 'github-dark':\n themeModule = await import('shiki/themes/github-dark.mjs');\n break;\n case 'github-light':\n default:\n themeModule = await import('shiki/themes/github-light.mjs');\n break;\n }\n\n const theme = themeModule.default;\n themeCache.set(themeName, theme);\n return theme;\n};\n\n// Singleton Highlighter Instance\nlet highlighterPromise: Promise<HighlighterGeneric<any, any>> | null = null;\n\nconst getHighlighterInstance = async () => {\n if (!highlighterPromise) {\n highlighterPromise = import('shiki/bundle/web').then(\n ({ createHighlighter }) =>\n createHighlighter({\n langs: [],\n themes: [],\n })\n );\n }\n return highlighterPromise;\n};\n\n// Create a promise for highlighting\nconst highlightCode = async (\n code: string,\n lang: BundledLanguage,\n isDarkMode?: boolean\n): Promise<string> => {\n const themeName: BundledTheme = isDarkMode ? 'github-dark' : 'github-light';\n\n // Load highlighter, language, and theme in parallel\n const [highlighter, languageModule, themeModule] = await Promise.all([\n getHighlighterInstance(),\n loadLanguage(lang),\n loadTheme(themeName),\n ]);\n\n // Load into the singleton instance if not already loaded\n if (!highlighter.getLoadedLanguages().includes(lang)) {\n await highlighter.loadLanguage(languageModule);\n }\n if (!highlighter.getLoadedThemes().includes(themeName)) {\n await highlighter.loadTheme(themeModule);\n }\n\n return highlighter.codeToHtml(code, {\n lang,\n theme: themeName,\n });\n};\n\nexport type CodeBlockShikiProps = {\n children: string;\n lang: BundledLanguage;\n isDarkMode?: boolean;\n};\n\nexport const CodeBlockShiki: FC<CodeBlockShikiProps> = ({\n children,\n lang,\n isDarkMode,\n}) => {\n const [html, setHtml] = useState<string | null>(null);\n\n useEffect(() => {\n let isCancelled = false;\n\n highlightCode(children, lang, isDarkMode)\n .then((result) => {\n if (!isCancelled) setHtml(result);\n })\n .catch((error) => {\n console.error('Failed to highlight code:', error);\n if (!isCancelled && html === null) setHtml('');\n });\n\n return () => {\n isCancelled = true;\n };\n }, [children, lang, isDarkMode]);\n\n return (\n <div className=\"min-w-0 max-w-full overflow-auto bg-transparent [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden [&_pre::-webkit-scrollbar]:hidden [&_pre]:[-ms-overflow-style:none] [&_pre]:[scrollbar-width:none]\">\n {html ? (\n // biome-ignore lint/security/noDangerouslySetInnerHtml: Shiki generates safe HTML for code highlighting\n <div dangerouslySetInnerHTML={{ __html: html }} />\n ) : (\n <CodeDefault>{children}</CodeDefault>\n )}\n </div>\n );\n};\n"],"mappings":"yJAWA,MAAM,EAAgB,IAAI,IACpB,EAAa,IAAI,IAGjB,EAAe,KAAO,IAAwC,CAClE,GAAI,EAAc,IAAI,EAAK,CAAE,OAAO,EAAc,IAAI,EAAK,CAE3D,IAAI,EACJ,OAAQ,EAAR,CACE,IAAK,aACL,IAAK,KACH,EAAiB,MAAM,OAAO,8BAC9B,MACF,IAAK,aACL,IAAK,KACH,EAAiB,MAAM,OAAO,8BAC9B,MACF,IAAK,OACL,IAAK,KACL,IAAK,QACH,EAAiB,MAAM,OAAO,wBAC9B,MACF,IAAK,OACH,EAAiB,MAAM,OAAO,wBAC9B,MACF,IAAK,MACH,EAAiB,MAAM,OAAO,uBAC9B,MACF,IAAK,MACH,EAAiB,MAAM,OAAO,uBAC9B,MACF,IAAK,OACH,EAAiB,MAAM,OAAO,wBAC9B,MACF,QACE,EAAiB,MAAM,OAAO,8BAC9B,MAGJ,IAAM,EAAW,EAAe,QAEhC,OADA,EAAc,IAAI,EAAM,EAAS,CAC1B,GAIH,EAAY,KAAO,IAA0C,CACjE,GAAI,EAAW,IAAI,EAAU,CAAE,OAAO,EAAW,IAAI,EAAU,CAE/D,IAAI,EACJ,OAAQ,EAAR,CACE,IAAK,cACH,EAAc,MAAM,OAAO,gCAC3B,MAEF,QACE,EAAc,MAAM,OAAO,iCAC3B,MAGJ,IAAM,EAAQ,EAAY,QAE1B,OADA,EAAW,IAAI,EAAW,EAAM,CACzB,GAIT,IAAI,EAAmE,KAEvE,MAAM,EAAyB,UAC7B,AACE,IAAqB,OAAO,oBAAoB,MAC7C,CAAE,uBACD,EAAkB,CAChB,MAAO,EAAE,CACT,OAAQ,EAAE,CACX,CAAC,CACL,CAEI,GAIH,EAAgB,MACpB,EACA,EACA,IACoB,CACpB,IAAM,EAA0B,EAAa,cAAgB,eAGvD,CAAC,EAAa,EAAgB,GAAe,MAAM,QAAQ,IAAI,CACnE,GAAwB,CACxB,EAAa,EAAK,CAClB,EAAU,EAAU,CACrB,CAAC,CAUF,OAPK,EAAY,oBAAoB,CAAC,SAAS,EAAK,EAClD,MAAM,EAAY,aAAa,EAAe,CAE3C,EAAY,iBAAiB,CAAC,SAAS,EAAU,EACpD,MAAM,EAAY,UAAU,EAAY,CAGnC,EAAY,WAAW,EAAM,CAClC,OACA,MAAO,EACR,CAAC,EASS,GAA2C,CACtD,WACA,OACA,gBACI,CACJ,GAAM,CAAC,EAAM,GAAW,EAAwB,KAAK,CAmBrD,OAjBA,MAAgB,CACd,IAAI,EAAc,GAWlB,OATA,EAAc,EAAU,EAAM,EAAW,CACtC,KAAM,GAAW,CACX,GAAa,EAAQ,EAAO,EACjC,CACD,MAAO,GAAU,CAChB,QAAQ,MAAM,4BAA6B,EAAM,CAC7C,CAAC,GAAe,IAAS,MAAM,EAAQ,GAAG,EAC9C,KAES,CACX,EAAc,KAEf,CAAC,EAAU,EAAM,EAAW,CAAC,CAG9B,EAAC,MAAA,CAAI,UAAU,6OACZ,EAEC,EAAC,MAAA,CAAI,wBAAyB,CAAE,OAAQ,EAAM,CAAA,CAAI,CAElD,EAAC,EAAA,CAAa,WAAA,CAAuB,EAEnC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{cn as e}from"../../utils/cn.mjs";import{ExternalLink as t,MoveRight as n}from"lucide-react";import{isValidElement as r}from"react";import{cva as i}from"class-variance-authority";import{jsx as a,jsxs as o}from"react/jsx-runtime";import{getLocalizedUrl as s}from"@intlayer/core/localization";let c=function(e){return e.DEFAULT=`default`,e.INVISIBLE_LINK=`invisible-link`,e.BUTTON=`button`,e.BUTTON_OUTLINED=`button-outlined`,e.HOVERABLE=`hoverable`,e}({}),l=function(e){return e.PRIMARY=`primary`,e.SECONDARY=`secondary`,e.DESTRUCTIVE=`destructive`,e.NEUTRAL=`neutral`,e.LIGHT=`light`,e.DARK=`dark`,e.TEXT=`text`,e.TEXT_INVERSE=`text-inverse`,e.ERROR=`error`,e.SUCCESS=`success`,e.CUSTOM=`custom`,e}({}),u=function(e){return e.NONE=`none`,e.SM=`sm`,e.MD=`md`,e.LG=`lg`,e.XL=`xl`,e.TWO_XL=`2xl`,e.THREE_XL=`3xl`,e.FULL=`full`,e}({}),d=function(e){return e.SM=`sm`,e.MD=`md`,e.LG=`lg`,e.XL=`xl`,e.CUSTOM=`custom`,e}({}),f=function(e){return e.DEFAULT=`default`,e.TRUE=`true`,e.FALSE=`false`,e}({});const p=i(`gap-3 transition-all duration-300 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50`,{variants:{variant:{[`${c.DEFAULT}`]:`h-auto justify-start border-inherit bg-current/0 px-1 decoration-1 underline-offset-
|
|
1
|
+
import{cn as e}from"../../utils/cn.mjs";import{ExternalLink as t,MoveRight as n}from"lucide-react";import{isValidElement as r}from"react";import{cva as i}from"class-variance-authority";import{jsx as a,jsxs as o}from"react/jsx-runtime";import{getLocalizedUrl as s}from"@intlayer/core/localization";let c=function(e){return e.DEFAULT=`default`,e.INVISIBLE_LINK=`invisible-link`,e.BUTTON=`button`,e.BUTTON_OUTLINED=`button-outlined`,e.HOVERABLE=`hoverable`,e}({}),l=function(e){return e.PRIMARY=`primary`,e.SECONDARY=`secondary`,e.DESTRUCTIVE=`destructive`,e.NEUTRAL=`neutral`,e.LIGHT=`light`,e.DARK=`dark`,e.TEXT=`text`,e.TEXT_INVERSE=`text-inverse`,e.ERROR=`error`,e.SUCCESS=`success`,e.CUSTOM=`custom`,e}({}),u=function(e){return e.NONE=`none`,e.SM=`sm`,e.MD=`md`,e.LG=`lg`,e.XL=`xl`,e.TWO_XL=`2xl`,e.THREE_XL=`3xl`,e.FULL=`full`,e}({}),d=function(e){return e.SM=`sm`,e.MD=`md`,e.LG=`lg`,e.XL=`xl`,e.CUSTOM=`custom`,e}({}),f=function(e){return e.DEFAULT=`default`,e.TRUE=`true`,e.FALSE=`false`,e}({});const p=i(`gap-3 transition-all duration-300 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50`,{variants:{variant:{[`${c.DEFAULT}`]:`h-auto justify-start border-inherit bg-current/0 px-1 font-medium decoration-[1.5] underline-offset-5 hover:bg-current/0 hover:text-current/80 hover:underline hover:underline-offset-6`,[`${c.INVISIBLE_LINK}`]:`h-auto justify-start border-inherit bg-current/0 px-1 underline-offset-5 hover:bg-current/0`,[`${c.BUTTON}`]:`relative flex cursor-pointer flex-row items-center justify-center gap-2 rounded-full bg-current text-center font-medium text-text ring-0 *:text-text-opposite hover:bg-current/90 hover:ring-5 aria-selected:ring-5`,[`${c.BUTTON_OUTLINED}`]:`relative flex cursor-pointer flex-row items-center justify-center gap-2 rounded-full border-[1.3px] border-current text-center font-medium text-text ring-0 *:text-text hover:bg-current/20 hover:ring-5 aria-selected:ring-5`,[`${c.HOVERABLE}`]:`block rounded-lg border-none bg-current/0 hover:bg-current/10 aria-[current]:bg-current/5`},roundedSize:{[`${u.NONE}`]:`rounded-none`,[`${u.SM}`]:`rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl`,[`${u.MD}`]:`rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl`,[`${u.LG}`]:`rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl`,[`${u.XL}`]:`rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl`,[`${u.TWO_XL}`]:`rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]`,[`${u.THREE_XL}`]:`rounded-[2.5rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[3rem]`,[`${u.FULL}`]:`rounded-full`},color:{[`${l.PRIMARY}`]:`text-primary`,[`${l.SECONDARY}`]:`text-secondary`,[`${l.DESTRUCTIVE}`]:`text-destructive`,[`${l.NEUTRAL}`]:`text-neutral`,[`${l.LIGHT}`]:`text-white`,[`${l.DARK}`]:`text-neutral-800`,[`${l.TEXT}`]:`text-text`,[`${l.TEXT_INVERSE}`]:`text-text-opposite`,[`${l.ERROR}`]:`text-error`,[`${l.SUCCESS}`]:`text-success`,[`${l.CUSTOM}`]:``},size:{[`${d.SM}`]:`text-sm`,[`${d.MD}`]:`text-base`,[`${d.LG}`]:`text-lg`,[`${d.XL}`]:`text-xl`,[`${d.CUSTOM}`]:``},underlined:{[f.DEFAULT]:``,[f.TRUE]:`underline`,[f.FALSE]:`no-underline`}},compoundVariants:[{variant:c.BUTTON,color:l.TEXT_INVERSE,class:`*:text-text`},{variant:c.BUTTON_OUTLINED,color:l.TEXT_INVERSE,class:`text-text-opposite *:text-text-opposite`},{variant:[c.BUTTON,c.BUTTON_OUTLINED],size:d.SM,class:`min-h-7 px-3 max-md:py-1`},{variant:[c.BUTTON,c.BUTTON_OUTLINED],size:d.MD,class:`min-h-8 px-6 max-md:py-2`},{variant:[c.BUTTON,c.BUTTON_OUTLINED],size:d.LG,class:`min-h-10 px-8 max-md:py-3`},{variant:[c.BUTTON,c.BUTTON_OUTLINED],size:d.XL,class:`min-h-11 px-10 max-md:py-4`},{variant:[c.BUTTON,c.BUTTON_OUTLINED],color:l.PRIMARY,class:`ring-primary/20`},{variant:[c.BUTTON,c.BUTTON_OUTLINED],color:l.SECONDARY,class:`ring-secondary/20`},{variant:[c.BUTTON,c.BUTTON_OUTLINED],color:l.DESTRUCTIVE,class:`ring-destructive/20`},{variant:[c.BUTTON,c.BUTTON_OUTLINED],color:l.NEUTRAL,class:`ring-neutral/20`},{variant:[c.BUTTON,c.BUTTON_OUTLINED],color:l.LIGHT,class:`ring-white/20`},{variant:[c.BUTTON,c.BUTTON_OUTLINED],color:l.DARK,class:`ring-neutral-800/20`},{variant:[c.BUTTON,c.BUTTON_OUTLINED],color:l.TEXT,class:`ring-text/20`},{variant:[c.BUTTON,c.BUTTON_OUTLINED],color:l.TEXT_INVERSE,class:`ring-text-opposite/20`},{variant:[c.BUTTON,c.BUTTON_OUTLINED],color:l.ERROR,class:`ring-error/20`},{variant:[c.BUTTON,c.BUTTON_OUTLINED],color:l.SUCCESS,class:`ring-success/20`}],defaultVariants:{variant:c.DEFAULT,roundedSize:u.MD,underlined:f.DEFAULT,size:d.MD}}),m=({href:e,isExternalLink:t})=>{let n=typeof e==`string`&&e.trim()!==``;return t===!0||t===void 0&&n&&/^https?:\/\//.test(e)},h=e=>typeof e==`string`||typeof e==`number`?!0:Array.isArray(e)?e.every(h):r(e)?h(e.props.children):!1,g=r=>{let{variant:i=c.DEFAULT,color:u=l.CUSTOM,roundedSize:d,children:f,label:g,className:_,isActive:v,underlined:y,locale:b,size:x,isExternalLink:S,isPageSection:C,href:w,...T}=r,E=S??m(r),D=C??w?.startsWith(`#`)??!1,O=h(f),k=i===c.BUTTON||i===c.BUTTON_OUTLINED,A=E?`noopener noreferrer nofollow`:void 0,j=E?`_blank`:`_self`;return o(`a`,{href:b&&w&&!E&&!D?s(w,b):w,"aria-label":g,rel:A,target:j,"aria-current":v?`page`:void 0,className:e(p({variant:i,color:u,roundedSize:d,underlined:y,size:x,className:_})),...T,children:[k&&O?a(`span`,{children:f}):f,E&&O&&a(t,{className:`ml-2 inline-block size-4`}),D&&a(n,{className:`ml-2 inline-block size-4`})]})};export{g as Link,l as LinkColor,u as LinkRoundedSize,d as LinkSize,f as LinkUnderlined,c as LinkVariant,m as checkIsExternalLink,h as isTextChildren,p as linkVariants};
|
|
2
2
|
//# sourceMappingURL=Link.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.mjs","names":[],"sources":["../../../../src/components/Link/Link.tsx"],"sourcesContent":["import { getLocalizedUrl } from '@intlayer/core/localization';\nimport type { LocalesValues } from '@intlayer/types';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ExternalLink, MoveRight } from 'lucide-react';\nimport {\n type AnchorHTMLAttributes,\n type DetailedHTMLProps,\n type FC,\n isValidElement,\n type ReactNode,\n} from 'react';\n\n/**\n * Visual style variants for Link component\n */\nexport enum LinkVariant {\n DEFAULT = 'default',\n INVISIBLE_LINK = 'invisible-link',\n BUTTON = 'button',\n BUTTON_OUTLINED = 'button-outlined',\n HOVERABLE = 'hoverable',\n}\n\n/**\n * Color theme variants for Link component\n */\nexport enum LinkColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n DESTRUCTIVE = 'destructive',\n NEUTRAL = 'neutral',\n LIGHT = 'light',\n DARK = 'dark',\n TEXT = 'text',\n TEXT_INVERSE = 'text-inverse',\n ERROR = 'error',\n SUCCESS = 'success',\n CUSTOM = 'custom',\n}\n\nexport enum LinkRoundedSize {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n TWO_XL = '2xl',\n THREE_XL = '3xl',\n FULL = 'full',\n}\n\nexport enum LinkSize {\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n CUSTOM = 'custom',\n}\n\nexport enum LinkUnderlined {\n DEFAULT = 'default',\n TRUE = 'true',\n FALSE = 'false',\n}\n\nexport const linkVariants = cva(\n 'gap-3 transition-all duration-300 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n [`${LinkVariant.DEFAULT}`]:\n 'h-auto justify-start border-inherit bg-current/0 px-1 decoration-1 underline-offset-4 hover:bg-current/0 hover:underline',\n [`${LinkVariant.INVISIBLE_LINK}`]:\n 'h-auto justify-start border-inherit bg-current/0 px-1 underline-offset-4 hover:bg-current/0',\n\n [`${LinkVariant.BUTTON}`]:\n 'relative flex cursor-pointer flex-row items-center justify-center gap-2 rounded-full bg-current text-center font-medium text-text ring-0 *:text-text-opposite hover:bg-current/90 hover:ring-5 aria-selected:ring-5',\n\n [`${LinkVariant.BUTTON_OUTLINED}`]:\n 'relative flex cursor-pointer flex-row items-center justify-center gap-2 rounded-full border-[1.3px] border-current text-center font-medium text-text ring-0 *:text-text hover:bg-current/20 hover:ring-5 aria-selected:ring-5',\n\n [`${LinkVariant.HOVERABLE}`]:\n 'block rounded-lg border-none bg-current/0 hover:bg-current/10 aria-[current]:bg-current/5',\n },\n roundedSize: {\n [`${LinkRoundedSize.NONE}`]: 'rounded-none',\n [`${LinkRoundedSize.SM}`]:\n 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n [`${LinkRoundedSize.MD}`]:\n 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n [`${LinkRoundedSize.LG}`]:\n 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n [`${LinkRoundedSize.XL}`]:\n 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n [`${LinkRoundedSize.TWO_XL}`]:\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n [`${LinkRoundedSize.THREE_XL}`]:\n 'rounded-[2.5rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[3rem]',\n [`${LinkRoundedSize.FULL}`]: 'rounded-full',\n },\n color: {\n [`${LinkColor.PRIMARY}`]: 'text-primary',\n [`${LinkColor.SECONDARY}`]: 'text-secondary',\n [`${LinkColor.DESTRUCTIVE}`]: 'text-destructive',\n [`${LinkColor.NEUTRAL}`]: 'text-neutral',\n [`${LinkColor.LIGHT}`]: 'text-white',\n [`${LinkColor.DARK}`]: 'text-neutral-800',\n [`${LinkColor.TEXT}`]: 'text-text',\n [`${LinkColor.TEXT_INVERSE}`]: 'text-text-opposite',\n [`${LinkColor.ERROR}`]: 'text-error',\n [`${LinkColor.SUCCESS}`]: 'text-success',\n [`${LinkColor.CUSTOM}`]: '',\n },\n size: {\n [`${LinkSize.SM}`]: 'text-sm',\n [`${LinkSize.MD}`]: 'text-base',\n [`${LinkSize.LG}`]: 'text-lg',\n [`${LinkSize.XL}`]: 'text-xl',\n [`${LinkSize.CUSTOM}`]: '',\n },\n underlined: {\n [LinkUnderlined.DEFAULT]: '',\n [LinkUnderlined.TRUE]: 'underline',\n [LinkUnderlined.FALSE]: 'no-underline',\n },\n },\n // Compound variants handle height and padding\n compoundVariants: [\n // ---------------------------------------------------------\n // FIX START: Correctly Handle Contrast for TEXT_INVERSE\n // ---------------------------------------------------------\n {\n // Filled Button + Inverse Color (e.g., White Button):\n // We DO NOT override parent text color (it must remain 'text-opposite' so bg-current is white).\n // We ONLY override children to be 'text-text' (Dark) so they show up on white.\n variant: LinkVariant.BUTTON,\n color: LinkColor.TEXT_INVERSE,\n class: '*:text-text',\n },\n {\n // Outlined Button + Inverse Color (e.g., White Border):\n // Parent is 'text-opposite' (Border is white).\n // Children must also be 'text-opposite' (White text) to show on dark background.\n variant: LinkVariant.BUTTON_OUTLINED,\n color: LinkColor.TEXT_INVERSE,\n class: 'text-text-opposite *:text-text-opposite',\n },\n\n // Min height and padding for button variants\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.SM,\n class: 'min-h-7 px-3 max-md:py-1',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.MD,\n class: 'min-h-8 px-6 max-md:py-2',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.LG,\n class: 'min-h-10 px-8 max-md:py-3',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.XL,\n class: 'min-h-11 px-10 max-md:py-4',\n },\n // Ring color variants\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.PRIMARY,\n class: 'ring-primary/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.SECONDARY,\n class: 'ring-secondary/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.DESTRUCTIVE,\n class: 'ring-destructive/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.NEUTRAL,\n class: 'ring-neutral/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.LIGHT,\n class: 'ring-white/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.DARK,\n class: 'ring-neutral-800/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.TEXT,\n class: 'ring-text/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.TEXT_INVERSE,\n class: 'ring-text-opposite/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.ERROR,\n class: 'ring-error/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.SUCCESS,\n class: 'ring-success/20',\n },\n ],\n\n defaultVariants: {\n variant: LinkVariant.DEFAULT,\n color: LinkColor.PRIMARY,\n roundedSize: LinkRoundedSize.MD,\n underlined: LinkUnderlined.DEFAULT,\n size: LinkSize.MD,\n },\n }\n);\n\nexport type LinkProps = DetailedHTMLProps<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n HTMLAnchorElement\n> &\n VariantProps<typeof linkVariants> & {\n label: string;\n isExternalLink?: boolean;\n isPageSection?: boolean;\n isActive?: boolean;\n locale?: LocalesValues;\n };\n\nexport const checkIsExternalLink = ({\n href,\n isExternalLink: isExternalLinkProp,\n}: LinkProps): boolean => {\n const isValidHref = typeof href === 'string' && href.trim() !== '';\n const isExternalLink =\n isExternalLinkProp === true ||\n (typeof isExternalLinkProp === 'undefined' &&\n isValidHref &&\n /^https?:\\/\\//.test(href));\n\n return isExternalLink;\n};\n\nexport const isTextChildren = (children: ReactNode): boolean => {\n if (typeof children === 'string' || typeof children === 'number') {\n return true;\n }\n if (Array.isArray(children)) {\n return children.every(isTextChildren);\n }\n if (isValidElement(children)) {\n return isTextChildren(\n (children.props as { children?: ReactNode }).children\n );\n }\n return false;\n};\n\nexport const Link: FC<LinkProps> = (props) => {\n const {\n variant = LinkVariant.DEFAULT,\n color = LinkColor.PRIMARY,\n roundedSize,\n children,\n label,\n className,\n isActive,\n underlined,\n locale,\n size,\n isExternalLink: isExternalLinkProp,\n isPageSection: isPageSectionProp,\n href: hrefProp,\n ...otherProps\n } = props;\n\n const isExternalLink = isExternalLinkProp ?? checkIsExternalLink(props);\n const isPageSection = isPageSectionProp ?? hrefProp?.startsWith('#') ?? false;\n\n const isChildrenString = isTextChildren(children);\n const isButton =\n variant === LinkVariant.BUTTON || variant === LinkVariant.BUTTON_OUTLINED;\n\n const rel = isExternalLink ? 'noopener noreferrer nofollow' : undefined;\n\n const target = isExternalLink ? '_blank' : '_self';\n\n const href =\n locale && hrefProp && !isExternalLink && !isPageSection\n ? getLocalizedUrl(hrefProp, locale)\n : hrefProp;\n\n return (\n <a\n href={href}\n aria-label={label}\n rel={rel}\n target={target}\n aria-current={isActive ? 'page' : undefined}\n className={cn(\n linkVariants({\n variant,\n color,\n roundedSize,\n underlined,\n size,\n className,\n })\n )}\n {...otherProps}\n >\n {isButton && isChildrenString ? <span>{children}</span> : children}\n\n {isExternalLink && isChildrenString && (\n <ExternalLink className=\"ml-2 inline-block size-4\" />\n )}\n {isPageSection && <MoveRight className=\"ml-2 inline-block size-4\" />}\n </a>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Link.mjs","names":[],"sources":["../../../../src/components/Link/Link.tsx"],"sourcesContent":["import { getLocalizedUrl } from '@intlayer/core/localization';\nimport type { LocalesValues } from '@intlayer/types';\nimport { cn } from '@utils/cn';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ExternalLink, MoveRight } from 'lucide-react';\nimport {\n type AnchorHTMLAttributes,\n type DetailedHTMLProps,\n type FC,\n isValidElement,\n type ReactNode,\n} from 'react';\n\n/**\n * Visual style variants for Link component\n */\nexport enum LinkVariant {\n DEFAULT = 'default',\n INVISIBLE_LINK = 'invisible-link',\n BUTTON = 'button',\n BUTTON_OUTLINED = 'button-outlined',\n HOVERABLE = 'hoverable',\n}\n\n/**\n * Color theme variants for Link component\n */\nexport enum LinkColor {\n PRIMARY = 'primary',\n SECONDARY = 'secondary',\n DESTRUCTIVE = 'destructive',\n NEUTRAL = 'neutral',\n LIGHT = 'light',\n DARK = 'dark',\n TEXT = 'text',\n TEXT_INVERSE = 'text-inverse',\n ERROR = 'error',\n SUCCESS = 'success',\n CUSTOM = 'custom',\n}\n\nexport enum LinkRoundedSize {\n NONE = 'none',\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n TWO_XL = '2xl',\n THREE_XL = '3xl',\n FULL = 'full',\n}\n\nexport enum LinkSize {\n SM = 'sm',\n MD = 'md',\n LG = 'lg',\n XL = 'xl',\n CUSTOM = 'custom',\n}\n\nexport enum LinkUnderlined {\n DEFAULT = 'default',\n TRUE = 'true',\n FALSE = 'false',\n}\n\nexport const linkVariants = cva(\n 'gap-3 transition-all duration-300 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n [`${LinkVariant.DEFAULT}`]:\n 'h-auto justify-start border-inherit bg-current/0 px-1 font-medium decoration-[1.5] underline-offset-5 hover:bg-current/0 hover:text-current/80 hover:underline hover:underline-offset-6',\n [`${LinkVariant.INVISIBLE_LINK}`]:\n 'h-auto justify-start border-inherit bg-current/0 px-1 underline-offset-5 hover:bg-current/0',\n\n [`${LinkVariant.BUTTON}`]:\n 'relative flex cursor-pointer flex-row items-center justify-center gap-2 rounded-full bg-current text-center font-medium text-text ring-0 *:text-text-opposite hover:bg-current/90 hover:ring-5 aria-selected:ring-5',\n\n [`${LinkVariant.BUTTON_OUTLINED}`]:\n 'relative flex cursor-pointer flex-row items-center justify-center gap-2 rounded-full border-[1.3px] border-current text-center font-medium text-text ring-0 *:text-text hover:bg-current/20 hover:ring-5 aria-selected:ring-5',\n\n [`${LinkVariant.HOVERABLE}`]:\n 'block rounded-lg border-none bg-current/0 hover:bg-current/10 aria-[current]:bg-current/5',\n },\n roundedSize: {\n [`${LinkRoundedSize.NONE}`]: 'rounded-none',\n [`${LinkRoundedSize.SM}`]:\n 'rounded-lg [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-xl',\n [`${LinkRoundedSize.MD}`]:\n 'rounded-xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-2xl',\n [`${LinkRoundedSize.LG}`]:\n 'rounded-2xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-3xl',\n [`${LinkRoundedSize.XL}`]:\n 'rounded-3xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-4xl',\n [`${LinkRoundedSize.TWO_XL}`]:\n 'rounded-4xl [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[2.5rem]',\n [`${LinkRoundedSize.THREE_XL}`]:\n 'rounded-[2.5rem] [corner-shape:squircle] supports-[corner-shape:squircle]:rounded-[3rem]',\n [`${LinkRoundedSize.FULL}`]: 'rounded-full',\n },\n color: {\n [`${LinkColor.PRIMARY}`]: 'text-primary',\n [`${LinkColor.SECONDARY}`]: 'text-secondary',\n [`${LinkColor.DESTRUCTIVE}`]: 'text-destructive',\n [`${LinkColor.NEUTRAL}`]: 'text-neutral',\n [`${LinkColor.LIGHT}`]: 'text-white',\n [`${LinkColor.DARK}`]: 'text-neutral-800',\n [`${LinkColor.TEXT}`]: 'text-text',\n [`${LinkColor.TEXT_INVERSE}`]: 'text-text-opposite',\n [`${LinkColor.ERROR}`]: 'text-error',\n [`${LinkColor.SUCCESS}`]: 'text-success',\n [`${LinkColor.CUSTOM}`]: '',\n },\n size: {\n [`${LinkSize.SM}`]: 'text-sm',\n [`${LinkSize.MD}`]: 'text-base',\n [`${LinkSize.LG}`]: 'text-lg',\n [`${LinkSize.XL}`]: 'text-xl',\n [`${LinkSize.CUSTOM}`]: '',\n },\n underlined: {\n [LinkUnderlined.DEFAULT]: '',\n [LinkUnderlined.TRUE]: 'underline',\n [LinkUnderlined.FALSE]: 'no-underline',\n },\n },\n // Compound variants handle height and padding\n compoundVariants: [\n // ---------------------------------------------------------\n // FIX START: Correctly Handle Contrast for TEXT_INVERSE\n // ---------------------------------------------------------\n {\n // Filled Button + Inverse Color (e.g., White Button):\n // We DO NOT override parent text color (it must remain 'text-opposite' so bg-current is white).\n // We ONLY override children to be 'text-text' (Dark) so they show up on white.\n variant: LinkVariant.BUTTON,\n color: LinkColor.TEXT_INVERSE,\n class: '*:text-text',\n },\n {\n // Outlined Button + Inverse Color (e.g., White Border):\n // Parent is 'text-opposite' (Border is white).\n // Children must also be 'text-opposite' (White text) to show on dark background.\n variant: LinkVariant.BUTTON_OUTLINED,\n color: LinkColor.TEXT_INVERSE,\n class: 'text-text-opposite *:text-text-opposite',\n },\n\n // Min height and padding for button variants\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.SM,\n class: 'min-h-7 px-3 max-md:py-1',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.MD,\n class: 'min-h-8 px-6 max-md:py-2',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.LG,\n class: 'min-h-10 px-8 max-md:py-3',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n size: LinkSize.XL,\n class: 'min-h-11 px-10 max-md:py-4',\n },\n // Ring color variants\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.PRIMARY,\n class: 'ring-primary/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.SECONDARY,\n class: 'ring-secondary/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.DESTRUCTIVE,\n class: 'ring-destructive/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.NEUTRAL,\n class: 'ring-neutral/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.LIGHT,\n class: 'ring-white/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.DARK,\n class: 'ring-neutral-800/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.TEXT,\n class: 'ring-text/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.TEXT_INVERSE,\n class: 'ring-text-opposite/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.ERROR,\n class: 'ring-error/20',\n },\n {\n variant: [LinkVariant.BUTTON, LinkVariant.BUTTON_OUTLINED],\n color: LinkColor.SUCCESS,\n class: 'ring-success/20',\n },\n ],\n\n defaultVariants: {\n variant: LinkVariant.DEFAULT,\n roundedSize: LinkRoundedSize.MD,\n underlined: LinkUnderlined.DEFAULT,\n size: LinkSize.MD,\n },\n }\n);\n\nexport type LinkProps = DetailedHTMLProps<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n HTMLAnchorElement\n> &\n VariantProps<typeof linkVariants> & {\n label: string;\n isExternalLink?: boolean;\n isPageSection?: boolean;\n isActive?: boolean;\n locale?: LocalesValues;\n };\n\nexport const checkIsExternalLink = ({\n href,\n isExternalLink: isExternalLinkProp,\n}: LinkProps): boolean => {\n const isValidHref = typeof href === 'string' && href.trim() !== '';\n const isExternalLink =\n isExternalLinkProp === true ||\n (typeof isExternalLinkProp === 'undefined' &&\n isValidHref &&\n /^https?:\\/\\//.test(href));\n\n return isExternalLink;\n};\n\nexport const isTextChildren = (children: ReactNode): boolean => {\n if (typeof children === 'string' || typeof children === 'number') {\n return true;\n }\n if (Array.isArray(children)) {\n return children.every(isTextChildren);\n }\n if (isValidElement(children)) {\n return isTextChildren(\n (children.props as { children?: ReactNode }).children\n );\n }\n return false;\n};\n\nexport const Link: FC<LinkProps> = (props) => {\n const {\n variant = LinkVariant.DEFAULT,\n color = LinkColor.CUSTOM,\n roundedSize,\n children,\n label,\n className,\n isActive,\n underlined,\n locale,\n size,\n isExternalLink: isExternalLinkProp,\n isPageSection: isPageSectionProp,\n href: hrefProp,\n ...otherProps\n } = props;\n\n const isExternalLink = isExternalLinkProp ?? checkIsExternalLink(props);\n const isPageSection = isPageSectionProp ?? hrefProp?.startsWith('#') ?? false;\n\n const isChildrenString = isTextChildren(children);\n const isButton =\n variant === LinkVariant.BUTTON || variant === LinkVariant.BUTTON_OUTLINED;\n\n const rel = isExternalLink ? 'noopener noreferrer nofollow' : undefined;\n\n const target = isExternalLink ? '_blank' : '_self';\n\n const href =\n locale && hrefProp && !isExternalLink && !isPageSection\n ? getLocalizedUrl(hrefProp, locale)\n : hrefProp;\n\n return (\n <a\n href={href}\n aria-label={label}\n rel={rel}\n target={target}\n aria-current={isActive ? 'page' : undefined}\n className={cn(\n linkVariants({\n variant,\n color,\n roundedSize,\n underlined,\n size,\n className,\n })\n )}\n {...otherProps}\n >\n {isButton && isChildrenString ? <span>{children}</span> : children}\n\n {isExternalLink && isChildrenString && (\n <ExternalLink className=\"ml-2 inline-block size-4\" />\n )}\n {isPageSection && <MoveRight className=\"ml-2 inline-block size-4\" />}\n </a>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{cn as e}from"../../utils/cn.mjs";import{Link as t}from"../Link/Link.mjs";import{H1 as n,H2 as r,H3 as i,H4 as a,H5 as o,H6 as s}from"../Headers/index.mjs";import{CodeProvider as c}from"../IDE/CodeContext.mjs";import{Code as l}from"../IDE/Code.mjs";import{TabProvider as u}from"../Tab/TabContext.mjs";import{Tab as d}from"../Tab/Tab.mjs";import{Table as f}from"../Table/Table.mjs";import{jsx as p}from"react/jsx-runtime";import{renderMarkdown as m}from"react-intlayer";const h=c=>({components:{h1:e=>p(n,{isClickable:!0
|
|
1
|
+
import{cn as e}from"../../utils/cn.mjs";import{Link as t}from"../Link/Link.mjs";import{H1 as n,H2 as r,H3 as i,H4 as a,H5 as o,H6 as s}from"../Headers/index.mjs";import{CodeProvider as c}from"../IDE/CodeContext.mjs";import{Code as l}from"../IDE/Code.mjs";import{TabProvider as u}from"../Tab/TabContext.mjs";import{Tab as d}from"../Tab/Tab.mjs";import{Table as f}from"../Table/Table.mjs";import{jsx as p}from"react/jsx-runtime";import{renderMarkdown as m}from"react-intlayer";const h=c=>({components:{h1:e=>p(n,{isClickable:!0,className:`text-text`,...e}),h2:e=>p(r,{isClickable:!0,className:`mt-16 text-text`,...e}),h3:e=>p(i,{isClickable:!0,className:`mt-5 text-text`,...e}),h4:e=>p(a,{isClickable:!0,className:`mt-3 text-text`,...e}),h5:e=>p(o,{isClickable:!0,className:`mt-3 text-text`,...e}),h6:e=>p(s,{isClickable:!0,className:`mt-3 text-text`,...e}),strong:e=>p(`strong`,{className:`text-text`,...e}),code:({className:e,children:t,...n})=>{let r=String(t??``).replace(/\n$/,``);if(!e)return p(`code`,{className:`rounded-md border border-neutral/30 bg-card/60 box-decoration-clone px-1.5 py-0.5 font-mono text-sm`,children:r});let i=e?.replace(/lang(?:uage)?-/,``)||`plaintext`;return p(l,{...n,language:i,showHeader:!0,isDarkMode:c,children:r})},blockquote:({className:t,...n})=>p(`blockquote`,{className:e(`mt-5 gap-3 border-card border-l-4 pl-5 text-neutral`,`[&_strong]:text-neutral`,t),...n}),ul:({className:t,...n})=>p(`ul`,{className:e(`mt-5 flex list-disc flex-col gap-3 pl-5 marker:text-neutral/80`,t),...n}),ol:({className:t,...n})=>p(`ol`,{className:e(`mt-5 flex list-decimal flex-col gap-3 pl-5 marker:text-neutral/80`,t),...n}),img:({className:t,...n})=>p(`img`,{...n,alt:n.alt??``,loading:`lazy`,className:e(`max-h-[80vh] max-w-full rounded-md`,t),src:`${n.src}?raw=true`}),a:e=>p(t,{isExternalLink:e.href?.startsWith(`http`),underlined:!0,...e}),pre:e=>e.children,table:e=>p(f,{isRollable:!0,...e}),th:({className:t,...n})=>p(`th`,{className:e(`border-neutral border-b bg-neutral/10 p-4`,t),...n}),tr:({className:t,...n})=>p(`tr`,{className:e(`hover:/10 hover:bg-neutral/10`,t),...n}),td:({className:t,...n})=>p(`td`,{className:e(`border-neutral-500/50 border-b p-4`,t),...n}),hr:({className:t,...n})=>p(`hr`,{className:e(`mx-6 mt-16 text-neutral`,t),...n}),Tabs:e=>p(d,{...e,className:`rounded-xl border border-card`,headerClassName:`sticky rounded-xl top-24 z-5 bg-background/70 backdrop-blur overflow-x-auto`}),Tab:d.Item,Columns:({className:t,...n})=>p(`div`,{className:e(`flex gap-4 max-md:flex-col`,t),...n}),Column:({className:t,...n})=>p(`div`,{className:e(`flex-1`,t),...n})}}),g=({children:e,isDarkMode:n,locale:r,forceBlock:i,preserveFrontmatter:a,tagfilter:o,components:s,wrapper:d})=>{let f=h(n??!1);return p(c,{children:p(u,{children:m(e,{components:{...f.components,code:({className:e,children:t,...r})=>{let i=String(t??``).replace(/\n$/,``);if(!e)return p(`code`,{className:`rounded-md border border-neutral/30 bg-card/60 box-decoration-clone px-1.5 py-0.5 font-mono text-sm`,children:i});let a=e?.replace(/lang(?:uage)?-/,``)||`plaintext`;return p(l,{...r,language:a,showHeader:!0,isDarkMode:n,children:i})},a:e=>p(t,{isExternalLink:e.href?.startsWith(`http`),underlined:!0,locale:r,label:``,...e,color:`text`}),...s},wrapper:d??f.wrapper,forceBlock:i??f.forceBlock,preserveFrontmatter:a??f.preserveFrontmatter,tagfilter:o??f.tagfilter})})})};export{g as MarkdownRenderer,h as getIntlayerMarkdownOptions};
|
|
2
2
|
//# sourceMappingURL=MarkDownRender.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkDownRender.mjs","names":[],"sources":["../../../../src/components/MarkDownRender/MarkDownRender.tsx"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types';\nimport { cn } from '@utils/cn';\nimport type { ComponentProps, ComponentPropsWithoutRef, FC } from 'react';\nimport {\n type MarkdownRenderer as MarkdownRendererIntlayer,\n type RenderMarkdownProps,\n renderMarkdown,\n} from 'react-intlayer';\nimport type { BundledLanguage } from 'shiki/bundle/web';\nimport { H1, H2, H3, H4, H5, H6 } from '../Headers';\nimport { Code } from '../IDE/Code';\nimport { CodeProvider } from '../IDE/CodeContext';\nimport { Link } from '../Link';\nimport { Tab } from '../Tab';\nimport { TabProvider } from '../Tab/TabContext';\nimport { Table } from '../Table';\n\ntype MarkdownRendererProps = {\n children: string;\n isDarkMode?: boolean;\n locale?: LocalesValues;\n forceBlock?: boolean;\n preserveFrontmatter?: boolean;\n tagfilter?: boolean;\n components?: ComponentProps<typeof MarkdownRendererIntlayer>['components'];\n wrapper?: ComponentProps<typeof MarkdownRendererIntlayer>['wrapper'];\n};\n\nexport const getIntlayerMarkdownOptions: (\n isDarkMode: boolean\n) => RenderMarkdownProps = (isDarkMode) => ({\n components: {\n h1: (props) => <H1 isClickable={true} {...props} />,\n h2: (props) => <H2 isClickable={true} className=\"mt-16\" {...props} />,\n h3: (props) => <H3 isClickable={true} className=\"mt-5\" {...props} />,\n h4: (props) => <H4 isClickable={true} className=\"mt-3\" {...props} />,\n h5: (props) => <H5 isClickable={true} className=\"mt-3\" {...props} />,\n h6: (props) => <H6 isClickable={true} className=\"mt-3\" {...props} />,\n\n code: ({ className, children, ...rest }: ComponentProps<'code'>) => {\n // Ensure children is a string (Markdown renderer might pass ReactNodes)\n const content = String(children ?? '').replace(/\\n$/, '');\n\n // Determine if it is inline code or a code block\n // Code blocks usually have a className like 'language-ts'\n const isBlock = !!className;\n\n if (!isBlock) {\n return (\n <strong className=\"rounded bg-card/60 box-decoration-clone px-1 py-0.5 font-mono text-sm\">\n {content}\n </strong>\n );\n }\n\n // Extract language from className (e.g., \"language-typescript\" -> \"typescript\")\n const language = (className?.replace(/lang(?:uage)?-/, '') ||\n 'plaintext') as BundledLanguage;\n\n return (\n <Code\n {...rest}\n language={language}\n showHeader={true}\n isDarkMode={isDarkMode} // Ensure this variable is available in scope\n >\n {content}\n </Code>\n );\n },\n\n blockquote: ({ className, ...props }) => (\n <blockquote\n className={cn(\n 'mt-5 gap-3 border-card border-l-4 pl-5 text-neutral',\n className\n )}\n {...props}\n />\n ),\n ul: ({ className, ...props }) => (\n <ul\n className={cn('mt-5 flex list-disc flex-col gap-3 pl-5', className)}\n {...props}\n />\n ),\n ol: ({ className, ...props }) => (\n <ol\n className={cn('mt-5 flex list-decimal flex-col gap-3 pl-5', className)}\n {...props}\n />\n ),\n img: ({ className, ...props }) => (\n <img\n {...props}\n alt={props.alt ?? ''}\n loading=\"lazy\"\n className={cn('max-h-[80vh] max-w-full rounded-md', className)}\n src={`${props.src}?raw=true`}\n />\n ),\n a: (props) => (\n // @ts-expect-error - label is not required in LinkProps\n <Link\n isExternalLink={props.href?.startsWith('http')}\n underlined={true}\n // locale={locale}\n {...props}\n color=\"neutral\"\n />\n ),\n pre: (props) => props.children,\n\n table: (props: ComponentProps<typeof Table>) => (\n <Table isRollable={true} {...props} />\n ),\n th: ({ className, ...props }) => (\n <th\n className={cn('border-neutral border-b bg-neutral/10 p-4', className)}\n {...props}\n />\n ),\n tr: ({ className, ...props }) => (\n <tr\n className={cn('hover:/10 hover:bg-neutral/10', className)}\n {...props}\n />\n ),\n td: ({ className, ...props }) => (\n <td\n className={cn('border-neutral-500/50 border-b p-4', className)}\n {...props}\n />\n ),\n hr: ({ className, ...props }) => (\n <hr className={cn('mx-6 mt-16 text-neutral', className)} {...props} />\n ),\n Tabs: (props: ComponentProps<typeof Tab>) => (\n <Tab\n {...props}\n className=\"rounded-xl border border-card\"\n headerClassName=\"sticky rounded-xl top-24 z-5 bg-background/70 backdrop-blur overflow-x-auto\"\n />\n ),\n Tab: Tab.Item,\n Columns: ({ className, ...props }: ComponentPropsWithoutRef<'div'>) => (\n <div className={cn('flex gap-4 max-md:flex-col', className)} {...props} />\n ),\n Column: ({ className, ...props }: ComponentPropsWithoutRef<'div'>) => (\n <div className={cn('flex-1', className)} {...props} />\n ),\n },\n});\n\n/**\n * MarkdownRenderer Component\n *\n * A comprehensive markdown renderer that transforms markdown text into rich,\n * interactive HTML with custom styling and Intlayer integration. Supports\n * code syntax highlighting, responsive tables, internationalized links,\n * and automatic frontmatter stripping.\n *\n * @component\n */\nexport const MarkdownRenderer: FC<MarkdownRendererProps> = ({\n children,\n isDarkMode,\n locale,\n forceBlock,\n preserveFrontmatter,\n tagfilter,\n components: componentsProp,\n wrapper,\n}) => {\n const markdownOptions = getIntlayerMarkdownOptions(isDarkMode ?? false);\n\n const markdownContent = renderMarkdown(children, {\n components: {\n ...markdownOptions.components,\n // Pass dynamic props to components\n code: ({ className, children, ...rest }: ComponentProps<'code'>) => {\n // Ensure children is a string (Markdown renderer might pass ReactNodes)\n const content = String(children ?? '').replace(/\\n$/, '');\n\n // Determine if it is inline code or a code block\n // Code blocks usually have a className like 'language-ts'\n const isBlock = !!className;\n\n if (!isBlock) {\n return (\n <strong className=\"rounded bg-card/60 box-decoration-clone px-1 py-0.5 font-mono text-sm\">\n {content}\n </strong>\n );\n }\n\n // Extract language from className (e.g., \"language-typescript\" -> \"typescript\")\n const language = (className?.replace(/lang(?:uage)?-/, '') ||\n 'plaintext') as BundledLanguage;\n\n return (\n <Code\n {...rest}\n language={language}\n showHeader={true}\n isDarkMode={isDarkMode} // Ensure this variable is available in scope\n >\n {content}\n </Code>\n );\n },\n\n a: (props) => (\n // @ts-expect-error - label is not required in LinkProps\n <Link\n isExternalLink={props.href?.startsWith('http')}\n underlined={true}\n locale={locale}\n {...props}\n color=\"neutral\"\n />\n ),\n ...componentsProp,\n },\n wrapper: wrapper ?? markdownOptions.wrapper,\n forceBlock: forceBlock ?? markdownOptions.forceBlock,\n preserveFrontmatter:\n preserveFrontmatter ?? markdownOptions.preserveFrontmatter,\n tagfilter: tagfilter ?? markdownOptions.tagfilter,\n });\n\n return (\n <CodeProvider>\n <TabProvider>{markdownContent}</TabProvider>\n </CodeProvider>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MarkDownRender.mjs","names":[],"sources":["../../../../src/components/MarkDownRender/MarkDownRender.tsx"],"sourcesContent":["import type { LocalesValues } from '@intlayer/types';\nimport { cn } from '@utils/cn';\nimport type { ComponentProps, ComponentPropsWithoutRef, FC } from 'react';\nimport {\n type MarkdownRenderer as MarkdownRendererIntlayer,\n type RenderMarkdownProps,\n renderMarkdown,\n} from 'react-intlayer';\nimport type { BundledLanguage } from 'shiki/bundle/web';\nimport { H1, H2, H3, H4, H5, H6 } from '../Headers';\nimport { Code } from '../IDE/Code';\nimport { CodeProvider } from '../IDE/CodeContext';\nimport { Link } from '../Link';\nimport { Tab } from '../Tab';\nimport { TabProvider } from '../Tab/TabContext';\nimport { Table } from '../Table';\n\ntype MarkdownRendererProps = {\n children: string;\n isDarkMode?: boolean;\n locale?: LocalesValues;\n forceBlock?: boolean;\n preserveFrontmatter?: boolean;\n tagfilter?: boolean;\n components?: ComponentProps<typeof MarkdownRendererIntlayer>['components'];\n wrapper?: ComponentProps<typeof MarkdownRendererIntlayer>['wrapper'];\n};\n\nexport const getIntlayerMarkdownOptions: (\n isDarkMode: boolean\n) => RenderMarkdownProps = (isDarkMode) => ({\n components: {\n h1: (props) => <H1 isClickable={true} className=\"text-text\" {...props} />,\n h2: (props) => (\n <H2 isClickable={true} className=\"mt-16 text-text\" {...props} />\n ),\n h3: (props) => (\n <H3 isClickable={true} className=\"mt-5 text-text\" {...props} />\n ),\n h4: (props) => (\n <H4 isClickable={true} className=\"mt-3 text-text\" {...props} />\n ),\n h5: (props) => (\n <H5 isClickable={true} className=\"mt-3 text-text\" {...props} />\n ),\n h6: (props) => (\n <H6 isClickable={true} className=\"mt-3 text-text\" {...props} />\n ),\n strong: (props) => <strong className=\"text-text\" {...props} />,\n\n code: ({ className, children, ...rest }: ComponentProps<'code'>) => {\n // Ensure children is a string (Markdown renderer might pass ReactNodes)\n const content = String(children ?? '').replace(/\\n$/, '');\n\n // Determine if it is inline code or a code block\n // Code blocks usually have a className like 'language-ts'\n const isBlock = !!className;\n\n if (!isBlock) {\n return (\n <code className=\"rounded-md border border-neutral/30 bg-card/60 box-decoration-clone px-1.5 py-0.5 font-mono text-sm\">\n {content}\n </code>\n );\n }\n\n // Extract language from className (e.g., \"language-typescript\" -> \"typescript\")\n const language = (className?.replace(/lang(?:uage)?-/, '') ||\n 'plaintext') as BundledLanguage;\n\n return (\n <Code\n {...rest}\n language={language}\n showHeader={true}\n isDarkMode={isDarkMode} // Ensure this variable is available in scope\n >\n {content}\n </Code>\n );\n },\n blockquote: ({ className, ...props }) => (\n <blockquote\n className={cn(\n 'mt-5 gap-3 border-card border-l-4 pl-5 text-neutral',\n '[&_strong]:text-neutral',\n className\n )}\n {...props}\n />\n ),\n ul: ({ className, ...props }) => (\n <ul\n className={cn(\n 'mt-5 flex list-disc flex-col gap-3 pl-5 marker:text-neutral/80',\n className\n )}\n {...props}\n />\n ),\n ol: ({ className, ...props }) => (\n <ol\n className={cn(\n 'mt-5 flex list-decimal flex-col gap-3 pl-5 marker:text-neutral/80',\n className\n )}\n {...props}\n />\n ),\n img: ({ className, ...props }) => (\n <img\n {...props}\n alt={props.alt ?? ''}\n loading=\"lazy\"\n className={cn('max-h-[80vh] max-w-full rounded-md', className)}\n src={`${props.src}?raw=true`}\n />\n ),\n a: (props) => (\n // @ts-expect-error - label is not required in LinkProps\n <Link\n isExternalLink={props.href?.startsWith('http')}\n underlined={true}\n // locale={locale}\n {...props}\n />\n ),\n pre: (props) => props.children,\n\n table: (props: ComponentProps<typeof Table>) => (\n <Table isRollable={true} {...props} />\n ),\n th: ({ className, ...props }) => (\n <th\n className={cn('border-neutral border-b bg-neutral/10 p-4', className)}\n {...props}\n />\n ),\n tr: ({ className, ...props }) => (\n <tr\n className={cn('hover:/10 hover:bg-neutral/10', className)}\n {...props}\n />\n ),\n td: ({ className, ...props }) => (\n <td\n className={cn('border-neutral-500/50 border-b p-4', className)}\n {...props}\n />\n ),\n hr: ({ className, ...props }) => (\n <hr className={cn('mx-6 mt-16 text-neutral', className)} {...props} />\n ),\n Tabs: (props: ComponentProps<typeof Tab>) => (\n <Tab\n {...props}\n className=\"rounded-xl border border-card\"\n headerClassName=\"sticky rounded-xl top-24 z-5 bg-background/70 backdrop-blur overflow-x-auto\"\n />\n ),\n Tab: Tab.Item,\n Columns: ({ className, ...props }: ComponentPropsWithoutRef<'div'>) => (\n <div className={cn('flex gap-4 max-md:flex-col', className)} {...props} />\n ),\n Column: ({ className, ...props }: ComponentPropsWithoutRef<'div'>) => (\n <div className={cn('flex-1', className)} {...props} />\n ),\n },\n});\n\n/**\n * MarkdownRenderer Component\n *\n * A comprehensive markdown renderer that transforms markdown text into rich,\n * interactive HTML with custom styling and Intlayer integration. Supports\n * code syntax highlighting, responsive tables, internationalized links,\n * and automatic frontmatter stripping.\n *\n * @component\n */\nexport const MarkdownRenderer: FC<MarkdownRendererProps> = ({\n children,\n isDarkMode,\n locale,\n forceBlock,\n preserveFrontmatter,\n tagfilter,\n components: componentsProp,\n wrapper,\n}) => {\n const markdownOptions = getIntlayerMarkdownOptions(isDarkMode ?? false);\n\n const markdownContent = renderMarkdown(children, {\n components: {\n ...markdownOptions.components,\n // Pass dynamic props to components\n code: ({ className, children, ...rest }: ComponentProps<'code'>) => {\n // Ensure children is a string (Markdown renderer might pass ReactNodes)\n const content = String(children ?? '').replace(/\\n$/, '');\n\n // Determine if it is inline code or a code block\n // Code blocks usually have a className like 'language-ts'\n const isBlock = !!className;\n\n if (!isBlock) {\n return (\n <code className=\"rounded-md border border-neutral/30 bg-card/60 box-decoration-clone px-1.5 py-0.5 font-mono text-sm\">\n {content}\n </code>\n );\n }\n\n // Extract language from className (e.g., \"language-typescript\" -> \"typescript\")\n const language = (className?.replace(/lang(?:uage)?-/, '') ||\n 'plaintext') as BundledLanguage;\n\n return (\n <Code\n {...rest}\n language={language}\n showHeader={true}\n isDarkMode={isDarkMode} // Ensure this variable is available in scope\n >\n {content}\n </Code>\n );\n },\n\n a: (props) => (\n <Link\n isExternalLink={props.href?.startsWith('http')}\n underlined={true}\n locale={locale}\n label=\"\"\n {...props}\n color=\"text\"\n />\n ),\n ...componentsProp,\n },\n wrapper: wrapper ?? markdownOptions.wrapper,\n forceBlock: forceBlock ?? markdownOptions.forceBlock,\n preserveFrontmatter:\n preserveFrontmatter ?? markdownOptions.preserveFrontmatter,\n tagfilter: tagfilter ?? markdownOptions.tagfilter,\n });\n\n return (\n <CodeProvider>\n <TabProvider>{markdownContent}</TabProvider>\n </CodeProvider>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{Select as e}from"../Select/Select.mjs";import{jsx as t,jsxs as n}from"react/jsx-runtime";import{useIntlayer as r}from"react-intlayer";const i=({value:i,onValueChange:a,min:o=5,max:s=500})=>{let{numberItemsSelector:c,selectPageSize:l}=r(`pagination`),u=[1,2,5,10,20,50,100,200,500,1e3,2e3,5e3,1e4,1e5].filter(e=>e>=o&&e<=s);return n(`div`,{className:`flex items-center gap-2`,children:[t(`span`,{className:`text-neutral-600 text-sm dark:text-neutral-400`,children:c}),n(e,{value:i,onValueChange:a,children:[t(e.Trigger,{className:`w-20`,children:t(e.Value,{placeholder:l})}),t(e.Content,{children:u.map(n=>t(e.Item,{value:n.toString(),children:n},n))})]})]})};export{i as NumberItemsSelector};
|
|
1
|
+
"use client";import{Select as e}from"../Select/Select.mjs";import{jsx as t,jsxs as n}from"react/jsx-runtime";import{useIntlayer as r}from"react-intlayer";const i=({value:i,onValueChange:a,min:o=5,max:s=500})=>{let{numberItemsSelector:c,selectPageSize:l}=r(`pagination`),u=[1,2,5,10,20,50,100,200,500,1e3,2e3,5e3,1e4,1e5].filter(e=>e>=o&&e<=s);return n(`div`,{className:`flex items-center gap-2`,children:[t(`span`,{className:`text-neutral-600 text-sm dark:text-neutral-400`,children:c}),n(e,{value:i.toString(),onValueChange:a,children:[t(e.Trigger,{className:`w-20`,children:t(e.Value,{placeholder:l})}),t(e.Content,{children:u.map(n=>t(e.Item,{value:n.toString(),children:n},n))})]})]})};export{i as NumberItemsSelector};
|
|
2
2
|
//# sourceMappingURL=NumberItemsSelector.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NumberItemsSelector.mjs","names":[],"sources":["../../../../src/components/Pagination/NumberItemsSelector.tsx"],"sourcesContent":["'use client';\n\nimport type { FC } from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { Select } from '../Select';\n\nexport type NumberItemsSelectorProps = {\n value: string;\n onValueChange: (value: string) => void;\n min?: number;\n max?: number;\n};\n\nexport const NumberItemsSelector: FC<NumberItemsSelectorProps> = ({\n value,\n onValueChange,\n min = 5,\n max = 500,\n}) => {\n const { numberItemsSelector, selectPageSize } = useIntlayer('pagination');\n\n const items = [\n 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 100000,\n ].filter((item) => item >= min && item <= max);\n\n return (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-neutral-600 text-sm dark:text-neutral-400\">\n {numberItemsSelector}\n </span>\n <Select value={value} onValueChange={onValueChange}>\n <Select.Trigger className=\"w-20\">\n <Select.Value placeholder={selectPageSize} />\n </Select.Trigger>\n <Select.Content>\n {items.map((item) => (\n <Select.Item key={item} value={item.toString()}>\n {item}\n </Select.Item>\n ))}\n </Select.Content>\n </Select>\n </div>\n );\n};\n"],"mappings":"0JAaA,MAAa,GAAqD,CAChE,QACA,gBACA,MAAM,EACN,MAAM,OACF,CACJ,GAAM,CAAE,sBAAqB,kBAAmB,EAAY,aAAa,CAEnE,EAAQ,CACZ,EAAG,EAAG,EAAG,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,IAAM,IAAM,IAAM,IAAO,IAC9D,CAAC,OAAQ,GAAS,GAAQ,GAAO,GAAQ,EAAI,CAE9C,OACE,EAAC,MAAA,CAAI,UAAU,oCACb,EAAC,OAAA,CAAK,UAAU,0DACb,GACI,CACP,EAAC,EAAA,
|
|
1
|
+
{"version":3,"file":"NumberItemsSelector.mjs","names":[],"sources":["../../../../src/components/Pagination/NumberItemsSelector.tsx"],"sourcesContent":["'use client';\n\nimport type { FC } from 'react';\nimport { useIntlayer } from 'react-intlayer';\nimport { Select } from '../Select';\n\nexport type NumberItemsSelectorProps = {\n value: string | number;\n onValueChange: (value: string) => void;\n min?: number;\n max?: number;\n};\n\nexport const NumberItemsSelector: FC<NumberItemsSelectorProps> = ({\n value,\n onValueChange,\n min = 5,\n max = 500,\n}) => {\n const { numberItemsSelector, selectPageSize } = useIntlayer('pagination');\n\n const items = [\n 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 100000,\n ].filter((item) => item >= min && item <= max);\n\n return (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-neutral-600 text-sm dark:text-neutral-400\">\n {numberItemsSelector}\n </span>\n <Select value={value.toString()} onValueChange={onValueChange}>\n <Select.Trigger className=\"w-20\">\n <Select.Value placeholder={selectPageSize} />\n </Select.Trigger>\n <Select.Content>\n {items.map((item) => (\n <Select.Item key={item} value={item.toString()}>\n {item}\n </Select.Item>\n ))}\n </Select.Content>\n </Select>\n </div>\n );\n};\n"],"mappings":"0JAaA,MAAa,GAAqD,CAChE,QACA,gBACA,MAAM,EACN,MAAM,OACF,CACJ,GAAM,CAAE,sBAAqB,kBAAmB,EAAY,aAAa,CAEnE,EAAQ,CACZ,EAAG,EAAG,EAAG,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,IAAM,IAAM,IAAM,IAAO,IAC9D,CAAC,OAAQ,GAAS,GAAQ,GAAO,GAAQ,EAAI,CAE9C,OACE,EAAC,MAAA,CAAI,UAAU,oCACb,EAAC,OAAA,CAAK,UAAU,0DACb,GACI,CACP,EAAC,EAAA,CAAO,MAAO,EAAM,UAAU,CAAiB,0BAC9C,EAAC,EAAO,QAAA,CAAQ,UAAU,gBACxB,EAAC,EAAO,MAAA,CAAM,YAAa,EAAA,CAAkB,EAC9B,CACjB,EAAC,EAAO,QAAA,CAAA,SACL,EAAM,IAAK,GACV,EAAC,EAAO,KAAA,CAAgB,MAAO,EAAK,UAAU,UAC3C,GADe,EAEJ,CACd,CAAA,CACa,CAAA,EACV,CAAA,EACL"}
|
|
@@ -43,38 +43,27 @@ declare enum BadgeSize {
|
|
|
43
43
|
* @description Defines the styling variants for different badge combinations
|
|
44
44
|
*/
|
|
45
45
|
declare const badgeVariants: (props?: {
|
|
46
|
-
color?:
|
|
47
|
-
variant?:
|
|
48
|
-
size?:
|
|
46
|
+
color?: "primary" | "secondary" | "destructive" | "neutral" | "light" | "dark" | "text" | "error" | "success" | "custom";
|
|
47
|
+
variant?: "default" | "none" | "outline" | "hoverable";
|
|
48
|
+
size?: "md" | "sm" | "lg";
|
|
49
49
|
} & class_variance_authority_types0.ClassProp) => string;
|
|
50
50
|
/**
|
|
51
51
|
* Badge component props interface
|
|
52
52
|
* @description Comprehensive props for the Badge component with accessibility and interactive features
|
|
53
53
|
*/
|
|
54
|
-
|
|
55
|
-
/** The content to display inside the badge */
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
|
|
65
|
-
/** Whether the badge is dismissible (shows close button) */
|
|
66
|
-
dismissible?: boolean;
|
|
67
|
-
/** Click handler for the badge */
|
|
68
|
-
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
|
69
|
-
/** Click handler for the dismiss button */
|
|
70
|
-
onDismiss?: () => void;
|
|
71
|
-
/** ARIA label for accessibility */
|
|
72
|
-
'aria-label'?: string;
|
|
73
|
-
/** Badge role for accessibility (default: 'status') */
|
|
74
|
-
role?: 'status' | 'button' | 'generic';
|
|
75
|
-
/** Whether badge should be focusable */
|
|
54
|
+
type BadgeProps = HTMLAttributes<HTMLElement> & {
|
|
55
|
+
/** The content to display inside the badge */children?: React.ReactNode; /** Color theme variant */
|
|
56
|
+
color?: BadgeColor | `${BadgeColor}`; /** Visual style variant */
|
|
57
|
+
variant?: BadgeVariant | `${BadgeVariant}`; /** Size of the badge */
|
|
58
|
+
size?: BadgeSize | `${BadgeSize}`; /** Whether the badge is clickable */
|
|
59
|
+
clickable?: boolean; /** Whether the badge is dismissible (shows close button) */
|
|
60
|
+
dismissible?: boolean; /** Click handler for the badge */
|
|
61
|
+
onClick?: (event: React.MouseEvent<HTMLElement>) => void; /** Click handler for the dismiss button */
|
|
62
|
+
onDismiss?: () => void; /** ARIA label for accessibility */
|
|
63
|
+
'aria-label'?: string; /** Badge role for accessibility (default: 'status') */
|
|
64
|
+
role?: 'status' | 'button' | 'generic'; /** Whether badge should be focusable */
|
|
76
65
|
tabIndex?: number;
|
|
77
|
-
}
|
|
66
|
+
};
|
|
78
67
|
/**
|
|
79
68
|
* Utility type for badge variant props
|
|
80
69
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/components/Badge/index.tsx"],"mappings":";;;;;;;;AAQA;aAAY,UAAA;EACV,OAAA;EACA,SAAA;EACA,WAAA;EACA,OAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA;EACA,IAAA;EACA,IAAA;EACA,MAAA;AAAA;;;;AAOF;aAAY,YAAA;EACV,OAAA;EACA,IAAA;EACA,OAAA;EACA,SAAA;AAAA;;;;AAOF;aAAY,SAAA;EACV,KAAA;EACA,MAAA;EACA,KAAA;AAAA;;;;AAOF;cAAa,aAAA,GAAa,KAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../../src/components/Badge/index.tsx"],"mappings":";;;;;;;;AAQA;aAAY,UAAA;EACV,OAAA;EACA,SAAA;EACA,WAAA;EACA,OAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA;EACA,IAAA;EACA,IAAA;EACA,MAAA;AAAA;;;;AAOF;aAAY,YAAA;EACV,OAAA;EACA,IAAA;EACA,OAAA;EACA,SAAA;AAAA;;;;AAOF;aAAY,SAAA;EACV,KAAA;EACA,MAAA;EACA,KAAA;AAAA;;;;AAOF;cAAa,aAAA,GAAa,KAAA;;;;IA8CzB,+BAAA,CAAA,SAAA;;;;;KAMW,UAAA,GAAa,cAAA,CAAe,WAAA;EAA5B,8CAEV,QAAA,GAAW,KAAA,CAAM,SAAA;EAEjB,KAAA,GAAQ,UAAA,MAAgB,UAAA,IAJD;EAMvB,OAAA,GAAU,YAAA,MAAkB,YAAA,IAFpB;EAIR,IAAA,GAAO,SAAA,MAAe,SAAA,IAFZ;EAIV,SAAA,YAFO;EAIP,WAAA,YAEmC;EAAnC,OAAA,IAAW,KAAA,EAAO,KAAA,CAAM,UAAA,CAAW,WAAA,YAAD;EAElC,SAAA,eAhBuB;EAkBvB,YAAA,WAhBA;EAkBA,IAAA,oCAlBiB;EAoBjB,QAAA;AAAA;;;;KAMU,iBAAA,GAAoB,YAAA,QAAoB,aAAA;;;;;;;;;;;;;;;;;AAApD;;;;;AA2BA;;;;cAAa,KAAA,EAAO,KAAA,CAAM,EAAA,CAAG,UAAA"}
|