@aloudata/aloudata-design 3.0.24 → 3.0.25

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 (58) hide show
  1. package/dist/Button/index.js +9 -3
  2. package/dist/Button/index.js.map +1 -1
  3. package/dist/Checkbox/index.js +7 -1
  4. package/dist/Checkbox/index.js.map +1 -1
  5. package/dist/Collapse/index.js +68 -22
  6. package/dist/Collapse/index.js.map +1 -1
  7. package/dist/Input/components/Input/index.js +7 -1
  8. package/dist/Input/components/Input/index.js.map +1 -1
  9. package/dist/Input/components/TextArea/index.js +7 -1
  10. package/dist/Input/components/TextArea/index.js.map +1 -1
  11. package/dist/InputNumber/index.js +7 -1
  12. package/dist/InputNumber/index.js.map +1 -1
  13. package/dist/Pagination/PageSizeChanger.d.ts +1 -0
  14. package/dist/Pagination/PageSizeChanger.js +3 -2
  15. package/dist/Pagination/PageSizeChanger.js.map +1 -1
  16. package/dist/Pagination/index.js +33 -19
  17. package/dist/Pagination/index.js.map +1 -1
  18. package/dist/Pagination/types.d.ts +3 -0
  19. package/dist/Select/BaseSelect.js +12 -12
  20. package/dist/Select/BaseSelect.js.map +1 -1
  21. package/dist/Steps/index.js +66 -14
  22. package/dist/Steps/index.js.map +1 -1
  23. package/dist/Switch/index.js +7 -1
  24. package/dist/Switch/index.js.map +1 -1
  25. package/dist/Table/components/ExpandCell.js +6 -2
  26. package/dist/Table/components/ExpandCell.js.map +1 -1
  27. package/dist/Table/components/Header.js +25 -17
  28. package/dist/Table/components/Header.js.map +1 -1
  29. package/dist/Table/hooks/useRowSelection.js +14 -7
  30. package/dist/Table/hooks/useRowSelection.js.map +1 -1
  31. package/dist/Table/index.js +8 -2
  32. package/dist/Table/index.js.map +1 -1
  33. package/dist/Tabs/index.js +7 -1
  34. package/dist/Tabs/index.js.map +1 -1
  35. package/dist/aloudata-design.css +1 -1
  36. package/dist/locale/default.d.ts +6 -0
  37. package/dist/locale/en_US.d.ts +6 -0
  38. package/dist/locale/en_US.js +6 -0
  39. package/dist/locale/en_US.js.map +1 -1
  40. package/dist/locale/zh_CN.d.ts +6 -0
  41. package/dist/locale/zh_CN.js +6 -0
  42. package/dist/locale/zh_CN.js.map +1 -1
  43. package/dist/theme/contract/controlStateColorArtifact.d.ts +73 -0
  44. package/dist/theme/contract/controlStateColorArtifact.js +2 -0
  45. package/dist/theme/contract/focusRingArtifact.d.ts +51 -0
  46. package/dist/theme/contract/focusRingArtifact.js +2 -0
  47. package/dist/theme/contract/tokenOutputContract.d.ts +1 -1
  48. package/dist/theme/contract/tokenOutputContract.js +4 -0
  49. package/dist/theme/contract/tokenOutputContract.js.map +1 -1
  50. package/dist/theme/runtime/colorValueMode/generated/darkBaselineDeclarations.d.ts +1 -1
  51. package/dist/theme/runtime/colorValueMode/generated/darkBaselineDeclarations.js +3 -0
  52. package/dist/theme/runtime/colorValueMode/generated/darkBaselineDeclarations.js.map +1 -1
  53. package/dist/theme/runtime/colorValueMode/generated/v3BaselineDeclarations.d.ts +1 -1
  54. package/dist/theme/runtime/colorValueMode/generated/v3BaselineDeclarations.js +3 -0
  55. package/dist/theme/runtime/colorValueMode/generated/v3BaselineDeclarations.js.map +1 -1
  56. package/dist/theme/runtime/themeToCssVars.js +3 -0
  57. package/dist/theme/runtime/themeToCssVars.js.map +1 -1
  58. package/package.json +1 -1
@@ -29,8 +29,7 @@ var setIcon = (iconNode, loading, size = "1em") => {
29
29
  var buttonVariants = cva([
30
30
  btnPrefix,
31
31
  "tw-inline-flex tw-cursor-pointer tw-appearance-none tw-items-center tw-justify-center tw-no-underline tw-transition-colors [&_.i-icon]:tw-inline-flex [&_.i-icon]:tw-items-center",
32
- "tw-border tw-border-solid",
33
- "focus-visible:tw-outline-none"
32
+ "tw-border tw-border-solid"
34
33
  ], {
35
34
  variants: {
36
35
  type: {
@@ -137,13 +136,20 @@ function Button(props, ref) {
137
136
  const iconNode = setIcon(icon, innerLoading, size === "small" ? 12 : 14);
138
137
  const compactClasses = compactItemClassnames ? cn(!compactItemClassnames[`ald-btn-compact-first-item`] && "!tw-rounded-l-none", !compactItemClassnames[`ald-btn-compact-last-item`] && "!tw-rounded-r-none", !compactItemClassnames[`ald-btn-compact-first-item`] && "-tw-ml-px") : void 0;
139
138
  const isIconOnly = !!icon && !children && !showArrow;
139
+ const focusRingClasses = !isDisabled && [
140
+ "focus-visible:tw-outline",
141
+ "focus-visible:tw-outline-2",
142
+ "focus-visible:tw-outline-offset-2",
143
+ "focus-visible:tw-outline-[var(--focus-ring)]",
144
+ "forced-colors:focus-visible:tw-outline-[Highlight]"
145
+ ];
140
146
  const classes = cn(buttonVariants({
141
147
  type,
142
148
  size,
143
149
  disabled: !!isDisabled,
144
150
  block: !!block,
145
151
  shape
146
- }), ghost && "!tw-border-[var(--action-ghost-normal)] !tw-bg-[var(--action-ghost-normal)] !tw-shadow-none hover:!tw-border-[var(--action-ghost-normal)]", ghost && type === "primary" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "dangerous" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "secondary" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "inverse" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-bg-[var(--action-ghost-normal)] !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "primary" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-primary-subtle-hover)]", ghost && type === "dangerous" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-destructive-hover)]", ghost && type === "secondary" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-hover)]", ghost && type === "inverse" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-inverted-hover)]", ghost && type === "primary" && "!tw-text-[var(--action-primary-normal)]", ghost && type === "dangerous" && "!tw-text-[var(--action-destructive-normal)]", ghost && type === "secondary" && "!tw-text-[var(--action-neutral-normal)]", ghost && type === "inverse" && "!tw-text-[var(--action-inverted-normal)]", isIconOnly && "tw-aspect-square !tw-px-0", isIconOnly && size === "small" && "!tw-min-w-7", isIconOnly && size === "middle" && "!tw-min-w-8", isIconOnly && size === "large" && "!tw-min-w-10", compactClasses, className);
152
+ }), ghost && "!tw-border-[var(--action-ghost-normal)] !tw-bg-[var(--action-ghost-normal)] !tw-shadow-none hover:!tw-border-[var(--action-ghost-normal)]", ghost && type === "primary" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "dangerous" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "secondary" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "inverse" && size === "middle" && "!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-bg-[var(--action-ghost-normal)] !tw-px-[var(--component-padding-md)] !tw-py-0", ghost && type === "primary" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-primary-subtle-hover)]", ghost && type === "dangerous" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-destructive-hover)]", ghost && type === "secondary" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-hover)]", ghost && type === "inverse" && "!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-inverted-hover)]", ghost && type === "primary" && "!tw-text-[var(--action-primary-normal)]", ghost && type === "dangerous" && "!tw-text-[var(--action-destructive-normal)]", ghost && type === "secondary" && "!tw-text-[var(--action-neutral-normal)]", ghost && type === "inverse" && "!tw-text-[var(--action-inverted-normal)]", isIconOnly && "tw-aspect-square !tw-px-0", isIconOnly && size === "small" && "!tw-min-w-7", isIconOnly && size === "middle" && "!tw-min-w-8", isIconOnly && size === "large" && "!tw-min-w-10", focusRingClasses, compactClasses, className);
147
153
  const contentClasses = cn("tw-inline-flex tw-min-w-0 tw-items-center tw-gap-1 tw-truncate tw-text-typography-label", ghost && type === "inverse" && size === "middle" && "tw-flex-[1_0_0] tw-text-[var(--action-inverted-normal)]");
148
154
  const buttonContent = /* @__PURE__ */ jsxs(Fragment, { children: [
149
155
  iconNode,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Button/index.tsx"],"sourcesContent":["import { cva } from 'class-variance-authority';\nimport React, { forwardRef, useContext, useEffect, useState } from 'react';\nimport DisabledContext from '../ConfigProvider/DisabledContext';\nimport SizeContext from '../ConfigProvider/sizeContext';\nimport { ChevronDownLine, LoadingLine } from '../Icon';\nimport { cn } from '../lib/utils';\nimport { useCompactItemContext } from '../Space/CompactContext';\n\nexport const btnPrefix = 'ald-btn';\n\nexport type ButtonType =\n | 'primary'\n | 'secondary'\n | 'dangerous'\n | 'text'\n | 'inverse'\n | 'link';\nexport type Size = 'small' | 'middle' | 'large';\nexport interface IButtonProps {\n type?: ButtonType;\n size?: Size;\n disabled?: boolean;\n icon?: React.ReactNode;\n shape?: 'circle' | 'default';\n href?: string;\n target?: string;\n onClick?: React.MouseEventHandler<HTMLElement>;\n loading?: boolean | { delay?: number };\n children?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n block?: boolean;\n htmlType?: 'submit' | 'button' | 'reset';\n id?: string;\n tabIndex?: number;\n title?: string;\n 'aria-label'?: string;\n /** 透传到 button 元素的 data-testid,用于自动化测试定位(经 rest props 透传) */\n 'data-testid'?: string;\n ghost?: boolean;\n danger?: boolean;\n color?: string;\n showArrow?: boolean;\n}\n\nexport function getButtonType(buttonType: ButtonType): string {\n return buttonType;\n}\nexport function getDangerStatus(buttonType: ButtonType): boolean {\n return buttonType === 'dangerous';\n}\nexport function getButtonSizeClass(s: Size): string {\n return ['small', 'large'].includes(s)\n ? `${btnPrefix}-${s}`\n : `${btnPrefix}-middle`;\n}\nexport function getShape(s: 'circle' | 'default'): 'circle' | 'default' {\n return s;\n}\nexport const setIcon = (\n iconNode: React.ReactElement,\n loading: boolean | { delay?: number },\n size: string | number = '1em',\n) => {\n if (loading) {\n return (\n <LoadingLine\n className=\"ald-loading-spin tw-shrink-0 tw-animate-spin\"\n size={size}\n color=\"currentColor\"\n />\n );\n }\n\n if (iconNode) {\n const p: Record<string, string | number> = {\n className: '',\n fill: 'currentColor',\n ...iconNode.props,\n };\n p.size = size;\n return React.cloneElement(iconNode, p);\n }\n return <></>;\n};\n\nconst buttonVariants = cva(\n [\n btnPrefix,\n 'tw-inline-flex tw-cursor-pointer tw-appearance-none tw-items-center tw-justify-center tw-no-underline tw-transition-colors [&_.i-icon]:tw-inline-flex [&_.i-icon]:tw-items-center',\n 'tw-border tw-border-solid',\n 'focus-visible:tw-outline-none',\n ],\n {\n variants: {\n type: {\n primary: [\n `${btnPrefix}-primary`,\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)] tw-text-[var(--action-inverted-normal)] tw-shadow-[var(--elevation-bottom-bottom-sm)]',\n 'hover:tw-bg-[var(--action-primary-hover)]',\n 'active:tw-bg-[var(--action-primary-active)]',\n ],\n secondary: [\n `${btnPrefix}-secondary`,\n 'tw-border-[var(--action-outline-normal)] tw-bg-[var(--action-inverted-normal)] tw-text-[var(--action-neutral-normal)] tw-shadow-[var(--elevation-bottom-bottom-sm)]',\n 'hover:tw-border-[var(--action-outline-hover)] hover:tw-bg-[var(--action-inverted-normal)]',\n 'active:tw-border-[var(--action-outline-active)] active:tw-bg-[var(--action-inverted-active)] active:tw-text-[var(--action-neutral-active)]',\n ],\n dangerous: [\n `${btnPrefix}-dangerous`,\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-destructive-normal)] tw-text-[var(--action-inverted-normal)] tw-shadow-[var(--elevation-bottom-bottom-sm)]',\n 'hover:tw-bg-[var(--action-destructive-hover)]',\n 'active:tw-bg-[var(--action-destructive-active)]',\n ],\n text: [\n `${btnPrefix}-text`,\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-ghost-normal)] tw-text-[var(--action-neutral-normal)]',\n 'hover:tw-bg-[var(--action-ghost-hover)] hover:tw-text-[var(--action-neutral-hover)]',\n 'active:tw-bg-[var(--action-ghost-active)] active:tw-text-[var(--action-neutral-active)]',\n ],\n inverse: [\n `${btnPrefix}-inverse`,\n 'tw-border-[var(--action-neutral-normal)] tw-bg-[var(--action-ghost-normal)] tw-text-[var(--content-inverted-primary)]',\n 'hover:tw-border-[var(--action-ghost-inverted-hover)] hover:tw-bg-[var(--action-ghost-normal)]',\n 'active:tw-bg-[var(--action-ghost-inverted-active)]',\n ],\n link: [\n `${btnPrefix}-link`,\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-ghost-normal)] tw-text-[var(--action-primary-normal)]',\n 'hover:tw-text-[var(--action-primary-hover)]',\n 'active:tw-text-[var(--action-primary-active)]',\n ],\n },\n size: {\n // Component Geometry: size variants own the control envelope. The\n // inline gap remains relationship-preserving implementation while the\n // Action Association Constraint has no Primitive Resolution.\n small: [\n `${btnPrefix}-small`,\n 'tw-h-7 tw-min-w-7 tw-gap-1 tw-rounded-r-75',\n 'tw-px-[var(--alias-padding-150-minus-1)] tw-py-[var(--alias-padding-75-minus-1)]',\n ],\n middle: [\n `${btnPrefix}-middle`,\n 'tw-h-8 tw-min-w-8 tw-gap-1 tw-rounded-r-75',\n 'tw-px-[var(--alias-padding-150-minus-1)] tw-py-[var(--alias-padding-75-minus-1)]',\n ],\n large: [\n `${btnPrefix}-large`,\n 'tw-h-10 tw-min-w-10 tw-gap-1 tw-rounded-r-75',\n 'tw-px-[var(--alias-padding-150-minus-1)] tw-py-[var(--alias-padding-75-minus-1)]',\n ],\n },\n disabled: {\n true: 'tw-pointer-events-none tw-cursor-default tw-opacity-50',\n false: '',\n },\n block: {\n true: 'tw-w-full',\n false: '',\n },\n shape: {\n circle: 'tw-min-w-0 tw-rounded-full tw-p-0',\n default: '',\n },\n },\n defaultVariants: {\n type: 'secondary',\n size: 'middle',\n disabled: false,\n block: false,\n shape: 'default',\n },\n },\n);\n\nconst VALID_TYPES: ButtonType[] = [\n 'primary',\n 'secondary',\n 'dangerous',\n 'text',\n 'inverse',\n 'link',\n];\n\nfunction Button(props: IButtonProps, ref: React.Ref<HTMLElement>) {\n const {\n type: rawType = 'secondary',\n size: customSize,\n shape = 'default',\n loading = false,\n disabled,\n icon,\n className,\n children,\n href,\n target,\n onClick,\n block,\n htmlType = 'button',\n style,\n ghost,\n showArrow = false,\n ...rest\n } = props;\n\n // Radix Trigger asChild 会传入 type=\"button\"(HTML button type),与组件的 type 变体冲突\n // 当收到非法变体值时回退到 'secondary'\n const type: ButtonType = VALID_TYPES.includes(rawType as ButtonType)\n ? (rawType as ButtonType)\n : 'secondary';\n\n const contextDisabled = useContext(DisabledContext);\n const mergedDisabled = disabled ?? contextDisabled;\n\n const contentSize = useContext(SizeContext);\n const { compactSize, compactItemClassnames } =\n useCompactItemContext(btnPrefix);\n const size = customSize || compactSize || contentSize || 'middle';\n\n const [innerLoading, setInnerLoading] = useState(false);\n\n useEffect(() => {\n if (typeof loading === 'object' && loading.delay) {\n const timer = setTimeout(() => setInnerLoading(true), loading.delay);\n return () => clearTimeout(timer);\n }\n setInnerLoading(!!loading);\n }, [loading]);\n\n const isDisabled = innerLoading || mergedDisabled;\n const iconSize = size === 'small' ? 12 : 14;\n const iconNode = setIcon(icon as React.ReactElement, innerLoading, iconSize);\n\n // Build compact-mode border-radius and margin overrides\n const compactClasses = compactItemClassnames\n ? cn(\n // all compact items: remove border-radius on inner edges\n !compactItemClassnames[`${btnPrefix}-compact-first-item`] &&\n '!tw-rounded-l-none',\n !compactItemClassnames[`${btnPrefix}-compact-last-item`] &&\n '!tw-rounded-r-none',\n // merge borders via negative margin (except first item)\n !compactItemClassnames[`${btnPrefix}-compact-first-item`] &&\n '-tw-ml-px',\n )\n : undefined;\n\n const isIconOnly = !!icon && !children && !showArrow;\n\n const classes = cn(\n buttonVariants({\n type,\n size,\n disabled: !!isDisabled,\n block: !!block,\n shape,\n }),\n ghost &&\n '!tw-border-[var(--action-ghost-normal)] !tw-bg-[var(--action-ghost-normal)] !tw-shadow-none hover:!tw-border-[var(--action-ghost-normal)]',\n ghost &&\n type === 'primary' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'dangerous' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'secondary' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'inverse' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-bg-[var(--action-ghost-normal)] !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'primary' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-primary-subtle-hover)]',\n ghost &&\n type === 'dangerous' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-destructive-hover)]',\n ghost &&\n type === 'secondary' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-hover)]',\n ghost &&\n type === 'inverse' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-inverted-hover)]',\n ghost && type === 'primary' && '!tw-text-[var(--action-primary-normal)]',\n ghost &&\n type === 'dangerous' &&\n '!tw-text-[var(--action-destructive-normal)]',\n ghost && type === 'secondary' && '!tw-text-[var(--action-neutral-normal)]',\n ghost && type === 'inverse' && '!tw-text-[var(--action-inverted-normal)]',\n // icon-only 方形按钮:宽度由 aspect-ratio 从 height 反推,但该反推值\n // 不构成 flex shrink 的下限——父行 max-content 被低估时(同行存在\n // width:auto Select / RangePicker 等子树时 Chromium 恒少算几 px),\n // 缺口会全压到本按钮上把它压扁。必须按 size 显式钳 min-width 兜底\n // (v2/antd 的 icon-only 即固定 width);带 ! 以盖过 shape=circle\n // 的 tw-min-w-0\n isIconOnly && 'tw-aspect-square !tw-px-0',\n isIconOnly && size === 'small' && '!tw-min-w-7',\n isIconOnly && size === 'middle' && '!tw-min-w-8',\n isIconOnly && size === 'large' && '!tw-min-w-10',\n compactClasses,\n className,\n );\n\n const contentClasses = cn(\n // Typography: the approved Label utility belongs to the text-bearing\n // element. Icon-only controls intentionally have no label Typography.\n 'tw-inline-flex tw-min-w-0 tw-items-center tw-gap-1 tw-truncate tw-text-typography-label',\n ghost &&\n type === 'inverse' &&\n size === 'middle' &&\n 'tw-flex-[1_0_0] tw-text-[var(--action-inverted-normal)]',\n );\n\n const arrowNode = showArrow ? (\n <span className=\"ald-btn-arrow tw-inline-flex tw-shrink-0 tw-items-center\">\n <ChevronDownLine size={16} />\n </span>\n ) : null;\n\n const buttonContent = (\n <>\n {iconNode}\n {children && <span className={contentClasses}>{children}</span>}\n {arrowNode}\n </>\n );\n\n if (href) {\n return (\n <a\n {...rest}\n className={classes}\n style={style}\n href={isDisabled ? undefined : href}\n target={target}\n ref={ref as React.Ref<HTMLAnchorElement>}\n onClick={isDisabled ? undefined : onClick}\n aria-disabled={isDisabled || undefined}\n >\n {buttonContent}\n </a>\n );\n }\n\n return (\n <button\n {...rest}\n type={\n htmlType === 'submit'\n ? 'submit'\n : htmlType === 'reset'\n ? 'reset'\n : 'button'\n }\n className={classes}\n style={style}\n disabled={isDisabled}\n aria-disabled={isDisabled || undefined}\n ref={ref as React.Ref<HTMLButtonElement>}\n onClick={onClick}\n >\n {buttonContent}\n </button>\n );\n}\n\nexport default forwardRef(Button);\n"],"mappings":";;;;;;;;;;AAQA,IAAa,YAAY;AAmDzB,IAAa,WACX,UACA,SACA,OAAwB,UACrB;AACH,KAAI,QACF,QACE,oBAAC,QAAD;EACE,WAAU;EACJ;EACN,OAAM;EACN,CAAA;AAIN,KAAI,UAAU;EACZ,MAAM,IAAqC;GACzC,WAAW;GACX,MAAM;GACN,GAAG,SAAS;GACb;AACD,IAAE,OAAO;AACT,SAAO,MAAM,aAAa,UAAU,EAAE;;AAExC,QAAO,oBAAA,UAAA,EAAK,CAAA;;AAGd,IAAM,iBAAiB,IACrB;CACE;CACA;CACA;CACA;CACD,EACD;CACE,UAAU;EACR,MAAM;GACJ,SAAS;IACP,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,WAAW;IACT,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,WAAW;IACT,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,MAAM;IACJ,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,SAAS;IACP,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,MAAM;IACJ,GAAG,UAAU;IACb;IACA;IACA;IACD;GACF;EACD,MAAM;GAIJ,OAAO;IACL,GAAG,UAAU;IACb;IACA;IACD;GACD,QAAQ;IACN,GAAG,UAAU;IACb;IACA;IACD;GACD,OAAO;IACL,GAAG,UAAU;IACb;IACA;IACD;GACF;EACD,UAAU;GACR,MAAM;GACN,OAAO;GACR;EACD,OAAO;GACL,MAAM;GACN,OAAO;GACR;EACD,OAAO;GACL,QAAQ;GACR,SAAS;GACV;EACF;CACD,iBAAiB;EACf,MAAM;EACN,MAAM;EACN,UAAU;EACV,OAAO;EACP,OAAO;EACR;CACF,CACF;AAED,IAAM,cAA4B;CAChC;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,OAAO,OAAqB,KAA6B;CAChE,MAAM,EACJ,MAAM,UAAU,aAChB,MAAM,YACN,QAAQ,WACR,UAAU,OACV,UACA,MACA,WACA,UACA,MACA,QACA,SACA,OACA,WAAW,UACX,OACA,OACA,YAAY,OACZ,GAAG,SACD;CAIJ,MAAM,OAAmB,YAAY,SAAS,QAAsB,GAC/D,UACD;CAEJ,MAAM,kBAAkB,WAAW,gBAAgB;CACnD,MAAM,iBAAiB,YAAY;CAEnC,MAAM,cAAc,WAAW,YAAY;CAC3C,MAAM,EAAE,aAAa,0BACnB,sBAAsB,UAAU;CAClC,MAAM,OAAO,cAAc,eAAe,eAAe;CAEzD,MAAM,CAAC,cAAc,mBAAmB,SAAS,MAAM;AAEvD,iBAAgB;AACd,MAAI,OAAO,YAAY,YAAY,QAAQ,OAAO;GAChD,MAAM,QAAQ,iBAAiB,gBAAgB,KAAK,EAAE,QAAQ,MAAM;AACpE,gBAAa,aAAa,MAAM;;AAElC,kBAAgB,CAAC,CAAC,QAAQ;IACzB,CAAC,QAAQ,CAAC;CAEb,MAAM,aAAa,gBAAgB;CAEnC,MAAM,WAAW,QAAQ,MAA4B,cADpC,SAAS,UAAU,KAAK,GACmC;CAG5E,MAAM,iBAAiB,wBACnB,GAEE,CAAC,sBAAsB,iCACrB,sBACF,CAAC,sBAAsB,gCACrB,sBAEF,CAAC,sBAAsB,iCACrB,YACH,GACD;CAEJ,MAAM,aAAa,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;CAE3C,MAAM,UAAU,GACd,eAAe;EACb;EACA;EACA,UAAU,CAAC,CAAC;EACZ,OAAO,CAAC,CAAC;EACT;EACD,CAAC,EACF,SACE,6IACF,SACE,SAAS,aACT,SAAS,YACT,wHACF,SACE,SAAS,eACT,SAAS,YACT,wHACF,SACE,SAAS,eACT,SAAS,YACT,wHACF,SACE,SAAS,aACT,SAAS,YACT,4JACF,SACE,SAAS,aACT,sEACF,SACE,SAAS,eACT,yEACF,SACE,SAAS,eACT,6DACF,SACE,SAAS,aACT,sEACF,SAAS,SAAS,aAAa,2CAC/B,SACE,SAAS,eACT,+CACF,SAAS,SAAS,eAAe,2CACjC,SAAS,SAAS,aAAa,4CAO/B,cAAc,6BACd,cAAc,SAAS,WAAW,eAClC,cAAc,SAAS,YAAY,eACnC,cAAc,SAAS,WAAW,gBAClC,gBACA,UACD;CAED,MAAM,iBAAiB,GAGrB,2FACA,SACE,SAAS,aACT,SAAS,YACT,0DACH;CAQD,MAAM,gBACJ,qBAAA,UAAA,EAAA,UAAA;EACG;EACA,YAAY,oBAAC,QAAD;GAAM,WAAW;GAAiB;GAAgB,CAAA;EATjD,YAChB,oBAAC,QAAD;GAAM,WAAU;aACd,oBAAC,MAAD,EAAiB,MAAM,IAAM,CAAA;GACxB,CAAA,GACL;EAOC,EAAA,CAAA;AAGL,KAAI,KACF,QACE,oBAAC,KAAD;EACE,GAAI;EACJ,WAAW;EACJ;EACP,MAAM,aAAa,SAAY;EACvB;EACH;EACL,SAAS,aAAa,SAAY;EAClC,iBAAe,cAAc;YAE5B;EACC,CAAA;AAIR,QACE,oBAAC,UAAD;EACE,GAAI;EACJ,MACE,aAAa,WACT,WACA,aAAa,UACb,UACA;EAEN,WAAW;EACJ;EACP,UAAU;EACV,iBAAe,cAAc;EACxB;EACI;YAER;EACM,CAAA;;AAIb,IAAA,iBAAe,WAAW,OAAO"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Button/index.tsx"],"sourcesContent":["import { cva } from 'class-variance-authority';\nimport React, { forwardRef, useContext, useEffect, useState } from 'react';\nimport DisabledContext from '../ConfigProvider/DisabledContext';\nimport SizeContext from '../ConfigProvider/sizeContext';\nimport { ChevronDownLine, LoadingLine } from '../Icon';\nimport { cn } from '../lib/utils';\nimport { useCompactItemContext } from '../Space/CompactContext';\n\nexport const btnPrefix = 'ald-btn';\n\nexport type ButtonType =\n | 'primary'\n | 'secondary'\n | 'dangerous'\n | 'text'\n | 'inverse'\n | 'link';\nexport type Size = 'small' | 'middle' | 'large';\nexport interface IButtonProps {\n type?: ButtonType;\n size?: Size;\n disabled?: boolean;\n icon?: React.ReactNode;\n shape?: 'circle' | 'default';\n href?: string;\n target?: string;\n onClick?: React.MouseEventHandler<HTMLElement>;\n loading?: boolean | { delay?: number };\n children?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n block?: boolean;\n htmlType?: 'submit' | 'button' | 'reset';\n id?: string;\n tabIndex?: number;\n title?: string;\n 'aria-label'?: string;\n /** 透传到 button 元素的 data-testid,用于自动化测试定位(经 rest props 透传) */\n 'data-testid'?: string;\n ghost?: boolean;\n danger?: boolean;\n color?: string;\n showArrow?: boolean;\n}\n\nexport function getButtonType(buttonType: ButtonType): string {\n return buttonType;\n}\nexport function getDangerStatus(buttonType: ButtonType): boolean {\n return buttonType === 'dangerous';\n}\nexport function getButtonSizeClass(s: Size): string {\n return ['small', 'large'].includes(s)\n ? `${btnPrefix}-${s}`\n : `${btnPrefix}-middle`;\n}\nexport function getShape(s: 'circle' | 'default'): 'circle' | 'default' {\n return s;\n}\nexport const setIcon = (\n iconNode: React.ReactElement,\n loading: boolean | { delay?: number },\n size: string | number = '1em',\n) => {\n if (loading) {\n return (\n <LoadingLine\n className=\"ald-loading-spin tw-shrink-0 tw-animate-spin\"\n size={size}\n color=\"currentColor\"\n />\n );\n }\n\n if (iconNode) {\n const p: Record<string, string | number> = {\n className: '',\n fill: 'currentColor',\n ...iconNode.props,\n };\n p.size = size;\n return React.cloneElement(iconNode, p);\n }\n return <></>;\n};\n\nconst buttonVariants = cva(\n [\n btnPrefix,\n 'tw-inline-flex tw-cursor-pointer tw-appearance-none tw-items-center tw-justify-center tw-no-underline tw-transition-colors [&_.i-icon]:tw-inline-flex [&_.i-icon]:tw-items-center',\n 'tw-border tw-border-solid',\n ],\n {\n variants: {\n type: {\n primary: [\n `${btnPrefix}-primary`,\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)] tw-text-[var(--action-inverted-normal)] tw-shadow-[var(--elevation-bottom-bottom-sm)]',\n 'hover:tw-bg-[var(--action-primary-hover)]',\n 'active:tw-bg-[var(--action-primary-active)]',\n ],\n secondary: [\n `${btnPrefix}-secondary`,\n 'tw-border-[var(--action-outline-normal)] tw-bg-[var(--action-inverted-normal)] tw-text-[var(--action-neutral-normal)] tw-shadow-[var(--elevation-bottom-bottom-sm)]',\n 'hover:tw-border-[var(--action-outline-hover)] hover:tw-bg-[var(--action-inverted-normal)]',\n 'active:tw-border-[var(--action-outline-active)] active:tw-bg-[var(--action-inverted-active)] active:tw-text-[var(--action-neutral-active)]',\n ],\n dangerous: [\n `${btnPrefix}-dangerous`,\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-destructive-normal)] tw-text-[var(--action-inverted-normal)] tw-shadow-[var(--elevation-bottom-bottom-sm)]',\n 'hover:tw-bg-[var(--action-destructive-hover)]',\n 'active:tw-bg-[var(--action-destructive-active)]',\n ],\n text: [\n `${btnPrefix}-text`,\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-ghost-normal)] tw-text-[var(--action-neutral-normal)]',\n 'hover:tw-bg-[var(--action-ghost-hover)] hover:tw-text-[var(--action-neutral-hover)]',\n 'active:tw-bg-[var(--action-ghost-active)] active:tw-text-[var(--action-neutral-active)]',\n ],\n inverse: [\n `${btnPrefix}-inverse`,\n 'tw-border-[var(--action-neutral-normal)] tw-bg-[var(--action-ghost-normal)] tw-text-[var(--content-inverted-primary)]',\n 'hover:tw-border-[var(--action-ghost-inverted-hover)] hover:tw-bg-[var(--action-ghost-normal)]',\n 'active:tw-bg-[var(--action-ghost-inverted-active)]',\n ],\n link: [\n `${btnPrefix}-link`,\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-ghost-normal)] tw-text-[var(--action-primary-normal)]',\n 'hover:tw-text-[var(--action-primary-hover)]',\n 'active:tw-text-[var(--action-primary-active)]',\n ],\n },\n size: {\n // Component Geometry: size variants own the control envelope. The\n // inline gap remains relationship-preserving implementation while the\n // Action Association Constraint has no Primitive Resolution.\n small: [\n `${btnPrefix}-small`,\n 'tw-h-7 tw-min-w-7 tw-gap-1 tw-rounded-r-75',\n 'tw-px-[var(--alias-padding-150-minus-1)] tw-py-[var(--alias-padding-75-minus-1)]',\n ],\n middle: [\n `${btnPrefix}-middle`,\n 'tw-h-8 tw-min-w-8 tw-gap-1 tw-rounded-r-75',\n 'tw-px-[var(--alias-padding-150-minus-1)] tw-py-[var(--alias-padding-75-minus-1)]',\n ],\n large: [\n `${btnPrefix}-large`,\n 'tw-h-10 tw-min-w-10 tw-gap-1 tw-rounded-r-75',\n 'tw-px-[var(--alias-padding-150-minus-1)] tw-py-[var(--alias-padding-75-minus-1)]',\n ],\n },\n disabled: {\n true: 'tw-pointer-events-none tw-cursor-default tw-opacity-50',\n false: '',\n },\n block: {\n true: 'tw-w-full',\n false: '',\n },\n shape: {\n circle: 'tw-min-w-0 tw-rounded-full tw-p-0',\n default: '',\n },\n },\n defaultVariants: {\n type: 'secondary',\n size: 'middle',\n disabled: false,\n block: false,\n shape: 'default',\n },\n },\n);\n\nconst VALID_TYPES: ButtonType[] = [\n 'primary',\n 'secondary',\n 'dangerous',\n 'text',\n 'inverse',\n 'link',\n];\n\nfunction Button(props: IButtonProps, ref: React.Ref<HTMLElement>) {\n const {\n type: rawType = 'secondary',\n size: customSize,\n shape = 'default',\n loading = false,\n disabled,\n icon,\n className,\n children,\n href,\n target,\n onClick,\n block,\n htmlType = 'button',\n style,\n ghost,\n showArrow = false,\n ...rest\n } = props;\n\n // Radix Trigger asChild 会传入 type=\"button\"(HTML button type),与组件的 type 变体冲突\n // 当收到非法变体值时回退到 'secondary'\n const type: ButtonType = VALID_TYPES.includes(rawType as ButtonType)\n ? (rawType as ButtonType)\n : 'secondary';\n\n const contextDisabled = useContext(DisabledContext);\n const mergedDisabled = disabled ?? contextDisabled;\n\n const contentSize = useContext(SizeContext);\n const { compactSize, compactItemClassnames } =\n useCompactItemContext(btnPrefix);\n const size = customSize || compactSize || contentSize || 'middle';\n\n const [innerLoading, setInnerLoading] = useState(false);\n\n useEffect(() => {\n if (typeof loading === 'object' && loading.delay) {\n const timer = setTimeout(() => setInnerLoading(true), loading.delay);\n return () => clearTimeout(timer);\n }\n setInnerLoading(!!loading);\n }, [loading]);\n\n const isDisabled = innerLoading || mergedDisabled;\n const iconSize = size === 'small' ? 12 : 14;\n const iconNode = setIcon(icon as React.ReactElement, innerLoading, iconSize);\n\n // Build compact-mode border-radius and margin overrides\n const compactClasses = compactItemClassnames\n ? cn(\n // all compact items: remove border-radius on inner edges\n !compactItemClassnames[`${btnPrefix}-compact-first-item`] &&\n '!tw-rounded-l-none',\n !compactItemClassnames[`${btnPrefix}-compact-last-item`] &&\n '!tw-rounded-r-none',\n // merge borders via negative margin (except first item)\n !compactItemClassnames[`${btnPrefix}-compact-first-item`] &&\n '-tw-ml-px',\n )\n : undefined;\n\n const isIconOnly = !!icon && !children && !showArrow;\n const focusRingClasses = !isDisabled && [\n 'focus-visible:tw-outline',\n 'focus-visible:tw-outline-2',\n 'focus-visible:tw-outline-offset-2',\n 'focus-visible:tw-outline-[var(--focus-ring)]',\n 'forced-colors:focus-visible:tw-outline-[Highlight]',\n ];\n\n const classes = cn(\n buttonVariants({\n type,\n size,\n disabled: !!isDisabled,\n block: !!block,\n shape,\n }),\n ghost &&\n '!tw-border-[var(--action-ghost-normal)] !tw-bg-[var(--action-ghost-normal)] !tw-shadow-none hover:!tw-border-[var(--action-ghost-normal)]',\n ghost &&\n type === 'primary' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'dangerous' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'secondary' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'inverse' &&\n size === 'middle' &&\n '!tw-h-8 !tw-min-w-8 !tw-gap-[var(--component-gap-xs)] !tw-rounded-r-75 !tw-bg-[var(--action-ghost-normal)] !tw-px-[var(--component-padding-md)] !tw-py-0',\n ghost &&\n type === 'primary' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-primary-subtle-hover)]',\n ghost &&\n type === 'dangerous' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-destructive-hover)]',\n ghost &&\n type === 'secondary' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-hover)]',\n ghost &&\n type === 'inverse' &&\n '!tw-rounded-r-75 hover:!tw-bg-[var(--action-ghost-inverted-hover)]',\n ghost && type === 'primary' && '!tw-text-[var(--action-primary-normal)]',\n ghost &&\n type === 'dangerous' &&\n '!tw-text-[var(--action-destructive-normal)]',\n ghost && type === 'secondary' && '!tw-text-[var(--action-neutral-normal)]',\n ghost && type === 'inverse' && '!tw-text-[var(--action-inverted-normal)]',\n // icon-only 方形按钮:宽度由 aspect-ratio 从 height 反推,但该反推值\n // 不构成 flex shrink 的下限——父行 max-content 被低估时(同行存在\n // width:auto Select / RangePicker 等子树时 Chromium 恒少算几 px),\n // 缺口会全压到本按钮上把它压扁。必须按 size 显式钳 min-width 兜底\n // (v2/antd 的 icon-only 即固定 width);带 ! 以盖过 shape=circle\n // 的 tw-min-w-0\n isIconOnly && 'tw-aspect-square !tw-px-0',\n isIconOnly && size === 'small' && '!tw-min-w-7',\n isIconOnly && size === 'middle' && '!tw-min-w-8',\n isIconOnly && size === 'large' && '!tw-min-w-10',\n focusRingClasses,\n compactClasses,\n className,\n );\n\n const contentClasses = cn(\n // Typography: the approved Label utility belongs to the text-bearing\n // element. Icon-only controls intentionally have no label Typography.\n 'tw-inline-flex tw-min-w-0 tw-items-center tw-gap-1 tw-truncate tw-text-typography-label',\n ghost &&\n type === 'inverse' &&\n size === 'middle' &&\n 'tw-flex-[1_0_0] tw-text-[var(--action-inverted-normal)]',\n );\n\n const arrowNode = showArrow ? (\n <span className=\"ald-btn-arrow tw-inline-flex tw-shrink-0 tw-items-center\">\n <ChevronDownLine size={16} />\n </span>\n ) : null;\n\n const buttonContent = (\n <>\n {iconNode}\n {children && <span className={contentClasses}>{children}</span>}\n {arrowNode}\n </>\n );\n\n if (href) {\n return (\n <a\n {...rest}\n className={classes}\n style={style}\n href={isDisabled ? undefined : href}\n target={target}\n ref={ref as React.Ref<HTMLAnchorElement>}\n onClick={isDisabled ? undefined : onClick}\n aria-disabled={isDisabled || undefined}\n >\n {buttonContent}\n </a>\n );\n }\n\n return (\n <button\n {...rest}\n type={\n htmlType === 'submit'\n ? 'submit'\n : htmlType === 'reset'\n ? 'reset'\n : 'button'\n }\n className={classes}\n style={style}\n disabled={isDisabled}\n aria-disabled={isDisabled || undefined}\n ref={ref as React.Ref<HTMLButtonElement>}\n onClick={onClick}\n >\n {buttonContent}\n </button>\n );\n}\n\nexport default forwardRef(Button);\n"],"mappings":";;;;;;;;;;AAQA,IAAa,YAAY;AAmDzB,IAAa,WACX,UACA,SACA,OAAwB,UACrB;AACH,KAAI,QACF,QACE,oBAAC,QAAD;EACE,WAAU;EACJ;EACN,OAAM;EACN,CAAA;AAIN,KAAI,UAAU;EACZ,MAAM,IAAqC;GACzC,WAAW;GACX,MAAM;GACN,GAAG,SAAS;GACb;AACD,IAAE,OAAO;AACT,SAAO,MAAM,aAAa,UAAU,EAAE;;AAExC,QAAO,oBAAA,UAAA,EAAK,CAAA;;AAGd,IAAM,iBAAiB,IACrB;CACE;CACA;CACA;CACD,EACD;CACE,UAAU;EACR,MAAM;GACJ,SAAS;IACP,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,WAAW;IACT,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,WAAW;IACT,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,MAAM;IACJ,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,SAAS;IACP,GAAG,UAAU;IACb;IACA;IACA;IACD;GACD,MAAM;IACJ,GAAG,UAAU;IACb;IACA;IACA;IACD;GACF;EACD,MAAM;GAIJ,OAAO;IACL,GAAG,UAAU;IACb;IACA;IACD;GACD,QAAQ;IACN,GAAG,UAAU;IACb;IACA;IACD;GACD,OAAO;IACL,GAAG,UAAU;IACb;IACA;IACD;GACF;EACD,UAAU;GACR,MAAM;GACN,OAAO;GACR;EACD,OAAO;GACL,MAAM;GACN,OAAO;GACR;EACD,OAAO;GACL,QAAQ;GACR,SAAS;GACV;EACF;CACD,iBAAiB;EACf,MAAM;EACN,MAAM;EACN,UAAU;EACV,OAAO;EACP,OAAO;EACR;CACF,CACF;AAED,IAAM,cAA4B;CAChC;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,OAAO,OAAqB,KAA6B;CAChE,MAAM,EACJ,MAAM,UAAU,aAChB,MAAM,YACN,QAAQ,WACR,UAAU,OACV,UACA,MACA,WACA,UACA,MACA,QACA,SACA,OACA,WAAW,UACX,OACA,OACA,YAAY,OACZ,GAAG,SACD;CAIJ,MAAM,OAAmB,YAAY,SAAS,QAAsB,GAC/D,UACD;CAEJ,MAAM,kBAAkB,WAAW,gBAAgB;CACnD,MAAM,iBAAiB,YAAY;CAEnC,MAAM,cAAc,WAAW,YAAY;CAC3C,MAAM,EAAE,aAAa,0BACnB,sBAAsB,UAAU;CAClC,MAAM,OAAO,cAAc,eAAe,eAAe;CAEzD,MAAM,CAAC,cAAc,mBAAmB,SAAS,MAAM;AAEvD,iBAAgB;AACd,MAAI,OAAO,YAAY,YAAY,QAAQ,OAAO;GAChD,MAAM,QAAQ,iBAAiB,gBAAgB,KAAK,EAAE,QAAQ,MAAM;AACpE,gBAAa,aAAa,MAAM;;AAElC,kBAAgB,CAAC,CAAC,QAAQ;IACzB,CAAC,QAAQ,CAAC;CAEb,MAAM,aAAa,gBAAgB;CAEnC,MAAM,WAAW,QAAQ,MAA4B,cADpC,SAAS,UAAU,KAAK,GACmC;CAG5E,MAAM,iBAAiB,wBACnB,GAEE,CAAC,sBAAsB,iCACrB,sBACF,CAAC,sBAAsB,gCACrB,sBAEF,CAAC,sBAAsB,iCACrB,YACH,GACD;CAEJ,MAAM,aAAa,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;CAC3C,MAAM,mBAAmB,CAAC,cAAc;EACtC;EACA;EACA;EACA;EACA;EACD;CAED,MAAM,UAAU,GACd,eAAe;EACb;EACA;EACA,UAAU,CAAC,CAAC;EACZ,OAAO,CAAC,CAAC;EACT;EACD,CAAC,EACF,SACE,6IACF,SACE,SAAS,aACT,SAAS,YACT,wHACF,SACE,SAAS,eACT,SAAS,YACT,wHACF,SACE,SAAS,eACT,SAAS,YACT,wHACF,SACE,SAAS,aACT,SAAS,YACT,4JACF,SACE,SAAS,aACT,sEACF,SACE,SAAS,eACT,yEACF,SACE,SAAS,eACT,6DACF,SACE,SAAS,aACT,sEACF,SAAS,SAAS,aAAa,2CAC/B,SACE,SAAS,eACT,+CACF,SAAS,SAAS,eAAe,2CACjC,SAAS,SAAS,aAAa,4CAO/B,cAAc,6BACd,cAAc,SAAS,WAAW,eAClC,cAAc,SAAS,YAAY,eACnC,cAAc,SAAS,WAAW,gBAClC,kBACA,gBACA,UACD;CAED,MAAM,iBAAiB,GAGrB,2FACA,SACE,SAAS,aACT,SAAS,YACT,0DACH;CAQD,MAAM,gBACJ,qBAAA,UAAA,EAAA,UAAA;EACG;EACA,YAAY,oBAAC,QAAD;GAAM,WAAW;GAAiB;GAAgB,CAAA;EATjD,YAChB,oBAAC,QAAD;GAAM,WAAU;aACd,oBAAC,MAAD,EAAiB,MAAM,IAAM,CAAA;GACxB,CAAA,GACL;EAOC,EAAA,CAAA;AAGL,KAAI,KACF,QACE,oBAAC,KAAD;EACE,GAAI;EACJ,WAAW;EACJ;EACP,MAAM,aAAa,SAAY;EACvB;EACH;EACL,SAAS,aAAa,SAAY;EAClC,iBAAe,cAAc;YAE5B;EACC,CAAA;AAIR,QACE,oBAAC,UAAD;EACE,GAAI;EACJ,MACE,aAAa,WACT,WACA,aAAa,UACb,UACA;EAEN,WAAW;EACJ;EACP,UAAU;EACV,iBAAe,cAAc;EACxB;EACI;YAER;EACM,CAAA;;AAIb,IAAA,iBAAe,WAAW,OAAO"}
@@ -45,7 +45,13 @@ function Checkbox(props) {
45
45
  className: cn("ald-checkbox-wrapper ald-checkbox tw-inline-flex tw-cursor-pointer tw-items-center tw-gap-2 tw-leading-5", mergedDisabled && "tw-cursor-default", size === "small" && "ald-checkbox-small", !mergedDisabled && "[&:hover_.ald-checkbox-inner]:tw-border-2 [&:hover_.ald-checkbox-inner]:tw-border-[var(--border-brand-strong)]", !mergedDisabled && checked && "[&:hover_.ald-checkbox-inner]:tw-border-[var(--action-ghost-normal)] [&:hover_.ald-checkbox-inner]:tw-bg-[var(--action-primary-hover)]", className),
46
46
  style,
47
47
  children: [/* @__PURE__ */ jsxs("span", {
48
- className: cn("ald-checkbox-inner tw-relative tw-box-border tw-flex tw-size-4 tw-min-h-4 tw-min-w-4 tw-items-center tw-justify-center tw-rounded-r-50 tw-border-2 tw-border-solid tw-transition-colors tw-duration-200", checked && "ald-checkbox-checked", checked && !mergedDisabled && "tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)]", checked && mergedDisabled && "tw-border-[var(--content-disabled)] tw-bg-[var(--content-disabled)]", !checked && !indeterminate && mergedDisabled && "tw-border-[var(--content-disabled)] tw-bg-[var(--background-neutral-on-subtle)]", !checked && !indeterminate && !mergedDisabled && !alert && "tw-border-[var(--border-neutral-subtle)] tw-bg-[var(--background-default)]", !checked && !indeterminate && !mergedDisabled && alert && "tw-border-[var(--border-negative-strong)] tw-bg-[var(--background-default)]", indeterminate && !checked && "ald-checkbox-indeterminate", indeterminate && !checked && !mergedDisabled && "tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)]", indeterminate && !checked && mergedDisabled && "tw-border-[var(--content-disabled)] tw-bg-[var(--content-disabled)]"),
48
+ className: cn("ald-checkbox-inner tw-relative tw-box-border tw-flex tw-size-4 tw-min-h-4 tw-min-w-4 tw-items-center tw-justify-center tw-rounded-r-50 tw-border-2 tw-border-solid tw-transition-colors tw-duration-200", !mergedDisabled && [
49
+ "has-[input:focus-visible]:tw-shadow-[0_0_0_2px_var(--focus-ring)]",
50
+ "forced-colors:has-[input:focus-visible]:tw-outline",
51
+ "forced-colors:has-[input:focus-visible]:tw-outline-2",
52
+ "forced-colors:has-[input:focus-visible]:tw-outline-offset-2",
53
+ "forced-colors:has-[input:focus-visible]:tw-outline-[Highlight]"
54
+ ], checked && "ald-checkbox-checked", checked && !mergedDisabled && "tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)]", checked && mergedDisabled && "tw-border-[var(--content-disabled)] tw-bg-[var(--content-disabled)]", !checked && !indeterminate && mergedDisabled && "tw-border-[var(--content-disabled)] tw-bg-[var(--background-neutral-on-subtle)]", !checked && !indeterminate && !mergedDisabled && !alert && "tw-border-[var(--border-neutral-subtle)] tw-bg-[var(--background-default)]", !checked && !indeterminate && !mergedDisabled && alert && "tw-border-[var(--border-negative-strong)] tw-bg-[var(--background-default)]", indeterminate && !checked && "ald-checkbox-indeterminate", indeterminate && !checked && !mergedDisabled && "tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)]", indeterminate && !checked && mergedDisabled && "tw-border-[var(--content-disabled)] tw-bg-[var(--content-disabled)]"),
49
55
  children: [/* @__PURE__ */ jsx("input", {
50
56
  ref: inputRef,
51
57
  type: "checkbox",
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Checkbox/index.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport DisabledContext from '../ConfigProvider/DisabledContext';\nimport { cn } from '../lib/utils';\nimport {\n CheckboxChangeEvent,\n CheckboxValueType,\n ICheckboxGroupProps,\n ICheckboxProps,\n} from './type';\n\nexport type { CheckboxChangeEvent, CheckboxValueType };\nexport type { CheckboxOptionType } from './type';\nexport type { ICheckboxProps, ICheckboxGroupProps };\n\ninterface CheckboxGroupContextValue {\n value: CheckboxValueType[];\n disabled?: boolean;\n name?: string;\n toggleOption: (value: CheckboxValueType, checked: boolean) => void;\n}\n\nconst CheckboxGroupContext = createContext<CheckboxGroupContextValue | null>(\n null,\n);\n\nfunction Checkbox(props: ICheckboxProps) {\n const {\n className,\n disabled: customDisabled,\n alert,\n bold,\n size,\n checked: controlledChecked,\n defaultChecked,\n indeterminate,\n onChange,\n onClick,\n autoFocus,\n children,\n value,\n name,\n style,\n 'data-testid': dataTestid,\n 'aria-label': ariaLabel,\n } = props;\n\n const disabled = useContext(DisabledContext);\n const group = useContext(CheckboxGroupContext);\n const isGroupCheckbox = group !== null && value !== undefined;\n const mergedDisabled = group?.disabled || customDisabled || disabled;\n\n const isControlled = isGroupCheckbox || 'checked' in props;\n const [innerChecked, setInnerChecked] = useState(defaultChecked ?? false);\n const checked = isGroupCheckbox\n ? group.value.includes(value)\n : isControlled\n ? controlledChecked\n : innerChecked;\n\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.indeterminate = !!indeterminate;\n }\n }, [indeterminate]);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (mergedDisabled) return;\n const newChecked = e.target.checked;\n if (isGroupCheckbox) {\n group.toggleOption(value, newChecked);\n } else if (!isControlled) {\n setInnerChecked(newChecked);\n }\n onChange?.({\n target: { checked: newChecked, value },\n nativeEvent: e.nativeEvent,\n });\n };\n\n const handleLabelClick = (e: React.MouseEvent) => {\n if (mergedDisabled) return;\n if (onClick) {\n // Table row selection uses onClick — prevent label from also toggling input\n e.preventDefault();\n e.stopPropagation();\n onClick(e);\n }\n };\n\n return (\n <label\n onClick={handleLabelClick}\n data-testid={dataTestid}\n aria-label={ariaLabel}\n className={cn(\n 'ald-checkbox-wrapper ald-checkbox tw-inline-flex tw-cursor-pointer tw-items-center tw-gap-2 tw-leading-5',\n mergedDisabled && 'tw-cursor-default',\n size === 'small' && 'ald-checkbox-small',\n !mergedDisabled &&\n '[&:hover_.ald-checkbox-inner]:tw-border-2 [&:hover_.ald-checkbox-inner]:tw-border-[var(--border-brand-strong)]',\n !mergedDisabled &&\n checked &&\n '[&:hover_.ald-checkbox-inner]:tw-border-[var(--action-ghost-normal)] [&:hover_.ald-checkbox-inner]:tw-bg-[var(--action-primary-hover)]',\n className,\n )}\n style={style}\n >\n <span\n className={cn(\n 'ald-checkbox-inner tw-relative tw-box-border tw-flex tw-size-4 tw-min-h-4 tw-min-w-4 tw-items-center tw-justify-center tw-rounded-r-50 tw-border-2 tw-border-solid tw-transition-colors tw-duration-200',\n checked && 'ald-checkbox-checked',\n checked &&\n !mergedDisabled &&\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)]',\n checked &&\n mergedDisabled &&\n 'tw-border-[var(--content-disabled)] tw-bg-[var(--content-disabled)]',\n !checked &&\n !indeterminate &&\n mergedDisabled &&\n 'tw-border-[var(--content-disabled)] tw-bg-[var(--background-neutral-on-subtle)]',\n !checked &&\n !indeterminate &&\n !mergedDisabled &&\n !alert &&\n 'tw-border-[var(--border-neutral-subtle)] tw-bg-[var(--background-default)]',\n !checked &&\n !indeterminate &&\n !mergedDisabled &&\n alert &&\n 'tw-border-[var(--border-negative-strong)] tw-bg-[var(--background-default)]',\n indeterminate && !checked && 'ald-checkbox-indeterminate',\n indeterminate &&\n !checked &&\n !mergedDisabled &&\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)]',\n indeterminate &&\n !checked &&\n mergedDisabled &&\n 'tw-border-[var(--content-disabled)] tw-bg-[var(--content-disabled)]',\n )}\n >\n <input\n ref={inputRef}\n type=\"checkbox\"\n className=\"tw-absolute tw-inset-0 tw-m-0 tw-cursor-pointer tw-opacity-0 disabled:tw-cursor-default\"\n checked={!!checked}\n disabled={mergedDisabled}\n onChange={handleChange}\n autoFocus={autoFocus}\n name={group?.name ?? name}\n value={value as string}\n />\n {(checked || (indeterminate && !checked)) && (\n <span\n className=\"tw-absolute tw-inset-0 tw-bg-center tw-bg-no-repeat\"\n style={{\n backgroundImage:\n indeterminate && !checked\n ? 'url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMiIgdmlld0JveD0iMCAwIDEwIDIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGlkPSJWZWN0b3IgMSAoU3Ryb2tlKSIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0wLjc1IDFDMC43NSAwLjU4NTc4NiAxLjA4NTc5IDAuMjUgMS41IDAuMjVIOC41QzguOTE0MjEgMC4yNSA5LjI1IDAuNTg1Nzg2IDkuMjUgMUM5LjI1IDEuNDE0MjEgOC45MTQyMSAxLjc1IDguNSAxLjc1SDEuNUMxLjA4NTc5IDEuNzUgMC43NSAxLjQxNDIxIDAuNzUgMVoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=\")'\n : 'url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iOCIgdmlld0JveD0iMCAwIDEwIDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGlkPSJJY29uIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTkuNTMwMzMgMC45Njk2N0M5LjgyMzIyIDEuMjYyNTYgOS44MjMyMiAxLjczNzQ0IDkuNTMwMzMgMi4wMzAzM0w0LjUzMDMzIDcuMDMwMzNDNC4yMzc0NCA3LjMyMzIyIDMuNzYyNTYgNy4zMjMyMiAzLjQ2OTY3IDcuMDMwMzNMMC45Njk2NyA0LjUzMDMzQzAuNjc2Nzc3IDQuMjM3NDQgMC42NzY3NzcgMy43NjI1NiAwLjk2OTY3IDMuNDY5NjdDMS4yNjI1NiAzLjE3Njc4IDEuNzM3NDQgMy4xNzY3OCAyLjAzMDMzIDMuNDY5NjdMNCA1LjQzOTM0TDguNDY5NjcgMC45Njk2N0M4Ljc2MjU2IDAuNjc2Nzc3IDkuMjM3NDQgMC42NzY3NzcgOS41MzAzMyAwLjk2OTY3WiIgZmlsbD0id2hpdGUiLz4KPC9zdmc+Cg==\")',\n backgroundSize:\n indeterminate && !checked ? '10px 2px' : '10px 8px',\n }}\n />\n )}\n </span>\n {children && (\n <span\n className={cn(\n 'ald-checkbox-label tw-inline-flex tw-select-none tw-items-center tw-gap-1 tw-text-[var(--content-primary)] [&_svg]:tw-inline-block [&_svg]:tw-shrink-0',\n 'tw-text-typography-label',\n bold && 'tw-font-medium',\n mergedDisabled &&\n 'tw-cursor-default tw-text-[var(--content-disabled)]',\n )}\n >\n {children}\n </span>\n )}\n </label>\n );\n}\n\nfunction CheckboxGroup(props: ICheckboxGroupProps) {\n const {\n className,\n disabled: customDisabled,\n size,\n options,\n value: controlledValue,\n defaultValue,\n onChange,\n direction,\n name,\n children,\n style,\n } = props;\n\n const disabled = useContext(DisabledContext);\n const mergedDisabled = customDisabled ?? disabled;\n\n const isControlled = 'value' in props;\n const [innerValue, setInnerValue] = useState<CheckboxValueType[]>(\n defaultValue ?? [],\n );\n const value = isControlled ? controlledValue ?? [] : innerValue;\n\n const handleGroupChange = (\n itemValue: CheckboxValueType,\n itemChecked: boolean,\n ) => {\n const newValue = itemChecked\n ? [...value, itemValue]\n : value.filter((v) => v !== itemValue);\n if (!isControlled) {\n setInnerValue(newValue);\n }\n onChange?.(newValue);\n };\n\n const renderOptions = () => {\n if (!options) return children;\n return options.map((opt) => {\n const optObj =\n typeof opt === 'object' ? opt : { label: String(opt), value: opt };\n return (\n <Checkbox\n key={String(optObj.value)}\n value={optObj.value}\n disabled={optObj.disabled}\n size={size}\n onChange={optObj.onChange}\n >\n {optObj.label}\n </Checkbox>\n );\n });\n };\n\n return (\n <div\n className={cn(\n 'ald-checkbox-group tw-flex tw-flex-wrap tw-gap-3',\n direction === 'vertical' && 'ald-checkbox-group-vertical tw-flex-col',\n size === 'small' && 'ald-checkbox-group-small',\n className,\n )}\n style={style}\n >\n <CheckboxGroupContext.Provider\n value={{\n value,\n disabled: mergedDisabled,\n name,\n toggleOption: handleGroupChange,\n }}\n >\n {renderOptions()}\n </CheckboxGroupContext.Provider>\n </div>\n );\n}\n\nCheckbox.Group = CheckboxGroup;\n\nexport default Checkbox;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Checkbox/index.tsx"],"sourcesContent":["import React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport DisabledContext from '../ConfigProvider/DisabledContext';\nimport { cn } from '../lib/utils';\nimport {\n CheckboxChangeEvent,\n CheckboxValueType,\n ICheckboxGroupProps,\n ICheckboxProps,\n} from './type';\n\nexport type { CheckboxChangeEvent, CheckboxValueType };\nexport type { CheckboxOptionType } from './type';\nexport type { ICheckboxProps, ICheckboxGroupProps };\n\ninterface CheckboxGroupContextValue {\n value: CheckboxValueType[];\n disabled?: boolean;\n name?: string;\n toggleOption: (value: CheckboxValueType, checked: boolean) => void;\n}\n\nconst CheckboxGroupContext = createContext<CheckboxGroupContextValue | null>(\n null,\n);\n\nfunction Checkbox(props: ICheckboxProps) {\n const {\n className,\n disabled: customDisabled,\n alert,\n bold,\n size,\n checked: controlledChecked,\n defaultChecked,\n indeterminate,\n onChange,\n onClick,\n autoFocus,\n children,\n value,\n name,\n style,\n 'data-testid': dataTestid,\n 'aria-label': ariaLabel,\n } = props;\n\n const disabled = useContext(DisabledContext);\n const group = useContext(CheckboxGroupContext);\n const isGroupCheckbox = group !== null && value !== undefined;\n const mergedDisabled = group?.disabled || customDisabled || disabled;\n\n const isControlled = isGroupCheckbox || 'checked' in props;\n const [innerChecked, setInnerChecked] = useState(defaultChecked ?? false);\n const checked = isGroupCheckbox\n ? group.value.includes(value)\n : isControlled\n ? controlledChecked\n : innerChecked;\n\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.indeterminate = !!indeterminate;\n }\n }, [indeterminate]);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (mergedDisabled) return;\n const newChecked = e.target.checked;\n if (isGroupCheckbox) {\n group.toggleOption(value, newChecked);\n } else if (!isControlled) {\n setInnerChecked(newChecked);\n }\n onChange?.({\n target: { checked: newChecked, value },\n nativeEvent: e.nativeEvent,\n });\n };\n\n const handleLabelClick = (e: React.MouseEvent) => {\n if (mergedDisabled) return;\n if (onClick) {\n // Table row selection uses onClick — prevent label from also toggling input\n e.preventDefault();\n e.stopPropagation();\n onClick(e);\n }\n };\n\n return (\n <label\n onClick={handleLabelClick}\n data-testid={dataTestid}\n aria-label={ariaLabel}\n className={cn(\n 'ald-checkbox-wrapper ald-checkbox tw-inline-flex tw-cursor-pointer tw-items-center tw-gap-2 tw-leading-5',\n mergedDisabled && 'tw-cursor-default',\n size === 'small' && 'ald-checkbox-small',\n !mergedDisabled &&\n '[&:hover_.ald-checkbox-inner]:tw-border-2 [&:hover_.ald-checkbox-inner]:tw-border-[var(--border-brand-strong)]',\n !mergedDisabled &&\n checked &&\n '[&:hover_.ald-checkbox-inner]:tw-border-[var(--action-ghost-normal)] [&:hover_.ald-checkbox-inner]:tw-bg-[var(--action-primary-hover)]',\n className,\n )}\n style={style}\n >\n <span\n className={cn(\n 'ald-checkbox-inner tw-relative tw-box-border tw-flex tw-size-4 tw-min-h-4 tw-min-w-4 tw-items-center tw-justify-center tw-rounded-r-50 tw-border-2 tw-border-solid tw-transition-colors tw-duration-200',\n // The native input owns focus and its visual control owns the\n // Focus State Layer. Checked, indeterminate, and alert styling\n // remain independent control states.\n !mergedDisabled && [\n 'has-[input:focus-visible]:tw-shadow-[0_0_0_2px_var(--focus-ring)]',\n 'forced-colors:has-[input:focus-visible]:tw-outline',\n 'forced-colors:has-[input:focus-visible]:tw-outline-2',\n 'forced-colors:has-[input:focus-visible]:tw-outline-offset-2',\n 'forced-colors:has-[input:focus-visible]:tw-outline-[Highlight]',\n ],\n checked && 'ald-checkbox-checked',\n checked &&\n !mergedDisabled &&\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)]',\n checked &&\n mergedDisabled &&\n 'tw-border-[var(--content-disabled)] tw-bg-[var(--content-disabled)]',\n !checked &&\n !indeterminate &&\n mergedDisabled &&\n 'tw-border-[var(--content-disabled)] tw-bg-[var(--background-neutral-on-subtle)]',\n !checked &&\n !indeterminate &&\n !mergedDisabled &&\n !alert &&\n 'tw-border-[var(--border-neutral-subtle)] tw-bg-[var(--background-default)]',\n !checked &&\n !indeterminate &&\n !mergedDisabled &&\n alert &&\n 'tw-border-[var(--border-negative-strong)] tw-bg-[var(--background-default)]',\n indeterminate && !checked && 'ald-checkbox-indeterminate',\n indeterminate &&\n !checked &&\n !mergedDisabled &&\n 'tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)]',\n indeterminate &&\n !checked &&\n mergedDisabled &&\n 'tw-border-[var(--content-disabled)] tw-bg-[var(--content-disabled)]',\n )}\n >\n <input\n ref={inputRef}\n type=\"checkbox\"\n className=\"tw-absolute tw-inset-0 tw-m-0 tw-cursor-pointer tw-opacity-0 disabled:tw-cursor-default\"\n checked={!!checked}\n disabled={mergedDisabled}\n onChange={handleChange}\n autoFocus={autoFocus}\n name={group?.name ?? name}\n value={value as string}\n />\n {(checked || (indeterminate && !checked)) && (\n <span\n className=\"tw-absolute tw-inset-0 tw-bg-center tw-bg-no-repeat\"\n style={{\n backgroundImage:\n indeterminate && !checked\n ? 'url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMiIgdmlld0JveD0iMCAwIDEwIDIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGlkPSJWZWN0b3IgMSAoU3Ryb2tlKSIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0wLjc1IDFDMC43NSAwLjU4NTc4NiAxLjA4NTc5IDAuMjUgMS41IDAuMjVIOC41QzguOTE0MjEgMC4yNSA5LjI1IDAuNTg1Nzg2IDkuMjUgMUM5LjI1IDEuNDE0MjEgOC45MTQyMSAxLjc1IDguNSAxLjc1SDEuNUMxLjA4NTc5IDEuNzUgMC43NSAxLjQxNDIxIDAuNzUgMVoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=\")'\n : 'url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iOCIgdmlld0JveD0iMCAwIDEwIDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGlkPSJJY29uIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTkuNTMwMzMgMC45Njk2N0M5LjgyMzIyIDEuMjYyNTYgOS44MjMyMiAxLjczNzQ0IDkuNTMwMzMgMi4wMzAzM0w0LjUzMDMzIDcuMDMwMzNDNC4yMzc0NCA3LjMyMzIyIDMuNzYyNTYgNy4zMjMyMiAzLjQ2OTY3IDcuMDMwMzNMMC45Njk2NyA0LjUzMDMzQzAuNjc2Nzc3IDQuMjM3NDQgMC42NzY3NzcgMy43NjI1NiAwLjk2OTY3IDMuNDY5NjdDMS4yNjI1NiAzLjE3Njc4IDEuNzM3NDQgMy4xNzY3OCAyLjAzMDMzIDMuNDY5NjdMNCA1LjQzOTM0TDguNDY5NjcgMC45Njk2N0M4Ljc2MjU2IDAuNjc2Nzc3IDkuMjM3NDQgMC42NzY3NzcgOS41MzAzMyAwLjk2OTY3WiIgZmlsbD0id2hpdGUiLz4KPC9zdmc+Cg==\")',\n backgroundSize:\n indeterminate && !checked ? '10px 2px' : '10px 8px',\n }}\n />\n )}\n </span>\n {children && (\n <span\n className={cn(\n 'ald-checkbox-label tw-inline-flex tw-select-none tw-items-center tw-gap-1 tw-text-[var(--content-primary)] [&_svg]:tw-inline-block [&_svg]:tw-shrink-0',\n 'tw-text-typography-label',\n bold && 'tw-font-medium',\n mergedDisabled &&\n 'tw-cursor-default tw-text-[var(--content-disabled)]',\n )}\n >\n {children}\n </span>\n )}\n </label>\n );\n}\n\nfunction CheckboxGroup(props: ICheckboxGroupProps) {\n const {\n className,\n disabled: customDisabled,\n size,\n options,\n value: controlledValue,\n defaultValue,\n onChange,\n direction,\n name,\n children,\n style,\n } = props;\n\n const disabled = useContext(DisabledContext);\n const mergedDisabled = customDisabled ?? disabled;\n\n const isControlled = 'value' in props;\n const [innerValue, setInnerValue] = useState<CheckboxValueType[]>(\n defaultValue ?? [],\n );\n const value = isControlled ? controlledValue ?? [] : innerValue;\n\n const handleGroupChange = (\n itemValue: CheckboxValueType,\n itemChecked: boolean,\n ) => {\n const newValue = itemChecked\n ? [...value, itemValue]\n : value.filter((v) => v !== itemValue);\n if (!isControlled) {\n setInnerValue(newValue);\n }\n onChange?.(newValue);\n };\n\n const renderOptions = () => {\n if (!options) return children;\n return options.map((opt) => {\n const optObj =\n typeof opt === 'object' ? opt : { label: String(opt), value: opt };\n return (\n <Checkbox\n key={String(optObj.value)}\n value={optObj.value}\n disabled={optObj.disabled}\n size={size}\n onChange={optObj.onChange}\n >\n {optObj.label}\n </Checkbox>\n );\n });\n };\n\n return (\n <div\n className={cn(\n 'ald-checkbox-group tw-flex tw-flex-wrap tw-gap-3',\n direction === 'vertical' && 'ald-checkbox-group-vertical tw-flex-col',\n size === 'small' && 'ald-checkbox-group-small',\n className,\n )}\n style={style}\n >\n <CheckboxGroupContext.Provider\n value={{\n value,\n disabled: mergedDisabled,\n name,\n toggleOption: handleGroupChange,\n }}\n >\n {renderOptions()}\n </CheckboxGroupContext.Provider>\n </div>\n );\n}\n\nCheckbox.Group = CheckboxGroup;\n\nexport default Checkbox;\n"],"mappings":";;;;;AA2BA,IAAM,uBAAuB,cAC3B,KACD;AAED,SAAS,SAAS,OAAuB;CACvC,MAAM,EACJ,WACA,UAAU,gBACV,OACA,MACA,MACA,SAAS,mBACT,gBACA,eACA,UACA,SACA,WACA,UACA,OACA,MACA,OACA,eAAe,YACf,cAAc,cACZ;CAEJ,MAAM,WAAW,WAAW,gBAAgB;CAC5C,MAAM,QAAQ,WAAW,qBAAqB;CAC9C,MAAM,kBAAkB,UAAU,QAAQ,UAAU;CACpD,MAAM,iBAAiB,OAAO,YAAY,kBAAkB;CAE5D,MAAM,eAAe,mBAAmB,aAAa;CACrD,MAAM,CAAC,cAAc,mBAAmB,SAAS,kBAAkB,MAAM;CACzE,MAAM,UAAU,kBACZ,MAAM,MAAM,SAAS,MAAM,GAC3B,eACA,oBACA;CAEJ,MAAM,WAAW,OAAyB,KAAK;AAE/C,iBAAgB;AACd,MAAI,SAAS,QACX,UAAS,QAAQ,gBAAgB,CAAC,CAAC;IAEpC,CAAC,cAAc,CAAC;CAEnB,MAAM,gBAAgB,MAA2C;AAC/D,MAAI,eAAgB;EACpB,MAAM,aAAa,EAAE,OAAO;AAC5B,MAAI,gBACF,OAAM,aAAa,OAAO,WAAW;WAC5B,CAAC,aACV,iBAAgB,WAAW;AAE7B,aAAW;GACT,QAAQ;IAAE,SAAS;IAAY;IAAO;GACtC,aAAa,EAAE;GAChB,CAAC;;CAGJ,MAAM,oBAAoB,MAAwB;AAChD,MAAI,eAAgB;AACpB,MAAI,SAAS;AAEX,KAAE,gBAAgB;AAClB,KAAE,iBAAiB;AACnB,WAAQ,EAAE;;;AAId,QACE,qBAAC,SAAD;EACE,SAAS;EACT,eAAa;EACb,cAAY;EACZ,WAAW,GACT,4GACA,kBAAkB,qBAClB,SAAS,WAAW,sBACpB,CAAC,kBACC,kHACF,CAAC,kBACC,WACA,0IACF,UACD;EACM;YAfT,CAiBE,qBAAC,QAAD;GACE,WAAW,GACT,2MAIA,CAAC,kBAAkB;IACjB;IACA;IACA;IACA;IACA;IACD,EACD,WAAW,wBACX,WACE,CAAC,kBACD,+EACF,WACE,kBACA,uEACF,CAAC,WACC,CAAC,iBACD,kBACA,mFACF,CAAC,WACC,CAAC,iBACD,CAAC,kBACD,CAAC,SACD,8EACF,CAAC,WACC,CAAC,iBACD,CAAC,kBACD,SACA,+EACF,iBAAiB,CAAC,WAAW,8BAC7B,iBACE,CAAC,WACD,CAAC,kBACD,+EACF,iBACE,CAAC,WACD,kBACA,sEACH;aA3CH,CA6CE,oBAAC,SAAD;IACE,KAAK;IACL,MAAK;IACL,WAAU;IACV,SAAS,CAAC,CAAC;IACX,UAAU;IACV,UAAU;IACC;IACX,MAAM,OAAO,QAAQ;IACd;IACP,CAAA,GACA,WAAY,iBAAiB,CAAC,YAC9B,oBAAC,QAAD;IACE,WAAU;IACV,OAAO;KACL,iBACE,iBAAiB,CAAC,UACd,ofACA;KACN,gBACE,iBAAiB,CAAC,UAAU,aAAa;KAC5C;IACD,CAAA,CAEC;MACN,YACC,oBAAC,QAAD;GACE,WAAW,GACT,0JACA,4BACA,QAAQ,kBACR,kBACE,sDACH;GAEA;GACI,CAAA,CAEH;;;AAIZ,SAAS,cAAc,OAA4B;CACjD,MAAM,EACJ,WACA,UAAU,gBACV,MACA,SACA,OAAO,iBACP,cACA,UACA,WACA,MACA,UACA,UACE;CAEJ,MAAM,WAAW,WAAW,gBAAgB;CAC5C,MAAM,iBAAiB,kBAAkB;CAEzC,MAAM,eAAe,WAAW;CAChC,MAAM,CAAC,YAAY,iBAAiB,SAClC,gBAAgB,EAAE,CACnB;CACD,MAAM,QAAQ,eAAe,mBAAmB,EAAE,GAAG;CAErD,MAAM,qBACJ,WACA,gBACG;EACH,MAAM,WAAW,cACb,CAAC,GAAG,OAAO,UAAU,GACrB,MAAM,QAAQ,MAAM,MAAM,UAAU;AACxC,MAAI,CAAC,aACH,eAAc,SAAS;AAEzB,aAAW,SAAS;;CAGtB,MAAM,sBAAsB;AAC1B,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO,QAAQ,KAAK,QAAQ;GAC1B,MAAM,SACJ,OAAO,QAAQ,WAAW,MAAM;IAAE,OAAO,OAAO,IAAI;IAAE,OAAO;IAAK;AACpE,UACE,oBAAC,UAAD;IAEE,OAAO,OAAO;IACd,UAAU,OAAO;IACX;IACN,UAAU,OAAO;cAEhB,OAAO;IACC,EAPJ,OAAO,OAAO,MAAM,CAOhB;IAEb;;AAGJ,QACE,oBAAC,OAAD;EACE,WAAW,GACT,oDACA,cAAc,cAAc,2CAC5B,SAAS,WAAW,4BACpB,UACD;EACM;YAEP,oBAAC,qBAAqB,UAAtB;GACE,OAAO;IACL;IACA,UAAU;IACV;IACA,cAAc;IACf;aAEA,eAAe;GACc,CAAA;EAC5B,CAAA;;AAIV,SAAS,QAAQ"}
@@ -1,7 +1,7 @@
1
1
  import { cn } from "../lib/utils.js";
2
2
  import Memo from "../Icon/components/ArrowRightLightLine.js";
3
- import React, { useContext, useRef, useState } from "react";
4
- import { jsx, jsxs } from "react/jsx-runtime";
3
+ import React, { useContext, useEffect, useId, useRef, useState } from "react";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/Collapse/index.tsx
6
6
  var CollapseContext = React.createContext(null);
7
7
  var normalizeKeys = (keys) => {
@@ -110,8 +110,13 @@ Panel.__COLLAPSE_PANEL = true;
110
110
  var CollapsePanelView = React.forwardRef((props, ref) => {
111
111
  const { header, isActive, onToggle, disabled, extra, className, style, children, forceRender, expandIcon, expandIconPosition = "start", bordered, size = "middle", collapsible = "header" } = props;
112
112
  const contentRef = useRef(null);
113
+ const triggerId = useId();
114
+ const headerId = useId();
115
+ const contentId = useId();
113
116
  const [rendered, setRendered] = useState(isActive || !!forceRender);
114
- if (isActive && !rendered) setRendered(true);
117
+ useEffect(() => {
118
+ if (isActive || forceRender) setRendered(true);
119
+ }, [forceRender, isActive]);
115
120
  const handleTransitionEnd = () => {
116
121
  if (!isActive && !forceRender) setRendered(false);
117
122
  };
@@ -121,37 +126,78 @@ var CollapsePanelView = React.forwardRef((props, ref) => {
121
126
  });
122
127
  const iconElement = /* @__PURE__ */ jsx("span", {
123
128
  className: "ald-collapse-expand-icon ant-collapse-expand-icon tw-flex tw-items-center",
129
+ "aria-hidden": "true",
124
130
  style: {
125
131
  transform: isActive ? "rotate(90deg)" : "rotate(0deg)",
126
132
  transition: "transform 200ms"
127
133
  },
128
- onClick: disabled || collapsible !== "icon" ? void 0 : (e) => {
129
- e.stopPropagation();
130
- onToggle();
131
- },
132
134
  children: iconNode
133
135
  });
136
+ const triggerProps = {
137
+ type: "button",
138
+ id: triggerId,
139
+ "aria-expanded": isActive,
140
+ "aria-controls": contentId,
141
+ disabled,
142
+ onClick: onToggle
143
+ };
144
+ const headerText = /* @__PURE__ */ jsx("span", {
145
+ className: "ald-collapse-header-text ant-collapse-header-text tw-flex-1 tw-text-sm tw-font-medium tw-leading-5 tw-text-[var(--content-primary)]",
146
+ children: header
147
+ });
148
+ const headerTrigger = collapsible === "disabled" ? /* @__PURE__ */ jsxs("div", {
149
+ id: triggerId,
150
+ className: "tw-flex tw-flex-1 tw-items-center tw-gap-2",
151
+ "aria-disabled": "true",
152
+ children: [
153
+ expandIconPosition === "start" && iconElement,
154
+ headerText,
155
+ expandIconPosition === "end" && iconElement
156
+ ]
157
+ }) : collapsible === "icon" ? /* @__PURE__ */ jsxs(Fragment, { children: [
158
+ expandIconPosition === "start" && /* @__PURE__ */ jsx("button", {
159
+ ...triggerProps,
160
+ className: "tw-flex tw-cursor-pointer tw-items-center tw-border-0 tw-bg-transparent tw-p-0",
161
+ "aria-labelledby": headerId,
162
+ children: iconElement
163
+ }),
164
+ /* @__PURE__ */ jsx("span", {
165
+ id: headerId,
166
+ className: "ald-collapse-header-text ant-collapse-header-text tw-flex-1 tw-text-sm tw-font-medium tw-leading-5 tw-text-[var(--content-primary)]",
167
+ children: header
168
+ }),
169
+ expandIconPosition === "end" && /* @__PURE__ */ jsx("button", {
170
+ ...triggerProps,
171
+ className: "tw-flex tw-cursor-pointer tw-items-center tw-border-0 tw-bg-transparent tw-p-0",
172
+ "aria-labelledby": headerId,
173
+ children: iconElement
174
+ })
175
+ ] }) : /* @__PURE__ */ jsxs("button", {
176
+ ...triggerProps,
177
+ className: "tw-flex tw-flex-1 tw-items-center tw-gap-2 tw-border-0 tw-bg-transparent tw-p-0 tw-text-left",
178
+ children: [
179
+ expandIconPosition === "start" && iconElement,
180
+ headerText,
181
+ expandIconPosition === "end" && iconElement
182
+ ]
183
+ });
134
184
  return /* @__PURE__ */ jsxs("div", {
135
185
  ref,
136
186
  className: cn("ald-collapse-item ant-collapse-item tw-w-full", isActive && "ald-collapse-item-active", disabled && "tw-pointer-events-none tw-opacity-50", `ald-collapse-item-${size}`, className),
137
187
  style,
188
+ "aria-disabled": disabled || collapsible === "disabled" || void 0,
138
189
  children: [/* @__PURE__ */ jsxs("div", {
139
- className: cn("ald-collapse-header ant-collapse-header tw-flex tw-items-center tw-gap-2 tw-p-3", !disabled && collapsible !== "icon" && "tw-cursor-pointer"),
140
- onClick: disabled || collapsible === "icon" ? void 0 : onToggle,
141
- children: [
142
- expandIconPosition === "start" && iconElement,
143
- /* @__PURE__ */ jsx("span", {
144
- className: "ald-collapse-header-text ant-collapse-header-text tw-flex-1 tw-text-sm tw-font-medium tw-leading-5 tw-text-[var(--content-primary)]",
145
- children: header
146
- }),
147
- extra && /* @__PURE__ */ jsx("span", {
148
- className: "ald-collapse-extra ant-collapse-extra",
149
- onClick: (e) => e.stopPropagation(),
150
- children: extra
151
- }),
152
- expandIconPosition === "end" && iconElement
153
- ]
190
+ className: cn("ald-collapse-header ant-collapse-header tw-flex tw-items-center tw-gap-2 tw-p-3", !disabled && collapsible !== "icon" && collapsible !== "disabled" && "tw-cursor-pointer"),
191
+ children: [headerTrigger, extra && /* @__PURE__ */ jsx("span", {
192
+ className: "ald-collapse-extra ant-collapse-extra",
193
+ onClick: (e) => e.stopPropagation(),
194
+ children: extra
195
+ })]
154
196
  }), /* @__PURE__ */ jsx("div", {
197
+ id: contentId,
198
+ role: "region",
199
+ "aria-labelledby": triggerId,
200
+ "aria-hidden": !isActive,
155
201
  className: "tw-grid tw-transition-[grid-template-rows] tw-duration-200",
156
202
  style: { gridTemplateRows: isActive ? "1fr" : "0fr" },
157
203
  onTransitionEnd: handleTransitionEnd,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Collapse/index.tsx"],"sourcesContent":["import React, { useContext, useRef, useState } from 'react';\nimport { ArrowRightLightLine } from '../Icon';\nimport { cn } from '../lib/utils';\n\n/**\n * Compound Components 模式:Collapse 通过 Context 注入受控状态 + 视觉配置,\n * Panel 始终自渲染(header + 折叠交互),靠 `panelKey` 与父协调 activeKey /\n * accordion。设计对齐 Radix / Mantine:Item 自渲染,靠声明式 value 与 Root 通信。\n *\n * 这里不再做\"扫描 children 提 Panel props 再替换渲染\"的 hack——后者无法穿透\n * forwardRef / 业务包装组件边界,是 ald v3 升级回归\"包装 Panel 丢 header\"的根因。\n */\ninterface CollapseContextValue {\n // 视觉配置\n expandIcon?: (props: { isActive: boolean }) => React.ReactNode;\n expandIconPosition: 'start' | 'end';\n bordered: boolean;\n size: 'large' | 'middle' | 'small';\n collapsible?: 'header' | 'icon' | 'disabled';\n // 受控状态协调\n activeKeys: string[];\n toggleKey: (key: string) => void;\n}\n\nconst CollapseContext = React.createContext<CollapseContextValue | null>(null);\n\nexport interface CollapsePanelProps {\n /**\n * 与父 Collapse 协调 activeKey / accordion 的 key。\n * 不提供时 Panel 走内部 state(视觉一致但不参与父协调)。\n * Radix Accordion 等同 prop 名是 `value`;这里沿用 `panelKey` 与已有\n * `Collapse items[].key` 命名一致,迁移成本最低。\n */\n panelKey?: string;\n header?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n disabled?: boolean;\n extra?: React.ReactNode;\n forceRender?: boolean;\n collapsible?: 'header' | 'icon' | 'disabled';\n showArrow?: boolean;\n}\n\nexport interface CollapseProps {\n activeKey?: string | string[];\n defaultActiveKey?: string | string[];\n accordion?: boolean;\n onChange?: (key: string | string[]) => void;\n className?: string;\n style?: React.CSSProperties;\n bordered?: boolean;\n expandIconPosition?: 'start' | 'end' | 'left' | 'right';\n expandIcon?: (props: { isActive: boolean }) => React.ReactNode;\n ghost?: boolean;\n size?: 'large' | 'middle' | 'small';\n collapsible?: 'header' | 'icon' | 'disabled';\n children?: React.ReactNode;\n items?: Array<{\n key: string;\n label: React.ReactNode;\n children?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n extra?: React.ReactNode;\n disabled?: boolean;\n collapsible?: 'header' | 'icon' | 'disabled';\n forceRender?: boolean;\n }>;\n}\n\nconst normalizeKeys = (keys: string | string[] | undefined): string[] => {\n if (!keys) return [];\n return Array.isArray(keys) ? keys : [keys];\n};\n\nconst Collapse = (props: CollapseProps) => {\n const {\n defaultActiveKey = [],\n activeKey: controlledActiveKey,\n accordion,\n onChange,\n className,\n style,\n bordered = true,\n ghost,\n size = 'middle',\n collapsible,\n expandIconPosition,\n expandIcon,\n items: itemsProp,\n children,\n } = props;\n\n const resolvedPosition =\n expandIconPosition === 'left'\n ? 'start'\n : expandIconPosition === 'right'\n ? 'end'\n : expandIconPosition ?? 'start';\n\n const [internalActiveKey, setInternalActiveKey] = useState<string[]>(\n normalizeKeys(defaultActiveKey),\n );\n\n const activeKeys =\n controlledActiveKey !== undefined\n ? normalizeKeys(controlledActiveKey)\n : internalActiveKey;\n\n const toggleKey = (key: string) => {\n let newKeys: string[];\n if (accordion) {\n newKeys = activeKeys.includes(key) ? [] : [key];\n } else {\n newKeys = activeKeys.includes(key)\n ? activeKeys.filter((k) => k !== key)\n : [...activeKeys, key];\n }\n if (controlledActiveKey === undefined) {\n setInternalActiveKey(newKeys);\n }\n onChange?.(accordion ? newKeys[0] || '' : newKeys);\n };\n\n const contextValue: CollapseContextValue = {\n expandIcon,\n expandIconPosition: resolvedPosition,\n bordered: bordered && !ghost,\n size,\n collapsible,\n activeKeys,\n toggleKey,\n };\n\n /**\n * children 路径:向后兼容老用法 `<Collapse><Collapse.Panel key=\"1\" ...>`\n * ——React `key` 是保留字不会进 Panel props,所以把它读出来 cloneElement\n * 注入到 `panelKey` 上(只对直接子元素生效;包装组件需要业务侧自己透传)。\n */\n const enhancedChildren = React.Children.map(children, (child) => {\n if (!React.isValidElement<CollapsePanelProps>(child)) return child;\n if ((child.type as any)?.__COLLAPSE_PANEL !== true) return child;\n if (child.props.panelKey !== undefined) return child;\n if (child.key === null || child.key === undefined) return child;\n return React.cloneElement(child, { panelKey: String(child.key) });\n });\n\n return (\n <CollapseContext.Provider value={contextValue}>\n <div\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n // 相邻 .ald-collapse-item 用 CSS 兄弟选择器画分隔线,避免在 React 树里\n // 注入 <div .ald-collapse-divider /> 节点——后者在\"业务包装 Panel\"场景\n // 需要 Collapse 知道子元素拓扑,与 Compound Components 解耦原则冲突。\n 'ald-collapse ant-collapse tw-flex tw-flex-col tw-items-stretch tw-overflow-hidden tw-rounded-r-75 [&>.ald-collapse-item+.ald-collapse-item]:tw-border-0 [&>.ald-collapse-item+.ald-collapse-item]:tw-border-t [&>.ald-collapse-item+.ald-collapse-item]:tw-border-solid [&>.ald-collapse-item+.ald-collapse-item]:tw-border-[var(--border-default)]',\n !ghost && !bordered && 'tw-bg-[var(--background-neutral-subtle)]',\n !ghost &&\n bordered &&\n 'tw-border tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-neutral-subtle)]',\n `ald-collapse-${size}`,\n className,\n )}\n style={style}\n >\n {itemsProp && itemsProp.length > 0\n ? itemsProp.map((item) => (\n <Panel\n key={item.key}\n panelKey={item.key}\n header={item.label}\n disabled={item.disabled}\n collapsible={item.collapsible ?? collapsible}\n extra={item.extra}\n className={item.className}\n style={item.style}\n forceRender={item.forceRender}\n >\n {item.children}\n </Panel>\n ))\n : enhancedChildren}\n </div>\n </CollapseContext.Provider>\n );\n};\n\n/**\n * Panel —— 始终自渲染。\n *\n * - 在 `<Collapse>` 内(ctx 存在)+ 提供 `panelKey`:受控渲染(参与父 activeKey\n * / accordion 协调),点击调 `ctx.toggleKey`,`isActive` 来自 `ctx.activeKeys`。\n * - 在 `<Collapse>` 内(ctx 存在)+ 未提供 `panelKey`:自渲染 + 独立 state,视觉\n * 配置仍来自 ctx,但与父受控状态隔离(业务包装组件没透传 panelKey 时的退化)。\n * - `<Collapse>` 外使用(ctx 不存在):完全自给自足,视觉配置走默认值。\n *\n * 用 forwardRef 转发 ref 到 `.ald-collapse-item` root div——业务侧包装组件常\n * 需要拿到 panel 容器引用做滚动定位等,向后兼容旧版本 Panel 暴露的 ref API。\n */\nconst Panel = React.forwardRef<HTMLDivElement, CollapsePanelProps>(\n (props, ref) => {\n const ctx = useContext(CollapseContext);\n const {\n panelKey,\n header,\n children,\n className,\n style,\n extra,\n disabled,\n collapsible,\n forceRender,\n } = props;\n\n const isControlled = ctx !== null && panelKey !== undefined;\n\n const [internalActive, setInternalActive] = useState(false);\n\n const isActive = isControlled\n ? ctx!.activeKeys.includes(panelKey!)\n : internalActive;\n\n const onToggle = () => {\n if (isControlled) {\n ctx!.toggleKey(panelKey!);\n } else {\n setInternalActive((v) => !v);\n }\n };\n\n const expandIcon = ctx?.expandIcon;\n const expandIconPosition = ctx?.expandIconPosition ?? 'start';\n const bordered = ctx?.bordered ?? true;\n const size = ctx?.size ?? 'middle';\n const mergedCollapsible = collapsible ?? ctx?.collapsible;\n\n return (\n <CollapsePanelView\n ref={ref}\n header={header}\n isActive={isActive}\n onToggle={onToggle}\n disabled={disabled || mergedCollapsible === 'disabled'}\n extra={extra}\n className={className}\n style={style}\n forceRender={forceRender}\n expandIcon={expandIcon}\n expandIconPosition={expandIconPosition}\n bordered={bordered}\n size={size}\n collapsible={mergedCollapsible}\n >\n {children}\n </CollapsePanelView>\n );\n },\n);\n\n(Panel as any).__COLLAPSE_PANEL = true;\n\ninterface CollapsePanelViewProps {\n header: React.ReactNode;\n isActive: boolean;\n onToggle: () => void;\n disabled?: boolean;\n extra?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n forceRender?: boolean;\n expandIcon?: (props: { isActive: boolean }) => React.ReactNode;\n expandIconPosition?: 'start' | 'end';\n bordered?: boolean;\n size?: 'large' | 'middle' | 'small';\n collapsible?: 'header' | 'icon' | 'disabled';\n}\n\n/** 哑视图组件,承担 DOM 结构 + 折叠动画;不持有受控状态,ref 转发到 root div。 */\nconst CollapsePanelView = React.forwardRef<\n HTMLDivElement,\n CollapsePanelViewProps\n>((props, ref) => {\n const {\n header,\n isActive,\n onToggle,\n disabled,\n extra,\n className,\n style,\n children,\n forceRender,\n expandIcon,\n expandIconPosition = 'start',\n bordered,\n size = 'middle',\n collapsible = 'header',\n } = props;\n\n const contentRef = useRef<HTMLDivElement>(null);\n const [rendered, setRendered] = useState(isActive || !!forceRender);\n\n if (isActive && !rendered) {\n setRendered(true);\n }\n\n const handleTransitionEnd = () => {\n if (!isActive && !forceRender) {\n setRendered(false);\n }\n };\n\n const iconNode = expandIcon ? (\n expandIcon({ isActive })\n ) : (\n <ArrowRightLightLine size={20} color=\"var(--content-secondary)\" />\n );\n\n const iconElement = (\n <span\n className=\"ald-collapse-expand-icon ant-collapse-expand-icon tw-flex tw-items-center\"\n style={{\n transform: isActive ? 'rotate(90deg)' : 'rotate(0deg)',\n transition: 'transform 200ms',\n }}\n onClick={\n disabled || collapsible !== 'icon'\n ? undefined\n : (e) => {\n e.stopPropagation();\n onToggle();\n }\n }\n >\n {iconNode}\n </span>\n );\n\n return (\n <div\n ref={ref}\n className={cn(\n 'ald-collapse-item ant-collapse-item tw-w-full',\n isActive && 'ald-collapse-item-active',\n disabled && 'tw-pointer-events-none tw-opacity-50',\n `ald-collapse-item-${size}`,\n className,\n )}\n style={style}\n >\n <div\n className={cn(\n 'ald-collapse-header ant-collapse-header tw-flex tw-items-center tw-gap-2 tw-p-3',\n !disabled && collapsible !== 'icon' && 'tw-cursor-pointer',\n )}\n onClick={disabled || collapsible === 'icon' ? undefined : onToggle}\n >\n {expandIconPosition === 'start' && iconElement}\n <span className=\"ald-collapse-header-text ant-collapse-header-text tw-flex-1 tw-text-sm tw-font-medium tw-leading-5 tw-text-[var(--content-primary)]\">\n {header}\n </span>\n {extra && (\n // extra 区域里常放 Switch / Button 等交互控件,点击不该冒泡触发 panel\n // 切展开/收起。antd Collapse 也是同样行为;不强制消费方在每个 extra\n // 控件上自己写 stopPropagation。\n <span\n className=\"ald-collapse-extra ant-collapse-extra\"\n onClick={(e) => e.stopPropagation()}\n >\n {extra}\n </span>\n )}\n {expandIconPosition === 'end' && iconElement}\n </div>\n <div\n className=\"tw-grid tw-transition-[grid-template-rows] tw-duration-200\"\n style={{ gridTemplateRows: isActive ? '1fr' : '0fr' }}\n onTransitionEnd={handleTransitionEnd}\n >\n <div className=\"tw-overflow-hidden\">\n {rendered && (\n <div\n ref={contentRef}\n className={cn(\n 'ald-collapse-content ant-collapse-content tw-flex tw-flex-col tw-items-stretch tw-gap-2.5 tw-self-stretch',\n bordered\n ? 'tw-bg-[var(--background-default)] tw-p-4'\n : 'tw-px-4 tw-pb-4 tw-pt-0',\n )}\n >\n {children}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n});\n\nCollapse.Panel = Panel;\n\nexport default Collapse;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Collapse/index.tsx"],"sourcesContent":["import React, { useContext, useEffect, useId, useRef, useState } from 'react';\nimport { ArrowRightLightLine } from '../Icon';\nimport { cn } from '../lib/utils';\n\n/**\n * Compound Components 模式:Collapse 通过 Context 注入受控状态 + 视觉配置,\n * Panel 始终自渲染(header + 折叠交互),靠 `panelKey` 与父协调 activeKey /\n * accordion。设计对齐 Radix / Mantine:Item 自渲染,靠声明式 value 与 Root 通信。\n *\n * 这里不再做\"扫描 children 提 Panel props 再替换渲染\"的 hack——后者无法穿透\n * forwardRef / 业务包装组件边界,是 ald v3 升级回归\"包装 Panel 丢 header\"的根因。\n */\ninterface CollapseContextValue {\n // 视觉配置\n expandIcon?: (props: { isActive: boolean }) => React.ReactNode;\n expandIconPosition: 'start' | 'end';\n bordered: boolean;\n size: 'large' | 'middle' | 'small';\n collapsible?: 'header' | 'icon' | 'disabled';\n // 受控状态协调\n activeKeys: string[];\n toggleKey: (key: string) => void;\n}\n\nconst CollapseContext = React.createContext<CollapseContextValue | null>(null);\n\nexport interface CollapsePanelProps {\n /**\n * 与父 Collapse 协调 activeKey / accordion 的 key。\n * 不提供时 Panel 走内部 state(视觉一致但不参与父协调)。\n * Radix Accordion 等同 prop 名是 `value`;这里沿用 `panelKey` 与已有\n * `Collapse items[].key` 命名一致,迁移成本最低。\n */\n panelKey?: string;\n header?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n disabled?: boolean;\n extra?: React.ReactNode;\n forceRender?: boolean;\n collapsible?: 'header' | 'icon' | 'disabled';\n showArrow?: boolean;\n}\n\nexport interface CollapseProps {\n activeKey?: string | string[];\n defaultActiveKey?: string | string[];\n accordion?: boolean;\n onChange?: (key: string | string[]) => void;\n className?: string;\n style?: React.CSSProperties;\n bordered?: boolean;\n expandIconPosition?: 'start' | 'end' | 'left' | 'right';\n expandIcon?: (props: { isActive: boolean }) => React.ReactNode;\n ghost?: boolean;\n size?: 'large' | 'middle' | 'small';\n collapsible?: 'header' | 'icon' | 'disabled';\n children?: React.ReactNode;\n items?: Array<{\n key: string;\n label: React.ReactNode;\n children?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n extra?: React.ReactNode;\n disabled?: boolean;\n collapsible?: 'header' | 'icon' | 'disabled';\n forceRender?: boolean;\n }>;\n}\n\nconst normalizeKeys = (keys: string | string[] | undefined): string[] => {\n if (!keys) return [];\n return Array.isArray(keys) ? keys : [keys];\n};\n\nconst Collapse = (props: CollapseProps) => {\n const {\n defaultActiveKey = [],\n activeKey: controlledActiveKey,\n accordion,\n onChange,\n className,\n style,\n bordered = true,\n ghost,\n size = 'middle',\n collapsible,\n expandIconPosition,\n expandIcon,\n items: itemsProp,\n children,\n } = props;\n\n const resolvedPosition =\n expandIconPosition === 'left'\n ? 'start'\n : expandIconPosition === 'right'\n ? 'end'\n : expandIconPosition ?? 'start';\n\n const [internalActiveKey, setInternalActiveKey] = useState<string[]>(\n normalizeKeys(defaultActiveKey),\n );\n\n const activeKeys =\n controlledActiveKey !== undefined\n ? normalizeKeys(controlledActiveKey)\n : internalActiveKey;\n\n const toggleKey = (key: string) => {\n let newKeys: string[];\n if (accordion) {\n newKeys = activeKeys.includes(key) ? [] : [key];\n } else {\n newKeys = activeKeys.includes(key)\n ? activeKeys.filter((k) => k !== key)\n : [...activeKeys, key];\n }\n if (controlledActiveKey === undefined) {\n setInternalActiveKey(newKeys);\n }\n onChange?.(accordion ? newKeys[0] || '' : newKeys);\n };\n\n const contextValue: CollapseContextValue = {\n expandIcon,\n expandIconPosition: resolvedPosition,\n bordered: bordered && !ghost,\n size,\n collapsible,\n activeKeys,\n toggleKey,\n };\n\n /**\n * children 路径:向后兼容老用法 `<Collapse><Collapse.Panel key=\"1\" ...>`\n * ——React `key` 是保留字不会进 Panel props,所以把它读出来 cloneElement\n * 注入到 `panelKey` 上(只对直接子元素生效;包装组件需要业务侧自己透传)。\n */\n const enhancedChildren = React.Children.map(children, (child) => {\n if (!React.isValidElement<CollapsePanelProps>(child)) return child;\n if ((child.type as any)?.__COLLAPSE_PANEL !== true) return child;\n if (child.props.panelKey !== undefined) return child;\n if (child.key === null || child.key === undefined) return child;\n return React.cloneElement(child, { panelKey: String(child.key) });\n });\n\n return (\n <CollapseContext.Provider value={contextValue}>\n <div\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n // 相邻 .ald-collapse-item 用 CSS 兄弟选择器画分隔线,避免在 React 树里\n // 注入 <div .ald-collapse-divider /> 节点——后者在\"业务包装 Panel\"场景\n // 需要 Collapse 知道子元素拓扑,与 Compound Components 解耦原则冲突。\n 'ald-collapse ant-collapse tw-flex tw-flex-col tw-items-stretch tw-overflow-hidden tw-rounded-r-75 [&>.ald-collapse-item+.ald-collapse-item]:tw-border-0 [&>.ald-collapse-item+.ald-collapse-item]:tw-border-t [&>.ald-collapse-item+.ald-collapse-item]:tw-border-solid [&>.ald-collapse-item+.ald-collapse-item]:tw-border-[var(--border-default)]',\n !ghost && !bordered && 'tw-bg-[var(--background-neutral-subtle)]',\n !ghost &&\n bordered &&\n 'tw-border tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-neutral-subtle)]',\n `ald-collapse-${size}`,\n className,\n )}\n style={style}\n >\n {itemsProp && itemsProp.length > 0\n ? itemsProp.map((item) => (\n <Panel\n key={item.key}\n panelKey={item.key}\n header={item.label}\n disabled={item.disabled}\n collapsible={item.collapsible ?? collapsible}\n extra={item.extra}\n className={item.className}\n style={item.style}\n forceRender={item.forceRender}\n >\n {item.children}\n </Panel>\n ))\n : enhancedChildren}\n </div>\n </CollapseContext.Provider>\n );\n};\n\n/**\n * Panel —— 始终自渲染。\n *\n * - 在 `<Collapse>` 内(ctx 存在)+ 提供 `panelKey`:受控渲染(参与父 activeKey\n * / accordion 协调),点击调 `ctx.toggleKey`,`isActive` 来自 `ctx.activeKeys`。\n * - 在 `<Collapse>` 内(ctx 存在)+ 未提供 `panelKey`:自渲染 + 独立 state,视觉\n * 配置仍来自 ctx,但与父受控状态隔离(业务包装组件没透传 panelKey 时的退化)。\n * - `<Collapse>` 外使用(ctx 不存在):完全自给自足,视觉配置走默认值。\n *\n * 用 forwardRef 转发 ref 到 `.ald-collapse-item` root div——业务侧包装组件常\n * 需要拿到 panel 容器引用做滚动定位等,向后兼容旧版本 Panel 暴露的 ref API。\n */\nconst Panel = React.forwardRef<HTMLDivElement, CollapsePanelProps>(\n (props, ref) => {\n const ctx = useContext(CollapseContext);\n const {\n panelKey,\n header,\n children,\n className,\n style,\n extra,\n disabled,\n collapsible,\n forceRender,\n } = props;\n\n const isControlled = ctx !== null && panelKey !== undefined;\n\n const [internalActive, setInternalActive] = useState(false);\n\n const isActive = isControlled\n ? ctx!.activeKeys.includes(panelKey!)\n : internalActive;\n\n const onToggle = () => {\n if (isControlled) {\n ctx!.toggleKey(panelKey!);\n } else {\n setInternalActive((v) => !v);\n }\n };\n\n const expandIcon = ctx?.expandIcon;\n const expandIconPosition = ctx?.expandIconPosition ?? 'start';\n const bordered = ctx?.bordered ?? true;\n const size = ctx?.size ?? 'middle';\n const mergedCollapsible = collapsible ?? ctx?.collapsible;\n\n return (\n <CollapsePanelView\n ref={ref}\n header={header}\n isActive={isActive}\n onToggle={onToggle}\n disabled={disabled || mergedCollapsible === 'disabled'}\n extra={extra}\n className={className}\n style={style}\n forceRender={forceRender}\n expandIcon={expandIcon}\n expandIconPosition={expandIconPosition}\n bordered={bordered}\n size={size}\n collapsible={mergedCollapsible}\n >\n {children}\n </CollapsePanelView>\n );\n },\n);\n\n(Panel as any).__COLLAPSE_PANEL = true;\n\ninterface CollapsePanelViewProps {\n header: React.ReactNode;\n isActive: boolean;\n onToggle: () => void;\n disabled?: boolean;\n extra?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n children?: React.ReactNode;\n forceRender?: boolean;\n expandIcon?: (props: { isActive: boolean }) => React.ReactNode;\n expandIconPosition?: 'start' | 'end';\n bordered?: boolean;\n size?: 'large' | 'middle' | 'small';\n collapsible?: 'header' | 'icon' | 'disabled';\n}\n\n/** 哑视图组件,承担 DOM 结构 + 折叠动画;不持有受控状态,ref 转发到 root div。 */\nconst CollapsePanelView = React.forwardRef<\n HTMLDivElement,\n CollapsePanelViewProps\n>((props, ref) => {\n const {\n header,\n isActive,\n onToggle,\n disabled,\n extra,\n className,\n style,\n children,\n forceRender,\n expandIcon,\n expandIconPosition = 'start',\n bordered,\n size = 'middle',\n collapsible = 'header',\n } = props;\n\n const contentRef = useRef<HTMLDivElement>(null);\n const triggerId = useId();\n const headerId = useId();\n const contentId = useId();\n const [rendered, setRendered] = useState(isActive || !!forceRender);\n\n useEffect(() => {\n if (isActive || forceRender) {\n setRendered(true);\n }\n }, [forceRender, isActive]);\n\n const handleTransitionEnd = () => {\n if (!isActive && !forceRender) {\n setRendered(false);\n }\n };\n\n const iconNode = expandIcon ? (\n expandIcon({ isActive })\n ) : (\n <ArrowRightLightLine size={20} color=\"var(--content-secondary)\" />\n );\n\n const iconElement = (\n <span\n className=\"ald-collapse-expand-icon ant-collapse-expand-icon tw-flex tw-items-center\"\n aria-hidden=\"true\"\n style={{\n transform: isActive ? 'rotate(90deg)' : 'rotate(0deg)',\n transition: 'transform 200ms',\n }}\n >\n {iconNode}\n </span>\n );\n\n const triggerProps = {\n type: 'button' as const,\n id: triggerId,\n 'aria-expanded': isActive,\n 'aria-controls': contentId,\n disabled,\n onClick: onToggle,\n };\n\n const headerText = (\n <span className=\"ald-collapse-header-text ant-collapse-header-text tw-flex-1 tw-text-sm tw-font-medium tw-leading-5 tw-text-[var(--content-primary)]\">\n {header}\n </span>\n );\n\n const headerTrigger =\n collapsible === 'disabled' ? (\n <div\n id={triggerId}\n className=\"tw-flex tw-flex-1 tw-items-center tw-gap-2\"\n aria-disabled=\"true\"\n >\n {expandIconPosition === 'start' && iconElement}\n {headerText}\n {expandIconPosition === 'end' && iconElement}\n </div>\n ) : collapsible === 'icon' ? (\n <>\n {expandIconPosition === 'start' && (\n <button\n {...triggerProps}\n className=\"tw-flex tw-cursor-pointer tw-items-center tw-border-0 tw-bg-transparent tw-p-0\"\n aria-labelledby={headerId}\n >\n {iconElement}\n </button>\n )}\n <span\n id={headerId}\n className=\"ald-collapse-header-text ant-collapse-header-text tw-flex-1 tw-text-sm tw-font-medium tw-leading-5 tw-text-[var(--content-primary)]\"\n >\n {header}\n </span>\n {expandIconPosition === 'end' && (\n <button\n {...triggerProps}\n className=\"tw-flex tw-cursor-pointer tw-items-center tw-border-0 tw-bg-transparent tw-p-0\"\n aria-labelledby={headerId}\n >\n {iconElement}\n </button>\n )}\n </>\n ) : (\n <button\n {...triggerProps}\n className=\"tw-flex tw-flex-1 tw-items-center tw-gap-2 tw-border-0 tw-bg-transparent tw-p-0 tw-text-left\"\n >\n {expandIconPosition === 'start' && iconElement}\n {headerText}\n {expandIconPosition === 'end' && iconElement}\n </button>\n );\n\n return (\n <div\n ref={ref}\n className={cn(\n 'ald-collapse-item ant-collapse-item tw-w-full',\n isActive && 'ald-collapse-item-active',\n disabled && 'tw-pointer-events-none tw-opacity-50',\n `ald-collapse-item-${size}`,\n className,\n )}\n style={style}\n aria-disabled={disabled || collapsible === 'disabled' || undefined}\n >\n <div\n className={cn(\n 'ald-collapse-header ant-collapse-header tw-flex tw-items-center tw-gap-2 tw-p-3',\n !disabled &&\n collapsible !== 'icon' &&\n collapsible !== 'disabled' &&\n 'tw-cursor-pointer',\n )}\n >\n {headerTrigger}\n {extra && (\n // extra 区域里常放 Switch / Button 等交互控件,点击不该冒泡触发 panel\n // 切展开/收起。antd Collapse 也是同样行为;不强制消费方在每个 extra\n // 控件上自己写 stopPropagation。\n <span\n className=\"ald-collapse-extra ant-collapse-extra\"\n onClick={(e) => e.stopPropagation()}\n >\n {extra}\n </span>\n )}\n </div>\n <div\n id={contentId}\n role=\"region\"\n aria-labelledby={triggerId}\n aria-hidden={!isActive}\n className=\"tw-grid tw-transition-[grid-template-rows] tw-duration-200\"\n style={{ gridTemplateRows: isActive ? '1fr' : '0fr' }}\n onTransitionEnd={handleTransitionEnd}\n >\n <div className=\"tw-overflow-hidden\">\n {rendered && (\n <div\n ref={contentRef}\n className={cn(\n 'ald-collapse-content ant-collapse-content tw-flex tw-flex-col tw-items-stretch tw-gap-2.5 tw-self-stretch',\n bordered\n ? 'tw-bg-[var(--background-default)] tw-p-4'\n : 'tw-px-4 tw-pb-4 tw-pt-0',\n )}\n >\n {children}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n});\n\nCollapse.Panel = Panel;\n\nexport default Collapse;\n"],"mappings":";;;;;AAwBA,IAAM,kBAAkB,MAAM,cAA2C,KAAK;AAgD9E,IAAM,iBAAiB,SAAkD;AACvE,KAAI,CAAC,KAAM,QAAO,EAAE;AACpB,QAAO,MAAM,QAAQ,KAAK,GAAG,OAAO,CAAC,KAAK;;AAG5C,IAAM,YAAY,UAAyB;CACzC,MAAM,EACJ,mBAAmB,EAAE,EACrB,WAAW,qBACX,WACA,UACA,WACA,OACA,WAAW,MACX,OACA,OAAO,UACP,aACA,oBACA,YACA,OAAO,WACP,aACE;CAEJ,MAAM,mBACJ,uBAAuB,SACnB,UACA,uBAAuB,UACvB,QACA,sBAAsB;CAE5B,MAAM,CAAC,mBAAmB,wBAAwB,SAChD,cAAc,iBAAiB,CAChC;CAED,MAAM,aACJ,wBAAwB,SACpB,cAAc,oBAAoB,GAClC;CAEN,MAAM,aAAa,QAAgB;EACjC,IAAI;AACJ,MAAI,UACF,WAAU,WAAW,SAAS,IAAI,GAAG,EAAE,GAAG,CAAC,IAAI;MAE/C,WAAU,WAAW,SAAS,IAAI,GAC9B,WAAW,QAAQ,MAAM,MAAM,IAAI,GACnC,CAAC,GAAG,YAAY,IAAI;AAE1B,MAAI,wBAAwB,OAC1B,sBAAqB,QAAQ;AAE/B,aAAW,YAAY,QAAQ,MAAM,KAAK,QAAQ;;CAGpD,MAAM,eAAqC;EACzC;EACA,oBAAoB;EACpB,UAAU,YAAY,CAAC;EACvB;EACA;EACA;EACA;EACD;;;;;;CAOD,MAAM,mBAAmB,MAAM,SAAS,IAAI,WAAW,UAAU;AAC/D,MAAI,CAAC,MAAM,eAAmC,MAAM,CAAE,QAAO;AAC7D,MAAK,MAAM,MAAc,qBAAqB,KAAM,QAAO;AAC3D,MAAI,MAAM,MAAM,aAAa,OAAW,QAAO;AAC/C,MAAI,MAAM,QAAQ,QAAQ,MAAM,QAAQ,OAAW,QAAO;AAC1D,SAAO,MAAM,aAAa,OAAO,EAAE,UAAU,OAAO,MAAM,IAAI,EAAE,CAAC;GACjE;AAEF,QACE,oBAAC,gBAAgB,UAAjB;EAA0B,OAAO;YAC/B,oBAAC,OAAD;GACE,WAAW,GAKT,uVACA,CAAC,SAAS,CAAC,YAAY,4CACvB,CAAC,SACC,YACA,wGACF,gBAAgB,QAChB,UACD;GACM;aAEN,aAAa,UAAU,SAAS,IAC7B,UAAU,KAAK,SACb,oBAAC,OAAD;IAEE,UAAU,KAAK;IACf,QAAQ,KAAK;IACb,UAAU,KAAK;IACf,aAAa,KAAK,eAAe;IACjC,OAAO,KAAK;IACZ,WAAW,KAAK;IAChB,OAAO,KAAK;IACZ,aAAa,KAAK;cAEjB,KAAK;IACA,EAXD,KAAK,IAWJ,CACR,GACF;GACA,CAAA;EACmB,CAAA;;;;;;;;;;;;;;AAgB/B,IAAM,QAAQ,MAAM,YACjB,OAAO,QAAQ;CACd,MAAM,MAAM,WAAW,gBAAgB;CACvC,MAAM,EACJ,UACA,QACA,UACA,WACA,OACA,OACA,UACA,aACA,gBACE;CAEJ,MAAM,eAAe,QAAQ,QAAQ,aAAa;CAElD,MAAM,CAAC,gBAAgB,qBAAqB,SAAS,MAAM;CAE3D,MAAM,WAAW,eACb,IAAK,WAAW,SAAS,SAAU,GACnC;CAEJ,MAAM,iBAAiB;AACrB,MAAI,aACF,KAAK,UAAU,SAAU;MAEzB,oBAAmB,MAAM,CAAC,EAAE;;CAIhC,MAAM,aAAa,KAAK;CACxB,MAAM,qBAAqB,KAAK,sBAAsB;CACtD,MAAM,WAAW,KAAK,YAAY;CAClC,MAAM,OAAO,KAAK,QAAQ;CAC1B,MAAM,oBAAoB,eAAe,KAAK;AAE9C,QACE,oBAAC,mBAAD;EACO;EACG;EACE;EACA;EACV,UAAU,YAAY,sBAAsB;EACrC;EACI;EACJ;EACM;EACD;EACQ;EACV;EACJ;EACN,aAAa;EAEZ;EACiB,CAAA;EAGzB;AAED,MAAe,mBAAmB;;AAoBlC,IAAM,oBAAoB,MAAM,YAG7B,OAAO,QAAQ;CAChB,MAAM,EACJ,QACA,UACA,UACA,UACA,OACA,WACA,OACA,UACA,aACA,YACA,qBAAqB,SACrB,UACA,OAAO,UACP,cAAc,aACZ;CAEJ,MAAM,aAAa,OAAuB,KAAK;CAC/C,MAAM,YAAY,OAAO;CACzB,MAAM,WAAW,OAAO;CACxB,MAAM,YAAY,OAAO;CACzB,MAAM,CAAC,UAAU,eAAe,SAAS,YAAY,CAAC,CAAC,YAAY;AAEnE,iBAAgB;AACd,MAAI,YAAY,YACd,aAAY,KAAK;IAElB,CAAC,aAAa,SAAS,CAAC;CAE3B,MAAM,4BAA4B;AAChC,MAAI,CAAC,YAAY,CAAC,YAChB,aAAY,MAAM;;CAItB,MAAM,WAAW,aACf,WAAW,EAAE,UAAU,CAAC,GAExB,oBAAC,MAAD;EAAqB,MAAM;EAAI,OAAM;EAA6B,CAAA;CAGpE,MAAM,cACJ,oBAAC,QAAD;EACE,WAAU;EACV,eAAY;EACZ,OAAO;GACL,WAAW,WAAW,kBAAkB;GACxC,YAAY;GACb;YAEA;EACI,CAAA;CAGT,MAAM,eAAe;EACnB,MAAM;EACN,IAAI;EACJ,iBAAiB;EACjB,iBAAiB;EACjB;EACA,SAAS;EACV;CAED,MAAM,aACJ,oBAAC,QAAD;EAAM,WAAU;YACb;EACI,CAAA;CAGT,MAAM,gBACJ,gBAAgB,aACd,qBAAC,OAAD;EACE,IAAI;EACJ,WAAU;EACV,iBAAc;YAHhB;GAKG,uBAAuB,WAAW;GAClC;GACA,uBAAuB,SAAS;GAC7B;MACJ,gBAAgB,SAClB,qBAAA,UAAA,EAAA,UAAA;EACG,uBAAuB,WACtB,oBAAC,UAAD;GACE,GAAI;GACJ,WAAU;GACV,mBAAiB;aAEhB;GACM,CAAA;EAEX,oBAAC,QAAD;GACE,IAAI;GACJ,WAAU;aAET;GACI,CAAA;EACN,uBAAuB,SACtB,oBAAC,UAAD;GACE,GAAI;GACJ,WAAU;GACV,mBAAiB;aAEhB;GACM,CAAA;EAEV,EAAA,CAAA,GAEH,qBAAC,UAAD;EACE,GAAI;EACJ,WAAU;YAFZ;GAIG,uBAAuB,WAAW;GAClC;GACA,uBAAuB,SAAS;GAC1B;;AAGb,QACE,qBAAC,OAAD;EACO;EACL,WAAW,GACT,iDACA,YAAY,4BACZ,YAAY,wCACZ,qBAAqB,QACrB,UACD;EACM;EACP,iBAAe,YAAY,gBAAgB,cAAc;YAV3D,CAYE,qBAAC,OAAD;GACE,WAAW,GACT,mFACA,CAAC,YACC,gBAAgB,UAChB,gBAAgB,cAChB,oBACH;aAPH,CASG,eACA,SAIC,oBAAC,QAAD;IACE,WAAU;IACV,UAAU,MAAM,EAAE,iBAAiB;cAElC;IACI,CAAA,CAEL;MACN,oBAAC,OAAD;GACE,IAAI;GACJ,MAAK;GACL,mBAAiB;GACjB,eAAa,CAAC;GACd,WAAU;GACV,OAAO,EAAE,kBAAkB,WAAW,QAAQ,OAAO;GACrD,iBAAiB;aAEjB,oBAAC,OAAD;IAAK,WAAU;cACZ,YACC,oBAAC,OAAD;KACE,KAAK;KACL,WAAW,GACT,6GACA,WACI,6CACA,0BACL;KAEA;KACG,CAAA;IAEJ,CAAA;GACF,CAAA,CACF;;EAER;AAEF,SAAS,QAAQ"}
@@ -54,7 +54,13 @@ var Input = forwardRef((props, ref) => {
54
54
  }) : showCount ? `${currentValue.length}${maxLength ? `/${maxLength}` : ""}` : null;
55
55
  const compactClasses = compactItemClassnames ? cn(!compactItemClassnames["ald-input-compact-first-item"] && "!tw-rounded-l-none", !compactItemClassnames["ald-input-compact-last-item"] && "!tw-rounded-r-none", !compactItemClassnames["ald-input-compact-first-item"] && "-tw-ml-px") : void 0;
56
56
  return /* @__PURE__ */ jsxs("span", {
57
- className: cn("ald-input ant-input-affix-wrapper tw-inline-flex tw-w-full tw-items-center tw-bg-[var(--background-default)]", bordered && "tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-neutral-subtle)]", focused && "ant-input-affix-wrapper-focused tw-border-[var(--border-brand-strong)]", !mergedDisabled && !focused && "hover:tw-border-[var(--border-brand-strong)]", `ald-input-${getSizeType(size)}`, "tw-text-typography-body-dense", size === "small" && "tw-h-7", size === "large" && "tw-h-9", (size === "middle" || !size) && "tw-h-8", status === "error" && `ald-input-error tw-border-[var(--border-negative-strong)]`, status === "warning" && `ald-input-warning tw-border-[var(--border-warning-subtle)]`, mergedDisabled && "ald-input-disabled tw-cursor-not-allowed tw-bg-[var(--background-neutral-on-subtle)] tw-text-[var(--content-secondary)]", compactClasses, className),
57
+ className: cn("ald-input ant-input-affix-wrapper tw-inline-flex tw-w-full tw-items-center tw-bg-[var(--background-default)]", bordered && "tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-neutral-subtle)]", !mergedDisabled && [
58
+ "has-[input:focus-visible]:tw-shadow-[0_0_0_2px_var(--focus-ring)]",
59
+ "forced-colors:has-[input:focus-visible]:tw-outline",
60
+ "forced-colors:has-[input:focus-visible]:tw-outline-2",
61
+ "forced-colors:has-[input:focus-visible]:tw-outline-offset-2",
62
+ "forced-colors:has-[input:focus-visible]:tw-outline-[Highlight]"
63
+ ], focused && "ant-input-affix-wrapper-focused tw-border-[var(--border-brand-strong)]", !mergedDisabled && !focused && "hover:tw-border-[var(--border-brand-strong)]", `ald-input-${getSizeType(size)}`, "tw-text-typography-body-dense", size === "small" && "tw-h-7", size === "large" && "tw-h-9", (size === "middle" || !size) && "tw-h-8", status === "error" && `ald-input-error tw-border-[var(--border-negative-strong)]`, status === "warning" && `ald-input-warning tw-border-[var(--border-warning-subtle)]`, mergedDisabled && "ald-input-disabled tw-cursor-not-allowed tw-bg-[var(--background-neutral-on-subtle)] tw-text-[var(--content-secondary)]", compactClasses, className),
58
64
  style: {
59
65
  ...style,
60
66
  width
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../src/Input/components/Input/index.tsx"],"sourcesContent":["import React, {\n ReactNode,\n forwardRef,\n useContext,\n useRef,\n useState,\n} from 'react';\nimport DisabledContext from '../../../ConfigProvider/DisabledContext';\nimport SizeContext, { SizeType } from '../../../ConfigProvider/sizeContext';\nimport { CloseCircleFill } from '../../../Icon';\nimport { cn } from '../../../lib/utils';\nimport { useCompactItemContext } from '../../../Space/CompactContext';\n\ninterface IShowCountProps {\n formatter: (args: { count: number; maxLength?: number }) => string;\n}\nexport type TSize = SizeType;\nexport type InputRef = HTMLInputElement & {\n /** antd v4 compat — points to the underlying <input> element */\n input?: HTMLInputElement | null;\n};\n\ntype ChangeEventHandler = (e: React.ChangeEvent<HTMLInputElement>) => void;\n\nexport interface IInputProps\n extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'size'\n | 'prefix'\n | 'value'\n | 'defaultValue'\n | 'onChange'\n | 'disabled'\n | 'type'\n | 'max'\n > {\n addonAfter?: ReactNode;\n addonBefore?: ReactNode;\n size?: TSize;\n id?: string;\n prefix?: ReactNode;\n suffix?: ReactNode;\n allowClear?: boolean;\n disabled?: boolean;\n showCount?: boolean | IShowCountProps;\n maxLength?: number;\n minLength?: number;\n max?: number;\n value?: string;\n defaultValue?: string;\n onPressEnter?: React.KeyboardEventHandler<HTMLInputElement>;\n onChange?: ChangeEventHandler;\n className?: string;\n style?: React.CSSProperties;\n placeholder?: string;\n type?: string;\n bordered?: boolean;\n status?: 'error' | 'warning' | '';\n autoComplete?: string;\n autoFocus?: boolean;\n readOnly?: boolean;\n width?: number | string;\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n onFocus?: React.FocusEventHandler<HTMLInputElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n onCompositionStart?: React.CompositionEventHandler<HTMLInputElement>;\n onCompositionEnd?: React.CompositionEventHandler<HTMLInputElement>;\n /** 透传到内部 input 元素的 data-testid,用于自动化测试定位 */\n 'data-testid'?: string;\n /** 透传到内部 input 元素的 aria-label,用于可访问性与自动化测试定位 */\n 'aria-label'?: string;\n}\n\nexport function getSizeType(sizeType: TSize): TSize {\n if (['small', 'middle', 'large'].includes(sizeType || '')) {\n return sizeType;\n }\n return 'middle';\n}\n\nconst Input = forwardRef<InputRef, IInputProps>((props, ref) => {\n const {\n size: customSize,\n className,\n bordered = true,\n status,\n disabled,\n allowClear,\n prefix,\n suffix,\n addonBefore,\n addonAfter,\n showCount,\n maxLength,\n minLength,\n value: controlledValue,\n defaultValue,\n onChange,\n onPressEnter,\n onBlur,\n onFocus,\n onKeyDown,\n onCompositionStart,\n onCompositionEnd,\n placeholder,\n type,\n id,\n autoComplete = 'off',\n autoFocus,\n readOnly,\n width,\n style,\n 'data-testid': dataTestid,\n 'aria-label': ariaLabel,\n ...restInputProps\n } = props;\n\n const contextDisabled = useContext(DisabledContext);\n const mergedDisabled = disabled ?? contextDisabled;\n\n const contentSize = useContext(SizeContext);\n const { compactSize, compactItemClassnames } =\n useCompactItemContext('ald-input');\n const size = customSize || compactSize || contentSize || 'middle';\n\n const isControlled = 'value' in props;\n const [innerValue, setInnerValue] = useState(defaultValue ?? '');\n const currentValue = isControlled ? controlledValue ?? '' : innerValue;\n const [focused, setFocused] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n React.useImperativeHandle(ref, () => {\n const el = inputRef.current!;\n // Expose .input for antd v4 compat (ref.current.input.focus())\n (el as InputRef).input = el;\n return el as InputRef;\n });\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) setInnerValue(e.target.value);\n onChange?.(e);\n };\n\n const handleClear = () => {\n // 通过原生 input 事件统一触发 React onChange,确保事件契约完整且只回调一次。\n const nativeEvent = new Event('input', { bubbles: true });\n if (inputRef.current) {\n const nativeSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n 'value',\n )?.set;\n nativeSetter?.call(inputRef.current, '');\n inputRef.current.dispatchEvent(nativeEvent);\n }\n if (!isControlled) setInnerValue('');\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') onPressEnter?.(e);\n onKeyDown?.(e);\n };\n\n const showClearIcon = allowClear && currentValue && !mergedDisabled;\n\n const countInfo =\n showCount && typeof showCount === 'object'\n ? showCount.formatter({\n count: currentValue.length,\n maxLength,\n })\n : showCount\n ? `${currentValue.length}${maxLength ? `/${maxLength}` : ''}`\n : null;\n\n // Build compact-mode border-radius and margin overrides\n const compactClasses = compactItemClassnames\n ? cn(\n !compactItemClassnames['ald-input-compact-first-item'] &&\n '!tw-rounded-l-none',\n !compactItemClassnames['ald-input-compact-last-item'] &&\n '!tw-rounded-r-none',\n !compactItemClassnames['ald-input-compact-first-item'] && '-tw-ml-px',\n )\n : undefined;\n\n return (\n <span\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-input ant-input-affix-wrapper tw-inline-flex tw-w-full tw-items-center tw-bg-[var(--background-default)]',\n bordered &&\n 'tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-neutral-subtle)]',\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n // focus 仅变 border-color,不加额外 box-shadow/outline。\n // 消费方通过 CSS 将 border 设为 0 后 focus 高亮自然消失,和 antd 行为一致。\n focused &&\n 'ant-input-affix-wrapper-focused tw-border-[var(--border-brand-strong)]',\n !mergedDisabled &&\n !focused &&\n 'hover:tw-border-[var(--border-brand-strong)]',\n `ald-input-${getSizeType(size)}`,\n // Typography Foundation: the wrapper owns the approved Body Dense\n // context for the editable value and placeholder. Count opts into its\n // approved Caption role below.\n 'tw-text-typography-body-dense',\n // Component Geometry: height belongs to the Input envelope, not to a\n // relationship-spacing Primitive.\n size === 'small' && 'tw-h-7',\n size === 'large' && 'tw-h-9',\n (size === 'middle' || !size) && 'tw-h-8',\n status === 'error' &&\n `ald-input-error tw-border-[var(--border-negative-strong)]`,\n status === 'warning' &&\n `ald-input-warning tw-border-[var(--border-warning-subtle)]`,\n mergedDisabled &&\n 'ald-input-disabled tw-cursor-not-allowed tw-bg-[var(--background-neutral-on-subtle)] tw-text-[var(--content-secondary)]',\n compactClasses,\n className,\n )}\n style={{\n ...style,\n width,\n }}\n onMouseDown={(e) => {\n // 点击 wrapper 非 input 区域时:\n // 如果 input 已聚焦 → preventDefault 防止点击 wrapper 导致丢焦\n // 如果 input 未聚焦 → 不阻止默认行为,让浏览器正常处理 blur 上一个元素\n if (e.target !== inputRef.current) {\n if (document.activeElement === inputRef.current) {\n e.preventDefault();\n }\n }\n }}\n onMouseUp={(e) => {\n // 在 mouseUp 时将焦点转发给内部 input(兼容 prefix/suffix/padding 区域的点击)\n if (e.target !== inputRef.current && inputRef.current) {\n inputRef.current.focus();\n }\n }}\n >\n {addonBefore && (\n <span className=\"ald-input-addon tw-flex tw-shrink-0 tw-items-center tw-self-stretch tw-border-r tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-neutral-subtle)] tw-px-3 tw-text-[var(--content-secondary)]\">\n {addonBefore}\n </span>\n )}\n {/* antd 兼容:保留 ant-input-prefix class,消费方 CSS 可能依赖该选择器 */}\n {prefix && (\n <span className=\"ald-input-prefix ant-input-prefix tw-flex tw-shrink-0 tw-items-center tw-pl-2 tw-text-[var(--content-secondary)]\">\n {prefix}\n </span>\n )}\n {/*\n * Value Affordance and Text Containment remain Constraint-owned and\n * Blocked. These shrink guards reserve local Geometry for affordances;\n * they do not define a spacing Primitive or Mapping.\n */}\n <input\n ref={inputRef}\n id={id}\n type={type || 'text'}\n className=\"tw-min-w-0 tw-flex-1 tw-self-stretch tw-border-0 tw-bg-[var(--action-ghost-normal)] tw-px-2 tw-text-[var(--content-primary)] tw-text-inherit tw-outline-none\"\n value={currentValue}\n onChange={handleChange}\n onBlur={(e) => {\n setFocused(false);\n onBlur?.(e);\n }}\n onFocus={(e) => {\n setFocused(true);\n onFocus?.(e);\n }}\n onKeyDown={handleKeyDown}\n onCompositionStart={onCompositionStart}\n onCompositionEnd={onCompositionEnd}\n disabled={mergedDisabled}\n placeholder={placeholder}\n maxLength={maxLength}\n minLength={minLength}\n autoComplete={autoComplete}\n autoFocus={autoFocus}\n readOnly={readOnly}\n spellCheck={false}\n data-testid={dataTestid}\n aria-label={ariaLabel}\n {...restInputProps}\n />\n {showClearIcon && (\n <span\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n className=\"ald-input-clear ant-input-clear-icon tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-pr-1\"\n onClick={handleClear}\n >\n <CloseCircleFill size={16} color=\"var(--content-secondary)\" />\n </span>\n )}\n {/* antd 兼容:保留 ant-input-suffix class,消费方 CSS 可能依赖该选择器 */}\n {suffix && (\n <span className=\"ald-input-suffix ant-input-suffix tw-flex tw-shrink-0 tw-items-center tw-pr-2 tw-text-[var(--content-secondary)]\">\n {suffix}\n </span>\n )}\n {countInfo && (\n <span className=\"ald-input-count tw-shrink-0 tw-pr-2 tw-text-[var(--content-tertiary)] tw-text-typography-caption\">\n {countInfo}\n </span>\n )}\n {addonAfter && (\n <span className=\"ald-input-addon tw-border-l tw-border-solid tw-border-[var(--border-default)] tw-px-2 tw-text-[var(--content-secondary)]\">\n {addonAfter}\n </span>\n )}\n </span>\n );\n});\n\nexport default Input;\n"],"mappings":";;;;;;;;AAyEA,SAAgB,YAAY,UAAwB;AAClD,KAAI;EAAC;EAAS;EAAU;EAAQ,CAAC,SAAS,YAAY,GAAG,CACvD,QAAO;AAET,QAAO;;AAGT,IAAM,QAAQ,YAAmC,OAAO,QAAQ;CAC9D,MAAM,EACJ,MAAM,YACN,WACA,WAAW,MACX,QACA,UACA,YACA,QACA,QACA,aACA,YACA,WACA,WACA,WACA,OAAO,iBACP,cACA,UACA,cACA,QACA,SACA,WACA,oBACA,kBACA,aACA,MACA,IACA,eAAe,OACf,WACA,UACA,OACA,OACA,eAAe,YACf,cAAc,WACd,GAAG,mBACD;CAEJ,MAAM,kBAAkB,WAAW,gBAAgB;CACnD,MAAM,iBAAiB,YAAY;CAEnC,MAAM,cAAc,WAAW,YAAY;CAC3C,MAAM,EAAE,aAAa,0BACnB,sBAAsB,YAAY;CACpC,MAAM,OAAO,cAAc,eAAe,eAAe;CAEzD,MAAM,eAAe,WAAW;CAChC,MAAM,CAAC,YAAY,iBAAiB,SAAS,gBAAgB,GAAG;CAChE,MAAM,eAAe,eAAe,mBAAmB,KAAK;CAC5D,MAAM,CAAC,SAAS,cAAc,SAAS,MAAM;CAC7C,MAAM,WAAW,OAAyB,KAAK;AAE/C,OAAM,oBAAoB,WAAW;EACnC,MAAM,KAAK,SAAS;AAEnB,KAAgB,QAAQ;AACzB,SAAO;GACP;CAEF,MAAM,gBAAgB,MAA2C;AAC/D,MAAI,CAAC,aAAc,eAAc,EAAE,OAAO,MAAM;AAChD,aAAW,EAAE;;CAGf,MAAM,oBAAoB;EAExB,MAAM,cAAc,IAAI,MAAM,SAAS,EAAE,SAAS,MAAM,CAAC;AACzD,MAAI,SAAS,SAAS;AAKpB,IAJqB,OAAO,yBAC1B,iBAAiB,WACjB,QACD,EAAE,MACW,KAAK,SAAS,SAAS,GAAG;AACxC,YAAS,QAAQ,cAAc,YAAY;;AAE7C,MAAI,CAAC,aAAc,eAAc,GAAG;;CAGtC,MAAM,iBAAiB,MAA6C;AAClE,MAAI,EAAE,QAAQ,QAAS,gBAAe,EAAE;AACxC,cAAY,EAAE;;CAGhB,MAAM,gBAAgB,cAAc,gBAAgB,CAAC;CAErD,MAAM,YACJ,aAAa,OAAO,cAAc,WAC9B,UAAU,UAAU;EAClB,OAAO,aAAa;EACpB;EACD,CAAC,GACF,YACA,GAAG,aAAa,SAAS,YAAY,IAAI,cAAc,OACvD;CAGN,MAAM,iBAAiB,wBACnB,GACE,CAAC,sBAAsB,mCACrB,sBACF,CAAC,sBAAsB,kCACrB,sBACF,CAAC,sBAAsB,mCAAmC,YAC3D,GACD;AAEJ,QACE,qBAAC,QAAD;EACE,WAAW,GAET,gHACA,YACE,sFAIF,WACE,0EACF,CAAC,kBACC,CAAC,WACD,gDACF,aAAa,YAAY,KAAK,IAI9B,iCAGA,SAAS,WAAW,UACpB,SAAS,WAAW,WACnB,SAAS,YAAY,CAAC,SAAS,UAChC,WAAW,WACT,6DACF,WAAW,aACT,8DACF,kBACE,2HACF,gBACA,UACD;EACD,OAAO;GACL,GAAG;GACH;GACD;EACD,cAAc,MAAM;AAIlB,OAAI,EAAE,WAAW,SAAS,SACxB;QAAI,SAAS,kBAAkB,SAAS,QACtC,GAAE,gBAAgB;;;EAIxB,YAAY,MAAM;AAEhB,OAAI,EAAE,WAAW,SAAS,WAAW,SAAS,QAC5C,UAAS,QAAQ,OAAO;;YAlD9B;GAsDG,eACC,oBAAC,QAAD;IAAM,WAAU;cACb;IACI,CAAA;GAGR,UACC,oBAAC,QAAD;IAAM,WAAU;cACb;IACI,CAAA;GAOT,oBAAC,SAAD;IACE,KAAK;IACD;IACJ,MAAM,QAAQ;IACd,WAAU;IACV,OAAO;IACP,UAAU;IACV,SAAS,MAAM;AACb,gBAAW,MAAM;AACjB,cAAS,EAAE;;IAEb,UAAU,MAAM;AACd,gBAAW,KAAK;AAChB,eAAU,EAAE;;IAEd,WAAW;IACS;IACF;IAClB,UAAU;IACG;IACF;IACA;IACG;IACH;IACD;IACV,YAAY;IACZ,eAAa;IACb,cAAY;IACZ,GAAI;IACJ,CAAA;GACD,iBACC,oBAAC,QAAD;IAEE,WAAU;IACV,SAAS;cAET,oBAAC,MAAD;KAAiB,MAAM;KAAI,OAAM;KAA6B,CAAA;IACzD,CAAA;GAGR,UACC,oBAAC,QAAD;IAAM,WAAU;cACb;IACI,CAAA;GAER,aACC,oBAAC,QAAD;IAAM,WAAU;cACb;IACI,CAAA;GAER,cACC,oBAAC,QAAD;IAAM,WAAU;cACb;IACI,CAAA;GAEJ;;EAET"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/Input/components/Input/index.tsx"],"sourcesContent":["import React, {\n ReactNode,\n forwardRef,\n useContext,\n useRef,\n useState,\n} from 'react';\nimport DisabledContext from '../../../ConfigProvider/DisabledContext';\nimport SizeContext, { SizeType } from '../../../ConfigProvider/sizeContext';\nimport { CloseCircleFill } from '../../../Icon';\nimport { cn } from '../../../lib/utils';\nimport { useCompactItemContext } from '../../../Space/CompactContext';\n\ninterface IShowCountProps {\n formatter: (args: { count: number; maxLength?: number }) => string;\n}\nexport type TSize = SizeType;\nexport type InputRef = HTMLInputElement & {\n /** antd v4 compat — points to the underlying <input> element */\n input?: HTMLInputElement | null;\n};\n\ntype ChangeEventHandler = (e: React.ChangeEvent<HTMLInputElement>) => void;\n\nexport interface IInputProps\n extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n | 'size'\n | 'prefix'\n | 'value'\n | 'defaultValue'\n | 'onChange'\n | 'disabled'\n | 'type'\n | 'max'\n > {\n addonAfter?: ReactNode;\n addonBefore?: ReactNode;\n size?: TSize;\n id?: string;\n prefix?: ReactNode;\n suffix?: ReactNode;\n allowClear?: boolean;\n disabled?: boolean;\n showCount?: boolean | IShowCountProps;\n maxLength?: number;\n minLength?: number;\n max?: number;\n value?: string;\n defaultValue?: string;\n onPressEnter?: React.KeyboardEventHandler<HTMLInputElement>;\n onChange?: ChangeEventHandler;\n className?: string;\n style?: React.CSSProperties;\n placeholder?: string;\n type?: string;\n bordered?: boolean;\n status?: 'error' | 'warning' | '';\n autoComplete?: string;\n autoFocus?: boolean;\n readOnly?: boolean;\n width?: number | string;\n onBlur?: React.FocusEventHandler<HTMLInputElement>;\n onFocus?: React.FocusEventHandler<HTMLInputElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>;\n onCompositionStart?: React.CompositionEventHandler<HTMLInputElement>;\n onCompositionEnd?: React.CompositionEventHandler<HTMLInputElement>;\n /** 透传到内部 input 元素的 data-testid,用于自动化测试定位 */\n 'data-testid'?: string;\n /** 透传到内部 input 元素的 aria-label,用于可访问性与自动化测试定位 */\n 'aria-label'?: string;\n}\n\nexport function getSizeType(sizeType: TSize): TSize {\n if (['small', 'middle', 'large'].includes(sizeType || '')) {\n return sizeType;\n }\n return 'middle';\n}\n\nconst Input = forwardRef<InputRef, IInputProps>((props, ref) => {\n const {\n size: customSize,\n className,\n bordered = true,\n status,\n disabled,\n allowClear,\n prefix,\n suffix,\n addonBefore,\n addonAfter,\n showCount,\n maxLength,\n minLength,\n value: controlledValue,\n defaultValue,\n onChange,\n onPressEnter,\n onBlur,\n onFocus,\n onKeyDown,\n onCompositionStart,\n onCompositionEnd,\n placeholder,\n type,\n id,\n autoComplete = 'off',\n autoFocus,\n readOnly,\n width,\n style,\n 'data-testid': dataTestid,\n 'aria-label': ariaLabel,\n ...restInputProps\n } = props;\n\n const contextDisabled = useContext(DisabledContext);\n const mergedDisabled = disabled ?? contextDisabled;\n\n const contentSize = useContext(SizeContext);\n const { compactSize, compactItemClassnames } =\n useCompactItemContext('ald-input');\n const size = customSize || compactSize || contentSize || 'middle';\n\n const isControlled = 'value' in props;\n const [innerValue, setInnerValue] = useState(defaultValue ?? '');\n const currentValue = isControlled ? controlledValue ?? '' : innerValue;\n const [focused, setFocused] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n React.useImperativeHandle(ref, () => {\n const el = inputRef.current!;\n // Expose .input for antd v4 compat (ref.current.input.focus())\n (el as InputRef).input = el;\n return el as InputRef;\n });\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) setInnerValue(e.target.value);\n onChange?.(e);\n };\n\n const handleClear = () => {\n // 通过原生 input 事件统一触发 React onChange,确保事件契约完整且只回调一次。\n const nativeEvent = new Event('input', { bubbles: true });\n if (inputRef.current) {\n const nativeSetter = Object.getOwnPropertyDescriptor(\n HTMLInputElement.prototype,\n 'value',\n )?.set;\n nativeSetter?.call(inputRef.current, '');\n inputRef.current.dispatchEvent(nativeEvent);\n }\n if (!isControlled) setInnerValue('');\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') onPressEnter?.(e);\n onKeyDown?.(e);\n };\n\n const showClearIcon = allowClear && currentValue && !mergedDisabled;\n\n const countInfo =\n showCount && typeof showCount === 'object'\n ? showCount.formatter({\n count: currentValue.length,\n maxLength,\n })\n : showCount\n ? `${currentValue.length}${maxLength ? `/${maxLength}` : ''}`\n : null;\n\n // Build compact-mode border-radius and margin overrides\n const compactClasses = compactItemClassnames\n ? cn(\n !compactItemClassnames['ald-input-compact-first-item'] &&\n '!tw-rounded-l-none',\n !compactItemClassnames['ald-input-compact-last-item'] &&\n '!tw-rounded-r-none',\n !compactItemClassnames['ald-input-compact-first-item'] && '-tw-ml-px',\n )\n : undefined;\n\n return (\n <span\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-input ant-input-affix-wrapper tw-inline-flex tw-w-full tw-items-center tw-bg-[var(--background-default)]',\n bordered &&\n 'tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-neutral-subtle)]',\n !mergedDisabled && [\n 'has-[input:focus-visible]:tw-shadow-[0_0_0_2px_var(--focus-ring)]',\n 'forced-colors:has-[input:focus-visible]:tw-outline',\n 'forced-colors:has-[input:focus-visible]:tw-outline-2',\n 'forced-colors:has-[input:focus-visible]:tw-outline-offset-2',\n 'forced-colors:has-[input:focus-visible]:tw-outline-[Highlight]',\n ],\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n // 保留既有 border 状态以维持 antd 兼容;键盘焦点由上方的 Focus State Layer 独立呈现。\n focused &&\n 'ant-input-affix-wrapper-focused tw-border-[var(--border-brand-strong)]',\n !mergedDisabled &&\n !focused &&\n 'hover:tw-border-[var(--border-brand-strong)]',\n `ald-input-${getSizeType(size)}`,\n // Typography Foundation: the wrapper owns the approved Body Dense\n // context for the editable value and placeholder. Count opts into its\n // approved Caption role below.\n 'tw-text-typography-body-dense',\n // Component Geometry: height belongs to the Input envelope, not to a\n // relationship-spacing Primitive.\n size === 'small' && 'tw-h-7',\n size === 'large' && 'tw-h-9',\n (size === 'middle' || !size) && 'tw-h-8',\n status === 'error' &&\n `ald-input-error tw-border-[var(--border-negative-strong)]`,\n status === 'warning' &&\n `ald-input-warning tw-border-[var(--border-warning-subtle)]`,\n mergedDisabled &&\n 'ald-input-disabled tw-cursor-not-allowed tw-bg-[var(--background-neutral-on-subtle)] tw-text-[var(--content-secondary)]',\n compactClasses,\n className,\n )}\n style={{\n ...style,\n width,\n }}\n onMouseDown={(e) => {\n // 点击 wrapper 非 input 区域时:\n // 如果 input 已聚焦 → preventDefault 防止点击 wrapper 导致丢焦\n // 如果 input 未聚焦 → 不阻止默认行为,让浏览器正常处理 blur 上一个元素\n if (e.target !== inputRef.current) {\n if (document.activeElement === inputRef.current) {\n e.preventDefault();\n }\n }\n }}\n onMouseUp={(e) => {\n // 在 mouseUp 时将焦点转发给内部 input(兼容 prefix/suffix/padding 区域的点击)\n if (e.target !== inputRef.current && inputRef.current) {\n inputRef.current.focus();\n }\n }}\n >\n {addonBefore && (\n <span className=\"ald-input-addon tw-flex tw-shrink-0 tw-items-center tw-self-stretch tw-border-r tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-neutral-subtle)] tw-px-3 tw-text-[var(--content-secondary)]\">\n {addonBefore}\n </span>\n )}\n {/* antd 兼容:保留 ant-input-prefix class,消费方 CSS 可能依赖该选择器 */}\n {prefix && (\n <span className=\"ald-input-prefix ant-input-prefix tw-flex tw-shrink-0 tw-items-center tw-pl-2 tw-text-[var(--content-secondary)]\">\n {prefix}\n </span>\n )}\n {/*\n * Value Affordance and Text Containment remain Constraint-owned and\n * Blocked. These shrink guards reserve local Geometry for affordances;\n * they do not define a spacing Primitive or Mapping.\n */}\n <input\n ref={inputRef}\n id={id}\n type={type || 'text'}\n className=\"tw-min-w-0 tw-flex-1 tw-self-stretch tw-border-0 tw-bg-[var(--action-ghost-normal)] tw-px-2 tw-text-[var(--content-primary)] tw-text-inherit tw-outline-none\"\n value={currentValue}\n onChange={handleChange}\n onBlur={(e) => {\n setFocused(false);\n onBlur?.(e);\n }}\n onFocus={(e) => {\n setFocused(true);\n onFocus?.(e);\n }}\n onKeyDown={handleKeyDown}\n onCompositionStart={onCompositionStart}\n onCompositionEnd={onCompositionEnd}\n disabled={mergedDisabled}\n placeholder={placeholder}\n maxLength={maxLength}\n minLength={minLength}\n autoComplete={autoComplete}\n autoFocus={autoFocus}\n readOnly={readOnly}\n spellCheck={false}\n data-testid={dataTestid}\n aria-label={ariaLabel}\n {...restInputProps}\n />\n {showClearIcon && (\n <span\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n className=\"ald-input-clear ant-input-clear-icon tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-pr-1\"\n onClick={handleClear}\n >\n <CloseCircleFill size={16} color=\"var(--content-secondary)\" />\n </span>\n )}\n {/* antd 兼容:保留 ant-input-suffix class,消费方 CSS 可能依赖该选择器 */}\n {suffix && (\n <span className=\"ald-input-suffix ant-input-suffix tw-flex tw-shrink-0 tw-items-center tw-pr-2 tw-text-[var(--content-secondary)]\">\n {suffix}\n </span>\n )}\n {countInfo && (\n <span className=\"ald-input-count tw-shrink-0 tw-pr-2 tw-text-[var(--content-tertiary)] tw-text-typography-caption\">\n {countInfo}\n </span>\n )}\n {addonAfter && (\n <span className=\"ald-input-addon tw-border-l tw-border-solid tw-border-[var(--border-default)] tw-px-2 tw-text-[var(--content-secondary)]\">\n {addonAfter}\n </span>\n )}\n </span>\n );\n});\n\nexport default Input;\n"],"mappings":"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"}
@@ -33,7 +33,13 @@ var TextArea_default = forwardRef((props, ref) => {
33
33
  const minRows = typeof autoSize === "object" ? autoSize.minRows : void 0;
34
34
  const maxRows = typeof autoSize === "object" ? autoSize.maxRows : void 0;
35
35
  return /* @__PURE__ */ jsxs("div", {
36
- className: cn("ald-input ald-input-textarea tw-relative", `ald-input-textarea-${getSizeType(size)}`, isBordered && "tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-neutral-subtle)]", mergedDisabled && "ald-input-disabled tw-opacity-50", className),
36
+ className: cn("ald-input ald-input-textarea tw-relative", `ald-input-textarea-${getSizeType(size)}`, isBordered && "tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-neutral-subtle)]", !mergedDisabled && [
37
+ "has-[textarea:focus-visible]:tw-shadow-[0_0_0_2px_var(--focus-ring)]",
38
+ "forced-colors:has-[textarea:focus-visible]:tw-outline",
39
+ "forced-colors:has-[textarea:focus-visible]:tw-outline-2",
40
+ "forced-colors:has-[textarea:focus-visible]:tw-outline-offset-2",
41
+ "forced-colors:has-[textarea:focus-visible]:tw-outline-[Highlight]"
42
+ ], mergedDisabled && "ald-input-disabled tw-opacity-50", className),
37
43
  style,
38
44
  children: [
39
45
  /* @__PURE__ */ jsx("textarea", {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../src/Input/components/TextArea/index.tsx"],"sourcesContent":["import React, { forwardRef, useContext, useRef, useState } from 'react';\nimport DisabledContext from '../../../ConfigProvider/DisabledContext';\nimport SizeContext from '../../../ConfigProvider/sizeContext';\nimport { CloseCircleFill } from '../../../Icon';\nimport { cn } from '../../../lib/utils';\nimport { TSize, getSizeType } from '../Input';\n\nexport type TextAreaRef = HTMLTextAreaElement;\n\nexport interface ITextAreaProps\n extends Omit<\n React.TextareaHTMLAttributes<HTMLTextAreaElement>,\n 'size' | 'value' | 'defaultValue' | 'onChange' | 'disabled' | 'rows'\n > {\n autoFocus?: boolean;\n allowClear?: boolean;\n autoSize?: boolean | { minRows?: number; maxRows?: number };\n defaultValue?: string;\n maxLength?: number;\n showCount?:\n | boolean\n | { formatter: (args: { count: number; maxLength?: number }) => string };\n value?: string;\n onPressEnter?: React.KeyboardEventHandler<HTMLTextAreaElement>;\n onResize?: (size: { width: number; height: number }) => void;\n border?: boolean;\n bordered?: boolean;\n className?: string;\n size?: TSize;\n disabled?: boolean;\n placeholder?: string;\n rows?: number;\n onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;\n onBlur?: React.FocusEventHandler<HTMLTextAreaElement>;\n onFocus?: React.FocusEventHandler<HTMLTextAreaElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLTextAreaElement>;\n onCompositionStart?: React.CompositionEventHandler<HTMLTextAreaElement>;\n onCompositionEnd?: React.CompositionEventHandler<HTMLTextAreaElement>;\n style?: React.CSSProperties;\n}\n\nexport default forwardRef<TextAreaRef, ITextAreaProps>((props, ref) => {\n const {\n bordered,\n border,\n size: customSize,\n disabled,\n className = '',\n allowClear = false,\n value: controlledValue,\n defaultValue,\n onChange,\n onPressEnter,\n maxLength,\n showCount,\n autoSize,\n placeholder,\n rows,\n onBlur,\n onFocus,\n onKeyDown,\n onCompositionStart,\n onCompositionEnd,\n style,\n ...restTextAreaProps\n } = props;\n\n const isBordered = bordered ?? border ?? true;\n\n const contextDisabled = useContext(DisabledContext);\n const mergedDisabled = disabled ?? contextDisabled;\n\n const contentSize = useContext(SizeContext);\n const size = customSize || contentSize || 'middle';\n const isControlled = 'value' in props;\n const [innerValue, setInnerValue] = useState(defaultValue ?? '');\n const currentValue = isControlled ? controlledValue ?? '' : innerValue;\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n React.useImperativeHandle(ref, () => textareaRef.current!);\n\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (!isControlled) setInnerValue(e.target.value);\n onChange?.(e);\n };\n\n const handleClear = () => {\n if (!isControlled) setInnerValue('');\n onChange?.({\n target: { value: '' },\n } as React.ChangeEvent<HTMLTextAreaElement>);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter') onPressEnter?.(e);\n onKeyDown?.(e);\n };\n\n const minRows = typeof autoSize === 'object' ? autoSize.minRows : undefined;\n const maxRows = typeof autoSize === 'object' ? autoSize.maxRows : undefined;\n\n return (\n <div\n className={cn(\n 'ald-input ald-input-textarea tw-relative',\n `ald-input-textarea-${getSizeType(size)}`,\n isBordered &&\n 'tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-neutral-subtle)]',\n mergedDisabled && 'ald-input-disabled tw-opacity-50',\n className,\n )}\n style={style}\n >\n <textarea\n ref={textareaRef}\n className=\"tw-w-full tw-resize-y tw-border-0 tw-bg-[var(--action-ghost-normal)] tw-px-3 tw-py-2 tw-text-[var(--content-primary)] tw-outline-none tw-text-typography-body-dense\"\n value={currentValue}\n onChange={handleChange}\n onBlur={onBlur}\n onFocus={onFocus}\n onKeyDown={handleKeyDown}\n onCompositionStart={onCompositionStart}\n onCompositionEnd={onCompositionEnd}\n disabled={mergedDisabled}\n placeholder={placeholder}\n maxLength={maxLength}\n rows={rows || (minRows ?? 3)}\n spellCheck={false}\n autoComplete=\"off\"\n {...restTextAreaProps}\n style={{\n minHeight: minRows ? `${minRows * 22}px` : undefined,\n maxHeight: maxRows ? `${maxRows * 22}px` : undefined,\n }}\n />\n {allowClear && currentValue && !mergedDisabled && (\n <span\n className=\"tw-absolute tw-right-2 tw-top-2 tw-cursor-pointer\"\n onClick={handleClear}\n >\n <CloseCircleFill size={16} color=\"var(--content-secondary)\" />\n </span>\n )}\n {showCount && (\n <div className=\"tw-px-2 tw-pb-1 tw-text-right tw-text-[var(--content-tertiary)] tw-text-typography-caption\">\n {typeof showCount === 'object'\n ? showCount.formatter({ count: currentValue.length, maxLength })\n : `${currentValue.length}${maxLength ? `/${maxLength}` : ''}`}\n </div>\n )}\n </div>\n );\n});\n"],"mappings":";;;;;;;;AAyCA,IAAA,mBAAe,YAAyC,OAAO,QAAQ;CACrE,MAAM,EACJ,UACA,QACA,MAAM,YACN,UACA,YAAY,IACZ,aAAa,OACb,OAAO,iBACP,cACA,UACA,cACA,WACA,WACA,UACA,aACA,MACA,QACA,SACA,WACA,oBACA,kBACA,OACA,GAAG,sBACD;CAEJ,MAAM,aAAa,YAAY,UAAU;CAEzC,MAAM,kBAAkB,WAAW,gBAAgB;CACnD,MAAM,iBAAiB,YAAY;CAEnC,MAAM,cAAc,WAAW,YAAY;CAC3C,MAAM,OAAO,cAAc,eAAe;CAC1C,MAAM,eAAe,WAAW;CAChC,MAAM,CAAC,YAAY,iBAAiB,SAAS,gBAAgB,GAAG;CAChE,MAAM,eAAe,eAAe,mBAAmB,KAAK;CAC5D,MAAM,cAAc,OAA4B,KAAK;AAErD,OAAM,oBAAoB,WAAW,YAAY,QAAS;CAE1D,MAAM,gBAAgB,MAA8C;AAClE,MAAI,CAAC,aAAc,eAAc,EAAE,OAAO,MAAM;AAChD,aAAW,EAAE;;CAGf,MAAM,oBAAoB;AACxB,MAAI,CAAC,aAAc,eAAc,GAAG;AACpC,aAAW,EACT,QAAQ,EAAE,OAAO,IAAI,EACtB,CAA2C;;CAG9C,MAAM,iBAAiB,MAAgD;AACrE,MAAI,EAAE,QAAQ,QAAS,gBAAe,EAAE;AACxC,cAAY,EAAE;;CAGhB,MAAM,UAAU,OAAO,aAAa,WAAW,SAAS,UAAU;CAClE,MAAM,UAAU,OAAO,aAAa,WAAW,SAAS,UAAU;AAElE,QACE,qBAAC,OAAD;EACE,WAAW,GACT,4CACA,sBAAsB,YAAY,KAAK,IACvC,cACE,sFACF,kBAAkB,oCAClB,UACD;EACM;YATT;GAWE,oBAAC,YAAD;IACE,KAAK;IACL,WAAU;IACV,OAAO;IACP,UAAU;IACF;IACC;IACT,WAAW;IACS;IACF;IAClB,UAAU;IACG;IACF;IACX,MAAM,SAAS,WAAW;IAC1B,YAAY;IACZ,cAAa;IACb,GAAI;IACJ,OAAO;KACL,WAAW,UAAU,GAAG,UAAU,GAAG,MAAM;KAC3C,WAAW,UAAU,GAAG,UAAU,GAAG,MAAM;KAC5C;IACD,CAAA;GACD,cAAc,gBAAgB,CAAC,kBAC9B,oBAAC,QAAD;IACE,WAAU;IACV,SAAS;cAET,oBAAC,MAAD;KAAiB,MAAM;KAAI,OAAM;KAA6B,CAAA;IACzD,CAAA;GAER,aACC,oBAAC,OAAD;IAAK,WAAU;cACZ,OAAO,cAAc,WAClB,UAAU,UAAU;KAAE,OAAO,aAAa;KAAQ;KAAW,CAAC,GAC9D,GAAG,aAAa,SAAS,YAAY,IAAI,cAAc;IACvD,CAAA;GAEJ;;EAER"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/Input/components/TextArea/index.tsx"],"sourcesContent":["import React, { forwardRef, useContext, useRef, useState } from 'react';\nimport DisabledContext from '../../../ConfigProvider/DisabledContext';\nimport SizeContext from '../../../ConfigProvider/sizeContext';\nimport { CloseCircleFill } from '../../../Icon';\nimport { cn } from '../../../lib/utils';\nimport { TSize, getSizeType } from '../Input';\n\nexport type TextAreaRef = HTMLTextAreaElement;\n\nexport interface ITextAreaProps\n extends Omit<\n React.TextareaHTMLAttributes<HTMLTextAreaElement>,\n 'size' | 'value' | 'defaultValue' | 'onChange' | 'disabled' | 'rows'\n > {\n autoFocus?: boolean;\n allowClear?: boolean;\n autoSize?: boolean | { minRows?: number; maxRows?: number };\n defaultValue?: string;\n maxLength?: number;\n showCount?:\n | boolean\n | { formatter: (args: { count: number; maxLength?: number }) => string };\n value?: string;\n onPressEnter?: React.KeyboardEventHandler<HTMLTextAreaElement>;\n onResize?: (size: { width: number; height: number }) => void;\n border?: boolean;\n bordered?: boolean;\n className?: string;\n size?: TSize;\n disabled?: boolean;\n placeholder?: string;\n rows?: number;\n onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;\n onBlur?: React.FocusEventHandler<HTMLTextAreaElement>;\n onFocus?: React.FocusEventHandler<HTMLTextAreaElement>;\n onKeyDown?: React.KeyboardEventHandler<HTMLTextAreaElement>;\n onCompositionStart?: React.CompositionEventHandler<HTMLTextAreaElement>;\n onCompositionEnd?: React.CompositionEventHandler<HTMLTextAreaElement>;\n style?: React.CSSProperties;\n}\n\nexport default forwardRef<TextAreaRef, ITextAreaProps>((props, ref) => {\n const {\n bordered,\n border,\n size: customSize,\n disabled,\n className = '',\n allowClear = false,\n value: controlledValue,\n defaultValue,\n onChange,\n onPressEnter,\n maxLength,\n showCount,\n autoSize,\n placeholder,\n rows,\n onBlur,\n onFocus,\n onKeyDown,\n onCompositionStart,\n onCompositionEnd,\n style,\n ...restTextAreaProps\n } = props;\n\n const isBordered = bordered ?? border ?? true;\n\n const contextDisabled = useContext(DisabledContext);\n const mergedDisabled = disabled ?? contextDisabled;\n\n const contentSize = useContext(SizeContext);\n const size = customSize || contentSize || 'middle';\n const isControlled = 'value' in props;\n const [innerValue, setInnerValue] = useState(defaultValue ?? '');\n const currentValue = isControlled ? controlledValue ?? '' : innerValue;\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n\n React.useImperativeHandle(ref, () => textareaRef.current!);\n\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n if (!isControlled) setInnerValue(e.target.value);\n onChange?.(e);\n };\n\n const handleClear = () => {\n if (!isControlled) setInnerValue('');\n onChange?.({\n target: { value: '' },\n } as React.ChangeEvent<HTMLTextAreaElement>);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === 'Enter') onPressEnter?.(e);\n onKeyDown?.(e);\n };\n\n const minRows = typeof autoSize === 'object' ? autoSize.minRows : undefined;\n const maxRows = typeof autoSize === 'object' ? autoSize.maxRows : undefined;\n\n return (\n <div\n className={cn(\n 'ald-input ald-input-textarea tw-relative',\n `ald-input-textarea-${getSizeType(size)}`,\n isBordered &&\n 'tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-neutral-subtle)]',\n !mergedDisabled && [\n 'has-[textarea:focus-visible]:tw-shadow-[0_0_0_2px_var(--focus-ring)]',\n 'forced-colors:has-[textarea:focus-visible]:tw-outline',\n 'forced-colors:has-[textarea:focus-visible]:tw-outline-2',\n 'forced-colors:has-[textarea:focus-visible]:tw-outline-offset-2',\n 'forced-colors:has-[textarea:focus-visible]:tw-outline-[Highlight]',\n ],\n mergedDisabled && 'ald-input-disabled tw-opacity-50',\n className,\n )}\n style={style}\n >\n <textarea\n ref={textareaRef}\n className=\"tw-w-full tw-resize-y tw-border-0 tw-bg-[var(--action-ghost-normal)] tw-px-3 tw-py-2 tw-text-[var(--content-primary)] tw-outline-none tw-text-typography-body-dense\"\n value={currentValue}\n onChange={handleChange}\n onBlur={onBlur}\n onFocus={onFocus}\n onKeyDown={handleKeyDown}\n onCompositionStart={onCompositionStart}\n onCompositionEnd={onCompositionEnd}\n disabled={mergedDisabled}\n placeholder={placeholder}\n maxLength={maxLength}\n rows={rows || (minRows ?? 3)}\n spellCheck={false}\n autoComplete=\"off\"\n {...restTextAreaProps}\n style={{\n minHeight: minRows ? `${minRows * 22}px` : undefined,\n maxHeight: maxRows ? `${maxRows * 22}px` : undefined,\n }}\n />\n {allowClear && currentValue && !mergedDisabled && (\n <span\n className=\"tw-absolute tw-right-2 tw-top-2 tw-cursor-pointer\"\n onClick={handleClear}\n >\n <CloseCircleFill size={16} color=\"var(--content-secondary)\" />\n </span>\n )}\n {showCount && (\n <div className=\"tw-px-2 tw-pb-1 tw-text-right tw-text-[var(--content-tertiary)] tw-text-typography-caption\">\n {typeof showCount === 'object'\n ? showCount.formatter({ count: currentValue.length, maxLength })\n : `${currentValue.length}${maxLength ? `/${maxLength}` : ''}`}\n </div>\n )}\n </div>\n );\n});\n"],"mappings":";;;;;;;;AAyCA,IAAA,mBAAe,YAAyC,OAAO,QAAQ;CACrE,MAAM,EACJ,UACA,QACA,MAAM,YACN,UACA,YAAY,IACZ,aAAa,OACb,OAAO,iBACP,cACA,UACA,cACA,WACA,WACA,UACA,aACA,MACA,QACA,SACA,WACA,oBACA,kBACA,OACA,GAAG,sBACD;CAEJ,MAAM,aAAa,YAAY,UAAU;CAEzC,MAAM,kBAAkB,WAAW,gBAAgB;CACnD,MAAM,iBAAiB,YAAY;CAEnC,MAAM,cAAc,WAAW,YAAY;CAC3C,MAAM,OAAO,cAAc,eAAe;CAC1C,MAAM,eAAe,WAAW;CAChC,MAAM,CAAC,YAAY,iBAAiB,SAAS,gBAAgB,GAAG;CAChE,MAAM,eAAe,eAAe,mBAAmB,KAAK;CAC5D,MAAM,cAAc,OAA4B,KAAK;AAErD,OAAM,oBAAoB,WAAW,YAAY,QAAS;CAE1D,MAAM,gBAAgB,MAA8C;AAClE,MAAI,CAAC,aAAc,eAAc,EAAE,OAAO,MAAM;AAChD,aAAW,EAAE;;CAGf,MAAM,oBAAoB;AACxB,MAAI,CAAC,aAAc,eAAc,GAAG;AACpC,aAAW,EACT,QAAQ,EAAE,OAAO,IAAI,EACtB,CAA2C;;CAG9C,MAAM,iBAAiB,MAAgD;AACrE,MAAI,EAAE,QAAQ,QAAS,gBAAe,EAAE;AACxC,cAAY,EAAE;;CAGhB,MAAM,UAAU,OAAO,aAAa,WAAW,SAAS,UAAU;CAClE,MAAM,UAAU,OAAO,aAAa,WAAW,SAAS,UAAU;AAElE,QACE,qBAAC,OAAD;EACE,WAAW,GACT,4CACA,sBAAsB,YAAY,KAAK,IACvC,cACE,sFACF,CAAC,kBAAkB;GACjB;GACA;GACA;GACA;GACA;GACD,EACD,kBAAkB,oCAClB,UACD;EACM;YAhBT;GAkBE,oBAAC,YAAD;IACE,KAAK;IACL,WAAU;IACV,OAAO;IACP,UAAU;IACF;IACC;IACT,WAAW;IACS;IACF;IAClB,UAAU;IACG;IACF;IACX,MAAM,SAAS,WAAW;IAC1B,YAAY;IACZ,cAAa;IACb,GAAI;IACJ,OAAO;KACL,WAAW,UAAU,GAAG,UAAU,GAAG,MAAM;KAC3C,WAAW,UAAU,GAAG,UAAU,GAAG,MAAM;KAC5C;IACD,CAAA;GACD,cAAc,gBAAgB,CAAC,kBAC9B,oBAAC,QAAD;IACE,WAAU;IACV,SAAS;cAET,oBAAC,MAAD;KAAiB,MAAM;KAAI,OAAM;KAA6B,CAAA;IACzD,CAAA;GAER,aACC,oBAAC,OAAD;IAAK,WAAU;cACZ,OAAO,cAAc,WAClB,UAAU,UAAU;KAAE,OAAO,aAAa;KAAQ;KAAW,CAAC,GAC9D,GAAG,aAAa,SAAS,YAAY,IAAI,cAAc;IACvD,CAAA;GAEJ;;EAER"}
@@ -84,7 +84,13 @@ function InputNumber(props) {
84
84
  const inputBox = /* @__PURE__ */ jsxs("div", {
85
85
  "data-testid": !hasAddon ? dataTestId : void 0,
86
86
  "aria-label": !hasAddon ? ariaLabel : void 0,
87
- className: cn("ald-input-number tw-inline-flex tw-w-[90px] tw-min-w-0 tw-items-center tw-overflow-hidden", bordered && "tw-border tw-border-solid tw-border-[var(--border-neutral-subtle)]", mergedDisabled ? "ald-input-number-disabled tw-cursor-not-allowed tw-bg-[var(--background-neutral-on-subtle)] tw-text-[var(--content-secondary)]" : "tw-bg-[var(--background-default)] tw-text-[var(--content-primary)] hover:tw-border-[var(--border-brand-strong)]", !hasAddon && sizeClasses, hasAddon ? "tw-h-auto tw-flex-1 tw-self-stretch tw-rounded-none" : radiusClasses, status === "error" && "tw-border-[var(--border-negative-strong)]", status === "warning" && "tw-border-[var(--border-warning-subtle)]", "focus-within:tw-border-[var(--border-brand-strong)] focus-within:tw-outline focus-within:tw-outline-1 focus-within:tw-outline-[var(--border-brand-strong)]", !hasAddon && className),
87
+ className: cn("ald-input-number tw-inline-flex tw-w-[90px] tw-min-w-0 tw-items-center tw-overflow-hidden", bordered && "tw-border tw-border-solid tw-border-[var(--border-neutral-subtle)]", mergedDisabled ? "ald-input-number-disabled tw-cursor-not-allowed tw-bg-[var(--background-neutral-on-subtle)] tw-text-[var(--content-secondary)]" : "tw-bg-[var(--background-default)] tw-text-[var(--content-primary)] hover:tw-border-[var(--border-brand-strong)]", !hasAddon && sizeClasses, hasAddon ? "tw-h-auto tw-flex-1 tw-self-stretch tw-rounded-none" : radiusClasses, status === "error" && "tw-border-[var(--border-negative-strong)]", status === "warning" && "tw-border-[var(--border-warning-subtle)]", !mergedDisabled && [
88
+ "has-[input:focus-visible]:tw-shadow-[0_0_0_2px_var(--focus-ring)]",
89
+ "forced-colors:has-[input:focus-visible]:tw-outline",
90
+ "forced-colors:has-[input:focus-visible]:tw-outline-2",
91
+ "forced-colors:has-[input:focus-visible]:tw-outline-offset-2",
92
+ "forced-colors:has-[input:focus-visible]:tw-outline-[Highlight]"
93
+ ], !hasAddon && className),
88
94
  style: !hasAddon ? style : void 0,
89
95
  children: [prefix && /* @__PURE__ */ jsx("span", {
90
96
  className: "tw-px-2 tw-text-[var(--content-secondary)]",