@aloudata/aloudata-design 3.1.3 → 3.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/ColorPicker/index.js +1 -1
  2. package/dist/ColorPicker/index.js.map +1 -1
  3. package/dist/Modal/index.js +1 -1
  4. package/dist/Modal/index.js.map +1 -1
  5. package/dist/Popconfirm/index.js +1 -1
  6. package/dist/Popconfirm/index.js.map +1 -1
  7. package/dist/Popover/index.js +2 -2
  8. package/dist/Popover/index.js.map +1 -1
  9. package/dist/Tabs/index.js +2 -2
  10. package/dist/Tabs/index.js.map +1 -1
  11. package/dist/Tour/index.js +1 -1
  12. package/dist/Tour/index.js.map +1 -1
  13. package/dist/aloudata-design.css +1 -1
  14. package/dist/governance/semantic.json +14 -5
  15. package/dist/theme/contract/tokenOutputContract.js +7 -5
  16. package/dist/theme/contract/tokenOutputContract.js.map +1 -1
  17. package/dist/theme/governance/semanticGovernanceContract.js +1 -1
  18. package/dist/theme/governance/semanticGovernanceContract.js.map +1 -1
  19. package/dist/theme/runtime/colorValueMode/generated/darkBaselineDeclarations.d.ts +1 -1
  20. package/dist/theme/runtime/colorValueMode/generated/darkBaselineDeclarations.js +2 -1
  21. package/dist/theme/runtime/colorValueMode/generated/darkBaselineDeclarations.js.map +1 -1
  22. package/dist/theme/runtime/colorValueMode/generated/slateDarkDeclarations.d.ts +1 -1
  23. package/dist/theme/runtime/colorValueMode/generated/slateLightDeclarations.d.ts +1 -1
  24. package/dist/theme/runtime/colorValueMode/generated/stoneDarkDeclarations.d.ts +1 -1
  25. package/dist/theme/runtime/colorValueMode/generated/stoneLightDeclarations.d.ts +1 -1
  26. package/dist/theme/runtime/colorValueMode/generated/v3BaselineDeclarations.d.ts +1 -1
  27. package/dist/theme/runtime/colorValueMode/generated/v3BaselineDeclarations.js +1 -0
  28. package/dist/theme/runtime/colorValueMode/generated/v3BaselineDeclarations.js.map +1 -1
  29. package/package.json +1 -1
@@ -125,7 +125,7 @@ function ColorPicker({ className, value, icon, onChange, defaultColor = colors[0
125
125
  id: popupId,
126
126
  role: "radiogroup",
127
127
  "aria-label": t.ColorPicker.standardColor,
128
- className: "tw-relative tw-box-border tw-w-[253px] tw-rounded-sm tw-bg-[var(--background-default)] tw-p-[8px_7px]",
128
+ className: "tw-relative tw-box-border tw-w-[253px] tw-rounded-sm tw-bg-[var(--background-floating)] tw-p-[8px_7px]",
129
129
  ref: overlayRef,
130
130
  onKeyDown: (event) => {
131
131
  if (event.key === "Escape") {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/ColorPicker/index.tsx"],"sourcesContent":["import { cn as cls } from '../lib/utils';\nimport React, { useContext, useEffect, useId, useRef, useState } from 'react';\nimport Dropdown from '../Dropdown';\nimport { FoldDownFill } from '../Icon';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport { colors as defaultColors, specialColors } from './constant';\nimport type { ColorPickerProps } from './interface';\nimport InnerColorPicker from './ComplexColorPicker';\nimport './color-picker.css';\n\nexport interface IColorPickerProps {\n className?: string;\n value?: string;\n defaultColor?: string;\n localStorageKey?: string;\n onChange?: (color: string) => void;\n icon?: React.ReactNode;\n bordered?: boolean;\n disabled?: boolean;\n mode?: 'simple' | 'complex';\n complexModeProps?: ColorPickerProps;\n}\n\nfunction getLocalRecentColors(localStorageKey: string) {\n if (!window.localStorage) {\n return [];\n }\n const colorStr = localStorage.getItem(localStorageKey);\n if (!colorStr) {\n return [];\n }\n\n return colorStr.split(',');\n}\n\nfunction setLocalRecentColors(localStorageKey: string, colors: string[]) {\n if (!window.localStorage) {\n return;\n }\n localStorage.setItem(localStorageKey, colors.join(','));\n}\n\nconst MAX_RECENT_COLORS = 10;\nexport default function ColorPicker({\n className,\n value,\n icon,\n onChange,\n defaultColor = defaultColors[0],\n localStorageKey = 'ald_recent_colors',\n disabled = false,\n mode = 'simple',\n complexModeProps,\n bordered = true,\n}: IColorPickerProps) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const [open, setOpen] = useState(false);\n const [recentColors, setRecentColors] = useState<string[]>([]);\n const overlayRef = useRef<HTMLDivElement>(null);\n const wrapRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const swatchRefs = useRef<Record<string, HTMLButtonElement | null>>({});\n const triggerId = `ald-color-picker-trigger-${useId().replace(/:/g, '')}`;\n const popupId = `ald-color-picker-popup-${useId().replace(/:/g, '')}`;\n const swatchOrder = Array.from(\n new Set([defaultColor, ...defaultColors, ...recentColors]),\n );\n\n useEffect(() => {\n setRecentColors(getLocalRecentColors(localStorageKey));\n }, [localStorageKey]);\n\n const onColorSelect = (color: string) => {\n const newRecentColors = [color, ...recentColors.filter((c) => c !== color)];\n if (newRecentColors.length > MAX_RECENT_COLORS) {\n newRecentColors.pop();\n }\n\n setRecentColors(newRecentColors);\n setLocalRecentColors(localStorageKey, newRecentColors);\n onChange?.(color);\n setOpen(false);\n window.setTimeout(() => triggerRef.current?.focus(), 0);\n };\n\n useEffect(() => {\n const handleClick = (e: MouseEvent) => {\n if (\n !wrapRef.current?.contains(e.target as Node) &&\n !overlayRef.current?.contains(e.target as Node)\n ) {\n return setOpen(false);\n }\n };\n\n document.addEventListener('click', handleClick);\n\n return () => {\n document.removeEventListener('click', handleClick);\n };\n }, []);\n\n useEffect(() => {\n if (!open) return;\n const selectedIndex = Math.max(\n 0,\n swatchOrder.indexOf(value ?? defaultColor),\n );\n window.setTimeout(() => {\n swatchRefs.current[swatchOrder[selectedIndex]]?.focus();\n }, 0);\n }, [defaultColor, open, swatchOrder, value]);\n\n useEffect(() => {\n triggerRef.current?.setAttribute('aria-expanded', String(open));\n triggerRef.current?.setAttribute('aria-controls', popupId);\n }, [open, popupId]);\n\n const renderSwatch = (color: string, label: string) => {\n const selected = color === value;\n const index = swatchOrder.indexOf(color);\n const selectedIndex = Math.max(\n 0,\n swatchOrder.indexOf(value ?? defaultColor),\n );\n return (\n <button\n type=\"button\"\n key={`${label}-${color}`}\n id={`${popupId}-swatch-${encodeURIComponent(color)}`}\n ref={(node) => {\n swatchRefs.current[color] = node;\n }}\n role=\"radio\"\n aria-label={label}\n aria-checked={selected}\n tabIndex={index === selectedIndex ? 0 : -1}\n disabled={disabled}\n className={cls(\n 'tw-box-border tw-h-[21px] tw-w-[21px] tw-cursor-pointer tw-border tw-border-solid tw-border-[var(--background-default)] tw-bg-transparent tw-p-0',\n {\n 'tw-border-[var(--border-neutral-strong)]': selected,\n },\n )}\n onClick={() => {\n if (!selected) onColorSelect(color);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n setOpen(false);\n triggerRef.current?.focus();\n return;\n }\n if (event.key === 'ArrowRight' || event.key === 'ArrowDown') {\n event.preventDefault();\n swatchRefs.current[\n swatchOrder[(index + 1) % swatchOrder.length]\n ]?.focus();\n return;\n }\n if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') {\n event.preventDefault();\n swatchRefs.current[\n swatchOrder[(index - 1 + swatchOrder.length) % swatchOrder.length]\n ]?.focus();\n return;\n }\n if (event.key === 'Home' || event.key === 'End') {\n event.preventDefault();\n swatchRefs.current[\n swatchOrder[event.key === 'Home' ? 0 : swatchOrder.length - 1]\n ]?.focus();\n }\n }}\n style={{\n borderColor: selected\n ? 'var(--border-neutral-strong)'\n : specialColors.includes(color)\n ? 'var(--border-neutral-subtle)'\n : color,\n }}\n >\n <span\n aria-hidden=\"true\"\n className={cls('tw-block tw-h-full tw-w-full', {\n 'tw-m-px tw-h-[17px] tw-w-[17px]': selected,\n })}\n style={{ backgroundColor: color }}\n />\n </button>\n );\n };\n\n const overlay = (\n <div\n id={popupId}\n role=\"radiogroup\"\n aria-label={t.ColorPicker.standardColor}\n className=\"tw-relative tw-box-border tw-w-[253px] tw-rounded-sm tw-bg-[var(--background-default)] tw-p-[8px_7px]\"\n ref={overlayRef}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n setOpen(false);\n triggerRef.current?.focus();\n }\n }}\n >\n <div className=\"tw-flex tw-items-center tw-text-xs\">\n <div className=\"tw-mr-2\">\n {renderSwatch(defaultColor, t.ColorPicker.default)}\n </div>\n {t.ColorPicker.default}\n </div>\n <div className=\"tw-mt-1.5 tw-text-xs\">\n <p>{t.ColorPicker.standardColor}</p>\n <div className=\"tw-mt-0.5 tw-flex tw-flex-wrap tw-justify-evenly tw-gap-[4px_2px] tw-text-[0px]\">\n {defaultColors.map((color) => renderSwatch(color, color))}\n </div>\n </div>\n <div className=\"tw-mt-1.5 tw-text-xs\">\n <p>{t.ColorPicker.recentlyUsed}</p>\n <div className=\"tw-mt-0.5 tw-flex tw-flex-wrap tw-justify-start tw-gap-[4px_2px] tw-text-[0px]\">\n {recentColors.map((color) => renderSwatch(color, color))}\n </div>\n </div>\n </div>\n );\n if (mode === 'simple') {\n return (\n <div\n className={cls(className, 'tw-relative tw-w-14', {\n 'tw-cursor-default [&_.ald-color-picker-wrapper]:tw-cursor-default':\n disabled,\n })}\n ref={wrapRef}\n >\n <Dropdown\n trigger={'click'}\n open={open}\n onOpenChange={setOpen}\n disabled={disabled}\n placement={'bottom-start'}\n overlayClassName={'ald-color-picker-overlay-wrapper'}\n dropdownRender={() => {\n return overlay;\n }}\n >\n <button\n type=\"button\"\n id={triggerId}\n ref={triggerRef}\n aria-label={t.ColorPicker.default}\n aria-controls={popupId}\n aria-expanded={open}\n className={cls(\n 'ald-color-picker-wrapper',\n 'tw-flex tw-flex-row tw-items-center tw-justify-between tw-gap-1 tw-h-7 tw-px-2.5 tw-py-1.5 tw-bg-[var(--background-default)] tw-border tw-border-solid tw-border-[var(--border-neutral-subtle)] tw-box-border tw-cursor-pointer tw-rounded tw-text-[var(--content-primary)] tw-transition-[border] tw-duration-500 tw-ease-in-out',\n {\n 'tw-border-[var(--border-brand-subtle)]':\n open && bordered !== false,\n 'tw-border-[var(--border-neutral-subtle)] tw-bg-[var(--background-neutral-on-subtle)]':\n disabled,\n 'tw-border-[var(--action-ghost-normal)]': bordered === false,\n 'hover:tw-border-[var(--border-brand-subtle)]':\n !disabled && bordered !== false,\n 'hover:tw-border-[var(--action-ghost-normal)]':\n bordered === false,\n },\n )}\n onClick={(e) => {\n if (disabled) {\n e.stopPropagation();\n return;\n }\n setOpen((current) => !current);\n }}\n onKeyDown={(event) => {\n if (disabled) return;\n if (\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp' ||\n event.key === 'Enter' ||\n event.key === ' '\n ) {\n event.preventDefault();\n setOpen(true);\n }\n }}\n >\n {icon ? (\n <div className=\"tw-relative -tw-top-px\">\n <div className=\"tw-mb-px\">{icon}</div>\n <div\n className=\"tw-absolute tw-bottom-[3px] tw-left-1/2 tw-h-0.5 tw-w-2.5 -tw-translate-x-1/2\"\n style={{\n backgroundColor: value ?? 'var(--content-secondary)',\n }}\n />\n </div>\n ) : (\n <div className=\"tw-relative -tw-top-px tw-ml-0.5 tw-mr-[3px]\">\n A\n <div\n className=\"tw-absolute tw-bottom-[3px] tw-h-0.5 tw-w-2.5\"\n style={{\n backgroundColor: value ?? 'var(--content-secondary)',\n }}\n />\n </div>\n )}\n <FoldDownFill size={14} color={'var(--content-secondary)'} />\n </button>\n </Dropdown>\n </div>\n );\n }\n if (mode === 'complex') {\n return <InnerColorPicker {...complexModeProps} />;\n }\n\n return null;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/ColorPicker/index.tsx"],"sourcesContent":["import { cn as cls } from '../lib/utils';\nimport React, { useContext, useEffect, useId, useRef, useState } from 'react';\nimport Dropdown from '../Dropdown';\nimport { FoldDownFill } from '../Icon';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport { colors as defaultColors, specialColors } from './constant';\nimport type { ColorPickerProps } from './interface';\nimport InnerColorPicker from './ComplexColorPicker';\nimport './color-picker.css';\n\nexport interface IColorPickerProps {\n className?: string;\n value?: string;\n defaultColor?: string;\n localStorageKey?: string;\n onChange?: (color: string) => void;\n icon?: React.ReactNode;\n bordered?: boolean;\n disabled?: boolean;\n mode?: 'simple' | 'complex';\n complexModeProps?: ColorPickerProps;\n}\n\nfunction getLocalRecentColors(localStorageKey: string) {\n if (!window.localStorage) {\n return [];\n }\n const colorStr = localStorage.getItem(localStorageKey);\n if (!colorStr) {\n return [];\n }\n\n return colorStr.split(',');\n}\n\nfunction setLocalRecentColors(localStorageKey: string, colors: string[]) {\n if (!window.localStorage) {\n return;\n }\n localStorage.setItem(localStorageKey, colors.join(','));\n}\n\nconst MAX_RECENT_COLORS = 10;\nexport default function ColorPicker({\n className,\n value,\n icon,\n onChange,\n defaultColor = defaultColors[0],\n localStorageKey = 'ald_recent_colors',\n disabled = false,\n mode = 'simple',\n complexModeProps,\n bordered = true,\n}: IColorPickerProps) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const [open, setOpen] = useState(false);\n const [recentColors, setRecentColors] = useState<string[]>([]);\n const overlayRef = useRef<HTMLDivElement>(null);\n const wrapRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const swatchRefs = useRef<Record<string, HTMLButtonElement | null>>({});\n const triggerId = `ald-color-picker-trigger-${useId().replace(/:/g, '')}`;\n const popupId = `ald-color-picker-popup-${useId().replace(/:/g, '')}`;\n const swatchOrder = Array.from(\n new Set([defaultColor, ...defaultColors, ...recentColors]),\n );\n\n useEffect(() => {\n setRecentColors(getLocalRecentColors(localStorageKey));\n }, [localStorageKey]);\n\n const onColorSelect = (color: string) => {\n const newRecentColors = [color, ...recentColors.filter((c) => c !== color)];\n if (newRecentColors.length > MAX_RECENT_COLORS) {\n newRecentColors.pop();\n }\n\n setRecentColors(newRecentColors);\n setLocalRecentColors(localStorageKey, newRecentColors);\n onChange?.(color);\n setOpen(false);\n window.setTimeout(() => triggerRef.current?.focus(), 0);\n };\n\n useEffect(() => {\n const handleClick = (e: MouseEvent) => {\n if (\n !wrapRef.current?.contains(e.target as Node) &&\n !overlayRef.current?.contains(e.target as Node)\n ) {\n return setOpen(false);\n }\n };\n\n document.addEventListener('click', handleClick);\n\n return () => {\n document.removeEventListener('click', handleClick);\n };\n }, []);\n\n useEffect(() => {\n if (!open) return;\n const selectedIndex = Math.max(\n 0,\n swatchOrder.indexOf(value ?? defaultColor),\n );\n window.setTimeout(() => {\n swatchRefs.current[swatchOrder[selectedIndex]]?.focus();\n }, 0);\n }, [defaultColor, open, swatchOrder, value]);\n\n useEffect(() => {\n triggerRef.current?.setAttribute('aria-expanded', String(open));\n triggerRef.current?.setAttribute('aria-controls', popupId);\n }, [open, popupId]);\n\n const renderSwatch = (color: string, label: string) => {\n const selected = color === value;\n const index = swatchOrder.indexOf(color);\n const selectedIndex = Math.max(\n 0,\n swatchOrder.indexOf(value ?? defaultColor),\n );\n return (\n <button\n type=\"button\"\n key={`${label}-${color}`}\n id={`${popupId}-swatch-${encodeURIComponent(color)}`}\n ref={(node) => {\n swatchRefs.current[color] = node;\n }}\n role=\"radio\"\n aria-label={label}\n aria-checked={selected}\n tabIndex={index === selectedIndex ? 0 : -1}\n disabled={disabled}\n className={cls(\n 'tw-box-border tw-h-[21px] tw-w-[21px] tw-cursor-pointer tw-border tw-border-solid tw-border-[var(--background-default)] tw-bg-transparent tw-p-0',\n {\n 'tw-border-[var(--border-neutral-strong)]': selected,\n },\n )}\n onClick={() => {\n if (!selected) onColorSelect(color);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n setOpen(false);\n triggerRef.current?.focus();\n return;\n }\n if (event.key === 'ArrowRight' || event.key === 'ArrowDown') {\n event.preventDefault();\n swatchRefs.current[\n swatchOrder[(index + 1) % swatchOrder.length]\n ]?.focus();\n return;\n }\n if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') {\n event.preventDefault();\n swatchRefs.current[\n swatchOrder[(index - 1 + swatchOrder.length) % swatchOrder.length]\n ]?.focus();\n return;\n }\n if (event.key === 'Home' || event.key === 'End') {\n event.preventDefault();\n swatchRefs.current[\n swatchOrder[event.key === 'Home' ? 0 : swatchOrder.length - 1]\n ]?.focus();\n }\n }}\n style={{\n borderColor: selected\n ? 'var(--border-neutral-strong)'\n : specialColors.includes(color)\n ? 'var(--border-neutral-subtle)'\n : color,\n }}\n >\n <span\n aria-hidden=\"true\"\n className={cls('tw-block tw-h-full tw-w-full', {\n 'tw-m-px tw-h-[17px] tw-w-[17px]': selected,\n })}\n style={{ backgroundColor: color }}\n />\n </button>\n );\n };\n\n const overlay = (\n <div\n id={popupId}\n role=\"radiogroup\"\n aria-label={t.ColorPicker.standardColor}\n className=\"tw-relative tw-box-border tw-w-[253px] tw-rounded-sm tw-bg-[var(--background-floating)] tw-p-[8px_7px]\"\n ref={overlayRef}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n setOpen(false);\n triggerRef.current?.focus();\n }\n }}\n >\n <div className=\"tw-flex tw-items-center tw-text-xs\">\n <div className=\"tw-mr-2\">\n {renderSwatch(defaultColor, t.ColorPicker.default)}\n </div>\n {t.ColorPicker.default}\n </div>\n <div className=\"tw-mt-1.5 tw-text-xs\">\n <p>{t.ColorPicker.standardColor}</p>\n <div className=\"tw-mt-0.5 tw-flex tw-flex-wrap tw-justify-evenly tw-gap-[4px_2px] tw-text-[0px]\">\n {defaultColors.map((color) => renderSwatch(color, color))}\n </div>\n </div>\n <div className=\"tw-mt-1.5 tw-text-xs\">\n <p>{t.ColorPicker.recentlyUsed}</p>\n <div className=\"tw-mt-0.5 tw-flex tw-flex-wrap tw-justify-start tw-gap-[4px_2px] tw-text-[0px]\">\n {recentColors.map((color) => renderSwatch(color, color))}\n </div>\n </div>\n </div>\n );\n if (mode === 'simple') {\n return (\n <div\n className={cls(className, 'tw-relative tw-w-14', {\n 'tw-cursor-default [&_.ald-color-picker-wrapper]:tw-cursor-default':\n disabled,\n })}\n ref={wrapRef}\n >\n <Dropdown\n trigger={'click'}\n open={open}\n onOpenChange={setOpen}\n disabled={disabled}\n placement={'bottom-start'}\n overlayClassName={'ald-color-picker-overlay-wrapper'}\n dropdownRender={() => {\n return overlay;\n }}\n >\n <button\n type=\"button\"\n id={triggerId}\n ref={triggerRef}\n aria-label={t.ColorPicker.default}\n aria-controls={popupId}\n aria-expanded={open}\n className={cls(\n 'ald-color-picker-wrapper',\n 'tw-flex tw-flex-row tw-items-center tw-justify-between tw-gap-1 tw-h-7 tw-px-2.5 tw-py-1.5 tw-bg-[var(--background-default)] tw-border tw-border-solid tw-border-[var(--border-neutral-subtle)] tw-box-border tw-cursor-pointer tw-rounded tw-text-[var(--content-primary)] tw-transition-[border] tw-duration-500 tw-ease-in-out',\n {\n 'tw-border-[var(--border-brand-subtle)]':\n open && bordered !== false,\n 'tw-border-[var(--border-neutral-subtle)] tw-bg-[var(--background-neutral-on-subtle)]':\n disabled,\n 'tw-border-[var(--action-ghost-normal)]': bordered === false,\n 'hover:tw-border-[var(--border-brand-subtle)]':\n !disabled && bordered !== false,\n 'hover:tw-border-[var(--action-ghost-normal)]':\n bordered === false,\n },\n )}\n onClick={(e) => {\n if (disabled) {\n e.stopPropagation();\n return;\n }\n setOpen((current) => !current);\n }}\n onKeyDown={(event) => {\n if (disabled) return;\n if (\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp' ||\n event.key === 'Enter' ||\n event.key === ' '\n ) {\n event.preventDefault();\n setOpen(true);\n }\n }}\n >\n {icon ? (\n <div className=\"tw-relative -tw-top-px\">\n <div className=\"tw-mb-px\">{icon}</div>\n <div\n className=\"tw-absolute tw-bottom-[3px] tw-left-1/2 tw-h-0.5 tw-w-2.5 -tw-translate-x-1/2\"\n style={{\n backgroundColor: value ?? 'var(--content-secondary)',\n }}\n />\n </div>\n ) : (\n <div className=\"tw-relative -tw-top-px tw-ml-0.5 tw-mr-[3px]\">\n A\n <div\n className=\"tw-absolute tw-bottom-[3px] tw-h-0.5 tw-w-2.5\"\n style={{\n backgroundColor: value ?? 'var(--content-secondary)',\n }}\n />\n </div>\n )}\n <FoldDownFill size={14} color={'var(--content-secondary)'} />\n </button>\n </Dropdown>\n </div>\n );\n }\n if (mode === 'complex') {\n return <InnerColorPicker {...complexModeProps} />;\n }\n\n return null;\n}\n"],"mappings":";;;;;;;;;;AAuBA,SAAS,qBAAqB,iBAAyB;AACrD,KAAI,CAAC,OAAO,aACV,QAAO,EAAE;CAEX,MAAM,WAAW,aAAa,QAAQ,gBAAgB;AACtD,KAAI,CAAC,SACH,QAAO,EAAE;AAGX,QAAO,SAAS,MAAM,IAAI;;AAG5B,SAAS,qBAAqB,iBAAyB,QAAkB;AACvE,KAAI,CAAC,OAAO,aACV;AAEF,cAAa,QAAQ,iBAAiB,OAAO,KAAK,IAAI,CAAC;;AAGzD,IAAM,oBAAoB;AAC1B,SAAwB,YAAY,EAClC,WACA,OACA,MACA,UACA,eAAe,OAAc,IAC7B,kBAAkB,qBAClB,WAAW,OACX,OAAO,UACP,kBACA,WAAW,QACS;CACpB,MAAM,EAAE,WAAW,WAAW,cAAc;CAC5C,MAAM,IAAI,cAAc,OAAO;CAE/B,MAAM,CAAC,MAAM,WAAW,SAAS,MAAM;CACvC,MAAM,CAAC,cAAc,mBAAmB,SAAmB,EAAE,CAAC;CAC9D,MAAM,aAAa,OAAuB,KAAK;CAC/C,MAAM,UAAU,OAAuB,KAAK;CAC5C,MAAM,aAAa,OAA0B,KAAK;CAClD,MAAM,aAAa,OAAiD,EAAE,CAAC;CACvE,MAAM,YAAY,4BAA4B,OAAO,CAAC,QAAQ,MAAM,GAAG;CACvE,MAAM,UAAU,0BAA0B,OAAO,CAAC,QAAQ,MAAM,GAAG;CACnE,MAAM,cAAc,MAAM,KACxB,IAAI,IAAI;EAAC;EAAc,GAAG;EAAe,GAAG;EAAa,CAAC,CAC3D;AAED,iBAAgB;AACd,kBAAgB,qBAAqB,gBAAgB,CAAC;IACrD,CAAC,gBAAgB,CAAC;CAErB,MAAM,iBAAiB,UAAkB;EACvC,MAAM,kBAAkB,CAAC,OAAO,GAAG,aAAa,QAAQ,MAAM,MAAM,MAAM,CAAC;AAC3E,MAAI,gBAAgB,SAAS,kBAC3B,iBAAgB,KAAK;AAGvB,kBAAgB,gBAAgB;AAChC,uBAAqB,iBAAiB,gBAAgB;AACtD,aAAW,MAAM;AACjB,UAAQ,MAAM;AACd,SAAO,iBAAiB,WAAW,SAAS,OAAO,EAAE,EAAE;;AAGzD,iBAAgB;EACd,MAAM,eAAe,MAAkB;AACrC,OACE,CAAC,QAAQ,SAAS,SAAS,EAAE,OAAe,IAC5C,CAAC,WAAW,SAAS,SAAS,EAAE,OAAe,CAE/C,QAAO,QAAQ,MAAM;;AAIzB,WAAS,iBAAiB,SAAS,YAAY;AAE/C,eAAa;AACX,YAAS,oBAAoB,SAAS,YAAY;;IAEnD,EAAE,CAAC;AAEN,iBAAgB;AACd,MAAI,CAAC,KAAM;EACX,MAAM,gBAAgB,KAAK,IACzB,GACA,YAAY,QAAQ,SAAS,aAAa,CAC3C;AACD,SAAO,iBAAiB;AACtB,cAAW,QAAQ,YAAY,iBAAiB,OAAO;KACtD,EAAE;IACJ;EAAC;EAAc;EAAM;EAAa;EAAM,CAAC;AAE5C,iBAAgB;AACd,aAAW,SAAS,aAAa,iBAAiB,OAAO,KAAK,CAAC;AAC/D,aAAW,SAAS,aAAa,iBAAiB,QAAQ;IACzD,CAAC,MAAM,QAAQ,CAAC;CAEnB,MAAM,gBAAgB,OAAe,UAAkB;EACrD,MAAM,WAAW,UAAU;EAC3B,MAAM,QAAQ,YAAY,QAAQ,MAAM;EACxC,MAAM,gBAAgB,KAAK,IACzB,GACA,YAAY,QAAQ,SAAS,aAAa,CAC3C;AACD,SACE,oBAAC,UAAD;GACE,MAAK;GAEL,IAAI,GAAG,QAAQ,UAAU,mBAAmB,MAAM;GAClD,MAAM,SAAS;AACb,eAAW,QAAQ,SAAS;;GAE9B,MAAK;GACL,cAAY;GACZ,gBAAc;GACd,UAAU,UAAU,gBAAgB,IAAI;GAC9B;GACV,WAAW,GACT,oJACA,EACE,4CAA4C,UAC7C,CACF;GACD,eAAe;AACb,QAAI,CAAC,SAAU,eAAc,MAAM;;GAErC,YAAY,UAAU;AACpB,QAAI,MAAM,QAAQ,UAAU;AAC1B,WAAM,gBAAgB;AACtB,aAAQ,MAAM;AACd,gBAAW,SAAS,OAAO;AAC3B;;AAEF,QAAI,MAAM,QAAQ,gBAAgB,MAAM,QAAQ,aAAa;AAC3D,WAAM,gBAAgB;AACtB,gBAAW,QACT,aAAa,QAAQ,KAAK,YAAY,UACrC,OAAO;AACV;;AAEF,QAAI,MAAM,QAAQ,eAAe,MAAM,QAAQ,WAAW;AACxD,WAAM,gBAAgB;AACtB,gBAAW,QACT,aAAa,QAAQ,IAAI,YAAY,UAAU,YAAY,UAC1D,OAAO;AACV;;AAEF,QAAI,MAAM,QAAQ,UAAU,MAAM,QAAQ,OAAO;AAC/C,WAAM,gBAAgB;AACtB,gBAAW,QACT,YAAY,MAAM,QAAQ,SAAS,IAAI,YAAY,SAAS,KAC3D,OAAO;;;GAGd,OAAO,EACL,aAAa,WACT,iCACA,cAAc,SAAS,MAAM,GAC7B,iCACA,OACL;aAED,oBAAC,QAAD;IACE,eAAY;IACZ,WAAW,GAAI,gCAAgC,EAC7C,mCAAmC,UACpC,CAAC;IACF,OAAO,EAAE,iBAAiB,OAAO;IACjC,CAAA;GACK,EA9DF,GAAG,MAAM,GAAG,QA8DV;;CAIb,MAAM,UACJ,qBAAC,OAAD;EACE,IAAI;EACJ,MAAK;EACL,cAAY,EAAE,YAAY;EAC1B,WAAU;EACV,KAAK;EACL,YAAY,UAAU;AACpB,OAAI,MAAM,QAAQ,UAAU;AAC1B,UAAM,gBAAgB;AACtB,YAAQ,MAAM;AACd,eAAW,SAAS,OAAO;;;YAVjC;GAcE,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,OAAD;KAAK,WAAU;eACZ,aAAa,cAAc,EAAE,YAAY,QAAQ;KAC9C,CAAA,EACL,EAAE,YAAY,QACX;;GACN,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,KAAD,EAAA,UAAI,EAAE,YAAY,eAAkB,CAAA,EACpC,oBAAC,OAAD;KAAK,WAAU;eACZ,OAAc,KAAK,UAAU,aAAa,OAAO,MAAM,CAAC;KACrD,CAAA,CACF;;GACN,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,KAAD,EAAA,UAAI,EAAE,YAAY,cAAiB,CAAA,EACnC,oBAAC,OAAD;KAAK,WAAU;eACZ,aAAa,KAAK,UAAU,aAAa,OAAO,MAAM,CAAC;KACpD,CAAA,CACF;;GACF;;AAER,KAAI,SAAS,SACX,QACE,oBAAC,OAAD;EACE,WAAW,GAAI,WAAW,uBAAuB,EAC/C,qEACE,UACH,CAAC;EACF,KAAK;YAEL,oBAAC,UAAD;GACE,SAAS;GACH;GACN,cAAc;GACJ;GACV,WAAW;GACX,kBAAkB;GAClB,sBAAsB;AACpB,WAAO;;aAGT,qBAAC,UAAD;IACE,MAAK;IACL,IAAI;IACJ,KAAK;IACL,cAAY,EAAE,YAAY;IAC1B,iBAAe;IACf,iBAAe;IACf,WAAW,GACT,4BACA,qUACA;KACE,0CACE,QAAQ,aAAa;KACvB,wFACE;KACF,0CAA0C,aAAa;KACvD,gDACE,CAAC,YAAY,aAAa;KAC5B,gDACE,aAAa;KAChB,CACF;IACD,UAAU,MAAM;AACd,SAAI,UAAU;AACZ,QAAE,iBAAiB;AACnB;;AAEF,cAAS,YAAY,CAAC,QAAQ;;IAEhC,YAAY,UAAU;AACpB,SAAI,SAAU;AACd,SACE,MAAM,QAAQ,eACd,MAAM,QAAQ,aACd,MAAM,QAAQ,WACd,MAAM,QAAQ,KACd;AACA,YAAM,gBAAgB;AACtB,cAAQ,KAAK;;;cAtCnB,CA0CG,OACC,qBAAC,OAAD;KAAK,WAAU;eAAf,CACE,oBAAC,OAAD;MAAK,WAAU;gBAAY;MAAW,CAAA,EACtC,oBAAC,OAAD;MACE,WAAU;MACV,OAAO,EACL,iBAAiB,SAAS,4BAC3B;MACD,CAAA,CACE;SAEN,qBAAC,OAAD;KAAK,WAAU;eAAf,CAA8D,KAE5D,oBAAC,OAAD;MACE,WAAU;MACV,OAAO,EACL,iBAAiB,SAAS,4BAC3B;MACD,CAAA,CACE;QAER,oBAAC,MAAD;KAAc,MAAM;KAAI,OAAO;KAA8B,CAAA,CACtD;;GACA,CAAA;EACP,CAAA;AAGV,KAAI,SAAS,UACX,QAAO,oBAAC,eAAD,EAAkB,GAAI,kBAAoB,CAAA;AAGnD,QAAO"}
@@ -141,7 +141,7 @@ function OriginModal(props) {
141
141
  open,
142
142
  modal: false,
143
143
  children: /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [isTop && /* @__PURE__ */ jsx("div", {
144
- className: "ald-modal-mask tw-animate-in tw-fade-in-0 tw-fixed tw-inset-0 tw-bg-[var(--background-inverted)] tw-opacity-45",
144
+ className: "ald-modal-mask tw-animate-in tw-fade-in-0 tw-fixed tw-inset-0 tw-bg-[var(--background-mask)]",
145
145
  style: { zIndex: maskZIndex },
146
146
  onPointerDown: () => {
147
147
  if (maskClosable) onCancel?.({});
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Modal/index.tsx"],"sourcesContent":["import * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { hideOthers } from 'aria-hidden';\nimport React, {\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { createRoot } from 'react-dom/client';\nimport Button, { ButtonType, IButtonProps } from '../Button';\nimport {\n AttentionTriangleLightLine,\n CheckCircleLightLine,\n CloseLLine,\n InformationCircleLightLine,\n} from '../Icon';\nimport '../IconButton/icon-button.css';\nimport ScrollArea from '../ScrollArea';\nimport {\n FLOATING_LAYER_BASE_Z_INDEX,\n FLOATING_LAYER_STEP,\n FloatingLayerProvider,\n} from '../_utils/floatingLayer';\nimport {\n ModalLayerProvider,\n useModalLayer,\n} from '../_utils/overlayCoordinator';\nimport {\n focusInitialDialogTarget,\n markDialogEscapeEvent,\n restoreDialogFocus,\n useDialogAccessibility,\n} from '../_utils/dialogAccessibility';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport { cn } from '../lib/utils';\n\nexport const destroyFns: Array<() => void> = [];\n\nexport interface ModalProps {\n open?: boolean;\n onOk?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n onCancel?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n afterClose?: () => void;\n title?: React.ReactNode;\n subTitle?: React.ReactNode;\n icon?: React.ReactElement;\n width?: number | string;\n footer?: React.ReactNode | null;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n confirmLoading?: boolean;\n maskClosable?: boolean;\n closable?: boolean;\n closeIcon?: React.ReactNode;\n centered?: boolean;\n destroyOnClose?: boolean;\n className?: string;\n /** Pass through to the modal content root for automated testing. */\n 'data-testid'?: string;\n /** Pass through to the modal content root for accessibility and automated testing. */\n 'aria-label'?: string;\n /** Dialog semantic role. Use alertdialog only for explicitly urgent confirmation flows. */\n role?: 'dialog' | 'alertdialog';\n /** Applied to the outer wrap layer (matches antd wrapClassName behavior) */\n wrapClassName?: string;\n style?: React.CSSProperties;\n bodyStyle?: React.CSSProperties;\n zIndex?: number;\n children?: React.ReactNode;\n paddingLess?: boolean;\n virtualScrollBar?: boolean;\n hideHeaderBottomBorder?: boolean;\n responsiveBounds?: boolean;\n fullscreen?: boolean;\n keyboard?: boolean;\n afterOpenChange?: (open: boolean) => void;\n getContainer?: (() => HTMLElement) | false;\n /** @internal used by static methods to pass modal type for icon styling */\n _modalType?: string;\n}\n\ninterface OriginModalProps extends ModalProps {\n onTopChange?: (isTop: boolean) => void;\n}\n\nexport interface ModalFuncProps {\n title?: React.ReactNode;\n subTitle?: React.ReactNode;\n content?: React.ReactNode;\n icon?: React.ReactElement;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n onOk?: (...args: any[]) => any;\n onCancel?: (...args: any[]) => any;\n width?: number | string;\n className?: string;\n /** @deprecated Use `className` instead. Preserved for antd v4 compat. */\n wrapClassName?: string;\n closable?: boolean;\n type?: 'info' | 'success' | 'error' | 'warn' | 'warning' | 'confirm';\n centered?: boolean;\n maskClosable?: boolean;\n /** Dialog semantic role. Use alertdialog only for explicitly urgent confirmation flows. */\n role?: 'dialog' | 'alertdialog';\n}\n\nconst DEFAULT_WIDTH = 552;\nfunction ModalContentProviders({\n layerId,\n floatingLevel,\n children,\n}: {\n layerId: number;\n floatingLevel: number;\n children: React.ReactNode;\n}) {\n return (\n <ModalLayerProvider id={layerId}>\n <FloatingLayerProvider value={floatingLevel}>\n {children}\n </FloatingLayerProvider>\n </ModalLayerProvider>\n );\n}\n\nconst ModalTitle = (\n {\n icon,\n title,\n subTitle,\n titleId,\n descriptionId,\n }: Pick<ModalProps, 'icon' | 'title' | 'subTitle'> & {\n titleId?: string;\n descriptionId?: string;\n },\n type?: string,\n) => (\n <div className=\"ald-modal-title-container tw-flex tw-items-center tw-gap-4\">\n {icon && (\n <div\n className={cn(\n 'ald-modal-icon-container tw-grid tw-size-10 tw-shrink-0 tw-place-items-center tw-rounded-[var(--global-grid-250)]',\n type === 'info' &&\n 'ald-modal-cion-info-container tw-bg-[var(--background-informative-muted)]',\n type === 'success' &&\n 'ald-modal-cion-success-container tw-bg-[var(--background-positive-muted)]',\n type === 'warning' &&\n 'ald-modal-cion-warning-container tw-bg-[var(--background-warning-muted)]',\n type === 'warn' &&\n 'ald-modal-cion-warning-container tw-bg-[var(--background-warning-muted)]',\n type === 'error' &&\n 'ald-modal-cion-error-container tw-bg-[var(--background-negative-muted)]',\n type === 'confirm' &&\n 'ald-modal-cion-confirm-container tw-bg-[var(--background-brand-muted)]',\n )}\n >\n {icon}\n </div>\n )}\n <div className=\"ald-modal-text-container\">\n {title && (\n <div\n id={titleId}\n className={cn(\n 'ald-modal-text-title tw-text-lg tw-font-semibold tw-leading-7 tw-text-[var(--content-primary)]',\n !subTitle && 'ald-modal-text-title-only tw-text-xl',\n )}\n >\n {title}\n </div>\n )}\n {subTitle && (\n <div\n id={descriptionId}\n className=\"ald-modal-text-sub-title tw-mt-1 tw-text-xs tw-leading-4 tw-text-[var(--content-secondary)]\"\n >\n {subTitle}\n </div>\n )}\n </div>\n </div>\n);\n\nfunction getIcon(\n type: 'info' | 'success' | 'error' | 'warn' | 'warning' | 'confirm',\n) {\n if (type === 'success')\n return (\n <CheckCircleLightLine\n fill=\"var(--content-inverted-primary)\"\n color=\"var(--background-positive-strong)\"\n size={24}\n />\n );\n if (type === 'error')\n return (\n <AttentionTriangleLightLine\n color=\"var(--background-negative-strong)\"\n fill=\"var(--content-inverted-primary)\"\n size={24}\n />\n );\n if (type === 'warning' || type === 'warn')\n return (\n <AttentionTriangleLightLine\n color=\"var(--background-warning-strong)\"\n size={24}\n />\n );\n return (\n <InformationCircleLightLine\n size={24}\n color=\"var(--action-primary-normal)\"\n />\n );\n}\n\nfunction OriginModal(props: OriginModalProps) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n const {\n className,\n 'data-testid': dataTestId,\n 'aria-label': ariaLabel,\n role = 'dialog',\n children,\n okType = 'primary',\n width,\n closeIcon,\n subTitle,\n okButtonProps = {},\n cancelButtonProps = {},\n okText = t.Modal.sure,\n cancelText = t.Modal.cancel,\n icon,\n title,\n paddingLess,\n responsiveBounds,\n hideHeaderBottomBorder,\n virtualScrollBar,\n style,\n maskClosable = false,\n fullscreen,\n open = false,\n onOk,\n onCancel,\n footer,\n confirmLoading,\n closable = true,\n zIndex = 1000,\n bodyStyle,\n keyboard = true,\n afterOpenChange,\n wrapClassName,\n _modalType,\n onTopChange,\n } = props;\n\n const prevOpenRef = useRef(open);\n const contentRef = useRef<HTMLDivElement>(null);\n const modalRef = useRef<HTMLDivElement>(null);\n const generatedId = React.useId();\n const titleId = `${generatedId}-title`;\n const descriptionId = `${generatedId}-description`;\n const modalLayer = useModalLayer(open, zIndex);\n const { id: modalLayerId, maskZIndex, contentZIndex, isTop } = modalLayer;\n const nextFloatingLevel =\n (maskZIndex - FLOATING_LAYER_BASE_Z_INDEX) / FLOATING_LAYER_STEP + 1;\n\n useDialogAccessibility({\n open,\n isTop,\n keyboard,\n containerRef: modalRef,\n onEscape: () => onCancel?.({} as React.MouseEvent<HTMLButtonElement>),\n });\n\n useLayoutEffect(() => {\n onTopChange?.(isTop);\n }, [isTop, onTopChange]);\n\n useEffect(() => {\n if (prevOpenRef.current !== open) {\n prevOpenRef.current = open;\n afterOpenChange?.(open);\n }\n }, [open, afterOpenChange]);\n\n // ---- modal={false} 补偿:aria-hidden(屏幕阅读器只感知弹窗) ----\n useEffect(() => {\n if (!open || !isTop || !contentRef.current) return;\n return hideOthers(contentRef.current);\n }, [isTop, open]);\n\n const responsiveBoundsStyle = useMemo(() => {\n if (!responsiveBounds) return {};\n return {\n width: 'calc(100% - 160px)',\n maxWidth: '1680px',\n minWidth: '1280px',\n height: 'calc(100% - 48px)',\n maxHeight: '900px',\n minHeight: '640px',\n };\n }, [responsiveBounds]);\n\n const mergedOkProps = { loading: confirmLoading, ...okButtonProps };\n const headerBorderClassName = hideHeaderBottomBorder\n ? '!tw-border-0'\n : 'tw-border-b tw-border-solid tw-border-[var(--border-default)] !tw-border-x-0 !tw-border-t-0';\n\n const renderFooter = () => {\n if (footer === null) return null;\n const footerBorderClassName =\n 'tw-border-t tw-border-solid tw-border-[var(--border-default)] !tw-border-x-0 !tw-border-b-0';\n if (footer)\n return (\n // antd 兼容:antd .ant-modal-footer 使用 text-align:right 让 inline 按钮右对齐,\n // 即使消费方传入 width:100% 的子容器,内部 inline 元素仍能右对齐。\n // 此处同时使用 tw-flex tw-justify-end(flexbox 对齐)和 tw-text-right(继承式对齐)保持兼容。\n <div\n className={cn(\n 'ald-modal-footer ant-modal-footer tw-flex tw-items-center tw-justify-end tw-gap-2 tw-bg-[var(--background-default)] tw-px-6 tw-py-3 tw-text-right',\n footerBorderClassName,\n )}\n >\n {footer}\n </div>\n );\n return (\n <div\n className={cn(\n 'ald-modal-footer ant-modal-footer tw-flex tw-justify-end tw-gap-2 tw-px-6 tw-py-4',\n footerBorderClassName,\n )}\n >\n <Button\n type=\"secondary\"\n size=\"middle\"\n {...cancelButtonProps}\n onClick={onCancel}\n >\n {cancelText}\n </Button>\n <Button type={okType} size=\"middle\" {...mergedOkProps} onClick={onOk}>\n {okText}\n </Button>\n </div>\n );\n };\n\n return (\n <DialogPrimitive.Root open={open} modal={false}>\n <DialogPrimitive.Portal>\n {/* modal={false} 时 DialogPrimitive.Overlay 不渲染,用普通 div 替代 */}\n {isTop && (\n <div\n className=\"ald-modal-mask tw-animate-in tw-fade-in-0 tw-fixed tw-inset-0 tw-bg-[var(--background-inverted)] tw-opacity-45\"\n style={{ zIndex: maskZIndex }}\n onPointerDown={() => {\n if (maskClosable) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n }\n }}\n />\n )}\n {/* Centering wrapper — replaces transform centering so consumer CSS (top/left overrides) works */}\n <div\n ref={contentRef}\n {...(!isTop ? { inert: '' } : {})}\n aria-hidden={!isTop || undefined}\n className={cn(\n // antd 兼容:保留 ant-modal-wrap class,消费方 CSS 通过 wrapClassName + :global(.ant-modal) 控制弹窗宽高\n 'ald-modal-wrap ant-modal-wrap tw-pointer-events-none tw-fixed tw-inset-0 tw-flex tw-items-center tw-justify-center',\n wrapClassName,\n )}\n style={{ zIndex: contentZIndex }}\n >\n <DialogPrimitive.Content\n ref={modalRef}\n tabIndex={-1}\n role={role}\n data-testid={dataTestId}\n aria-modal={isTop || undefined}\n aria-labelledby={title ? titleId : undefined}\n aria-describedby={subTitle ? descriptionId : undefined}\n aria-label={ariaLabel}\n className={cn(\n // antd 兼容:保留 ant-modal class,消费方 CSS 通过 .ant-modal 选择器控制弹窗宽高等样式\n // tw-outline-none:Radix 打开时会聚焦 Content,不抑制 outline 会渲染出蓝色焦点框\n 'ald-modal ant-modal tw-pointer-events-auto tw-box-border tw-flex tw-flex-col tw-overflow-hidden tw-border-0 tw-bg-[var(--background-default)] tw-shadow-none tw-outline-none',\n fullscreen\n ? 'ald-modal-fullscreen tw-fixed tw-inset-0 tw-size-full tw-rounded-none'\n : 'tw-rounded-r-75',\n paddingLess && 'ald-modal-padding-less',\n virtualScrollBar && 'ald-modal-virtual-scroll-bar',\n hideHeaderBottomBorder && 'ald-modal-hide-header-bottom-border',\n responsiveBounds && 'ald-modal-responsive-bounds',\n className,\n )}\n style={{\n ...(fullscreen\n ? {}\n : {\n width: responsiveBounds\n ? responsiveBoundsStyle.width\n : width || DEFAULT_WIDTH,\n ...responsiveBoundsStyle,\n }),\n ...style,\n }}\n onOpenAutoFocus={(event) => {\n event.preventDefault();\n requestAnimationFrame(() => {\n const modal = modalRef.current;\n if (modal) focusInitialDialogTarget(modal);\n });\n }}\n onEscapeKeyDown={(event) => {\n if (!event.defaultPrevented) markDialogEscapeEvent(event);\n event.preventDefault();\n }}\n onPointerDownOutside={(e) => {\n if (maskClosable) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n } else {\n e.preventDefault();\n }\n }}\n onInteractOutside={(e) => {\n if (!maskClosable) {\n e.preventDefault();\n }\n }}\n >\n {/* ant-modal-content compat wrapper — matches antd DOM nesting for consumer CSS.\n Visual chrome is owned by .ald-modal to avoid nested antd styles adding\n an extra footer-side/bottom edge. */}\n <div className=\"ant-modal-content tw-flex tw-h-full tw-flex-col !tw-rounded-none !tw-border-0 !tw-bg-transparent !tw-p-0 !tw-shadow-none\">\n <ModalContentProviders\n layerId={modalLayerId}\n floatingLevel={nextFloatingLevel}\n >\n {!fullscreen && (\n <div\n className={cn(\n 'ald-modal-header ant-modal-header tw-flex tw-items-start tw-justify-between tw-bg-[var(--background-default)] tw-px-6 tw-py-4',\n headerBorderClassName,\n )}\n >\n <DialogPrimitive.Title asChild>\n <div className=\"tw-flex-1\">\n {ModalTitle(\n { icon, title, subTitle, titleId, descriptionId },\n _modalType,\n )}\n </div>\n </DialogPrimitive.Title>\n {closable && (\n <DialogPrimitive.Close asChild>\n <button\n type=\"button\"\n className=\"ant-modal-close ald-icon-button ald-icon-button-middle focus-visible:tw-outline focus-visible:tw-outline-2 focus-visible:tw-outline-offset-2 focus-visible:tw-outline-[var(--focus-ring)] forced-colors:focus-visible:tw-outline-[Highlight]\"\n aria-label=\"Close\"\n data-overlay-close=\"true\"\n onClick={onCancel}\n >\n <span className=\"ald-icon-button-wrap\">\n {closeIcon || <CloseLLine size={20} />}\n </span>\n </button>\n </DialogPrimitive.Close>\n )}\n </div>\n )}\n {/* Hidden title for accessibility when fullscreen hides the header */}\n {fullscreen && (\n <DialogPrimitive.Title asChild>\n <div className=\"tw-sr-only\">\n {title && <span id={titleId}>{title}</span>}\n </div>\n </DialogPrimitive.Title>\n )}\n {subTitle && (\n <DialogPrimitive.Description className=\"tw-sr-only\">\n {subTitle}\n </DialogPrimitive.Description>\n )}\n <div\n className={cn(\n 'ald-modal-body ant-modal-body tw-flex-1 tw-text-sm tw-leading-5',\n fullscreen\n ? 'tw-h-full tw-overflow-auto tw-p-0'\n : 'tw-min-h-[130px]',\n !fullscreen &&\n (virtualScrollBar\n ? 'tw-overflow-hidden tw-p-0'\n : 'tw-overflow-auto'),\n !fullscreen &&\n !responsiveBounds &&\n !virtualScrollBar &&\n 'tw-max-h-[68vh]',\n !fullscreen &&\n !paddingLess &&\n !virtualScrollBar &&\n 'tw-p-6',\n )}\n style={bodyStyle}\n >\n {virtualScrollBar ? (\n <ScrollArea\n className=\"ald-modal-body-wrap !tw-h-auto\"\n innerClassName={cn(\n 'ald-modal-body-wrap-inner tw-max-h-[68vh]',\n paddingLess ? 'tw-p-0' : 'tw-px-[23px] tw-py-0',\n )}\n >\n {children}\n </ScrollArea>\n ) : (\n children\n )}\n </div>\n {!fullscreen && renderFooter()}\n </ModalContentProviders>\n </div>\n </DialogPrimitive.Content>\n </div>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n\n// Static method helper\nfunction createStaticModal(\n type: ModalFuncProps['type'],\n props: ModalFuncProps,\n) {\n const focusTarget = document.activeElement as HTMLElement | null;\n const container = document.createElement('div');\n document.body.appendChild(container);\n const root = createRoot(container);\n\n let currentProps = { ...props };\n let destroyed = false;\n let isTop = true;\n\n const destroy = () => {\n if (destroyed) return;\n destroyed = true;\n const shouldRestoreFocus = isTop;\n root.unmount();\n container.remove();\n const idx = destroyFns.indexOf(destroy);\n if (idx >= 0) destroyFns.splice(idx, 1);\n if (shouldRestoreFocus) restoreDialogFocus(focusTarget);\n };\n\n const update = (newProps: Partial<ModalFuncProps>) => {\n currentProps = { ...currentProps, ...newProps };\n render(currentProps);\n };\n\n const isConfirm = type === 'confirm';\n\n const render = (p: ModalFuncProps) => {\n const handleOk = () => {\n p.onOk?.();\n destroy();\n };\n const handleCancel = () => {\n p.onCancel?.();\n destroy();\n };\n\n root.render(\n <OriginModal\n open={true}\n title={p.title}\n subTitle={p.subTitle}\n icon={p.icon || getIcon(type || 'info')}\n onOk={handleOk}\n onCancel={handleCancel}\n okText={p.okText}\n cancelText={p.cancelText}\n okButtonProps={p.okButtonProps}\n cancelButtonProps={p.cancelButtonProps}\n okType={p.okType || (isConfirm ? 'dangerous' : 'primary')}\n width={p.width || DEFAULT_WIDTH}\n className={cn('ald-modal', p.className)}\n closable={p.closable}\n maskClosable={p.maskClosable}\n role={p.role}\n _modalType={type}\n onTopChange={(nextIsTop) => {\n isTop = nextIsTop;\n }}\n footer={\n isConfirm ? undefined : (\n <Button\n type=\"primary\"\n size=\"middle\"\n {...(p.okButtonProps || {})}\n onClick={handleOk}\n >\n {p.okText || 'OK'}\n </Button>\n )\n }\n >\n {p.content}\n </OriginModal>,\n );\n };\n\n destroyFns.push(destroy);\n render(currentProps);\n\n return { destroy, update };\n}\n\n// Attach static methods\ntype ModalFunc = (props: ModalFuncProps) => {\n destroy: () => void;\n update: (props: Partial<ModalFuncProps>) => void;\n};\n\n// ---------- useModal hook ----------\n\ninterface ModalInstance {\n id: number;\n type: ModalFuncProps['type'];\n props: ModalFuncProps;\n open: boolean;\n}\n\nexport interface ModalApiInstance {\n destroy: () => void;\n update: (newProps: Partial<ModalFuncProps>) => void;\n}\n\nexport interface ModalStaticFunctions {\n info: (props: ModalFuncProps) => ModalApiInstance;\n success: (props: ModalFuncProps) => ModalApiInstance;\n error: (props: ModalFuncProps) => ModalApiInstance;\n warning: (props: ModalFuncProps) => ModalApiInstance;\n confirm: (props: ModalFuncProps) => ModalApiInstance;\n}\n\nfunction useModal(): [ModalStaticFunctions, React.ReactElement] {\n const [modals, setModals] = useState<ModalInstance[]>([]);\n const idCounter = useRef(0);\n\n const removeModal = useCallback((id: number) => {\n setModals((prev) =>\n prev.map((m) => (m.id === id ? { ...m, open: false } : m)),\n );\n // Remove from DOM after animation\n setTimeout(() => {\n setModals((prev) => prev.filter((m) => m.id !== id));\n }, 300);\n }, []);\n\n const updateModal = useCallback(\n (id: number, newProps: Partial<ModalFuncProps>) => {\n setModals((prev) =>\n prev.map((m) =>\n m.id === id ? { ...m, props: { ...m.props, ...newProps } } : m,\n ),\n );\n },\n [],\n );\n\n const openModal = useCallback(\n (type: ModalFuncProps['type'], props: ModalFuncProps): ModalApiInstance => {\n const id = ++idCounter.current;\n const instance: ModalInstance = { id, type, props, open: true };\n setModals((prev) => [...prev, instance]);\n\n return {\n destroy: () => removeModal(id),\n update: (newProps: Partial<ModalFuncProps>) =>\n updateModal(id, newProps),\n };\n },\n [removeModal, updateModal],\n );\n\n const api = useMemo<ModalStaticFunctions>(\n () => ({\n info: (props) => openModal('info', props),\n success: (props) => openModal('success', props),\n error: (props) => openModal('error', props),\n warning: (props) => openModal('warning', props),\n confirm: (props) =>\n openModal('confirm', { ...props, type: props.type || 'confirm' }),\n }),\n [openModal],\n );\n\n const contextHolder = (\n <>\n {modals.map((m) => {\n const isConfirmType = m.type === 'confirm';\n const handleOk = () => {\n m.props.onOk?.();\n removeModal(m.id);\n };\n const handleCancel = () => {\n m.props.onCancel?.();\n removeModal(m.id);\n };\n return (\n <OriginModal\n key={m.id}\n open={m.open}\n title={m.props.title}\n subTitle={m.props.subTitle}\n icon={m.props.icon || getIcon(m.type || 'info')}\n onOk={handleOk}\n onCancel={handleCancel}\n okText={m.props.okText}\n cancelText={m.props.cancelText}\n okButtonProps={m.props.okButtonProps}\n cancelButtonProps={m.props.cancelButtonProps}\n okType={m.props.okType || (isConfirmType ? 'dangerous' : 'primary')}\n width={m.props.width || DEFAULT_WIDTH}\n className={cn('ald-modal', m.props.className)}\n closable={m.props.closable}\n maskClosable={m.props.maskClosable}\n role={m.props.role}\n _modalType={m.type}\n footer={\n isConfirmType ? undefined : (\n <Button\n type=\"primary\"\n size=\"middle\"\n {...(m.props.okButtonProps || {})}\n onClick={handleOk}\n >\n {m.props.okText || 'OK'}\n </Button>\n )\n }\n >\n {m.props.content}\n </OriginModal>\n );\n })}\n </>\n );\n\n return [api, contextHolder];\n}\n\n// ---------- end useModal ----------\n\nconst Modal = OriginModal as typeof OriginModal & {\n info: ModalFunc;\n success: ModalFunc;\n error: ModalFunc;\n warning: ModalFunc;\n confirm: ModalFunc;\n destroyAll: () => void;\n useModal: typeof useModal;\n config: (config: any) => void;\n};\n\nModal.info = (props) => createStaticModal('info', props);\nModal.success = (props) => createStaticModal('success', props);\nModal.error = (props) => createStaticModal('error', props);\nModal.warning = (props) => createStaticModal('warning', props);\nModal.confirm = (props) =>\n createStaticModal('confirm', { ...props, type: props.type || 'confirm' });\n\nModal.destroyAll = () => {\n while (destroyFns.length) {\n const close = destroyFns.pop();\n if (close) close();\n }\n};\n\nModal.useModal = useModal;\nModal.config = () => {};\n\nexport default Modal;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Modal/index.tsx"],"sourcesContent":["import * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { hideOthers } from 'aria-hidden';\nimport React, {\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { createRoot } from 'react-dom/client';\nimport Button, { ButtonType, IButtonProps } from '../Button';\nimport {\n AttentionTriangleLightLine,\n CheckCircleLightLine,\n CloseLLine,\n InformationCircleLightLine,\n} from '../Icon';\nimport '../IconButton/icon-button.css';\nimport ScrollArea from '../ScrollArea';\nimport {\n FLOATING_LAYER_BASE_Z_INDEX,\n FLOATING_LAYER_STEP,\n FloatingLayerProvider,\n} from '../_utils/floatingLayer';\nimport {\n ModalLayerProvider,\n useModalLayer,\n} from '../_utils/overlayCoordinator';\nimport {\n focusInitialDialogTarget,\n markDialogEscapeEvent,\n restoreDialogFocus,\n useDialogAccessibility,\n} from '../_utils/dialogAccessibility';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport { cn } from '../lib/utils';\n\nexport const destroyFns: Array<() => void> = [];\n\nexport interface ModalProps {\n open?: boolean;\n onOk?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n onCancel?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n afterClose?: () => void;\n title?: React.ReactNode;\n subTitle?: React.ReactNode;\n icon?: React.ReactElement;\n width?: number | string;\n footer?: React.ReactNode | null;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n confirmLoading?: boolean;\n maskClosable?: boolean;\n closable?: boolean;\n closeIcon?: React.ReactNode;\n centered?: boolean;\n destroyOnClose?: boolean;\n className?: string;\n /** Pass through to the modal content root for automated testing. */\n 'data-testid'?: string;\n /** Pass through to the modal content root for accessibility and automated testing. */\n 'aria-label'?: string;\n /** Dialog semantic role. Use alertdialog only for explicitly urgent confirmation flows. */\n role?: 'dialog' | 'alertdialog';\n /** Applied to the outer wrap layer (matches antd wrapClassName behavior) */\n wrapClassName?: string;\n style?: React.CSSProperties;\n bodyStyle?: React.CSSProperties;\n zIndex?: number;\n children?: React.ReactNode;\n paddingLess?: boolean;\n virtualScrollBar?: boolean;\n hideHeaderBottomBorder?: boolean;\n responsiveBounds?: boolean;\n fullscreen?: boolean;\n keyboard?: boolean;\n afterOpenChange?: (open: boolean) => void;\n getContainer?: (() => HTMLElement) | false;\n /** @internal used by static methods to pass modal type for icon styling */\n _modalType?: string;\n}\n\ninterface OriginModalProps extends ModalProps {\n onTopChange?: (isTop: boolean) => void;\n}\n\nexport interface ModalFuncProps {\n title?: React.ReactNode;\n subTitle?: React.ReactNode;\n content?: React.ReactNode;\n icon?: React.ReactElement;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n onOk?: (...args: any[]) => any;\n onCancel?: (...args: any[]) => any;\n width?: number | string;\n className?: string;\n /** @deprecated Use `className` instead. Preserved for antd v4 compat. */\n wrapClassName?: string;\n closable?: boolean;\n type?: 'info' | 'success' | 'error' | 'warn' | 'warning' | 'confirm';\n centered?: boolean;\n maskClosable?: boolean;\n /** Dialog semantic role. Use alertdialog only for explicitly urgent confirmation flows. */\n role?: 'dialog' | 'alertdialog';\n}\n\nconst DEFAULT_WIDTH = 552;\nfunction ModalContentProviders({\n layerId,\n floatingLevel,\n children,\n}: {\n layerId: number;\n floatingLevel: number;\n children: React.ReactNode;\n}) {\n return (\n <ModalLayerProvider id={layerId}>\n <FloatingLayerProvider value={floatingLevel}>\n {children}\n </FloatingLayerProvider>\n </ModalLayerProvider>\n );\n}\n\nconst ModalTitle = (\n {\n icon,\n title,\n subTitle,\n titleId,\n descriptionId,\n }: Pick<ModalProps, 'icon' | 'title' | 'subTitle'> & {\n titleId?: string;\n descriptionId?: string;\n },\n type?: string,\n) => (\n <div className=\"ald-modal-title-container tw-flex tw-items-center tw-gap-4\">\n {icon && (\n <div\n className={cn(\n 'ald-modal-icon-container tw-grid tw-size-10 tw-shrink-0 tw-place-items-center tw-rounded-[var(--global-grid-250)]',\n type === 'info' &&\n 'ald-modal-cion-info-container tw-bg-[var(--background-informative-muted)]',\n type === 'success' &&\n 'ald-modal-cion-success-container tw-bg-[var(--background-positive-muted)]',\n type === 'warning' &&\n 'ald-modal-cion-warning-container tw-bg-[var(--background-warning-muted)]',\n type === 'warn' &&\n 'ald-modal-cion-warning-container tw-bg-[var(--background-warning-muted)]',\n type === 'error' &&\n 'ald-modal-cion-error-container tw-bg-[var(--background-negative-muted)]',\n type === 'confirm' &&\n 'ald-modal-cion-confirm-container tw-bg-[var(--background-brand-muted)]',\n )}\n >\n {icon}\n </div>\n )}\n <div className=\"ald-modal-text-container\">\n {title && (\n <div\n id={titleId}\n className={cn(\n 'ald-modal-text-title tw-text-lg tw-font-semibold tw-leading-7 tw-text-[var(--content-primary)]',\n !subTitle && 'ald-modal-text-title-only tw-text-xl',\n )}\n >\n {title}\n </div>\n )}\n {subTitle && (\n <div\n id={descriptionId}\n className=\"ald-modal-text-sub-title tw-mt-1 tw-text-xs tw-leading-4 tw-text-[var(--content-secondary)]\"\n >\n {subTitle}\n </div>\n )}\n </div>\n </div>\n);\n\nfunction getIcon(\n type: 'info' | 'success' | 'error' | 'warn' | 'warning' | 'confirm',\n) {\n if (type === 'success')\n return (\n <CheckCircleLightLine\n fill=\"var(--content-inverted-primary)\"\n color=\"var(--background-positive-strong)\"\n size={24}\n />\n );\n if (type === 'error')\n return (\n <AttentionTriangleLightLine\n color=\"var(--background-negative-strong)\"\n fill=\"var(--content-inverted-primary)\"\n size={24}\n />\n );\n if (type === 'warning' || type === 'warn')\n return (\n <AttentionTriangleLightLine\n color=\"var(--background-warning-strong)\"\n size={24}\n />\n );\n return (\n <InformationCircleLightLine\n size={24}\n color=\"var(--action-primary-normal)\"\n />\n );\n}\n\nfunction OriginModal(props: OriginModalProps) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n const {\n className,\n 'data-testid': dataTestId,\n 'aria-label': ariaLabel,\n role = 'dialog',\n children,\n okType = 'primary',\n width,\n closeIcon,\n subTitle,\n okButtonProps = {},\n cancelButtonProps = {},\n okText = t.Modal.sure,\n cancelText = t.Modal.cancel,\n icon,\n title,\n paddingLess,\n responsiveBounds,\n hideHeaderBottomBorder,\n virtualScrollBar,\n style,\n maskClosable = false,\n fullscreen,\n open = false,\n onOk,\n onCancel,\n footer,\n confirmLoading,\n closable = true,\n zIndex = 1000,\n bodyStyle,\n keyboard = true,\n afterOpenChange,\n wrapClassName,\n _modalType,\n onTopChange,\n } = props;\n\n const prevOpenRef = useRef(open);\n const contentRef = useRef<HTMLDivElement>(null);\n const modalRef = useRef<HTMLDivElement>(null);\n const generatedId = React.useId();\n const titleId = `${generatedId}-title`;\n const descriptionId = `${generatedId}-description`;\n const modalLayer = useModalLayer(open, zIndex);\n const { id: modalLayerId, maskZIndex, contentZIndex, isTop } = modalLayer;\n const nextFloatingLevel =\n (maskZIndex - FLOATING_LAYER_BASE_Z_INDEX) / FLOATING_LAYER_STEP + 1;\n\n useDialogAccessibility({\n open,\n isTop,\n keyboard,\n containerRef: modalRef,\n onEscape: () => onCancel?.({} as React.MouseEvent<HTMLButtonElement>),\n });\n\n useLayoutEffect(() => {\n onTopChange?.(isTop);\n }, [isTop, onTopChange]);\n\n useEffect(() => {\n if (prevOpenRef.current !== open) {\n prevOpenRef.current = open;\n afterOpenChange?.(open);\n }\n }, [open, afterOpenChange]);\n\n // ---- modal={false} 补偿:aria-hidden(屏幕阅读器只感知弹窗) ----\n useEffect(() => {\n if (!open || !isTop || !contentRef.current) return;\n return hideOthers(contentRef.current);\n }, [isTop, open]);\n\n const responsiveBoundsStyle = useMemo(() => {\n if (!responsiveBounds) return {};\n return {\n width: 'calc(100% - 160px)',\n maxWidth: '1680px',\n minWidth: '1280px',\n height: 'calc(100% - 48px)',\n maxHeight: '900px',\n minHeight: '640px',\n };\n }, [responsiveBounds]);\n\n const mergedOkProps = { loading: confirmLoading, ...okButtonProps };\n const headerBorderClassName = hideHeaderBottomBorder\n ? '!tw-border-0'\n : 'tw-border-b tw-border-solid tw-border-[var(--border-default)] !tw-border-x-0 !tw-border-t-0';\n\n const renderFooter = () => {\n if (footer === null) return null;\n const footerBorderClassName =\n 'tw-border-t tw-border-solid tw-border-[var(--border-default)] !tw-border-x-0 !tw-border-b-0';\n if (footer)\n return (\n // antd 兼容:antd .ant-modal-footer 使用 text-align:right 让 inline 按钮右对齐,\n // 即使消费方传入 width:100% 的子容器,内部 inline 元素仍能右对齐。\n // 此处同时使用 tw-flex tw-justify-end(flexbox 对齐)和 tw-text-right(继承式对齐)保持兼容。\n <div\n className={cn(\n 'ald-modal-footer ant-modal-footer tw-flex tw-items-center tw-justify-end tw-gap-2 tw-bg-[var(--background-default)] tw-px-6 tw-py-3 tw-text-right',\n footerBorderClassName,\n )}\n >\n {footer}\n </div>\n );\n return (\n <div\n className={cn(\n 'ald-modal-footer ant-modal-footer tw-flex tw-justify-end tw-gap-2 tw-px-6 tw-py-4',\n footerBorderClassName,\n )}\n >\n <Button\n type=\"secondary\"\n size=\"middle\"\n {...cancelButtonProps}\n onClick={onCancel}\n >\n {cancelText}\n </Button>\n <Button type={okType} size=\"middle\" {...mergedOkProps} onClick={onOk}>\n {okText}\n </Button>\n </div>\n );\n };\n\n return (\n <DialogPrimitive.Root open={open} modal={false}>\n <DialogPrimitive.Portal>\n {/* modal={false} 时 DialogPrimitive.Overlay 不渲染,用普通 div 替代 */}\n {isTop && (\n <div\n className=\"ald-modal-mask tw-animate-in tw-fade-in-0 tw-fixed tw-inset-0 tw-bg-[var(--background-mask)]\"\n style={{ zIndex: maskZIndex }}\n onPointerDown={() => {\n if (maskClosable) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n }\n }}\n />\n )}\n {/* Centering wrapper — replaces transform centering so consumer CSS (top/left overrides) works */}\n <div\n ref={contentRef}\n {...(!isTop ? { inert: '' } : {})}\n aria-hidden={!isTop || undefined}\n className={cn(\n // antd 兼容:保留 ant-modal-wrap class,消费方 CSS 通过 wrapClassName + :global(.ant-modal) 控制弹窗宽高\n 'ald-modal-wrap ant-modal-wrap tw-pointer-events-none tw-fixed tw-inset-0 tw-flex tw-items-center tw-justify-center',\n wrapClassName,\n )}\n style={{ zIndex: contentZIndex }}\n >\n <DialogPrimitive.Content\n ref={modalRef}\n tabIndex={-1}\n role={role}\n data-testid={dataTestId}\n aria-modal={isTop || undefined}\n aria-labelledby={title ? titleId : undefined}\n aria-describedby={subTitle ? descriptionId : undefined}\n aria-label={ariaLabel}\n className={cn(\n // antd 兼容:保留 ant-modal class,消费方 CSS 通过 .ant-modal 选择器控制弹窗宽高等样式\n // tw-outline-none:Radix 打开时会聚焦 Content,不抑制 outline 会渲染出蓝色焦点框\n 'ald-modal ant-modal tw-pointer-events-auto tw-box-border tw-flex tw-flex-col tw-overflow-hidden tw-border-0 tw-bg-[var(--background-default)] tw-shadow-none tw-outline-none',\n fullscreen\n ? 'ald-modal-fullscreen tw-fixed tw-inset-0 tw-size-full tw-rounded-none'\n : 'tw-rounded-r-75',\n paddingLess && 'ald-modal-padding-less',\n virtualScrollBar && 'ald-modal-virtual-scroll-bar',\n hideHeaderBottomBorder && 'ald-modal-hide-header-bottom-border',\n responsiveBounds && 'ald-modal-responsive-bounds',\n className,\n )}\n style={{\n ...(fullscreen\n ? {}\n : {\n width: responsiveBounds\n ? responsiveBoundsStyle.width\n : width || DEFAULT_WIDTH,\n ...responsiveBoundsStyle,\n }),\n ...style,\n }}\n onOpenAutoFocus={(event) => {\n event.preventDefault();\n requestAnimationFrame(() => {\n const modal = modalRef.current;\n if (modal) focusInitialDialogTarget(modal);\n });\n }}\n onEscapeKeyDown={(event) => {\n if (!event.defaultPrevented) markDialogEscapeEvent(event);\n event.preventDefault();\n }}\n onPointerDownOutside={(e) => {\n if (maskClosable) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n } else {\n e.preventDefault();\n }\n }}\n onInteractOutside={(e) => {\n if (!maskClosable) {\n e.preventDefault();\n }\n }}\n >\n {/* ant-modal-content compat wrapper — matches antd DOM nesting for consumer CSS.\n Visual chrome is owned by .ald-modal to avoid nested antd styles adding\n an extra footer-side/bottom edge. */}\n <div className=\"ant-modal-content tw-flex tw-h-full tw-flex-col !tw-rounded-none !tw-border-0 !tw-bg-transparent !tw-p-0 !tw-shadow-none\">\n <ModalContentProviders\n layerId={modalLayerId}\n floatingLevel={nextFloatingLevel}\n >\n {!fullscreen && (\n <div\n className={cn(\n 'ald-modal-header ant-modal-header tw-flex tw-items-start tw-justify-between tw-bg-[var(--background-default)] tw-px-6 tw-py-4',\n headerBorderClassName,\n )}\n >\n <DialogPrimitive.Title asChild>\n <div className=\"tw-flex-1\">\n {ModalTitle(\n { icon, title, subTitle, titleId, descriptionId },\n _modalType,\n )}\n </div>\n </DialogPrimitive.Title>\n {closable && (\n <DialogPrimitive.Close asChild>\n <button\n type=\"button\"\n className=\"ant-modal-close ald-icon-button ald-icon-button-middle focus-visible:tw-outline focus-visible:tw-outline-2 focus-visible:tw-outline-offset-2 focus-visible:tw-outline-[var(--focus-ring)] forced-colors:focus-visible:tw-outline-[Highlight]\"\n aria-label=\"Close\"\n data-overlay-close=\"true\"\n onClick={onCancel}\n >\n <span className=\"ald-icon-button-wrap\">\n {closeIcon || <CloseLLine size={20} />}\n </span>\n </button>\n </DialogPrimitive.Close>\n )}\n </div>\n )}\n {/* Hidden title for accessibility when fullscreen hides the header */}\n {fullscreen && (\n <DialogPrimitive.Title asChild>\n <div className=\"tw-sr-only\">\n {title && <span id={titleId}>{title}</span>}\n </div>\n </DialogPrimitive.Title>\n )}\n {subTitle && (\n <DialogPrimitive.Description className=\"tw-sr-only\">\n {subTitle}\n </DialogPrimitive.Description>\n )}\n <div\n className={cn(\n 'ald-modal-body ant-modal-body tw-flex-1 tw-text-sm tw-leading-5',\n fullscreen\n ? 'tw-h-full tw-overflow-auto tw-p-0'\n : 'tw-min-h-[130px]',\n !fullscreen &&\n (virtualScrollBar\n ? 'tw-overflow-hidden tw-p-0'\n : 'tw-overflow-auto'),\n !fullscreen &&\n !responsiveBounds &&\n !virtualScrollBar &&\n 'tw-max-h-[68vh]',\n !fullscreen &&\n !paddingLess &&\n !virtualScrollBar &&\n 'tw-p-6',\n )}\n style={bodyStyle}\n >\n {virtualScrollBar ? (\n <ScrollArea\n className=\"ald-modal-body-wrap !tw-h-auto\"\n innerClassName={cn(\n 'ald-modal-body-wrap-inner tw-max-h-[68vh]',\n paddingLess ? 'tw-p-0' : 'tw-px-[23px] tw-py-0',\n )}\n >\n {children}\n </ScrollArea>\n ) : (\n children\n )}\n </div>\n {!fullscreen && renderFooter()}\n </ModalContentProviders>\n </div>\n </DialogPrimitive.Content>\n </div>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n\n// Static method helper\nfunction createStaticModal(\n type: ModalFuncProps['type'],\n props: ModalFuncProps,\n) {\n const focusTarget = document.activeElement as HTMLElement | null;\n const container = document.createElement('div');\n document.body.appendChild(container);\n const root = createRoot(container);\n\n let currentProps = { ...props };\n let destroyed = false;\n let isTop = true;\n\n const destroy = () => {\n if (destroyed) return;\n destroyed = true;\n const shouldRestoreFocus = isTop;\n root.unmount();\n container.remove();\n const idx = destroyFns.indexOf(destroy);\n if (idx >= 0) destroyFns.splice(idx, 1);\n if (shouldRestoreFocus) restoreDialogFocus(focusTarget);\n };\n\n const update = (newProps: Partial<ModalFuncProps>) => {\n currentProps = { ...currentProps, ...newProps };\n render(currentProps);\n };\n\n const isConfirm = type === 'confirm';\n\n const render = (p: ModalFuncProps) => {\n const handleOk = () => {\n p.onOk?.();\n destroy();\n };\n const handleCancel = () => {\n p.onCancel?.();\n destroy();\n };\n\n root.render(\n <OriginModal\n open={true}\n title={p.title}\n subTitle={p.subTitle}\n icon={p.icon || getIcon(type || 'info')}\n onOk={handleOk}\n onCancel={handleCancel}\n okText={p.okText}\n cancelText={p.cancelText}\n okButtonProps={p.okButtonProps}\n cancelButtonProps={p.cancelButtonProps}\n okType={p.okType || (isConfirm ? 'dangerous' : 'primary')}\n width={p.width || DEFAULT_WIDTH}\n className={cn('ald-modal', p.className)}\n closable={p.closable}\n maskClosable={p.maskClosable}\n role={p.role}\n _modalType={type}\n onTopChange={(nextIsTop) => {\n isTop = nextIsTop;\n }}\n footer={\n isConfirm ? undefined : (\n <Button\n type=\"primary\"\n size=\"middle\"\n {...(p.okButtonProps || {})}\n onClick={handleOk}\n >\n {p.okText || 'OK'}\n </Button>\n )\n }\n >\n {p.content}\n </OriginModal>,\n );\n };\n\n destroyFns.push(destroy);\n render(currentProps);\n\n return { destroy, update };\n}\n\n// Attach static methods\ntype ModalFunc = (props: ModalFuncProps) => {\n destroy: () => void;\n update: (props: Partial<ModalFuncProps>) => void;\n};\n\n// ---------- useModal hook ----------\n\ninterface ModalInstance {\n id: number;\n type: ModalFuncProps['type'];\n props: ModalFuncProps;\n open: boolean;\n}\n\nexport interface ModalApiInstance {\n destroy: () => void;\n update: (newProps: Partial<ModalFuncProps>) => void;\n}\n\nexport interface ModalStaticFunctions {\n info: (props: ModalFuncProps) => ModalApiInstance;\n success: (props: ModalFuncProps) => ModalApiInstance;\n error: (props: ModalFuncProps) => ModalApiInstance;\n warning: (props: ModalFuncProps) => ModalApiInstance;\n confirm: (props: ModalFuncProps) => ModalApiInstance;\n}\n\nfunction useModal(): [ModalStaticFunctions, React.ReactElement] {\n const [modals, setModals] = useState<ModalInstance[]>([]);\n const idCounter = useRef(0);\n\n const removeModal = useCallback((id: number) => {\n setModals((prev) =>\n prev.map((m) => (m.id === id ? { ...m, open: false } : m)),\n );\n // Remove from DOM after animation\n setTimeout(() => {\n setModals((prev) => prev.filter((m) => m.id !== id));\n }, 300);\n }, []);\n\n const updateModal = useCallback(\n (id: number, newProps: Partial<ModalFuncProps>) => {\n setModals((prev) =>\n prev.map((m) =>\n m.id === id ? { ...m, props: { ...m.props, ...newProps } } : m,\n ),\n );\n },\n [],\n );\n\n const openModal = useCallback(\n (type: ModalFuncProps['type'], props: ModalFuncProps): ModalApiInstance => {\n const id = ++idCounter.current;\n const instance: ModalInstance = { id, type, props, open: true };\n setModals((prev) => [...prev, instance]);\n\n return {\n destroy: () => removeModal(id),\n update: (newProps: Partial<ModalFuncProps>) =>\n updateModal(id, newProps),\n };\n },\n [removeModal, updateModal],\n );\n\n const api = useMemo<ModalStaticFunctions>(\n () => ({\n info: (props) => openModal('info', props),\n success: (props) => openModal('success', props),\n error: (props) => openModal('error', props),\n warning: (props) => openModal('warning', props),\n confirm: (props) =>\n openModal('confirm', { ...props, type: props.type || 'confirm' }),\n }),\n [openModal],\n );\n\n const contextHolder = (\n <>\n {modals.map((m) => {\n const isConfirmType = m.type === 'confirm';\n const handleOk = () => {\n m.props.onOk?.();\n removeModal(m.id);\n };\n const handleCancel = () => {\n m.props.onCancel?.();\n removeModal(m.id);\n };\n return (\n <OriginModal\n key={m.id}\n open={m.open}\n title={m.props.title}\n subTitle={m.props.subTitle}\n icon={m.props.icon || getIcon(m.type || 'info')}\n onOk={handleOk}\n onCancel={handleCancel}\n okText={m.props.okText}\n cancelText={m.props.cancelText}\n okButtonProps={m.props.okButtonProps}\n cancelButtonProps={m.props.cancelButtonProps}\n okType={m.props.okType || (isConfirmType ? 'dangerous' : 'primary')}\n width={m.props.width || DEFAULT_WIDTH}\n className={cn('ald-modal', m.props.className)}\n closable={m.props.closable}\n maskClosable={m.props.maskClosable}\n role={m.props.role}\n _modalType={m.type}\n footer={\n isConfirmType ? undefined : (\n <Button\n type=\"primary\"\n size=\"middle\"\n {...(m.props.okButtonProps || {})}\n onClick={handleOk}\n >\n {m.props.okText || 'OK'}\n </Button>\n )\n }\n >\n {m.props.content}\n </OriginModal>\n );\n })}\n </>\n );\n\n return [api, contextHolder];\n}\n\n// ---------- end useModal ----------\n\nconst Modal = OriginModal as typeof OriginModal & {\n info: ModalFunc;\n success: ModalFunc;\n error: ModalFunc;\n warning: ModalFunc;\n confirm: ModalFunc;\n destroyAll: () => void;\n useModal: typeof useModal;\n config: (config: any) => void;\n};\n\nModal.info = (props) => createStaticModal('info', props);\nModal.success = (props) => createStaticModal('success', props);\nModal.error = (props) => createStaticModal('error', props);\nModal.warning = (props) => createStaticModal('warning', props);\nModal.confirm = (props) =>\n createStaticModal('confirm', { ...props, type: props.type || 'confirm' });\n\nModal.destroyAll = () => {\n while (destroyFns.length) {\n const close = destroyFns.pop();\n if (close) close();\n }\n};\n\nModal.useModal = useModal;\nModal.config = () => {};\n\nexport default Modal;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAuCA,IAAa,aAAgC,EAAE;AA4E/C,IAAM,gBAAgB;AACtB,SAAS,sBAAsB,EAC7B,SACA,eACA,YAKC;AACD,QACE,oBAAC,oBAAD;EAAoB,IAAI;YACtB,oBAAC,uBAAD;GAAuB,OAAO;GAC3B;GACqB,CAAA;EACL,CAAA;;AAIzB,IAAM,cACJ,EACE,MACA,OACA,UACA,SACA,iBAKF,SAEA,qBAAC,OAAD;CAAK,WAAU;WAAf,CACG,QACC,oBAAC,OAAD;EACE,WAAW,GACT,qHACA,SAAS,UACP,6EACF,SAAS,aACP,6EACF,SAAS,aACP,4EACF,SAAS,UACP,4EACF,SAAS,WACP,2EACF,SAAS,aACP,yEACH;YAEA;EACG,CAAA,EAER,qBAAC,OAAD;EAAK,WAAU;YAAf,CACG,SACC,oBAAC,OAAD;GACE,IAAI;GACJ,WAAW,GACT,kGACA,CAAC,YAAY,uCACd;aAEA;GACG,CAAA,EAEP,YACC,oBAAC,OAAD;GACE,IAAI;GACJ,WAAU;aAET;GACG,CAAA,CAEJ;IACF;;AAGR,SAAS,QACP,MACA;AACA,KAAI,SAAS,UACX,QACE,oBAAC,QAAD;EACE,MAAK;EACL,OAAM;EACN,MAAM;EACN,CAAA;AAEN,KAAI,SAAS,QACX,QACE,oBAAC,MAAD;EACE,OAAM;EACN,MAAK;EACL,MAAM;EACN,CAAA;AAEN,KAAI,SAAS,aAAa,SAAS,OACjC,QACE,oBAAC,MAAD;EACE,OAAM;EACN,MAAM;EACN,CAAA;AAEN,QACE,oBAAC,QAAD;EACE,MAAM;EACN,OAAM;EACN,CAAA;;AAIN,SAAS,YAAY,OAAyB;CAC5C,MAAM,EAAE,WAAW,WAAW,cAAc;CAC5C,MAAM,IAAI,cAAc,OAAO;CAC/B,MAAM,EACJ,WACA,eAAe,YACf,cAAc,WACd,OAAO,UACP,UACA,SAAS,WACT,OACA,WACA,UACA,gBAAgB,EAAE,EAClB,oBAAoB,EAAE,EACtB,SAAS,EAAE,MAAM,MACjB,aAAa,EAAE,MAAM,QACrB,MACA,OACA,aACA,kBACA,wBACA,kBACA,OACA,eAAe,OACf,YACA,OAAO,OACP,MACA,UACA,QACA,gBACA,WAAW,MACX,SAAS,KACT,WACA,WAAW,MACX,iBACA,eACA,YACA,gBACE;CAEJ,MAAM,cAAc,OAAO,KAAK;CAChC,MAAM,aAAa,OAAuB,KAAK;CAC/C,MAAM,WAAW,OAAuB,KAAK;CAC7C,MAAM,cAAc,MAAM,OAAO;CACjC,MAAM,UAAU,GAAG,YAAY;CAC/B,MAAM,gBAAgB,GAAG,YAAY;CAErC,MAAM,EAAE,IAAI,cAAc,YAAY,eAAe,UADlC,cAAc,MAAM,OAAO;CAE9C,MAAM,qBACH,aAAa,+BAAA,KAAqD;AAErE,wBAAuB;EACrB;EACA;EACA;EACA,cAAc;EACd,gBAAgB,WAAW,EAAE,CAAwC;EACtE,CAAC;AAEF,uBAAsB;AACpB,gBAAc,MAAM;IACnB,CAAC,OAAO,YAAY,CAAC;AAExB,iBAAgB;AACd,MAAI,YAAY,YAAY,MAAM;AAChC,eAAY,UAAU;AACtB,qBAAkB,KAAK;;IAExB,CAAC,MAAM,gBAAgB,CAAC;AAG3B,iBAAgB;AACd,MAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,QAAS;AAC5C,SAAO,WAAW,WAAW,QAAQ;IACpC,CAAC,OAAO,KAAK,CAAC;CAEjB,MAAM,wBAAwB,cAAc;AAC1C,MAAI,CAAC,iBAAkB,QAAO,EAAE;AAChC,SAAO;GACL,OAAO;GACP,UAAU;GACV,UAAU;GACV,QAAQ;GACR,WAAW;GACX,WAAW;GACZ;IACA,CAAC,iBAAiB,CAAC;CAEtB,MAAM,gBAAgB;EAAE,SAAS;EAAgB,GAAG;EAAe;CACnE,MAAM,wBAAwB,yBAC1B,iBACA;CAEJ,MAAM,qBAAqB;AACzB,MAAI,WAAW,KAAM,QAAO;EAC5B,MAAM,wBACJ;AACF,MAAI,OACF,QAIE,oBAAC,OAAD;GACE,WAAW,GACT,qJACA,sBACD;aAEA;GACG,CAAA;AAEV,SACE,qBAAC,OAAD;GACE,WAAW,GACT,qFACA,sBACD;aAJH,CAME,oBAAC,gBAAD;IACE,MAAK;IACL,MAAK;IACL,GAAI;IACJ,SAAS;cAER;IACM,CAAA,EACT,oBAAC,gBAAD;IAAQ,MAAM;IAAQ,MAAK;IAAS,GAAI;IAAe,SAAS;cAC7D;IACM,CAAA,CACL;;;AAIV,QACE,oBAAC,gBAAgB,MAAjB;EAA4B;EAAM,OAAO;YACvC,qBAAC,gBAAgB,QAAjB,EAAA,UAAA,CAEG,SACC,oBAAC,OAAD;GACE,WAAU;GACV,OAAO,EAAE,QAAQ,YAAY;GAC7B,qBAAqB;AACnB,QAAI,aACF,YAAW,EAAE,CAAwC;;GAGzD,CAAA,EAGJ,oBAAC,OAAD;GACE,KAAK;GACL,GAAK,CAAC,QAAQ,EAAE,OAAO,IAAI,GAAG,EAAE;GAChC,eAAa,CAAC,SAAS;GACvB,WAAW,GAET,sHACA,cACD;GACD,OAAO,EAAE,QAAQ,eAAe;aAEhC,oBAAC,gBAAgB,SAAjB;IACE,KAAK;IACL,UAAU;IACJ;IACN,eAAa;IACb,cAAY,SAAS;IACrB,mBAAiB,QAAQ,UAAU;IACnC,oBAAkB,WAAW,gBAAgB;IAC7C,cAAY;IACZ,WAAW,GAGT,gLACA,aACI,0EACA,mBACJ,eAAe,0BACf,oBAAoB,gCACpB,0BAA0B,uCAC1B,oBAAoB,+BACpB,UACD;IACD,OAAO;KACL,GAAI,aACA,EAAE,GACF;MACE,OAAO,mBACH,sBAAsB,QACtB,SAAS;MACb,GAAG;MACJ;KACL,GAAG;KACJ;IACD,kBAAkB,UAAU;AAC1B,WAAM,gBAAgB;AACtB,iCAA4B;MAC1B,MAAM,QAAQ,SAAS;AACvB,UAAI,MAAO,0BAAyB,MAAM;OAC1C;;IAEJ,kBAAkB,UAAU;AAC1B,SAAI,CAAC,MAAM,iBAAkB,uBAAsB,MAAM;AACzD,WAAM,gBAAgB;;IAExB,uBAAuB,MAAM;AAC3B,SAAI,aACF,YAAW,EAAE,CAAwC;SAErD,GAAE,gBAAgB;;IAGtB,oBAAoB,MAAM;AACxB,SAAI,CAAC,aACH,GAAE,gBAAgB;;cAOtB,oBAAC,OAAD;KAAK,WAAU;eACb,qBAAC,uBAAD;MACE,SAAS;MACT,eAAe;gBAFjB;OAIG,CAAC,cACA,qBAAC,OAAD;QACE,WAAW,GACT,iIACA,sBACD;kBAJH,CAME,oBAAC,gBAAgB,OAAjB;SAAuB,SAAA;mBACrB,oBAAC,OAAD;UAAK,WAAU;oBACZ,WACC;WAAE;WAAM;WAAO;WAAU;WAAS;WAAe,EACjD,WACD;UACG,CAAA;SACgB,CAAA,EACvB,YACC,oBAAC,gBAAgB,OAAjB;SAAuB,SAAA;mBACrB,oBAAC,UAAD;UACE,MAAK;UACL,WAAU;UACV,cAAW;UACX,sBAAmB;UACnB,SAAS;oBAET,oBAAC,QAAD;WAAM,WAAU;qBACb,aAAa,oBAAC,QAAD,EAAY,MAAM,IAAM,CAAA;WACjC,CAAA;UACA,CAAA;SACa,CAAA,CAEtB;;OAGP,cACC,oBAAC,gBAAgB,OAAjB;QAAuB,SAAA;kBACrB,oBAAC,OAAD;SAAK,WAAU;mBACZ,SAAS,oBAAC,QAAD;UAAM,IAAI;oBAAU;UAAa,CAAA;SACvC,CAAA;QACgB,CAAA;OAEzB,YACC,oBAAC,gBAAgB,aAAjB;QAA6B,WAAU;kBACpC;QAC2B,CAAA;OAEhC,oBAAC,OAAD;QACE,WAAW,GACT,mEACA,aACI,sCACA,oBACJ,CAAC,eACE,mBACG,8BACA,qBACN,CAAC,cACC,CAAC,oBACD,CAAC,oBACD,mBACF,CAAC,cACC,CAAC,eACD,CAAC,oBACD,SACH;QACD,OAAO;kBAEN,mBACC,oBAAC,oBAAD;SACE,WAAU;SACV,gBAAgB,GACd,6CACA,cAAc,WAAW,uBAC1B;SAEA;SACU,CAAA,GAEb;QAEE,CAAA;OACL,CAAC,cAAc,cAAc;OACR;;KACpB,CAAA;IACkB,CAAA;GACtB,CAAA,CACiB,EAAA,CAAA;EACJ,CAAA;;AAK3B,SAAS,kBACP,MACA,OACA;CACA,MAAM,cAAc,SAAS;CAC7B,MAAM,YAAY,SAAS,cAAc,MAAM;AAC/C,UAAS,KAAK,YAAY,UAAU;CACpC,MAAM,OAAO,WAAW,UAAU;CAElC,IAAI,eAAe,EAAE,GAAG,OAAO;CAC/B,IAAI,YAAY;CAChB,IAAI,QAAQ;CAEZ,MAAM,gBAAgB;AACpB,MAAI,UAAW;AACf,cAAY;EACZ,MAAM,qBAAqB;AAC3B,OAAK,SAAS;AACd,YAAU,QAAQ;EAClB,MAAM,MAAM,WAAW,QAAQ,QAAQ;AACvC,MAAI,OAAO,EAAG,YAAW,OAAO,KAAK,EAAE;AACvC,MAAI,mBAAoB,oBAAmB,YAAY;;CAGzD,MAAM,UAAU,aAAsC;AACpD,iBAAe;GAAE,GAAG;GAAc,GAAG;GAAU;AAC/C,SAAO,aAAa;;CAGtB,MAAM,YAAY,SAAS;CAE3B,MAAM,UAAU,MAAsB;EACpC,MAAM,iBAAiB;AACrB,KAAE,QAAQ;AACV,YAAS;;EAEX,MAAM,qBAAqB;AACzB,KAAE,YAAY;AACd,YAAS;;AAGX,OAAK,OACH,oBAAC,aAAD;GACE,MAAM;GACN,OAAO,EAAE;GACT,UAAU,EAAE;GACZ,MAAM,EAAE,QAAQ,QAAQ,QAAQ,OAAO;GACvC,MAAM;GACN,UAAU;GACV,QAAQ,EAAE;GACV,YAAY,EAAE;GACd,eAAe,EAAE;GACjB,mBAAmB,EAAE;GACrB,QAAQ,EAAE,WAAW,YAAY,cAAc;GAC/C,OAAO,EAAE,SAAS;GAClB,WAAW,GAAG,aAAa,EAAE,UAAU;GACvC,UAAU,EAAE;GACZ,cAAc,EAAE;GAChB,MAAM,EAAE;GACR,YAAY;GACZ,cAAc,cAAc;AAC1B,YAAQ;;GAEV,QACE,YAAY,SACV,oBAAC,gBAAD;IACE,MAAK;IACL,MAAK;IACL,GAAK,EAAE,iBAAiB,EAAE;IAC1B,SAAS;cAER,EAAE,UAAU;IACN,CAAA;aAIZ,EAAE;GACS,CAAA,CACf;;AAGH,YAAW,KAAK,QAAQ;AACxB,QAAO,aAAa;AAEpB,QAAO;EAAE;EAAS;EAAQ;;AA+B5B,SAAS,WAAuD;CAC9D,MAAM,CAAC,QAAQ,aAAa,SAA0B,EAAE,CAAC;CACzD,MAAM,YAAY,OAAO,EAAE;CAE3B,MAAM,cAAc,aAAa,OAAe;AAC9C,aAAW,SACT,KAAK,KAAK,MAAO,EAAE,OAAO,KAAK;GAAE,GAAG;GAAG,MAAM;GAAO,GAAG,EAAG,CAC3D;AAED,mBAAiB;AACf,cAAW,SAAS,KAAK,QAAQ,MAAM,EAAE,OAAO,GAAG,CAAC;KACnD,IAAI;IACN,EAAE,CAAC;CAEN,MAAM,cAAc,aACjB,IAAY,aAAsC;AACjD,aAAW,SACT,KAAK,KAAK,MACR,EAAE,OAAO,KAAK;GAAE,GAAG;GAAG,OAAO;IAAE,GAAG,EAAE;IAAO,GAAG;IAAU;GAAE,GAAG,EAC9D,CACF;IAEH,EAAE,CACH;CAED,MAAM,YAAY,aACf,MAA8B,UAA4C;EACzE,MAAM,KAAK,EAAE,UAAU;EACvB,MAAM,WAA0B;GAAE;GAAI;GAAM;GAAO,MAAM;GAAM;AAC/D,aAAW,SAAS,CAAC,GAAG,MAAM,SAAS,CAAC;AAExC,SAAO;GACL,eAAe,YAAY,GAAG;GAC9B,SAAS,aACP,YAAY,IAAI,SAAS;GAC5B;IAEH,CAAC,aAAa,YAAY,CAC3B;AAkED,QAAO,CAhEK,eACH;EACL,OAAO,UAAU,UAAU,QAAQ,MAAM;EACzC,UAAU,UAAU,UAAU,WAAW,MAAM;EAC/C,QAAQ,UAAU,UAAU,SAAS,MAAM;EAC3C,UAAU,UAAU,UAAU,WAAW,MAAM;EAC/C,UAAU,UACR,UAAU,WAAW;GAAE,GAAG;GAAO,MAAM,MAAM,QAAQ;GAAW,CAAC;EACpE,GACD,CAAC,UAAU,CACZ,EAGC,oBAAA,UAAA,EAAA,UACG,OAAO,KAAK,MAAM;EACjB,MAAM,gBAAgB,EAAE,SAAS;EACjC,MAAM,iBAAiB;AACrB,KAAE,MAAM,QAAQ;AAChB,eAAY,EAAE,GAAG;;EAEnB,MAAM,qBAAqB;AACzB,KAAE,MAAM,YAAY;AACpB,eAAY,EAAE,GAAG;;AAEnB,SACE,oBAAC,aAAD;GAEE,MAAM,EAAE;GACR,OAAO,EAAE,MAAM;GACf,UAAU,EAAE,MAAM;GAClB,MAAM,EAAE,MAAM,QAAQ,QAAQ,EAAE,QAAQ,OAAO;GAC/C,MAAM;GACN,UAAU;GACV,QAAQ,EAAE,MAAM;GAChB,YAAY,EAAE,MAAM;GACpB,eAAe,EAAE,MAAM;GACvB,mBAAmB,EAAE,MAAM;GAC3B,QAAQ,EAAE,MAAM,WAAW,gBAAgB,cAAc;GACzD,OAAO,EAAE,MAAM,SAAS;GACxB,WAAW,GAAG,aAAa,EAAE,MAAM,UAAU;GAC7C,UAAU,EAAE,MAAM;GAClB,cAAc,EAAE,MAAM;GACtB,MAAM,EAAE,MAAM;GACd,YAAY,EAAE;GACd,QACE,gBAAgB,SACd,oBAAC,gBAAD;IACE,MAAK;IACL,MAAK;IACL,GAAK,EAAE,MAAM,iBAAiB,EAAE;IAChC,SAAS;cAER,EAAE,MAAM,UAAU;IACZ,CAAA;aAIZ,EAAE,MAAM;GACG,EAhCP,EAAE,GAgCK;GAEhB,EACD,CAAA,CAGsB;;AAK7B,IAAM,QAAQ;AAWd,MAAM,QAAQ,UAAU,kBAAkB,QAAQ,MAAM;AACxD,MAAM,WAAW,UAAU,kBAAkB,WAAW,MAAM;AAC9D,MAAM,SAAS,UAAU,kBAAkB,SAAS,MAAM;AAC1D,MAAM,WAAW,UAAU,kBAAkB,WAAW,MAAM;AAC9D,MAAM,WAAW,UACf,kBAAkB,WAAW;CAAE,GAAG;CAAO,MAAM,MAAM,QAAQ;CAAW,CAAC;AAE3E,MAAM,mBAAmB;AACvB,QAAO,WAAW,QAAQ;EACxB,MAAM,QAAQ,WAAW,KAAK;AAC9B,MAAI,MAAO,QAAO;;;AAItB,MAAM,WAAW;AACjB,MAAM,eAAe"}
@@ -96,7 +96,7 @@ function Popconfirm(props) {
96
96
  side,
97
97
  align,
98
98
  sideOffset: 4,
99
- className: cn("ald-pop-confirm tw-z-50 tw-w-[240px] tw-rounded-[6px] tw-border tw-border-solid tw-border-[var(--border-default-alpha)] tw-bg-[var(--background-default)] tw-p-3 tw-outline-none", rootClassName, overlayClassName),
99
+ className: cn("ald-pop-confirm tw-z-50 tw-w-[240px] tw-rounded-[6px] tw-border tw-border-solid tw-border-[var(--border-default-alpha)] tw-bg-[var(--background-floating)] tw-p-3 tw-outline-none", rootClassName, overlayClassName),
100
100
  style: {
101
101
  zIndex: popupZIndex,
102
102
  boxShadow: "var(--elevation-bottom-bottom-md)"
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Popconfirm/index.tsx"],"sourcesContent":["import * as PopoverPrimitive from '@radix-ui/react-popover';\nimport React, { useState } from 'react';\nimport Button, { ButtonType, IButtonProps } from '../Button';\nimport { AttentionTriangleFill } from '../Icon';\nimport { useFloatingPopupZIndex } from '../_utils/floatingLayer';\nimport { cn } from '../lib/utils';\n\nexport interface PopconfirmProps {\n title?: React.ReactNode;\n onConfirm?: (e?: React.MouseEvent) => void;\n onCancel?: (e?: React.MouseEvent) => void;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n icon?: React.ReactNode;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n placement?:\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight'\n | 'leftTop'\n | 'leftBottom'\n | 'rightTop'\n | 'rightBottom';\n rootClassName?: string;\n className?: string;\n overlayClassName?: string;\n getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;\n children?: React.ReactNode;\n disabled?: boolean;\n}\n\nconst sideMap: Record<string, PopoverPrimitive.PopoverContentProps['side']> = {\n top: 'top',\n bottom: 'bottom',\n left: 'left',\n right: 'right',\n topLeft: 'top',\n topRight: 'top',\n bottomLeft: 'bottom',\n bottomRight: 'bottom',\n leftTop: 'left',\n leftBottom: 'left',\n rightTop: 'right',\n rightBottom: 'right',\n};\n\nconst alignMap: Record<string, PopoverPrimitive.PopoverContentProps['align']> =\n {\n topLeft: 'start',\n topRight: 'end',\n bottomLeft: 'start',\n bottomRight: 'end',\n leftTop: 'start',\n leftBottom: 'end',\n rightTop: 'start',\n rightBottom: 'end',\n };\n\nfunction Popconfirm(props: PopconfirmProps) {\n const {\n title,\n onConfirm,\n onCancel,\n okText = 'OK',\n cancelText = 'Cancel',\n okButtonProps = {},\n cancelButtonProps = {},\n okType = 'dangerous',\n icon = (\n <AttentionTriangleFill\n size={16}\n color=\"var(--action-destructive-normal)\"\n fill=\"var(--action-inverted-normal)\"\n />\n ),\n open: controlledOpen,\n onOpenChange,\n placement = 'top',\n rootClassName,\n overlayClassName,\n getPopupContainer,\n children,\n disabled,\n } = props;\n\n const [innerOpen, setInnerOpen] = useState(false);\n const triggerRef = React.useRef<HTMLElement | null>(null);\n const getPopupContainerRef = React.useRef(getPopupContainer);\n const lastGetPopupContainerRef = React.useRef(getPopupContainer);\n const [popupContainer, setPopupContainer] = useState<\n HTMLElement | undefined\n >();\n getPopupContainerRef.current = getPopupContainer;\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : innerOpen;\n const mergedOpen = disabled ? false : isOpen;\n const updatePopupContainer = React.useCallback((node: HTMLElement | null) => {\n const nextContainer =\n node && getPopupContainerRef.current\n ? getPopupContainerRef.current(node)\n : undefined;\n setPopupContainer((prevContainer) =>\n prevContainer === nextContainer ? prevContainer : nextContainer,\n );\n }, []);\n const setTriggerNode = React.useCallback(\n (node: HTMLElement | null) => {\n if (!node) return;\n if (triggerRef.current === node) return;\n triggerRef.current = node;\n updatePopupContainer(node);\n },\n [updatePopupContainer],\n );\n\n React.useEffect(() => {\n if (lastGetPopupContainerRef.current === getPopupContainer) return;\n lastGetPopupContainerRef.current = getPopupContainer;\n updatePopupContainer(triggerRef.current);\n }, [getPopupContainer, updatePopupContainer]);\n\n const handleOpenChange = (val: boolean) => {\n if (disabled) return;\n if (!isControlled) setInnerOpen(val);\n onOpenChange?.(val);\n };\n\n const handleConfirm = (e?: React.MouseEvent) => {\n onConfirm?.(e);\n handleOpenChange(false);\n };\n\n const handleCancel = (e?: React.MouseEvent) => {\n onCancel?.(e);\n handleOpenChange(false);\n };\n\n const side = sideMap[placement] || 'top';\n const align = alignMap[placement] || 'center';\n const popupZIndex = useFloatingPopupZIndex();\n const idBase = React.useId().replace(/:/g, '');\n const contentId = `ald-popconfirm-${idBase}`;\n const titleId = `ald-popconfirm-title-${idBase}`;\n const triggerChild = React.isValidElement(children) ? (\n React.cloneElement(children as React.ReactElement, {\n 'aria-controls': contentId,\n })\n ) : (\n <span>{children}</span>\n );\n\n return (\n <PopoverPrimitive.Root\n open={mergedOpen}\n onOpenChange={handleOpenChange}\n modal={false}\n >\n <PopoverPrimitive.Trigger asChild ref={setTriggerNode}>\n {triggerChild}\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={popupContainer}>\n <PopoverPrimitive.Content\n id={contentId}\n role=\"region\"\n aria-labelledby={title ? titleId : undefined}\n side={side}\n align={align}\n sideOffset={4}\n className={cn(\n 'ald-pop-confirm tw-z-50 tw-w-[240px] tw-rounded-[6px] tw-border tw-border-solid tw-border-[var(--border-default-alpha)] tw-bg-[var(--background-default)] tw-p-3 tw-outline-none',\n rootClassName,\n overlayClassName,\n )}\n style={{\n zIndex: popupZIndex,\n boxShadow: 'var(--elevation-bottom-bottom-md)',\n }}\n >\n <div className=\"tw-flex tw-gap-2\">\n {icon && <span className=\"tw-mt-0.5 tw-shrink-0\">{icon}</span>}\n <div className=\"tw-flex-1\">\n <div\n id={titleId}\n className=\"tw-mb-2 tw-break-all tw-text-xs tw-leading-4 tw-text-[var(--content-primary)]\"\n >\n {title}\n </div>\n <div className=\"tw-flex tw-justify-end tw-gap-2\">\n <Button\n type=\"secondary\"\n size=\"small\"\n {...cancelButtonProps}\n onClick={handleCancel}\n >\n {cancelText}\n </Button>\n <Button\n type={okType}\n size=\"small\"\n {...okButtonProps}\n onClick={handleConfirm}\n >\n {okText}\n </Button>\n </div>\n </div>\n </div>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n}\n\nexport default Popconfirm;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Popconfirm/index.tsx"],"sourcesContent":["import * as PopoverPrimitive from '@radix-ui/react-popover';\nimport React, { useState } from 'react';\nimport Button, { ButtonType, IButtonProps } from '../Button';\nimport { AttentionTriangleFill } from '../Icon';\nimport { useFloatingPopupZIndex } from '../_utils/floatingLayer';\nimport { cn } from '../lib/utils';\n\nexport interface PopconfirmProps {\n title?: React.ReactNode;\n onConfirm?: (e?: React.MouseEvent) => void;\n onCancel?: (e?: React.MouseEvent) => void;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n icon?: React.ReactNode;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n placement?:\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight'\n | 'leftTop'\n | 'leftBottom'\n | 'rightTop'\n | 'rightBottom';\n rootClassName?: string;\n className?: string;\n overlayClassName?: string;\n getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;\n children?: React.ReactNode;\n disabled?: boolean;\n}\n\nconst sideMap: Record<string, PopoverPrimitive.PopoverContentProps['side']> = {\n top: 'top',\n bottom: 'bottom',\n left: 'left',\n right: 'right',\n topLeft: 'top',\n topRight: 'top',\n bottomLeft: 'bottom',\n bottomRight: 'bottom',\n leftTop: 'left',\n leftBottom: 'left',\n rightTop: 'right',\n rightBottom: 'right',\n};\n\nconst alignMap: Record<string, PopoverPrimitive.PopoverContentProps['align']> =\n {\n topLeft: 'start',\n topRight: 'end',\n bottomLeft: 'start',\n bottomRight: 'end',\n leftTop: 'start',\n leftBottom: 'end',\n rightTop: 'start',\n rightBottom: 'end',\n };\n\nfunction Popconfirm(props: PopconfirmProps) {\n const {\n title,\n onConfirm,\n onCancel,\n okText = 'OK',\n cancelText = 'Cancel',\n okButtonProps = {},\n cancelButtonProps = {},\n okType = 'dangerous',\n icon = (\n <AttentionTriangleFill\n size={16}\n color=\"var(--action-destructive-normal)\"\n fill=\"var(--action-inverted-normal)\"\n />\n ),\n open: controlledOpen,\n onOpenChange,\n placement = 'top',\n rootClassName,\n overlayClassName,\n getPopupContainer,\n children,\n disabled,\n } = props;\n\n const [innerOpen, setInnerOpen] = useState(false);\n const triggerRef = React.useRef<HTMLElement | null>(null);\n const getPopupContainerRef = React.useRef(getPopupContainer);\n const lastGetPopupContainerRef = React.useRef(getPopupContainer);\n const [popupContainer, setPopupContainer] = useState<\n HTMLElement | undefined\n >();\n getPopupContainerRef.current = getPopupContainer;\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : innerOpen;\n const mergedOpen = disabled ? false : isOpen;\n const updatePopupContainer = React.useCallback((node: HTMLElement | null) => {\n const nextContainer =\n node && getPopupContainerRef.current\n ? getPopupContainerRef.current(node)\n : undefined;\n setPopupContainer((prevContainer) =>\n prevContainer === nextContainer ? prevContainer : nextContainer,\n );\n }, []);\n const setTriggerNode = React.useCallback(\n (node: HTMLElement | null) => {\n if (!node) return;\n if (triggerRef.current === node) return;\n triggerRef.current = node;\n updatePopupContainer(node);\n },\n [updatePopupContainer],\n );\n\n React.useEffect(() => {\n if (lastGetPopupContainerRef.current === getPopupContainer) return;\n lastGetPopupContainerRef.current = getPopupContainer;\n updatePopupContainer(triggerRef.current);\n }, [getPopupContainer, updatePopupContainer]);\n\n const handleOpenChange = (val: boolean) => {\n if (disabled) return;\n if (!isControlled) setInnerOpen(val);\n onOpenChange?.(val);\n };\n\n const handleConfirm = (e?: React.MouseEvent) => {\n onConfirm?.(e);\n handleOpenChange(false);\n };\n\n const handleCancel = (e?: React.MouseEvent) => {\n onCancel?.(e);\n handleOpenChange(false);\n };\n\n const side = sideMap[placement] || 'top';\n const align = alignMap[placement] || 'center';\n const popupZIndex = useFloatingPopupZIndex();\n const idBase = React.useId().replace(/:/g, '');\n const contentId = `ald-popconfirm-${idBase}`;\n const titleId = `ald-popconfirm-title-${idBase}`;\n const triggerChild = React.isValidElement(children) ? (\n React.cloneElement(children as React.ReactElement, {\n 'aria-controls': contentId,\n })\n ) : (\n <span>{children}</span>\n );\n\n return (\n <PopoverPrimitive.Root\n open={mergedOpen}\n onOpenChange={handleOpenChange}\n modal={false}\n >\n <PopoverPrimitive.Trigger asChild ref={setTriggerNode}>\n {triggerChild}\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={popupContainer}>\n <PopoverPrimitive.Content\n id={contentId}\n role=\"region\"\n aria-labelledby={title ? titleId : undefined}\n side={side}\n align={align}\n sideOffset={4}\n className={cn(\n 'ald-pop-confirm tw-z-50 tw-w-[240px] tw-rounded-[6px] tw-border tw-border-solid tw-border-[var(--border-default-alpha)] tw-bg-[var(--background-floating)] tw-p-3 tw-outline-none',\n rootClassName,\n overlayClassName,\n )}\n style={{\n zIndex: popupZIndex,\n boxShadow: 'var(--elevation-bottom-bottom-md)',\n }}\n >\n <div className=\"tw-flex tw-gap-2\">\n {icon && <span className=\"tw-mt-0.5 tw-shrink-0\">{icon}</span>}\n <div className=\"tw-flex-1\">\n <div\n id={titleId}\n className=\"tw-mb-2 tw-break-all tw-text-xs tw-leading-4 tw-text-[var(--content-primary)]\"\n >\n {title}\n </div>\n <div className=\"tw-flex tw-justify-end tw-gap-2\">\n <Button\n type=\"secondary\"\n size=\"small\"\n {...cancelButtonProps}\n onClick={handleCancel}\n >\n {cancelText}\n </Button>\n <Button\n type={okType}\n size=\"small\"\n {...okButtonProps}\n onClick={handleConfirm}\n >\n {okText}\n </Button>\n </div>\n </div>\n </div>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n}\n\nexport default Popconfirm;\n"],"mappings":"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"}
@@ -142,7 +142,7 @@ function Popover(props) {
142
142
  align,
143
143
  sideOffset,
144
144
  alignOffset,
145
- className: cn("ald-popover ant-popover-inner tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-default-alpha)] tw-bg-[var(--background-default)] tw-p-3 tw-outline-none", "tw-animate-in tw-fade-in-0 tw-zoom-in-95", overlayClassName),
145
+ className: cn("ald-popover ant-popover-inner tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-default-alpha)] tw-bg-[var(--background-floating)] tw-p-3 tw-outline-none", "tw-animate-in tw-fade-in-0 tw-zoom-in-95", overlayClassName),
146
146
  style: {
147
147
  boxShadow: "var(--elevation-bottom-bottom-sm)",
148
148
  backgroundColor: color,
@@ -165,7 +165,7 @@ function Popover(props) {
165
165
  className: "ald-popover-inner-content ant-popover-inner-content",
166
166
  children: content
167
167
  }),
168
- arrow && /* @__PURE__ */ jsx(PopoverPrimitive.Arrow, { style: { fill: "var(--background-default)" } })
168
+ arrow && /* @__PURE__ */ jsx(PopoverPrimitive.Arrow, { style: { fill: color || "var(--background-floating)" } })
169
169
  ]
170
170
  })
171
171
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Popover/index.tsx"],"sourcesContent":["import * as PopoverPrimitive from '@radix-ui/react-popover';\nimport React from 'react';\nimport { useFloatingPopupZIndex } from '../_utils/floatingLayer';\nimport { cn } from '../lib/utils';\n\ntype TriggerType = 'hover' | 'click' | 'focus';\n\nconst interactiveRoles = new Set([\n 'button',\n 'checkbox',\n 'combobox',\n 'link',\n 'menuitem',\n 'option',\n 'radio',\n 'searchbox',\n 'slider',\n 'spinbutton',\n 'switch',\n 'tab',\n 'textbox',\n]);\n\nfunction hasInteractiveContent(node: React.ReactNode): boolean {\n return React.Children.toArray(node).some((child) => {\n if (!React.isValidElement(child)) return false;\n\n if (typeof child.type === 'string') {\n if (\n ['a', 'button', 'input', 'select', 'textarea', 'summary'].includes(\n child.type,\n )\n ) {\n return true;\n }\n\n if (interactiveRoles.has(child.props.role)) return true;\n if (\n typeof child.props.tabIndex === 'number' &&\n child.props.tabIndex >= 0\n ) {\n return true;\n }\n }\n\n return hasInteractiveContent(child.props.children);\n });\n}\n\nexport interface PopoverProps {\n content?: React.ReactNode;\n title?: React.ReactNode;\n children?: React.ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: TriggerType | TriggerType[];\n rootClassName?: string;\n placement?:\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight'\n | 'leftTop'\n | 'leftBottom'\n | 'rightTop'\n | 'rightBottom';\n overlayClassName?: string;\n overlayStyle?: React.CSSProperties;\n overlayInnerStyle?: React.CSSProperties;\n color?: string;\n align?: {\n offset?: [number, number];\n [key: string]: any;\n };\n arrow?: boolean;\n mouseEnterDelay?: number;\n mouseLeaveDelay?: number;\n className?: string;\n style?: React.CSSProperties;\n getPopupContainer?: () => HTMLElement;\n zIndex?: number;\n}\n\nconst placementMap: Record<\n string,\n PopoverPrimitive.PopoverContentProps['side']\n> = {\n top: 'top',\n bottom: 'bottom',\n left: 'left',\n right: 'right',\n topLeft: 'top',\n topRight: 'top',\n bottomLeft: 'bottom',\n bottomRight: 'bottom',\n leftTop: 'left',\n leftBottom: 'left',\n rightTop: 'right',\n rightBottom: 'right',\n};\n\nconst alignMap: Record<string, PopoverPrimitive.PopoverContentProps['align']> =\n {\n topLeft: 'start',\n topRight: 'end',\n bottomLeft: 'start',\n bottomRight: 'end',\n leftTop: 'start',\n leftBottom: 'end',\n rightTop: 'start',\n rightBottom: 'end',\n };\n\nconst DEFAULT_SIDE_OFFSET = 4;\n\nfunction normalizeTrigger(trigger: PopoverProps['trigger']): Set<TriggerType> {\n if (Array.isArray(trigger)) return new Set(trigger);\n if (trigger) return new Set([trigger]);\n return new Set<TriggerType>(['hover']);\n}\n\nfunction getPopoverOffsets(\n side: PopoverPrimitive.PopoverContentProps['side'],\n offset?: [number, number],\n) {\n if (!offset) {\n return {\n alignOffset: undefined,\n sideOffset: DEFAULT_SIDE_OFFSET,\n };\n }\n\n const [x = 0, y = 0] = offset;\n switch (side) {\n case 'left':\n return {\n alignOffset: y,\n sideOffset: -x,\n };\n case 'right':\n return {\n alignOffset: y,\n sideOffset: x,\n };\n case 'bottom':\n return {\n alignOffset: x,\n sideOffset: y,\n };\n case 'top':\n default:\n return {\n alignOffset: x,\n sideOffset: -y,\n };\n }\n}\n\nfunction Popover(props: PopoverProps) {\n const {\n content,\n title,\n children,\n open,\n defaultOpen,\n onOpenChange,\n trigger = 'hover',\n placement = 'top',\n overlayClassName,\n overlayStyle,\n overlayInnerStyle,\n color,\n align: popupAlign,\n arrow = false,\n getPopupContainer,\n zIndex,\n } = props;\n\n const containerRef = React.useRef<HTMLElement | undefined>(\n getPopupContainer?.(),\n );\n\n const [hoverOpen, setHoverOpen] = React.useState(false);\n const triggers = normalizeTrigger(trigger);\n const idBase = React.useId().replace(/:/g, '');\n const contentId = `ald-popover-${idBase}`;\n const titleId = `ald-popover-title-${idBase}`;\n\n const isControlled = open !== undefined;\n const isHoverTrigger = triggers.has('hover');\n const isOpen = isControlled\n ? open\n : isHoverTrigger\n ? hoverOpen\n : triggers.size === 0\n ? false\n : undefined;\n\n const handleOpenChange = (val: boolean) => {\n if (!isControlled && isHoverTrigger) {\n setHoverOpen(val);\n }\n onOpenChange?.(val);\n };\n\n const side = placementMap[placement] || 'top';\n const align = alignMap[placement] || 'center';\n const popupZIndex = useFloatingPopupZIndex(zIndex);\n const { alignOffset, sideOffset } = getPopoverOffsets(\n side,\n popupAlign?.offset,\n );\n\n const triggerChild = React.isValidElement(children) ? (\n React.cloneElement(children as React.ReactElement, {\n 'aria-controls': contentId,\n 'aria-haspopup': false,\n })\n ) : (\n <span aria-controls={contentId} aria-haspopup={false}>\n {children}\n </span>\n );\n\n if (triggers.size === 0 && !isControlled) {\n return <>{children}</>;\n }\n\n return (\n <PopoverPrimitive.Root\n open={isOpen}\n defaultOpen={defaultOpen}\n onOpenChange={handleOpenChange}\n modal={false}\n >\n <PopoverPrimitive.Trigger asChild>\n {isHoverTrigger ? (\n <span\n onMouseEnter={() => handleOpenChange(true)}\n onMouseLeave={() => handleOpenChange(false)}\n >\n {triggerChild}\n </span>\n ) : (\n triggerChild\n )}\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={containerRef.current}>\n <PopoverPrimitive.Content\n id={contentId}\n role=\"region\"\n aria-labelledby={title ? titleId : undefined}\n side={side}\n align={align}\n sideOffset={sideOffset}\n alignOffset={alignOffset}\n // antd 兼容:保留 ant-popover-inner class,消费方 CSS 可能通过该选择器自定义内边距、背景等样式\n className={cn(\n 'ald-popover ant-popover-inner tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-default-alpha)] tw-bg-[var(--background-default)] tw-p-3 tw-outline-none',\n 'tw-animate-in tw-fade-in-0 tw-zoom-in-95',\n overlayClassName,\n )}\n style={{\n boxShadow: 'var(--elevation-bottom-bottom-sm)',\n backgroundColor: color,\n zIndex: popupZIndex,\n ...overlayStyle,\n ...overlayInnerStyle,\n }}\n onOpenAutoFocus={(event) => {\n if (!hasInteractiveContent(content)) {\n event.preventDefault();\n }\n }}\n onMouseEnter={\n isHoverTrigger ? () => handleOpenChange(true) : undefined\n }\n onMouseLeave={\n isHoverTrigger ? () => handleOpenChange(false) : undefined\n }\n >\n {title && (\n <div\n id={titleId}\n className=\"ald-popover-title tw-mb-2 tw-text-sm tw-font-medium tw-text-[var(--content-primary)]\"\n >\n {title}\n </div>\n )}\n {content && (\n // antd 兼容:保留 ant-popover-inner-content class,消费方 CSS 可能通过该选择器自定义样式\n <div className=\"ald-popover-inner-content ant-popover-inner-content\">\n {content}\n </div>\n )}\n {arrow && (\n <PopoverPrimitive.Arrow\n style={{ fill: 'var(--background-default)' }}\n />\n )}\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n}\n\nexport default Popover;\n"],"mappings":";;;;;;AAOA,IAAM,mBAAmB,IAAI,IAAI;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,SAAS,sBAAsB,MAAgC;AAC7D,QAAO,MAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,UAAU;AAClD,MAAI,CAAC,MAAM,eAAe,MAAM,CAAE,QAAO;AAEzC,MAAI,OAAO,MAAM,SAAS,UAAU;AAClC,OACE;IAAC;IAAK;IAAU;IAAS;IAAU;IAAY;IAAU,CAAC,SACxD,MAAM,KACP,CAED,QAAO;AAGT,OAAI,iBAAiB,IAAI,MAAM,MAAM,KAAK,CAAE,QAAO;AACnD,OACE,OAAO,MAAM,MAAM,aAAa,YAChC,MAAM,MAAM,YAAY,EAExB,QAAO;;AAIX,SAAO,sBAAsB,MAAM,MAAM,SAAS;GAClD;;AA0CJ,IAAM,eAGF;CACF,KAAK;CACL,QAAQ;CACR,MAAM;CACN,OAAO;CACP,SAAS;CACT,UAAU;CACV,YAAY;CACZ,aAAa;CACb,SAAS;CACT,YAAY;CACZ,UAAU;CACV,aAAa;CACd;AAED,IAAM,WACJ;CACE,SAAS;CACT,UAAU;CACV,YAAY;CACZ,aAAa;CACb,SAAS;CACT,YAAY;CACZ,UAAU;CACV,aAAa;CACd;AAEH,IAAM,sBAAsB;AAE5B,SAAS,iBAAiB,SAAoD;AAC5E,KAAI,MAAM,QAAQ,QAAQ,CAAE,QAAO,IAAI,IAAI,QAAQ;AACnD,KAAI,QAAS,QAAO,IAAI,IAAI,CAAC,QAAQ,CAAC;AACtC,QAAO,IAAI,IAAiB,CAAC,QAAQ,CAAC;;AAGxC,SAAS,kBACP,MACA,QACA;AACA,KAAI,CAAC,OACH,QAAO;EACL,aAAa;EACb,YAAY;EACb;CAGH,MAAM,CAAC,IAAI,GAAG,IAAI,KAAK;AACvB,SAAQ,MAAR;EACE,KAAK,OACH,QAAO;GACL,aAAa;GACb,YAAY,CAAC;GACd;EACH,KAAK,QACH,QAAO;GACL,aAAa;GACb,YAAY;GACb;EACH,KAAK,SACH,QAAO;GACL,aAAa;GACb,YAAY;GACb;EAEH,QACE,QAAO;GACL,aAAa;GACb,YAAY,CAAC;GACd;;;AAIP,SAAS,QAAQ,OAAqB;CACpC,MAAM,EACJ,SACA,OACA,UACA,MACA,aACA,cACA,UAAU,SACV,YAAY,OACZ,kBACA,cACA,mBACA,OACA,OAAO,YACP,QAAQ,OACR,mBACA,WACE;CAEJ,MAAM,eAAe,MAAM,OACzB,qBAAqB,CACtB;CAED,MAAM,CAAC,WAAW,gBAAgB,MAAM,SAAS,MAAM;CACvD,MAAM,WAAW,iBAAiB,QAAQ;CAC1C,MAAM,SAAS,MAAM,OAAO,CAAC,QAAQ,MAAM,GAAG;CAC9C,MAAM,YAAY,eAAe;CACjC,MAAM,UAAU,qBAAqB;CAErC,MAAM,eAAe,SAAS;CAC9B,MAAM,iBAAiB,SAAS,IAAI,QAAQ;CAC5C,MAAM,SAAS,eACX,OACA,iBACA,YACA,SAAS,SAAS,IAClB,QACA;CAEJ,MAAM,oBAAoB,QAAiB;AACzC,MAAI,CAAC,gBAAgB,eACnB,cAAa,IAAI;AAEnB,iBAAe,IAAI;;CAGrB,MAAM,OAAO,aAAa,cAAc;CACxC,MAAM,QAAQ,SAAS,cAAc;CACrC,MAAM,cAAc,uBAAuB,OAAO;CAClD,MAAM,EAAE,aAAa,eAAe,kBAClC,MACA,YAAY,OACb;CAED,MAAM,eAAe,MAAM,eAAe,SAAS,GACjD,MAAM,aAAa,UAAgC;EACjD,iBAAiB;EACjB,iBAAiB;EAClB,CAAC,GAEF,oBAAC,QAAD;EAAM,iBAAe;EAAW,iBAAe;EAC5C;EACI,CAAA;AAGT,KAAI,SAAS,SAAS,KAAK,CAAC,aAC1B,QAAO,oBAAA,UAAA,EAAG,UAAY,CAAA;AAGxB,QACE,qBAAC,iBAAiB,MAAlB;EACE,MAAM;EACO;EACb,cAAc;EACd,OAAO;YAJT,CAME,oBAAC,iBAAiB,SAAlB;GAA0B,SAAA;aACvB,iBACC,oBAAC,QAAD;IACE,oBAAoB,iBAAiB,KAAK;IAC1C,oBAAoB,iBAAiB,MAAM;cAE1C;IACI,CAAA,GAEP;GAEuB,CAAA,EAC3B,oBAAC,iBAAiB,QAAlB;GAAyB,WAAW,aAAa;aAC/C,qBAAC,iBAAiB,SAAlB;IACE,IAAI;IACJ,MAAK;IACL,mBAAiB,QAAQ,UAAU;IAC7B;IACC;IACK;IACC;IAEb,WAAW,GACT,4KACA,4CACA,iBACD;IACD,OAAO;KACL,WAAW;KACX,iBAAiB;KACjB,QAAQ;KACR,GAAG;KACH,GAAG;KACJ;IACD,kBAAkB,UAAU;AAC1B,SAAI,CAAC,sBAAsB,QAAQ,CACjC,OAAM,gBAAgB;;IAG1B,cACE,uBAAuB,iBAAiB,KAAK,GAAG;IAElD,cACE,uBAAuB,iBAAiB,MAAM,GAAG;cA9BrD;KAiCG,SACC,oBAAC,OAAD;MACE,IAAI;MACJ,WAAU;gBAET;MACG,CAAA;KAEP,WAEC,oBAAC,OAAD;MAAK,WAAU;gBACZ;MACG,CAAA;KAEP,SACC,oBAAC,iBAAiB,OAAlB,EACE,OAAO,EAAE,MAAM,6BAA6B,EAC5C,CAAA;KAEqB;;GACH,CAAA,CACJ"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Popover/index.tsx"],"sourcesContent":["import * as PopoverPrimitive from '@radix-ui/react-popover';\nimport React from 'react';\nimport { useFloatingPopupZIndex } from '../_utils/floatingLayer';\nimport { cn } from '../lib/utils';\n\ntype TriggerType = 'hover' | 'click' | 'focus';\n\nconst interactiveRoles = new Set([\n 'button',\n 'checkbox',\n 'combobox',\n 'link',\n 'menuitem',\n 'option',\n 'radio',\n 'searchbox',\n 'slider',\n 'spinbutton',\n 'switch',\n 'tab',\n 'textbox',\n]);\n\nfunction hasInteractiveContent(node: React.ReactNode): boolean {\n return React.Children.toArray(node).some((child) => {\n if (!React.isValidElement(child)) return false;\n\n if (typeof child.type === 'string') {\n if (\n ['a', 'button', 'input', 'select', 'textarea', 'summary'].includes(\n child.type,\n )\n ) {\n return true;\n }\n\n if (interactiveRoles.has(child.props.role)) return true;\n if (\n typeof child.props.tabIndex === 'number' &&\n child.props.tabIndex >= 0\n ) {\n return true;\n }\n }\n\n return hasInteractiveContent(child.props.children);\n });\n}\n\nexport interface PopoverProps {\n content?: React.ReactNode;\n title?: React.ReactNode;\n children?: React.ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: TriggerType | TriggerType[];\n rootClassName?: string;\n placement?:\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight'\n | 'leftTop'\n | 'leftBottom'\n | 'rightTop'\n | 'rightBottom';\n overlayClassName?: string;\n overlayStyle?: React.CSSProperties;\n overlayInnerStyle?: React.CSSProperties;\n color?: string;\n align?: {\n offset?: [number, number];\n [key: string]: any;\n };\n arrow?: boolean;\n mouseEnterDelay?: number;\n mouseLeaveDelay?: number;\n className?: string;\n style?: React.CSSProperties;\n getPopupContainer?: () => HTMLElement;\n zIndex?: number;\n}\n\nconst placementMap: Record<\n string,\n PopoverPrimitive.PopoverContentProps['side']\n> = {\n top: 'top',\n bottom: 'bottom',\n left: 'left',\n right: 'right',\n topLeft: 'top',\n topRight: 'top',\n bottomLeft: 'bottom',\n bottomRight: 'bottom',\n leftTop: 'left',\n leftBottom: 'left',\n rightTop: 'right',\n rightBottom: 'right',\n};\n\nconst alignMap: Record<string, PopoverPrimitive.PopoverContentProps['align']> =\n {\n topLeft: 'start',\n topRight: 'end',\n bottomLeft: 'start',\n bottomRight: 'end',\n leftTop: 'start',\n leftBottom: 'end',\n rightTop: 'start',\n rightBottom: 'end',\n };\n\nconst DEFAULT_SIDE_OFFSET = 4;\n\nfunction normalizeTrigger(trigger: PopoverProps['trigger']): Set<TriggerType> {\n if (Array.isArray(trigger)) return new Set(trigger);\n if (trigger) return new Set([trigger]);\n return new Set<TriggerType>(['hover']);\n}\n\nfunction getPopoverOffsets(\n side: PopoverPrimitive.PopoverContentProps['side'],\n offset?: [number, number],\n) {\n if (!offset) {\n return {\n alignOffset: undefined,\n sideOffset: DEFAULT_SIDE_OFFSET,\n };\n }\n\n const [x = 0, y = 0] = offset;\n switch (side) {\n case 'left':\n return {\n alignOffset: y,\n sideOffset: -x,\n };\n case 'right':\n return {\n alignOffset: y,\n sideOffset: x,\n };\n case 'bottom':\n return {\n alignOffset: x,\n sideOffset: y,\n };\n case 'top':\n default:\n return {\n alignOffset: x,\n sideOffset: -y,\n };\n }\n}\n\nfunction Popover(props: PopoverProps) {\n const {\n content,\n title,\n children,\n open,\n defaultOpen,\n onOpenChange,\n trigger = 'hover',\n placement = 'top',\n overlayClassName,\n overlayStyle,\n overlayInnerStyle,\n color,\n align: popupAlign,\n arrow = false,\n getPopupContainer,\n zIndex,\n } = props;\n\n const containerRef = React.useRef<HTMLElement | undefined>(\n getPopupContainer?.(),\n );\n\n const [hoverOpen, setHoverOpen] = React.useState(false);\n const triggers = normalizeTrigger(trigger);\n const idBase = React.useId().replace(/:/g, '');\n const contentId = `ald-popover-${idBase}`;\n const titleId = `ald-popover-title-${idBase}`;\n\n const isControlled = open !== undefined;\n const isHoverTrigger = triggers.has('hover');\n const isOpen = isControlled\n ? open\n : isHoverTrigger\n ? hoverOpen\n : triggers.size === 0\n ? false\n : undefined;\n\n const handleOpenChange = (val: boolean) => {\n if (!isControlled && isHoverTrigger) {\n setHoverOpen(val);\n }\n onOpenChange?.(val);\n };\n\n const side = placementMap[placement] || 'top';\n const align = alignMap[placement] || 'center';\n const popupZIndex = useFloatingPopupZIndex(zIndex);\n const { alignOffset, sideOffset } = getPopoverOffsets(\n side,\n popupAlign?.offset,\n );\n\n const triggerChild = React.isValidElement(children) ? (\n React.cloneElement(children as React.ReactElement, {\n 'aria-controls': contentId,\n 'aria-haspopup': false,\n })\n ) : (\n <span aria-controls={contentId} aria-haspopup={false}>\n {children}\n </span>\n );\n\n if (triggers.size === 0 && !isControlled) {\n return <>{children}</>;\n }\n\n return (\n <PopoverPrimitive.Root\n open={isOpen}\n defaultOpen={defaultOpen}\n onOpenChange={handleOpenChange}\n modal={false}\n >\n <PopoverPrimitive.Trigger asChild>\n {isHoverTrigger ? (\n <span\n onMouseEnter={() => handleOpenChange(true)}\n onMouseLeave={() => handleOpenChange(false)}\n >\n {triggerChild}\n </span>\n ) : (\n triggerChild\n )}\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={containerRef.current}>\n <PopoverPrimitive.Content\n id={contentId}\n role=\"region\"\n aria-labelledby={title ? titleId : undefined}\n side={side}\n align={align}\n sideOffset={sideOffset}\n alignOffset={alignOffset}\n // antd 兼容:保留 ant-popover-inner class,消费方 CSS 可能通过该选择器自定义内边距、背景等样式\n className={cn(\n 'ald-popover ant-popover-inner tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-default-alpha)] tw-bg-[var(--background-floating)] tw-p-3 tw-outline-none',\n 'tw-animate-in tw-fade-in-0 tw-zoom-in-95',\n overlayClassName,\n )}\n style={{\n boxShadow: 'var(--elevation-bottom-bottom-sm)',\n backgroundColor: color,\n zIndex: popupZIndex,\n ...overlayStyle,\n ...overlayInnerStyle,\n }}\n onOpenAutoFocus={(event) => {\n if (!hasInteractiveContent(content)) {\n event.preventDefault();\n }\n }}\n onMouseEnter={\n isHoverTrigger ? () => handleOpenChange(true) : undefined\n }\n onMouseLeave={\n isHoverTrigger ? () => handleOpenChange(false) : undefined\n }\n >\n {title && (\n <div\n id={titleId}\n className=\"ald-popover-title tw-mb-2 tw-text-sm tw-font-medium tw-text-[var(--content-primary)]\"\n >\n {title}\n </div>\n )}\n {content && (\n // antd 兼容:保留 ant-popover-inner-content class,消费方 CSS 可能通过该选择器自定义样式\n <div className=\"ald-popover-inner-content ant-popover-inner-content\">\n {content}\n </div>\n )}\n {arrow && (\n <PopoverPrimitive.Arrow\n style={{ fill: color || 'var(--background-floating)' }}\n />\n )}\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n}\n\nexport default Popover;\n"],"mappings":"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"}
@@ -186,10 +186,10 @@ function Tabs(props) {
186
186
  const closeLabel = typeof item.label === "string" || typeof item.label === "number" ? `Remove ${item.label}` : "Remove tab";
187
187
  return /* @__PURE__ */ jsxs("div", {
188
188
  className: cn("ald-tabs-tab ant-tabs-tab tw-relative tw-flex tw-shrink-0 tw-items-center tw-gap-2 tw-whitespace-nowrap tw-transition-colors", isVertical && "tw-w-full tw-self-stretch", isCard ? cn("tw-h-10 tw-rounded-t-[6px] tw-border tw-border-b-0 tw-border-solid tw-px-4 tw-text-sm tw-leading-5", "tw-gap-sp-75", isActive ? "tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-font-medium tw-text-[var(--content-brand-primary)]" : "tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-text-[var(--content-secondary)] hover:tw-text-inherit") : cn(size === "small" ? "tw-py-2 tw-text-xs tw-leading-4" : "tw-py-2.5 tw-text-sm tw-leading-5", monospace && "tw-justify-center", isActive ? "tw-font-medium tw-text-[var(--content-brand-primary)]" : "tw-font-medium tw-text-[var(--content-secondary)] hover:tw-text-inherit"), item.disabled && "tw-pointer-events-none tw-cursor-default tw-opacity-50", !item.disabled && [
189
- "has-[.ald-tabs-tab-trigger:focus-visible]:tw-shadow-[0_0_0_2px_var(--focus-ring)]",
189
+ "has-[.ald-tabs-tab-trigger:focus-visible]:tw-shadow-[inset_0_0_0_2px_var(--focus-ring)]",
190
190
  "forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline",
191
191
  "forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-2",
192
- "forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-offset-2",
192
+ "forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-offset-[-2px]",
193
193
  "forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-[Highlight]"
194
194
  ]),
195
195
  children: [
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Tabs/index.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../lib/utils';\nimport { ChevronLeftLine, ChevronRightLine, CloseLightLine } from '../Icon';\nimport TabPane from './TabPane';\n\nexport type TabsSize = 'default' | 'small';\n\ninterface TabItem {\n key: string;\n label: React.ReactNode;\n children?: React.ReactNode;\n disabled?: boolean;\n closable?: boolean;\n icon?: React.ReactNode;\n forceRender?: boolean;\n className?: string;\n}\n\nexport interface ITabsProps {\n size?: TabsSize;\n activeKey?: string;\n defaultActiveKey?: string;\n onChange?: (activeKey: string) => void;\n onTabClick?: (activeKey: string, e: React.MouseEvent) => void;\n destroyInactiveTabPane?: boolean;\n centered?: boolean;\n adaptHeight?: boolean;\n tabPosition?: 'left' | 'right' | 'top' | 'bottom';\n className?: string;\n children?: React.ReactNode;\n headerBackgroundColor?: string;\n monospace?: boolean;\n padding?: boolean | number;\n compact?: boolean;\n hasDividing?: boolean;\n items?: TabItem[];\n type?: 'line' | 'card' | 'editable-card';\n tabBarExtraContent?:\n | React.ReactNode\n | { left?: React.ReactNode; right?: React.ReactNode };\n onEdit?: (\n targetKey: string | React.MouseEvent | React.KeyboardEvent,\n action: 'add' | 'remove',\n ) => void;\n hideAdd?: boolean;\n style?: React.CSSProperties;\n tabBarStyle?: React.CSSProperties;\n popupClassName?: string;\n tabBarGutter?: number;\n moreIcon?: React.ReactNode;\n /** 透传到 Tabs 根容器的 data-testid,用于自动化测试定位 */\n 'data-testid'?: string;\n /** 透传到 tablist 的 aria-label,用于可访问性与自动化测试定位 */\n 'aria-label'?: string;\n}\n\nexport default function Tabs(props: ITabsProps) {\n const {\n size,\n className,\n adaptHeight,\n style = {},\n monospace: propsMonospace,\n tabPosition = 'top',\n padding: propsPadding = false,\n compact,\n hasDividing = true,\n items,\n activeKey: controlledActiveKey,\n defaultActiveKey,\n onChange,\n onTabClick,\n destroyInactiveTabPane,\n centered,\n tabBarExtraContent,\n headerBackgroundColor,\n children,\n type,\n onEdit,\n hideAdd,\n tabBarStyle,\n 'data-testid': dataTestId,\n 'aria-label': ariaLabel,\n } = props;\n\n const isEditable = type === 'editable-card';\n const isCard = type === 'card' || type === 'editable-card';\n\n // Derive items from children if not provided\n const resolvedItems: TabItem[] = useMemo(() => {\n if (items) return items;\n return React.Children.toArray(children)\n .filter(React.isValidElement)\n .map((child: any) => ({\n key: child.key || child.props.key || '',\n label: child.props.tab,\n children: child.props.children,\n disabled: child.props.disabled,\n closable: child.props.closable,\n forceRender: child.props.forceRender,\n }));\n }, [items, children]);\n\n const firstKey = resolvedItems[0]?.key || '';\n const [innerActiveKey, setInnerActiveKey] = useState(\n defaultActiveKey || firstKey,\n );\n const mergedActiveKey =\n controlledActiveKey !== undefined ? controlledActiveKey : innerActiveKey;\n const activeKey = resolvedItems.some((item) => item.key === mergedActiveKey)\n ? mergedActiveKey\n : firstKey;\n\n const tabsId = React.useId();\n const tabRefs = useRef<Record<string, HTMLDivElement | null>>({});\n const pendingFocusKeyRef = useRef<string | null>(null);\n const getPreferredFocusKey = useCallback(\n (items: TabItem[] = resolvedItems) =>\n items.find((item) => item.key === activeKey && !item.disabled)?.key ||\n items.find((item) => !item.disabled)?.key ||\n '',\n [activeKey, resolvedItems],\n );\n const [focusedKey, setFocusedKey] = useState(() => getPreferredFocusKey());\n\n const getTabId = (key: string) => `${tabsId}-tab-${key}`;\n const getPanelId = (key: string) => `${tabsId}-panel-${key}`;\n\n const focusTab = useCallback((key: string) => {\n setFocusedKey(key);\n tabRefs.current[key]?.focus();\n }, []);\n\n useEffect(() => {\n const pendingFocusKey = pendingFocusKeyRef.current;\n if (\n pendingFocusKey &&\n resolvedItems.some(\n (item) => item.key === pendingFocusKey && !item.disabled,\n )\n ) {\n pendingFocusKeyRef.current = null;\n focusTab(pendingFocusKey);\n return;\n }\n\n setFocusedKey((currentFocusedKey) => {\n const focusedItem = resolvedItems.find(\n (item) => item.key === currentFocusedKey,\n );\n return focusedItem && !focusedItem.disabled\n ? currentFocusedKey\n : getPreferredFocusKey();\n });\n }, [focusTab, getPreferredFocusKey, resolvedItems]);\n\n const activateTab = useCallback(\n (key: string) => {\n if (controlledActiveKey === undefined) {\n setInnerActiveKey(key);\n }\n onChange?.(key);\n },\n [controlledActiveKey, onChange],\n );\n\n const handleTabClick = (key: string, e: React.MouseEvent) => {\n setFocusedKey(key);\n activateTab(key);\n onTabClick?.(key, e);\n };\n\n const handleRemove = (key: string, e: React.MouseEvent) => {\n e.stopPropagation();\n const itemIndex = resolvedItems.findIndex((item) => item.key === key);\n const nextFocusableItem = [\n ...resolvedItems.slice(itemIndex + 1),\n ...resolvedItems.slice(0, itemIndex).reverse(),\n ].find((item) => !item.disabled);\n pendingFocusKeyRef.current = nextFocusableItem?.key || null;\n onEdit?.(key, 'remove');\n };\n\n const handleTabKeyDown = (\n item: TabItem,\n e: React.KeyboardEvent<HTMLDivElement>,\n ) => {\n const enabledItems = resolvedItems.filter(\n (candidate) => !candidate.disabled,\n );\n const currentIndex = enabledItems.findIndex(\n (candidate) => candidate.key === item.key,\n );\n if (currentIndex === -1) return;\n\n let nextIndex: number | undefined;\n if (\n (!isVertical && e.key === 'ArrowRight') ||\n (isVertical && e.key === 'ArrowDown')\n ) {\n nextIndex = (currentIndex + 1) % enabledItems.length;\n } else if (\n (!isVertical && e.key === 'ArrowLeft') ||\n (isVertical && e.key === 'ArrowUp')\n ) {\n nextIndex =\n (currentIndex - 1 + enabledItems.length) % enabledItems.length;\n } else if (e.key === 'Home') {\n nextIndex = 0;\n } else if (e.key === 'End') {\n nextIndex = enabledItems.length - 1;\n }\n\n if (nextIndex !== undefined) {\n e.preventDefault();\n focusTab(enabledItems[nextIndex].key);\n return;\n }\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n activateTab(item.key);\n }\n };\n\n const handleAdd = (e: React.MouseEvent) => {\n onEdit?.(e, 'add');\n };\n\n const monospace = tabPosition !== 'top' ? false : propsMonospace;\n const paddingVal = useMemo(() => {\n if (tabPosition !== 'top') return 0;\n if (typeof propsPadding === 'number') return propsPadding;\n if (typeof propsPadding === 'boolean' && propsPadding) return 20;\n return 0;\n }, [propsPadding, tabPosition]);\n\n const isTop = tabPosition === 'top';\n const isBottom = tabPosition === 'bottom';\n const isLeft = tabPosition === 'left';\n const isRight = tabPosition === 'right';\n const isVertical = tabPosition === 'left' || tabPosition === 'right';\n const rootDirectionClass = isRight\n ? 'tw-flex-row-reverse'\n : isLeft\n ? 'tw-flex-row'\n : isBottom\n ? 'tw-flex-col-reverse'\n : 'tw-flex-col';\n\n const extraLeft =\n tabBarExtraContent &&\n typeof tabBarExtraContent === 'object' &&\n 'left' in tabBarExtraContent\n ? tabBarExtraContent.left\n : null;\n const extraRight = tabBarExtraContent\n ? typeof tabBarExtraContent === 'object' && 'right' in tabBarExtraContent\n ? tabBarExtraContent.right\n : React.isValidElement(tabBarExtraContent)\n ? tabBarExtraContent\n : null\n : null;\n\n // Scroll state for overflow\n const navListRef = useRef<HTMLDivElement>(null);\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const checkScroll = useCallback(() => {\n const el = navListRef.current;\n if (!el || isVertical) {\n setCanScrollLeft(false);\n setCanScrollRight(false);\n return;\n }\n const { scrollLeft, scrollWidth, clientWidth } = el;\n setCanScrollLeft(scrollLeft > 1);\n setCanScrollRight(scrollLeft + clientWidth < scrollWidth - 1);\n }, [isVertical]);\n\n useEffect(() => {\n checkScroll();\n const el = navListRef.current;\n if (!el) return;\n // Use ResizeObserver to detect size changes\n let ro: ResizeObserver | undefined;\n if (typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(() => checkScroll());\n ro.observe(el);\n }\n el.addEventListener('scroll', checkScroll, { passive: true });\n return () => {\n el.removeEventListener('scroll', checkScroll);\n ro?.disconnect();\n };\n }, [checkScroll, resolvedItems.length]);\n\n const scrollBy = (delta: number) => {\n const el = navListRef.current;\n if (el) {\n el.scrollBy({ left: delta, behavior: 'smooth' });\n }\n };\n\n const showScrollButtons = canScrollLeft || canScrollRight;\n\n return (\n <div\n data-testid={dataTestId}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs ant-tabs tw-flex',\n rootDirectionClass,\n adaptHeight && 'ald-adapt-height tw-h-full',\n size !== 'small' && 'ald-tabs-default',\n monospace && 'ald-tabs-monospace',\n compact && 'ald-tabs-compact',\n !hasDividing && 'ald-tabs-no-dividing',\n className,\n )}\n style={\n {\n ...style,\n '--header-bg-color': headerBackgroundColor,\n '--tabs-padding': `${paddingVal}px`,\n } as React.CSSProperties\n }\n >\n {/* Tab nav */}\n <div\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-nav ant-tabs-nav tw-flex',\n isVertical ? 'tw-shrink-0 tw-items-stretch' : 'tw-items-center',\n isTop && 'tw-mb-5',\n isBottom && 'tw-mt-5',\n isTop &&\n hasDividing &&\n 'tw-border-0 tw-border-b tw-border-solid tw-border-b-[var(--border-default)]',\n isBottom &&\n hasDividing &&\n 'tw-border-0 tw-border-t tw-border-solid tw-border-t-[var(--border-default)]',\n isTop && compact && '!tw-mb-0',\n isBottom && compact && '!tw-mt-0',\n isLeft &&\n 'tw-flex-col tw-border-0 tw-border-r tw-border-solid tw-border-r-[var(--border-default)]',\n isRight &&\n 'tw-flex-col tw-border-0 tw-border-l tw-border-solid tw-border-l-[var(--border-default)]',\n )}\n style={\n headerBackgroundColor || tabBarStyle\n ? {\n ...tabBarStyle,\n ...(headerBackgroundColor\n ? { backgroundColor: headerBackgroundColor }\n : {}),\n }\n : undefined\n }\n >\n {extraLeft}\n\n {/* Scroll left button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-[var(--action-ghost-normal)] tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollLeft && 'tw-invisible',\n )}\n onClick={() => scrollBy(-200)}\n aria-label=\"Scroll tabs left\"\n >\n <ChevronLeftLine size={16} />\n </button>\n )}\n\n <div\n className={cn(\n 'ald-tabs-nav-wrap ant-tabs-nav-wrap',\n isVertical\n ? 'tw-w-full tw-shrink-0 tw-self-stretch'\n : 'tw-min-w-0 tw-flex-1',\n )}\n style={paddingVal ? { margin: `0 ${paddingVal}px` } : undefined}\n >\n <div\n ref={navListRef}\n role=\"tablist\"\n aria-label={ariaLabel}\n aria-orientation={isVertical ? 'vertical' : 'horizontal'}\n onBlur={(e) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) {\n setFocusedKey(getPreferredFocusKey());\n }\n }}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-nav-list ant-tabs-nav-list tw-flex tw-overflow-hidden',\n isVertical && 'tw-w-full tw-shrink-0 tw-flex-col tw-self-stretch',\n centered && !isVertical && 'tw-justify-center',\n monospace && '[&>*]:tw-flex-1',\n isCard ? 'tw-gap-1' : !isVertical && !monospace && 'tw-gap-8',\n )}\n style={\n !isVertical\n ? { scrollbarWidth: 'none', msOverflowStyle: 'none' }\n : undefined\n }\n >\n {resolvedItems.map((item) => {\n const isActive = activeKey === item.key;\n // For editable-card, closable defaults to true unless explicitly set to false\n const showClose = isEditable && item.closable !== false;\n const closeLabel =\n typeof item.label === 'string' || typeof item.label === 'number'\n ? `Remove ${item.label}`\n : 'Remove tab';\n\n return (\n <div\n key={item.key}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-tab ant-tabs-tab tw-relative tw-flex tw-shrink-0 tw-items-center tw-gap-2 tw-whitespace-nowrap tw-transition-colors',\n isVertical && 'tw-w-full tw-self-stretch',\n // Card / editable-card styling\n isCard\n ? cn(\n 'tw-h-10 tw-rounded-t-[6px] tw-border tw-border-b-0 tw-border-solid tw-px-4 tw-text-sm tw-leading-5',\n 'tw-gap-sp-75',\n isActive\n ? 'tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-font-medium tw-text-[var(--content-brand-primary)]'\n : 'tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-text-[var(--content-secondary)] hover:tw-text-inherit',\n )\n : cn(\n size === 'small'\n ? 'tw-py-2 tw-text-xs tw-leading-4'\n : 'tw-py-2.5 tw-text-sm tw-leading-5',\n monospace && 'tw-justify-center',\n isActive\n ? 'tw-font-medium tw-text-[var(--content-brand-primary)]'\n : 'tw-font-medium tw-text-[var(--content-secondary)] hover:tw-text-inherit',\n ),\n item.disabled &&\n 'tw-pointer-events-none tw-cursor-default tw-opacity-50',\n // Focus belongs to the roving tab trigger, not to the\n // selected/active state. Render it on the tab envelope so\n // card and line tab geometry remain unchanged.\n !item.disabled && [\n 'has-[.ald-tabs-tab-trigger:focus-visible]:tw-shadow-[0_0_0_2px_var(--focus-ring)]',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-2',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-offset-2',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-[Highlight]',\n ],\n )}\n >\n <div\n ref={(node) => {\n tabRefs.current[item.key] = node;\n }}\n id={getTabId(item.key)}\n role=\"tab\"\n aria-selected={isActive}\n aria-controls={getPanelId(item.key)}\n aria-disabled={item.disabled || undefined}\n tabIndex={\n !item.disabled && focusedKey === item.key ? 0 : -1\n }\n className={cn(\n 'ald-tabs-tab-trigger tw-flex tw-min-w-0 tw-flex-1 tw-cursor-pointer tw-items-center tw-whitespace-nowrap',\n isCard ? 'tw-gap-sp-75' : 'tw-gap-2',\n monospace && 'tw-justify-center',\n )}\n onClick={\n item.disabled\n ? undefined\n : (e) => handleTabClick(item.key, e)\n }\n onFocus={() => setFocusedKey(item.key)}\n onKeyDown={(e) => handleTabKeyDown(item, e)}\n >\n {item.icon}\n {/* antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器 */}\n <span className=\"ant-tabs-tab-btn\">{item.label}</span>\n </div>\n {/* Close button for editable-card */}\n {showClose && (\n <button\n type=\"button\"\n className=\"ald-tabs-tab-remove tw-m-0 tw-grid tw-size-4 tw-cursor-pointer tw-place-items-center tw-border-0 tw-bg-transparent tw-p-0 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]\"\n onClick={(e) => handleRemove(item.key, e)}\n aria-label={closeLabel}\n >\n <CloseLightLine size={12} />\n </button>\n )}\n {/* Active indicator for non-card line tabs */}\n {/* antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器 */}\n {!isCard && isActive && isTop && (\n <div className=\"ant-tabs-ink-bar tw-absolute tw-inset-x-0 tw--bottom-px tw-h-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n {!isCard && isActive && isBottom && (\n <div className=\"ant-tabs-ink-bar tw-absolute tw-inset-x-0 tw--top-px tw-h-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n {!isCard && isActive && isLeft && (\n <div className=\"tw-absolute tw-inset-y-0 tw--right-px tw-w-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n {!isCard && isActive && isRight && (\n <div className=\"tw-absolute tw-inset-y-0 tw--left-px tw-w-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n </div>\n );\n })}\n </div>\n </div>\n\n {/* Scroll right button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-[var(--action-ghost-normal)] tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollRight && 'tw-invisible',\n )}\n onClick={() => scrollBy(200)}\n aria-label=\"Scroll tabs right\"\n >\n <ChevronRightLine size={16} />\n </button>\n )}\n\n {/* Add button for editable-card */}\n {isEditable && !hideAdd && (\n <button\n type=\"button\"\n className=\"ald-tabs-nav-add tw-ml-1 tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-justify-center tw-rounded tw-border tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-px-2 tw-py-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]\"\n onClick={handleAdd}\n aria-label=\"Add tab\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </button>\n )}\n\n {extraRight}\n </div>\n\n {/* Tab content */}\n {/* antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器 */}\n <div\n className={cn(\n 'ald-tabs-content ant-tabs-content ant-tabs-content-holder tw-min-h-0 tw-flex-1',\n adaptHeight && 'tw-h-full',\n )}\n style={\n paddingVal\n ? { padding: `0 ${paddingVal}px ${paddingVal}px` }\n : undefined\n }\n >\n {resolvedItems.map((item) => {\n const isActive = item.key === activeKey;\n if (!isActive && destroyInactiveTabPane && !item.forceRender) {\n return null;\n }\n return (\n <div\n key={item.key}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-tabpane ant-tabs-tabpane',\n // v2 行为:adaptHeight 时 tabpane 撑满内容区,子元素的百分比高度才能解析\n adaptHeight && 'tw-h-full tw-overflow-y-auto',\n isActive ? 'ant-tabs-tabpane-active tw-block' : 'tw-hidden',\n )}\n role=\"tabpanel\"\n id={getPanelId(item.key)}\n aria-labelledby={getTabId(item.key)}\n aria-hidden={!isActive || undefined}\n >\n {item.children}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nTabs.TabPane = TabPane;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Tabs/index.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../lib/utils';\nimport { ChevronLeftLine, ChevronRightLine, CloseLightLine } from '../Icon';\nimport TabPane from './TabPane';\n\nexport type TabsSize = 'default' | 'small';\n\ninterface TabItem {\n key: string;\n label: React.ReactNode;\n children?: React.ReactNode;\n disabled?: boolean;\n closable?: boolean;\n icon?: React.ReactNode;\n forceRender?: boolean;\n className?: string;\n}\n\nexport interface ITabsProps {\n size?: TabsSize;\n activeKey?: string;\n defaultActiveKey?: string;\n onChange?: (activeKey: string) => void;\n onTabClick?: (activeKey: string, e: React.MouseEvent) => void;\n destroyInactiveTabPane?: boolean;\n centered?: boolean;\n adaptHeight?: boolean;\n tabPosition?: 'left' | 'right' | 'top' | 'bottom';\n className?: string;\n children?: React.ReactNode;\n headerBackgroundColor?: string;\n monospace?: boolean;\n padding?: boolean | number;\n compact?: boolean;\n hasDividing?: boolean;\n items?: TabItem[];\n type?: 'line' | 'card' | 'editable-card';\n tabBarExtraContent?:\n | React.ReactNode\n | { left?: React.ReactNode; right?: React.ReactNode };\n onEdit?: (\n targetKey: string | React.MouseEvent | React.KeyboardEvent,\n action: 'add' | 'remove',\n ) => void;\n hideAdd?: boolean;\n style?: React.CSSProperties;\n tabBarStyle?: React.CSSProperties;\n popupClassName?: string;\n tabBarGutter?: number;\n moreIcon?: React.ReactNode;\n /** 透传到 Tabs 根容器的 data-testid,用于自动化测试定位 */\n 'data-testid'?: string;\n /** 透传到 tablist 的 aria-label,用于可访问性与自动化测试定位 */\n 'aria-label'?: string;\n}\n\nexport default function Tabs(props: ITabsProps) {\n const {\n size,\n className,\n adaptHeight,\n style = {},\n monospace: propsMonospace,\n tabPosition = 'top',\n padding: propsPadding = false,\n compact,\n hasDividing = true,\n items,\n activeKey: controlledActiveKey,\n defaultActiveKey,\n onChange,\n onTabClick,\n destroyInactiveTabPane,\n centered,\n tabBarExtraContent,\n headerBackgroundColor,\n children,\n type,\n onEdit,\n hideAdd,\n tabBarStyle,\n 'data-testid': dataTestId,\n 'aria-label': ariaLabel,\n } = props;\n\n const isEditable = type === 'editable-card';\n const isCard = type === 'card' || type === 'editable-card';\n\n // Derive items from children if not provided\n const resolvedItems: TabItem[] = useMemo(() => {\n if (items) return items;\n return React.Children.toArray(children)\n .filter(React.isValidElement)\n .map((child: any) => ({\n key: child.key || child.props.key || '',\n label: child.props.tab,\n children: child.props.children,\n disabled: child.props.disabled,\n closable: child.props.closable,\n forceRender: child.props.forceRender,\n }));\n }, [items, children]);\n\n const firstKey = resolvedItems[0]?.key || '';\n const [innerActiveKey, setInnerActiveKey] = useState(\n defaultActiveKey || firstKey,\n );\n const mergedActiveKey =\n controlledActiveKey !== undefined ? controlledActiveKey : innerActiveKey;\n const activeKey = resolvedItems.some((item) => item.key === mergedActiveKey)\n ? mergedActiveKey\n : firstKey;\n\n const tabsId = React.useId();\n const tabRefs = useRef<Record<string, HTMLDivElement | null>>({});\n const pendingFocusKeyRef = useRef<string | null>(null);\n const getPreferredFocusKey = useCallback(\n (items: TabItem[] = resolvedItems) =>\n items.find((item) => item.key === activeKey && !item.disabled)?.key ||\n items.find((item) => !item.disabled)?.key ||\n '',\n [activeKey, resolvedItems],\n );\n const [focusedKey, setFocusedKey] = useState(() => getPreferredFocusKey());\n\n const getTabId = (key: string) => `${tabsId}-tab-${key}`;\n const getPanelId = (key: string) => `${tabsId}-panel-${key}`;\n\n const focusTab = useCallback((key: string) => {\n setFocusedKey(key);\n tabRefs.current[key]?.focus();\n }, []);\n\n useEffect(() => {\n const pendingFocusKey = pendingFocusKeyRef.current;\n if (\n pendingFocusKey &&\n resolvedItems.some(\n (item) => item.key === pendingFocusKey && !item.disabled,\n )\n ) {\n pendingFocusKeyRef.current = null;\n focusTab(pendingFocusKey);\n return;\n }\n\n setFocusedKey((currentFocusedKey) => {\n const focusedItem = resolvedItems.find(\n (item) => item.key === currentFocusedKey,\n );\n return focusedItem && !focusedItem.disabled\n ? currentFocusedKey\n : getPreferredFocusKey();\n });\n }, [focusTab, getPreferredFocusKey, resolvedItems]);\n\n const activateTab = useCallback(\n (key: string) => {\n if (controlledActiveKey === undefined) {\n setInnerActiveKey(key);\n }\n onChange?.(key);\n },\n [controlledActiveKey, onChange],\n );\n\n const handleTabClick = (key: string, e: React.MouseEvent) => {\n setFocusedKey(key);\n activateTab(key);\n onTabClick?.(key, e);\n };\n\n const handleRemove = (key: string, e: React.MouseEvent) => {\n e.stopPropagation();\n const itemIndex = resolvedItems.findIndex((item) => item.key === key);\n const nextFocusableItem = [\n ...resolvedItems.slice(itemIndex + 1),\n ...resolvedItems.slice(0, itemIndex).reverse(),\n ].find((item) => !item.disabled);\n pendingFocusKeyRef.current = nextFocusableItem?.key || null;\n onEdit?.(key, 'remove');\n };\n\n const handleTabKeyDown = (\n item: TabItem,\n e: React.KeyboardEvent<HTMLDivElement>,\n ) => {\n const enabledItems = resolvedItems.filter(\n (candidate) => !candidate.disabled,\n );\n const currentIndex = enabledItems.findIndex(\n (candidate) => candidate.key === item.key,\n );\n if (currentIndex === -1) return;\n\n let nextIndex: number | undefined;\n if (\n (!isVertical && e.key === 'ArrowRight') ||\n (isVertical && e.key === 'ArrowDown')\n ) {\n nextIndex = (currentIndex + 1) % enabledItems.length;\n } else if (\n (!isVertical && e.key === 'ArrowLeft') ||\n (isVertical && e.key === 'ArrowUp')\n ) {\n nextIndex =\n (currentIndex - 1 + enabledItems.length) % enabledItems.length;\n } else if (e.key === 'Home') {\n nextIndex = 0;\n } else if (e.key === 'End') {\n nextIndex = enabledItems.length - 1;\n }\n\n if (nextIndex !== undefined) {\n e.preventDefault();\n focusTab(enabledItems[nextIndex].key);\n return;\n }\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n activateTab(item.key);\n }\n };\n\n const handleAdd = (e: React.MouseEvent) => {\n onEdit?.(e, 'add');\n };\n\n const monospace = tabPosition !== 'top' ? false : propsMonospace;\n const paddingVal = useMemo(() => {\n if (tabPosition !== 'top') return 0;\n if (typeof propsPadding === 'number') return propsPadding;\n if (typeof propsPadding === 'boolean' && propsPadding) return 20;\n return 0;\n }, [propsPadding, tabPosition]);\n\n const isTop = tabPosition === 'top';\n const isBottom = tabPosition === 'bottom';\n const isLeft = tabPosition === 'left';\n const isRight = tabPosition === 'right';\n const isVertical = tabPosition === 'left' || tabPosition === 'right';\n const rootDirectionClass = isRight\n ? 'tw-flex-row-reverse'\n : isLeft\n ? 'tw-flex-row'\n : isBottom\n ? 'tw-flex-col-reverse'\n : 'tw-flex-col';\n\n const extraLeft =\n tabBarExtraContent &&\n typeof tabBarExtraContent === 'object' &&\n 'left' in tabBarExtraContent\n ? tabBarExtraContent.left\n : null;\n const extraRight = tabBarExtraContent\n ? typeof tabBarExtraContent === 'object' && 'right' in tabBarExtraContent\n ? tabBarExtraContent.right\n : React.isValidElement(tabBarExtraContent)\n ? tabBarExtraContent\n : null\n : null;\n\n // Scroll state for overflow\n const navListRef = useRef<HTMLDivElement>(null);\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const checkScroll = useCallback(() => {\n const el = navListRef.current;\n if (!el || isVertical) {\n setCanScrollLeft(false);\n setCanScrollRight(false);\n return;\n }\n const { scrollLeft, scrollWidth, clientWidth } = el;\n setCanScrollLeft(scrollLeft > 1);\n setCanScrollRight(scrollLeft + clientWidth < scrollWidth - 1);\n }, [isVertical]);\n\n useEffect(() => {\n checkScroll();\n const el = navListRef.current;\n if (!el) return;\n // Use ResizeObserver to detect size changes\n let ro: ResizeObserver | undefined;\n if (typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(() => checkScroll());\n ro.observe(el);\n }\n el.addEventListener('scroll', checkScroll, { passive: true });\n return () => {\n el.removeEventListener('scroll', checkScroll);\n ro?.disconnect();\n };\n }, [checkScroll, resolvedItems.length]);\n\n const scrollBy = (delta: number) => {\n const el = navListRef.current;\n if (el) {\n el.scrollBy({ left: delta, behavior: 'smooth' });\n }\n };\n\n const showScrollButtons = canScrollLeft || canScrollRight;\n\n return (\n <div\n data-testid={dataTestId}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs ant-tabs tw-flex',\n rootDirectionClass,\n adaptHeight && 'ald-adapt-height tw-h-full',\n size !== 'small' && 'ald-tabs-default',\n monospace && 'ald-tabs-monospace',\n compact && 'ald-tabs-compact',\n !hasDividing && 'ald-tabs-no-dividing',\n className,\n )}\n style={\n {\n ...style,\n '--header-bg-color': headerBackgroundColor,\n '--tabs-padding': `${paddingVal}px`,\n } as React.CSSProperties\n }\n >\n {/* Tab nav */}\n <div\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-nav ant-tabs-nav tw-flex',\n isVertical ? 'tw-shrink-0 tw-items-stretch' : 'tw-items-center',\n isTop && 'tw-mb-5',\n isBottom && 'tw-mt-5',\n isTop &&\n hasDividing &&\n 'tw-border-0 tw-border-b tw-border-solid tw-border-b-[var(--border-default)]',\n isBottom &&\n hasDividing &&\n 'tw-border-0 tw-border-t tw-border-solid tw-border-t-[var(--border-default)]',\n isTop && compact && '!tw-mb-0',\n isBottom && compact && '!tw-mt-0',\n isLeft &&\n 'tw-flex-col tw-border-0 tw-border-r tw-border-solid tw-border-r-[var(--border-default)]',\n isRight &&\n 'tw-flex-col tw-border-0 tw-border-l tw-border-solid tw-border-l-[var(--border-default)]',\n )}\n style={\n headerBackgroundColor || tabBarStyle\n ? {\n ...tabBarStyle,\n ...(headerBackgroundColor\n ? { backgroundColor: headerBackgroundColor }\n : {}),\n }\n : undefined\n }\n >\n {extraLeft}\n\n {/* Scroll left button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-[var(--action-ghost-normal)] tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollLeft && 'tw-invisible',\n )}\n onClick={() => scrollBy(-200)}\n aria-label=\"Scroll tabs left\"\n >\n <ChevronLeftLine size={16} />\n </button>\n )}\n\n <div\n className={cn(\n 'ald-tabs-nav-wrap ant-tabs-nav-wrap',\n isVertical\n ? 'tw-w-full tw-shrink-0 tw-self-stretch'\n : 'tw-min-w-0 tw-flex-1',\n )}\n style={paddingVal ? { margin: `0 ${paddingVal}px` } : undefined}\n >\n <div\n ref={navListRef}\n role=\"tablist\"\n aria-label={ariaLabel}\n aria-orientation={isVertical ? 'vertical' : 'horizontal'}\n onBlur={(e) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) {\n setFocusedKey(getPreferredFocusKey());\n }\n }}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-nav-list ant-tabs-nav-list tw-flex tw-overflow-hidden',\n isVertical && 'tw-w-full tw-shrink-0 tw-flex-col tw-self-stretch',\n centered && !isVertical && 'tw-justify-center',\n monospace && '[&>*]:tw-flex-1',\n isCard ? 'tw-gap-1' : !isVertical && !monospace && 'tw-gap-8',\n )}\n style={\n !isVertical\n ? { scrollbarWidth: 'none', msOverflowStyle: 'none' }\n : undefined\n }\n >\n {resolvedItems.map((item) => {\n const isActive = activeKey === item.key;\n // For editable-card, closable defaults to true unless explicitly set to false\n const showClose = isEditable && item.closable !== false;\n const closeLabel =\n typeof item.label === 'string' || typeof item.label === 'number'\n ? `Remove ${item.label}`\n : 'Remove tab';\n\n return (\n <div\n key={item.key}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-tab ant-tabs-tab tw-relative tw-flex tw-shrink-0 tw-items-center tw-gap-2 tw-whitespace-nowrap tw-transition-colors',\n isVertical && 'tw-w-full tw-self-stretch',\n // Card / editable-card styling\n isCard\n ? cn(\n 'tw-h-10 tw-rounded-t-[6px] tw-border tw-border-b-0 tw-border-solid tw-px-4 tw-text-sm tw-leading-5',\n 'tw-gap-sp-75',\n isActive\n ? 'tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-font-medium tw-text-[var(--content-brand-primary)]'\n : 'tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-text-[var(--content-secondary)] hover:tw-text-inherit',\n )\n : cn(\n size === 'small'\n ? 'tw-py-2 tw-text-xs tw-leading-4'\n : 'tw-py-2.5 tw-text-sm tw-leading-5',\n monospace && 'tw-justify-center',\n isActive\n ? 'tw-font-medium tw-text-[var(--content-brand-primary)]'\n : 'tw-font-medium tw-text-[var(--content-secondary)] hover:tw-text-inherit',\n ),\n item.disabled &&\n 'tw-pointer-events-none tw-cursor-default tw-opacity-50',\n // Focus belongs to the roving tab trigger, not to the\n // selected/active state. Render it on the tab envelope so\n // card and line tab geometry remain unchanged.\n !item.disabled && [\n 'has-[.ald-tabs-tab-trigger:focus-visible]:tw-shadow-[inset_0_0_0_2px_var(--focus-ring)]',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-2',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-offset-[-2px]',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-[Highlight]',\n ],\n )}\n >\n <div\n ref={(node) => {\n tabRefs.current[item.key] = node;\n }}\n id={getTabId(item.key)}\n role=\"tab\"\n aria-selected={isActive}\n aria-controls={getPanelId(item.key)}\n aria-disabled={item.disabled || undefined}\n tabIndex={\n !item.disabled && focusedKey === item.key ? 0 : -1\n }\n className={cn(\n 'ald-tabs-tab-trigger tw-flex tw-min-w-0 tw-flex-1 tw-cursor-pointer tw-items-center tw-whitespace-nowrap',\n isCard ? 'tw-gap-sp-75' : 'tw-gap-2',\n monospace && 'tw-justify-center',\n )}\n onClick={\n item.disabled\n ? undefined\n : (e) => handleTabClick(item.key, e)\n }\n onFocus={() => setFocusedKey(item.key)}\n onKeyDown={(e) => handleTabKeyDown(item, e)}\n >\n {item.icon}\n {/* antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器 */}\n <span className=\"ant-tabs-tab-btn\">{item.label}</span>\n </div>\n {/* Close button for editable-card */}\n {showClose && (\n <button\n type=\"button\"\n className=\"ald-tabs-tab-remove tw-m-0 tw-grid tw-size-4 tw-cursor-pointer tw-place-items-center tw-border-0 tw-bg-transparent tw-p-0 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]\"\n onClick={(e) => handleRemove(item.key, e)}\n aria-label={closeLabel}\n >\n <CloseLightLine size={12} />\n </button>\n )}\n {/* Active indicator for non-card line tabs */}\n {/* antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器 */}\n {!isCard && isActive && isTop && (\n <div className=\"ant-tabs-ink-bar tw-absolute tw-inset-x-0 tw--bottom-px tw-h-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n {!isCard && isActive && isBottom && (\n <div className=\"ant-tabs-ink-bar tw-absolute tw-inset-x-0 tw--top-px tw-h-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n {!isCard && isActive && isLeft && (\n <div className=\"tw-absolute tw-inset-y-0 tw--right-px tw-w-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n {!isCard && isActive && isRight && (\n <div className=\"tw-absolute tw-inset-y-0 tw--left-px tw-w-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n </div>\n );\n })}\n </div>\n </div>\n\n {/* Scroll right button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-[var(--action-ghost-normal)] tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollRight && 'tw-invisible',\n )}\n onClick={() => scrollBy(200)}\n aria-label=\"Scroll tabs right\"\n >\n <ChevronRightLine size={16} />\n </button>\n )}\n\n {/* Add button for editable-card */}\n {isEditable && !hideAdd && (\n <button\n type=\"button\"\n className=\"ald-tabs-nav-add tw-ml-1 tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-justify-center tw-rounded tw-border tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-px-2 tw-py-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]\"\n onClick={handleAdd}\n aria-label=\"Add tab\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </button>\n )}\n\n {extraRight}\n </div>\n\n {/* Tab content */}\n {/* antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器 */}\n <div\n className={cn(\n 'ald-tabs-content ant-tabs-content ant-tabs-content-holder tw-min-h-0 tw-flex-1',\n adaptHeight && 'tw-h-full',\n )}\n style={\n paddingVal\n ? { padding: `0 ${paddingVal}px ${paddingVal}px` }\n : undefined\n }\n >\n {resolvedItems.map((item) => {\n const isActive = item.key === activeKey;\n if (!isActive && destroyInactiveTabPane && !item.forceRender) {\n return null;\n }\n return (\n <div\n key={item.key}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-tabpane ant-tabs-tabpane',\n // v2 行为:adaptHeight 时 tabpane 撑满内容区,子元素的百分比高度才能解析\n adaptHeight && 'tw-h-full tw-overflow-y-auto',\n isActive ? 'ant-tabs-tabpane-active tw-block' : 'tw-hidden',\n )}\n role=\"tabpanel\"\n id={getPanelId(item.key)}\n aria-labelledby={getTabId(item.key)}\n aria-hidden={!isActive || undefined}\n >\n {item.children}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nTabs.TabPane = TabPane;\n"],"mappings":"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"}