@aloudata/aloudata-design 3.0.22 → 3.0.23

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 (47) hide show
  1. package/dist/App/index.js +5 -2
  2. package/dist/App/index.js.map +1 -1
  3. package/dist/Button/index.d.ts +1 -1
  4. package/dist/Button/index.js +10 -10
  5. package/dist/Button/index.js.map +1 -1
  6. package/dist/Checkbox/index.js +2 -2
  7. package/dist/Checkbox/index.js.map +1 -1
  8. package/dist/Drawer/index.js +2 -8
  9. package/dist/Drawer/index.js.map +1 -1
  10. package/dist/Dropdown/index.js +8 -5
  11. package/dist/Dropdown/index.js.map +1 -1
  12. package/dist/Form/index.js +5 -5
  13. package/dist/Form/index.js.map +1 -1
  14. package/dist/Input/components/Input/index.js +2 -2
  15. package/dist/Input/components/Input/index.js.map +1 -1
  16. package/dist/Input/components/TextArea/index.js +2 -2
  17. package/dist/Input/components/TextArea/index.js.map +1 -1
  18. package/dist/Menu/index.js +9 -7
  19. package/dist/Menu/index.js.map +1 -1
  20. package/dist/Modal/index.d.ts +4 -1
  21. package/dist/Modal/index.js +63 -22
  22. package/dist/Modal/index.js.map +1 -1
  23. package/dist/Popconfirm/index.js +1 -1
  24. package/dist/Select/BaseSelect.js +1 -1
  25. package/dist/Select/BaseSelect.js.map +1 -1
  26. package/dist/Select/hooks/useOptions.js +4 -1
  27. package/dist/Select/hooks/useOptions.js.map +1 -1
  28. package/dist/Select/index.js +1 -1
  29. package/dist/Select/index.js.map +1 -1
  30. package/dist/Select/interface.d.ts +1 -0
  31. package/dist/Tour/index.js +1 -1
  32. package/dist/Typography/index.js +5 -5
  33. package/dist/Typography/index.js.map +1 -1
  34. package/dist/_utils/floatingLayer.js +1 -1
  35. package/dist/_utils/overlayCoordinator.d.ts +14 -0
  36. package/dist/_utils/overlayCoordinator.js +151 -0
  37. package/dist/_utils/overlayCoordinator.js.map +1 -0
  38. package/dist/aloudata-design.css +1 -1
  39. package/dist/index.d.ts +1 -1
  40. package/dist/index.js +3 -3
  41. package/dist/theme/contract/tokenOutputContract.js +2 -45
  42. package/dist/theme/contract/tokenOutputContract.js.map +1 -1
  43. package/dist/theme/index.d.ts +2 -2
  44. package/dist/theme/typography/index.d.ts +75 -0
  45. package/dist/theme/typography/index.js +2 -0
  46. package/dist/theme/typography.d.ts +2 -0
  47. package/package.json +1 -1
package/dist/App/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { cn } from "../lib/utils.js";
2
+ import { useTopModalContentZIndex } from "../_utils/overlayCoordinator.js";
2
3
  import "react";
3
4
  import { jsx, jsxs } from "react/jsx-runtime";
4
5
  import { createPortal } from "react-dom";
@@ -10,6 +11,8 @@ var OverlayPortal = ({ children }) => {
10
11
  return createPortal(children, document.body);
11
12
  };
12
13
  var AldApp = ({ children, className, style, overlayZIndex = DEFAULT_OVERLAY_Z_INDEX, ...restProps }) => {
14
+ const topModalContentZIndex = useTopModalContentZIndex();
15
+ const effectiveOverlayZIndex = topModalContentZIndex === void 0 ? overlayZIndex : Math.max(overlayZIndex, topModalContentZIndex + 1e3);
13
16
  return /* @__PURE__ */ jsxs("div", {
14
17
  className: cn("ald-app", className),
15
18
  style,
@@ -17,10 +20,10 @@ var AldApp = ({ children, className, style, overlayZIndex = DEFAULT_OVERLAY_Z_IN
17
20
  children: [/* @__PURE__ */ jsxs(OverlayPortal, { children: [/* @__PURE__ */ jsx(ToastContainer, {
18
21
  containerId: "message-container",
19
22
  limit: 1,
20
- style: { zIndex: overlayZIndex }
23
+ style: { zIndex: effectiveOverlayZIndex }
21
24
  }), /* @__PURE__ */ jsx(ToastContainer, {
22
25
  containerId: "notification-container",
23
- style: { zIndex: overlayZIndex }
26
+ style: { zIndex: effectiveOverlayZIndex }
24
27
  })] }), children]
25
28
  });
26
29
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/App/index.tsx"],"sourcesContent":["import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { ToastContainer } from 'react-toastify';\nimport { cn } from '../lib/utils';\n\ninterface AppProps {\n children?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n /** z-index used by the global message and notification containers. */\n overlayZIndex?: number;\n}\n\nexport const DEFAULT_OVERLAY_Z_INDEX = 11000;\n\nconst OverlayPortal: React.FC<{ children: React.ReactNode }> = ({\n children,\n}) => {\n if (typeof document === 'undefined') return null;\n return createPortal(children, document.body);\n};\n\nconst AldApp: React.FC<AppProps> = ({\n children,\n className,\n style,\n overlayZIndex = DEFAULT_OVERLAY_Z_INDEX,\n ...restProps\n}) => {\n return (\n <div className={cn('ald-app', className)} style={style} {...restProps}>\n <OverlayPortal>\n <ToastContainer\n containerId={'message-container'}\n limit={1}\n style={{ zIndex: overlayZIndex }}\n />\n <ToastContainer\n containerId={'notification-container'}\n style={{ zIndex: overlayZIndex }}\n />\n </OverlayPortal>\n {children}\n </div>\n );\n};\n\nexport default AldApp;\n"],"mappings":";;;;;;AAaA,IAAa,0BAA0B;AAEvC,IAAM,iBAA0D,EAC9D,eACI;AACJ,KAAI,OAAO,aAAa,YAAa,QAAO;AAC5C,QAAO,aAAa,UAAU,SAAS,KAAK;;AAG9C,IAAM,UAA8B,EAClC,UACA,WACA,OACA,gBAAgB,yBAChB,GAAG,gBACC;AACJ,QACE,qBAAC,OAAD;EAAK,WAAW,GAAG,WAAW,UAAU;EAAS;EAAO,GAAI;YAA5D,CACE,qBAAC,eAAD,EAAA,UAAA,CACE,oBAAC,gBAAD;GACE,aAAa;GACb,OAAO;GACP,OAAO,EAAE,QAAQ,eAAe;GAChC,CAAA,EACF,oBAAC,gBAAD;GACE,aAAa;GACb,OAAO,EAAE,QAAQ,eAAe;GAChC,CAAA,CACY,EAAA,CAAA,EACf,SACG"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/App/index.tsx"],"sourcesContent":["import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { ToastContainer } from 'react-toastify';\nimport { useTopModalContentZIndex } from '../_utils/overlayCoordinator';\nimport { cn } from '../lib/utils';\n\ninterface AppProps {\n children?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n /** z-index used by the global message and notification containers. */\n overlayZIndex?: number;\n}\n\nexport const DEFAULT_OVERLAY_Z_INDEX = 11000;\n\nconst OverlayPortal: React.FC<{ children: React.ReactNode }> = ({\n children,\n}) => {\n if (typeof document === 'undefined') return null;\n return createPortal(children, document.body);\n};\n\nconst AldApp: React.FC<AppProps> = ({\n children,\n className,\n style,\n overlayZIndex = DEFAULT_OVERLAY_Z_INDEX,\n ...restProps\n}) => {\n const topModalContentZIndex = useTopModalContentZIndex();\n const effectiveOverlayZIndex =\n topModalContentZIndex === undefined\n ? overlayZIndex\n : Math.max(overlayZIndex, topModalContentZIndex + 1000);\n\n return (\n <div className={cn('ald-app', className)} style={style} {...restProps}>\n <OverlayPortal>\n <ToastContainer\n containerId={'message-container'}\n limit={1}\n style={{ zIndex: effectiveOverlayZIndex }}\n />\n <ToastContainer\n containerId={'notification-container'}\n style={{ zIndex: effectiveOverlayZIndex }}\n />\n </OverlayPortal>\n {children}\n </div>\n );\n};\n\nexport default AldApp;\n"],"mappings":";;;;;;;AAcA,IAAa,0BAA0B;AAEvC,IAAM,iBAA0D,EAC9D,eACI;AACJ,KAAI,OAAO,aAAa,YAAa,QAAO;AAC5C,QAAO,aAAa,UAAU,SAAS,KAAK;;AAG9C,IAAM,UAA8B,EAClC,UACA,WACA,OACA,gBAAgB,yBAChB,GAAG,gBACC;CACJ,MAAM,wBAAwB,0BAA0B;CACxD,MAAM,yBACJ,0BAA0B,SACtB,gBACA,KAAK,IAAI,eAAe,wBAAwB,IAAK;AAE3D,QACE,qBAAC,OAAD;EAAK,WAAW,GAAG,WAAW,UAAU;EAAS;EAAO,GAAI;YAA5D,CACE,qBAAC,eAAD,EAAA,UAAA,CACE,oBAAC,gBAAD;GACE,aAAa;GACb,OAAO;GACP,OAAO,EAAE,QAAQ,wBAAwB;GACzC,CAAA,EACF,oBAAC,gBAAD;GACE,aAAa;GACb,OAAO,EAAE,QAAQ,wBAAwB;GACzC,CAAA,CACY,EAAA,CAAA,EACf,SACG"}
@@ -36,6 +36,6 @@ export declare function getButtonSizeClass(s: Size): string;
36
36
  export declare function getShape(s: 'circle' | 'default'): 'circle' | 'default';
37
37
  export declare const setIcon: (iconNode: React.ReactElement, loading: boolean | {
38
38
  delay?: number;
39
- }) => import("react/jsx-runtime").JSX.Element;
39
+ }, size?: string | number) => import("react/jsx-runtime").JSX.Element;
40
40
  declare const _default: React.ForwardRefExoticComponent<IButtonProps & React.RefAttributes<HTMLElement>>;
41
41
  export default _default;
@@ -9,10 +9,10 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
9
  import { cva } from "class-variance-authority";
10
10
  //#region src/Button/index.tsx
11
11
  var btnPrefix = "ald-btn";
12
- var setIcon = (iconNode, loading) => {
12
+ var setIcon = (iconNode, loading, size = "1em") => {
13
13
  if (loading) return /* @__PURE__ */ jsx(Memo$1, {
14
14
  className: "ald-loading-spin tw-shrink-0 tw-animate-spin",
15
- size: "1em",
15
+ size,
16
16
  color: "currentColor"
17
17
  });
18
18
  if (iconNode) {
@@ -21,14 +21,14 @@ var setIcon = (iconNode, loading) => {
21
21
  fill: "currentColor",
22
22
  ...iconNode.props
23
23
  };
24
- p.size = "1em";
24
+ p.size = size;
25
25
  return React.cloneElement(iconNode, p);
26
26
  }
27
27
  return /* @__PURE__ */ jsx(Fragment, {});
28
28
  };
29
29
  var buttonVariants = cva([
30
30
  btnPrefix,
31
- "tw-inline-flex tw-cursor-pointer tw-appearance-none tw-items-center tw-justify-center tw-font-medium tw-no-underline tw-transition-colors [&_.i-icon]:tw-inline-flex [&_.i-icon]:tw-items-center",
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
32
  "tw-border tw-border-solid",
33
33
  "focus-visible:tw-outline-none"
34
34
  ], {
@@ -74,17 +74,17 @@ var buttonVariants = cva([
74
74
  size: {
75
75
  small: [
76
76
  `${btnPrefix}-small`,
77
- "tw-h-7 tw-min-w-7 tw-gap-1 tw-rounded-r-75 tw-text-xs tw-leading-4",
77
+ "tw-h-7 tw-min-w-7 tw-gap-1 tw-rounded-r-75",
78
78
  "tw-px-[var(--alias-padding-150-minus-1)] tw-py-[var(--alias-padding-75-minus-1)]"
79
79
  ],
80
80
  middle: [
81
81
  `${btnPrefix}-middle`,
82
- "tw-h-8 tw-min-w-8 tw-gap-1 tw-rounded-r-75 tw-text-sm tw-leading-5",
82
+ "tw-h-8 tw-min-w-8 tw-gap-1 tw-rounded-r-75",
83
83
  "tw-px-[var(--alias-padding-150-minus-1)] tw-py-[var(--alias-padding-75-minus-1)]"
84
84
  ],
85
85
  large: [
86
86
  `${btnPrefix}-large`,
87
- "tw-h-10 tw-min-w-10 tw-gap-1 tw-rounded-r-75 tw-text-sm tw-leading-6",
87
+ "tw-h-10 tw-min-w-10 tw-gap-1 tw-rounded-r-75",
88
88
  "tw-px-[var(--alias-padding-150-minus-1)] tw-py-[var(--alias-padding-75-minus-1)]"
89
89
  ]
90
90
  },
@@ -134,7 +134,7 @@ function Button(props, ref) {
134
134
  setInnerLoading(!!loading);
135
135
  }, [loading]);
136
136
  const isDisabled = innerLoading || mergedDisabled;
137
- const iconNode = setIcon(icon, innerLoading);
137
+ const iconNode = setIcon(icon, innerLoading, size === "small" ? 12 : 14);
138
138
  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
139
  const isIconOnly = !!icon && !children && !showArrow;
140
140
  const classes = cn(buttonVariants({
@@ -143,8 +143,8 @@ function Button(props, ref) {
143
143
  disabled: !!isDisabled,
144
144
  block: !!block,
145
145
  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);
147
- const contentClasses = cn("tw-inline-flex tw-min-w-0 tw-items-center tw-gap-1 tw-truncate", ghost && type === "inverse" && size === "middle" && "tw-flex-[1_0_0] tw-text-sm tw-font-medium tw-leading-5 tw-text-[var(--action-inverted-normal)]");
146
+ }), Boolean(children) && "tw-text-typography-label", 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);
147
+ const contentClasses = cn("tw-inline-flex tw-min-w-0 tw-items-center tw-gap-1 tw-truncate", ghost && type === "inverse" && size === "middle" && "tw-flex-[1_0_0] tw-text-[var(--action-inverted-normal)]");
148
148
  const buttonContent = /* @__PURE__ */ jsxs(Fragment, { children: [
149
149
  iconNode,
150
150
  children && /* @__PURE__ */ jsx("span", {
@@ -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) => {\n if (loading) {\n return (\n <LoadingLine\n className=\"ald-loading-spin tw-shrink-0 tw-animate-spin\"\n size={'1em'}\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 = '1em';\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-font-medium 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 small: [\n `${btnPrefix}-small`,\n 'tw-h-7 tw-min-w-7 tw-gap-1 tw-rounded-r-75 tw-text-xs tw-leading-4',\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 tw-text-sm tw-leading-5',\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 tw-text-sm tw-leading-6',\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 iconNode = setIcon(icon as React.ReactElement, innerLoading);\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 'tw-inline-flex tw-min-w-0 tw-items-center tw-gap-1 tw-truncate',\n ghost &&\n type === 'inverse' &&\n size === 'middle' &&\n 'tw-flex-[1_0_0] tw-text-sm tw-font-medium tw-leading-5 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,YACG;AACH,KAAI,QACF,QACE,oBAAC,QAAD;EACE,WAAU;EACV,MAAM;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;GACJ,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;CACnC,MAAM,WAAW,QAAQ,MAA4B,aAAa;CAGlE,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,GACrB,kEACA,SACE,SAAS,aACT,SAAS,YACT,iGACH;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 '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 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 Boolean(children) && 'tw-text-typography-label',\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 'tw-inline-flex tw-min-w-0 tw-items-center tw-gap-1 tw-truncate',\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;GACJ,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,QAAQ,SAAS,IAAI,4BACrB,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,GACrB,kEACA,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"}
@@ -41,7 +41,7 @@ function Checkbox(props) {
41
41
  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),
42
42
  style,
43
43
  children: [/* @__PURE__ */ jsxs("span", {
44
- 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-all tw-duration-200", checked && "ald-checkbox-checked tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)]", mergedDisabled && "tw-opacity-50", !checked && !indeterminate && !alert && "tw-border-[var(--border-neutral-subtle)] tw-bg-[var(--background-default)]", !checked && !indeterminate && alert && "tw-border-[var(--border-negative-strong)] tw-bg-[var(--background-default)]", indeterminate && !checked && "ald-checkbox-indeterminate tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)]"),
44
+ 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-all 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)]"),
45
45
  children: [/* @__PURE__ */ jsx("input", {
46
46
  ref: inputRef,
47
47
  type: "checkbox",
@@ -60,7 +60,7 @@ function Checkbox(props) {
60
60
  }
61
61
  })]
62
62
  }), children && /* @__PURE__ */ jsx("span", {
63
- className: cn("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", size === "small" ? "tw-text-xs" : "tw-text-sm", bold && "tw-font-medium", mergedDisabled && "tw-cursor-default"),
63
+ className: cn("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", size === "small" ? "tw-text-xs" : "tw-text-sm", bold && "tw-font-medium", mergedDisabled && "tw-cursor-default tw-text-[var(--content-disabled)]"),
64
64
  children
65
65
  })]
66
66
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Checkbox/index.tsx"],"sourcesContent":["import React, { useContext, useEffect, useRef, useState } 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\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 mergedDisabled = customDisabled ?? disabled;\n\n const isControlled = 'checked' in props;\n const [innerChecked, setInnerChecked] = useState(defaultChecked ?? false);\n const checked = isControlled ? controlledChecked : 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 (!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-all tw-duration-200',\n checked &&\n 'ald-checkbox-checked tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)]',\n mergedDisabled && 'tw-opacity-50',\n !checked &&\n !indeterminate &&\n !alert &&\n 'tw-border-[var(--border-neutral-subtle)] tw-bg-[var(--background-default)]',\n !checked &&\n !indeterminate &&\n alert &&\n 'tw-border-[var(--border-negative-strong)] tw-bg-[var(--background-default)]',\n indeterminate &&\n !checked &&\n 'ald-checkbox-indeterminate tw-border-[var(--action-ghost-normal)] tw-bg-[var(--action-primary-normal)]',\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={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 size === 'small' ? 'tw-text-xs' : 'tw-text-sm',\n bold && 'tw-font-medium',\n mergedDisabled && 'tw-cursor-default',\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={mergedDisabled || optObj.disabled}\n checked={value.includes(optObj.value)}\n size={size}\n name={name}\n onChange={(e) => handleGroupChange(optObj.value, e.target.checked)}\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 {renderOptions()}\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, { useContext, useEffect, useRef, useState } 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\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 mergedDisabled = customDisabled ?? disabled;\n\n const isControlled = 'checked' in props;\n const [innerChecked, setInnerChecked] = useState(defaultChecked ?? false);\n const checked = isControlled ? controlledChecked : 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 (!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-all 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={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 size === 'small' ? 'tw-text-xs' : 'tw-text-sm',\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={mergedDisabled || optObj.disabled}\n checked={value.includes(optObj.value)}\n size={size}\n name={name}\n onChange={(e) => handleGroupChange(optObj.value, e.target.checked)}\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 {renderOptions()}\n </div>\n );\n}\n\nCheckbox.Group = CheckboxGroup;\n\nexport default Checkbox;\n"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { cn } from "../lib/utils.js";
2
2
  import Memo from "../Icon/components/CloseLightLine.js";
3
3
  import { FloatingLayerProvider, useFloatingLayer } from "../_utils/floatingLayer.js";
4
+ import { useBodyScrollLock } from "../_utils/overlayCoordinator.js";
4
5
  import { useEffect, useRef } from "react";
5
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
7
  import * as DialogPrimitive from "@radix-ui/react-dialog";
@@ -25,14 +26,7 @@ var slideAnimationStyles = {
25
26
  function Drawer(props) {
26
27
  const { open = false, onClose, title, description, placement = "right", width, height, size = "default", closable = true, mask = true, maskClosable = true, className, rootClassName, style, contentWrapperStyle, bodyStyle, headerStyle, footer, footerStyle, extra, children, zIndex = 1e3 } = props;
27
28
  const contentRef = useRef(null);
28
- useEffect(() => {
29
- if (!open) return;
30
- const prev = document.body.style.overflow;
31
- document.body.style.overflow = "hidden";
32
- return () => {
33
- document.body.style.overflow = prev;
34
- };
35
- }, [open]);
29
+ useBodyScrollLock(open);
36
30
  useEffect(() => {
37
31
  if (!open || !contentRef.current) return;
38
32
  return hideOthers(contentRef.current);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Drawer/index.tsx"],"sourcesContent":["import * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { hideOthers } from 'aria-hidden';\nimport React, { useEffect, useRef } from 'react';\nimport { CloseLightLine } from '../Icon';\nimport {\n FloatingLayerProvider,\n useFloatingLayer,\n} from '../_utils/floatingLayer';\nimport { cn } from '../lib/utils';\n\nexport interface DrawerProps {\n open?: boolean;\n onClose?: (e?: React.MouseEvent | React.KeyboardEvent) => void;\n title?: React.ReactNode;\n description?: React.ReactNode;\n placement?: 'top' | 'right' | 'bottom' | 'left';\n width?: number | string;\n height?: number | string;\n size?: 'default' | 'large';\n closable?: boolean;\n mask?: boolean;\n maskClosable?: boolean;\n destroyOnClose?: boolean;\n className?: string;\n rootClassName?: string;\n style?: React.CSSProperties;\n contentWrapperStyle?: React.CSSProperties;\n bodyStyle?: React.CSSProperties;\n headerStyle?: React.CSSProperties;\n maskStyle?: React.CSSProperties;\n footer?: React.ReactNode;\n footerStyle?: React.CSSProperties;\n extra?: React.ReactNode;\n children?: React.ReactNode;\n zIndex?: number;\n keyboard?: boolean;\n getContainer?: () => HTMLElement;\n}\n\nconst sizePresets: Record<string, number> = {\n default: 378,\n large: 736,\n};\n\nconst placementStyles: Record<string, string> = {\n right: 'tw-inset-y-0 tw-right-0 tw-h-full',\n left: 'tw-inset-y-0 tw-left-0 tw-h-full',\n top: 'tw-inset-x-0 tw-top-0 tw-w-full',\n bottom: 'tw-inset-x-0 tw-bottom-0 tw-w-full',\n};\n\nconst slideAnimationStyles: Record<string, string> = {\n right:\n 'data-[state=open]:tw-animate-drawer-in-right data-[state=closed]:tw-animate-drawer-out-right',\n left: 'data-[state=open]:tw-animate-drawer-in-left data-[state=closed]:tw-animate-drawer-out-left',\n top: 'data-[state=open]:tw-animate-drawer-in-top data-[state=closed]:tw-animate-drawer-out-top',\n bottom:\n 'data-[state=open]:tw-animate-drawer-in-bottom data-[state=closed]:tw-animate-drawer-out-bottom',\n};\n\nfunction Drawer(props: DrawerProps) {\n const {\n open = false,\n onClose,\n title,\n description,\n placement = 'right',\n width,\n height,\n size = 'default',\n closable = true,\n mask = true,\n maskClosable = true,\n className,\n rootClassName,\n style,\n contentWrapperStyle,\n bodyStyle,\n headerStyle,\n footer,\n footerStyle,\n extra,\n children,\n zIndex = 1000,\n } = props;\n\n const contentRef = useRef<HTMLDivElement>(null);\n\n // ---- modal={false} 补偿:锁定背景滚动 ----\n useEffect(() => {\n if (!open) return;\n const prev = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n return () => {\n document.body.style.overflow = prev;\n };\n }, [open]);\n\n // ---- modal={false} 补偿:aria-hidden(屏幕阅读器只感知抽屉) ----\n useEffect(() => {\n if (!open || !contentRef.current) return;\n return hideOthers(contentRef.current);\n }, [open]);\n\n // ---- modal={false} 补偿:Tab 焦点循环(不使用 MutationObserver,避免 FocusScope 劫持焦点)----\n useEffect(() => {\n if (!open || !contentRef.current) return;\n const container = contentRef.current;\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Tab') return;\n const focusable = container.querySelectorAll<HTMLElement>(\n 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"]):not([disabled])',\n );\n if (focusable.length === 0) return;\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (e.shiftKey) {\n if (\n document.activeElement === first ||\n !container.contains(document.activeElement)\n ) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (\n document.activeElement === last ||\n !container.contains(document.activeElement)\n ) {\n e.preventDefault();\n first.focus();\n }\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [open]);\n\n const isHorizontal = placement === 'left' || placement === 'right';\n const preset = sizePresets[size] || sizePresets.default;\n const effectiveWidth = width ?? preset;\n const effectiveHeight = height ?? preset;\n const sizeStyle = isHorizontal\n ? { width: effectiveWidth, maxWidth: '100vw' }\n : { height: effectiveHeight, maxHeight: '100vh' };\n const { maskZIndex, contentZIndex, nextLevel } = useFloatingLayer(zIndex);\n\n // modal={false}:禁用 Radix FocusScope 的 MutationObserver,\n // 避免表单校验触发 DOM 变动时劫持焦点。手动补偿滚动锁定、aria-hidden、Tab 循环。\n return (\n <DialogPrimitive.Root\n open={open}\n modal={false}\n onOpenChange={(val) => {\n if (!val) onClose?.();\n }}\n >\n <DialogPrimitive.Portal>\n {/* modal={false} 时 DialogPrimitive.Overlay 不渲染,用普通 div 替代 */}\n {mask && (\n <div\n data-state={open ? 'open' : 'closed'}\n className=\"ald-drawer-mask tw-fixed tw-inset-0 tw-bg-[var(--background-inverted)] tw-opacity-45 data-[state=closed]:tw-animate-mask-out data-[state=open]:tw-animate-mask-in\"\n style={{ zIndex: maskZIndex }}\n onClick={maskClosable ? () => onClose?.() : undefined}\n />\n )}\n <DialogPrimitive.Content\n ref={contentRef}\n className={cn(\n 'ald-drawer tw-fixed tw-flex tw-flex-col tw-bg-[var(--background-default)] tw-shadow-xl',\n placementStyles[placement],\n slideAnimationStyles[placement],\n rootClassName,\n className,\n )}\n style={{\n zIndex: contentZIndex,\n ...sizeStyle,\n ...contentWrapperStyle,\n ...style,\n }}\n onEscapeKeyDown={() => onClose?.()}\n onInteractOutside={(event) => {\n if (!maskClosable) {\n event.preventDefault();\n }\n }}\n >\n <FloatingLayerProvider value={nextLevel}>\n {(title || description || closable || extra) && (\n <>\n {/* antd 兼容:保留 ant-drawer-header / ant-drawer-header-title class,消费方 CSS 可能依赖这些选择器 */}\n <div\n className=\"ald-drawer-header ant-drawer-header tw-flex tw-flex-col tw-items-start tw-gap-[var(--component-gap-lg)] tw-self-stretch tw-bg-[var(--background-default)] tw-px-6 tw-pb-0 tw-pt-4\"\n style={headerStyle}\n >\n <div className=\"tw-flex tw-w-full tw-flex-col tw-gap-[6px]\">\n <div className=\"tw-flex tw-w-full tw-items-start tw-justify-between tw-gap-[var(--component-gap-sm)]\">\n <DialogPrimitive.Title className='ald-drawer-title ant-drawer-header-title tw-[font-feature-settings:\"liga\"_off,\"clig\"_off] tw-m-0 tw-flex-[1_0_0] tw-text-lg tw-font-semibold tw-leading-7 tw-text-[var(--content-primary)]'>\n {title}\n </DialogPrimitive.Title>\n {extra || closable ? (\n <div className=\"ald-drawer-actions tw-flex tw-items-center tw-gap-[var(--component-gap-sm)]\">\n {extra}\n {closable && (\n <DialogPrimitive.Close asChild>\n <button\n type=\"button\"\n className=\"ald-drawer-close tw-flex tw-size-8 tw-cursor-pointer tw-items-center tw-justify-center tw-rounded-r-50 tw-border-0 tw-bg-[var(--action-ghost-normal)] hover:tw-bg-[var(--action-ghost-hover)]\"\n onClick={() => onClose?.()}\n >\n <CloseLightLine\n size={20}\n color=\"var(--content-secondary)\"\n />\n </button>\n </DialogPrimitive.Close>\n )}\n </div>\n ) : null}\n </div>\n {description ? (\n <div className='ald-drawer-description tw-[font-feature-settings:\"liga\"_off,\"clig\"_off] tw-self-stretch tw-text-sm tw-font-normal tw-leading-5 tw-text-[var(--content-secondary)]'>\n {description}\n </div>\n ) : null}\n </div>\n </div>\n </>\n )}\n {/* antd 兼容:保留 ant-drawer-body class */}\n <div\n className=\"ald-drawer-body ant-drawer-body tw-min-w-0 tw-flex-[1_0_0] tw-self-stretch tw-overflow-auto tw-p-[var(--component-padding-2xl)]\"\n style={bodyStyle}\n >\n {children}\n </div>\n {footer && (\n <>\n <div className=\"ald-drawer-footer-divider tw-h-px tw-bg-[var(--border-default)]\" />\n {/* antd 兼容:antd .ant-drawer-footer 使用 text-align:right 让 inline 按钮右对齐,\n 此处加 tw-text-right 保持消费方传入 width:100% 子容器时 inline 元素仍右对齐。 */}\n <div\n className=\"ald-drawer-footer ant-drawer-footer tw-flex tw-items-center tw-justify-end tw-gap-[var(--component-gap-lg)] tw-self-stretch tw-px-[var(--component-padding-2xl)] tw-py-[var(--component-padding-lg)]\"\n style={footerStyle}\n >\n {footer}\n </div>\n </>\n )}\n </FloatingLayerProvider>\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n\nexport default Drawer;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Drawer/index.tsx"],"sourcesContent":["import * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { hideOthers } from 'aria-hidden';\nimport React, { useEffect, useRef } from 'react';\nimport { CloseLightLine } from '../Icon';\nimport {\n FloatingLayerProvider,\n useFloatingLayer,\n} from '../_utils/floatingLayer';\nimport { useBodyScrollLock } from '../_utils/overlayCoordinator';\nimport { cn } from '../lib/utils';\n\nexport interface DrawerProps {\n open?: boolean;\n onClose?: (e?: React.MouseEvent | React.KeyboardEvent) => void;\n title?: React.ReactNode;\n description?: React.ReactNode;\n placement?: 'top' | 'right' | 'bottom' | 'left';\n width?: number | string;\n height?: number | string;\n size?: 'default' | 'large';\n closable?: boolean;\n mask?: boolean;\n maskClosable?: boolean;\n destroyOnClose?: boolean;\n className?: string;\n rootClassName?: string;\n style?: React.CSSProperties;\n contentWrapperStyle?: React.CSSProperties;\n bodyStyle?: React.CSSProperties;\n headerStyle?: React.CSSProperties;\n maskStyle?: React.CSSProperties;\n footer?: React.ReactNode;\n footerStyle?: React.CSSProperties;\n extra?: React.ReactNode;\n children?: React.ReactNode;\n zIndex?: number;\n keyboard?: boolean;\n getContainer?: () => HTMLElement;\n}\n\nconst sizePresets: Record<string, number> = {\n default: 378,\n large: 736,\n};\n\nconst placementStyles: Record<string, string> = {\n right: 'tw-inset-y-0 tw-right-0 tw-h-full',\n left: 'tw-inset-y-0 tw-left-0 tw-h-full',\n top: 'tw-inset-x-0 tw-top-0 tw-w-full',\n bottom: 'tw-inset-x-0 tw-bottom-0 tw-w-full',\n};\n\nconst slideAnimationStyles: Record<string, string> = {\n right:\n 'data-[state=open]:tw-animate-drawer-in-right data-[state=closed]:tw-animate-drawer-out-right',\n left: 'data-[state=open]:tw-animate-drawer-in-left data-[state=closed]:tw-animate-drawer-out-left',\n top: 'data-[state=open]:tw-animate-drawer-in-top data-[state=closed]:tw-animate-drawer-out-top',\n bottom:\n 'data-[state=open]:tw-animate-drawer-in-bottom data-[state=closed]:tw-animate-drawer-out-bottom',\n};\n\nfunction Drawer(props: DrawerProps) {\n const {\n open = false,\n onClose,\n title,\n description,\n placement = 'right',\n width,\n height,\n size = 'default',\n closable = true,\n mask = true,\n maskClosable = true,\n className,\n rootClassName,\n style,\n contentWrapperStyle,\n bodyStyle,\n headerStyle,\n footer,\n footerStyle,\n extra,\n children,\n zIndex = 1000,\n } = props;\n\n const contentRef = useRef<HTMLDivElement>(null);\n useBodyScrollLock(open);\n\n // ---- modal={false} 补偿:aria-hidden(屏幕阅读器只感知抽屉) ----\n useEffect(() => {\n if (!open || !contentRef.current) return;\n return hideOthers(contentRef.current);\n }, [open]);\n\n // ---- modal={false} 补偿:Tab 焦点循环(不使用 MutationObserver,避免 FocusScope 劫持焦点)----\n useEffect(() => {\n if (!open || !contentRef.current) return;\n const container = contentRef.current;\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Tab') return;\n const focusable = container.querySelectorAll<HTMLElement>(\n 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"]):not([disabled])',\n );\n if (focusable.length === 0) return;\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (e.shiftKey) {\n if (\n document.activeElement === first ||\n !container.contains(document.activeElement)\n ) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (\n document.activeElement === last ||\n !container.contains(document.activeElement)\n ) {\n e.preventDefault();\n first.focus();\n }\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [open]);\n\n const isHorizontal = placement === 'left' || placement === 'right';\n const preset = sizePresets[size] || sizePresets.default;\n const effectiveWidth = width ?? preset;\n const effectiveHeight = height ?? preset;\n const sizeStyle = isHorizontal\n ? { width: effectiveWidth, maxWidth: '100vw' }\n : { height: effectiveHeight, maxHeight: '100vh' };\n const { maskZIndex, contentZIndex, nextLevel } = useFloatingLayer(zIndex);\n\n // modal={false}:禁用 Radix FocusScope 的 MutationObserver,\n // 避免表单校验触发 DOM 变动时劫持焦点。手动补偿滚动锁定、aria-hidden、Tab 循环。\n return (\n <DialogPrimitive.Root\n open={open}\n modal={false}\n onOpenChange={(val) => {\n if (!val) onClose?.();\n }}\n >\n <DialogPrimitive.Portal>\n {/* modal={false} 时 DialogPrimitive.Overlay 不渲染,用普通 div 替代 */}\n {mask && (\n <div\n data-state={open ? 'open' : 'closed'}\n className=\"ald-drawer-mask tw-fixed tw-inset-0 tw-bg-[var(--background-inverted)] tw-opacity-45 data-[state=closed]:tw-animate-mask-out data-[state=open]:tw-animate-mask-in\"\n style={{ zIndex: maskZIndex }}\n onClick={maskClosable ? () => onClose?.() : undefined}\n />\n )}\n <DialogPrimitive.Content\n ref={contentRef}\n className={cn(\n 'ald-drawer tw-fixed tw-flex tw-flex-col tw-bg-[var(--background-default)] tw-shadow-xl',\n placementStyles[placement],\n slideAnimationStyles[placement],\n rootClassName,\n className,\n )}\n style={{\n zIndex: contentZIndex,\n ...sizeStyle,\n ...contentWrapperStyle,\n ...style,\n }}\n onEscapeKeyDown={() => onClose?.()}\n onInteractOutside={(event) => {\n if (!maskClosable) {\n event.preventDefault();\n }\n }}\n >\n <FloatingLayerProvider value={nextLevel}>\n {(title || description || closable || extra) && (\n <>\n {/* antd 兼容:保留 ant-drawer-header / ant-drawer-header-title class,消费方 CSS 可能依赖这些选择器 */}\n <div\n className=\"ald-drawer-header ant-drawer-header tw-flex tw-flex-col tw-items-start tw-gap-[var(--component-gap-lg)] tw-self-stretch tw-bg-[var(--background-default)] tw-px-6 tw-pb-0 tw-pt-4\"\n style={headerStyle}\n >\n <div className=\"tw-flex tw-w-full tw-flex-col tw-gap-[6px]\">\n <div className=\"tw-flex tw-w-full tw-items-start tw-justify-between tw-gap-[var(--component-gap-sm)]\">\n <DialogPrimitive.Title className='ald-drawer-title ant-drawer-header-title tw-[font-feature-settings:\"liga\"_off,\"clig\"_off] tw-m-0 tw-flex-[1_0_0] tw-text-lg tw-font-semibold tw-leading-7 tw-text-[var(--content-primary)]'>\n {title}\n </DialogPrimitive.Title>\n {extra || closable ? (\n <div className=\"ald-drawer-actions tw-flex tw-items-center tw-gap-[var(--component-gap-sm)]\">\n {extra}\n {closable && (\n <DialogPrimitive.Close asChild>\n <button\n type=\"button\"\n className=\"ald-drawer-close tw-flex tw-size-8 tw-cursor-pointer tw-items-center tw-justify-center tw-rounded-r-50 tw-border-0 tw-bg-[var(--action-ghost-normal)] hover:tw-bg-[var(--action-ghost-hover)]\"\n onClick={() => onClose?.()}\n >\n <CloseLightLine\n size={20}\n color=\"var(--content-secondary)\"\n />\n </button>\n </DialogPrimitive.Close>\n )}\n </div>\n ) : null}\n </div>\n {description ? (\n <div className='ald-drawer-description tw-[font-feature-settings:\"liga\"_off,\"clig\"_off] tw-self-stretch tw-text-sm tw-font-normal tw-leading-5 tw-text-[var(--content-secondary)]'>\n {description}\n </div>\n ) : null}\n </div>\n </div>\n </>\n )}\n {/* antd 兼容:保留 ant-drawer-body class */}\n <div\n className=\"ald-drawer-body ant-drawer-body tw-min-w-0 tw-flex-[1_0_0] tw-self-stretch tw-overflow-auto tw-p-[var(--component-padding-2xl)]\"\n style={bodyStyle}\n >\n {children}\n </div>\n {footer && (\n <>\n <div className=\"ald-drawer-footer-divider tw-h-px tw-bg-[var(--border-default)]\" />\n {/* antd 兼容:antd .ant-drawer-footer 使用 text-align:right 让 inline 按钮右对齐,\n 此处加 tw-text-right 保持消费方传入 width:100% 子容器时 inline 元素仍右对齐。 */}\n <div\n className=\"ald-drawer-footer ant-drawer-footer tw-flex tw-items-center tw-justify-end tw-gap-[var(--component-gap-lg)] tw-self-stretch tw-px-[var(--component-padding-2xl)] tw-py-[var(--component-padding-lg)]\"\n style={footerStyle}\n >\n {footer}\n </div>\n </>\n )}\n </FloatingLayerProvider>\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n\nexport default Drawer;\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { cn } from "../lib/utils.js";
2
+ import { useFloatingPopupZIndex } from "../_utils/floatingLayer.js";
2
3
  /* empty css */
3
4
  import Menu from "../Menu/index.js";
4
- import { useFloatingPopupZIndex } from "../_utils/floatingLayer.js";
5
5
  import { ensureWeakRefFallback } from "../_utils/weakRefFallback.js";
6
6
  import { cloneElement, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
7
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -98,9 +98,11 @@ function Dropdown(props) {
98
98
  };
99
99
  }, []);
100
100
  const onChangeOpen = useCallback((newOpen) => {
101
- if (newOpen) stopCloseAnimation();
102
- else startCloseAnimation();
103
- if (!isOpenControlled) setIsOpen(newOpen);
101
+ if (!isOpenControlled) {
102
+ if (newOpen) stopCloseAnimation();
103
+ else startCloseAnimation();
104
+ setIsOpen(newOpen);
105
+ }
104
106
  onOpenChangeFn(newOpen);
105
107
  }, [
106
108
  isOpenControlled,
@@ -235,7 +237,7 @@ function Dropdown(props) {
235
237
  } : void 0,
236
238
  ...menu?.menuStyle
237
239
  },
238
- onBeforeLeafItemClick: markRootClosing,
240
+ onBeforeLeafItemClick: isOpenControlled ? void 0 : markRootClosing,
239
241
  rootClosing: isAnimatingOut,
240
242
  onClick: onMenuItemClick,
241
243
  externalOverflow: allowOverlap
@@ -243,6 +245,7 @@ function Dropdown(props) {
243
245
  }, [
244
246
  allowOverlap,
245
247
  isAnimatingOut,
248
+ isOpenControlled,
246
249
  markRootClosing,
247
250
  menu,
248
251
  onMenuItemClick,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Dropdown/index.tsx"],"sourcesContent":["import './dropdown.css';\nimport {\n FloatingFocusManager,\n FloatingFocusManagerProps,\n FloatingNode,\n FloatingTree,\n OffsetOptions,\n UseHoverProps,\n autoUpdate,\n flip,\n offset,\n safePolygon,\n shift,\n size,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingParentNodeId,\n useHover,\n useId,\n useInteractions,\n useRole,\n} from '@floating-ui/react';\nimport { useMemoizedFn } from 'ahooks';\nimport { cn } from '../lib/utils';\nimport React, {\n cloneElement,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport ReactDOM from 'react-dom';\nimport Menu, { MenuInfo, MenuProps } from '../Menu';\nimport { useFloatingPopupZIndex } from '../_utils/floatingLayer';\nimport { ensureWeakRefFallback } from '../_utils/weakRefFallback';\n\nconst OVERLAY_EXIT_ANIMATION_MS = 200;\n\nensureWeakRefFallback();\n\nfunction resolvePlacementSide(\n currentPlacement: string,\n): 'top' | 'bottom' | 'left' | 'right' {\n const [side] = currentPlacement.split('-');\n if (\n side === 'top' ||\n side === 'bottom' ||\n side === 'left' ||\n side === 'right'\n ) {\n return side;\n }\n if (currentPlacement.startsWith('top')) {\n return 'top';\n }\n if (currentPlacement.startsWith('bottom')) {\n return 'bottom';\n }\n if (currentPlacement.startsWith('left')) {\n return 'left';\n }\n if (currentPlacement.startsWith('right')) {\n return 'right';\n }\n return 'bottom';\n}\n\nfunction parsePopupMatchWidth(value: unknown): number | undefined {\n if (typeof value === 'number') {\n return value;\n }\n\n if (typeof value === 'string' && value.trim() !== '') {\n const parsedValue = Number(value);\n return Number.isNaN(parsedValue) ? undefined : parsedValue;\n }\n\n return undefined;\n}\n\nexport type ActionType = 'hover' | 'click';\nexport type PlacementType =\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'top-start'\n | 'top-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'left-start'\n | 'left-end'\n | 'right-start'\n | 'right-end'\n // Legacy antd-style placement names\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight';\nexport interface IDropdownProps {\n children: React.ReactNode;\n /**\n * @description 菜单弹出位置的偏移量\n */\n offset?: OffsetOptions;\n /**\n * @description 关闭后是否销毁 Dropdown\n * @default false\n */\n destroyPopupOnHide?: boolean;\n /**\n * @description 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位\n * @default () => document.body\n */\n getPopupContainer?: () => HTMLElement;\n /**\n * @description 菜单\n * @type Menu | () => Menu\n * @default -\n */\n menu?: MenuProps;\n // /**\n // * @description 菜单\n // * @type Menu | () => Menu\n // * @default -\n // */\n // menu?: ReactElement | (() => ReactElement);\n /**\n * @description 下拉根元素的类名称\n * @default -\n */\n overlayClassName?: string;\n /**\n * @description 菜单弹出位置\n * @default bottomLeft\n */\n placement?: PlacementType;\n /**\n * @description 触发下拉的行为\n * @type ActionType, 其中 ActionType 为 'hover' | 'click' | 'contextMenu';\n * @default click\n */\n trigger?: ActionType | ActionType[];\n /**\n * @description 菜单是否显示\n * @default -\n */\n open?: boolean;\n /**\n * @description 菜单显示状态改变时调用,参数为 open,点击菜单按钮导致的消失不会触发\n * @default -\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * @description 焦点移出触发元素和浮层时是否关闭 Dropdown\n * @default true\n */\n closeOnFocusOut?: boolean;\n /**\n * @description 下拉框外层 overlay 的内联样式(与定位 transform 合并)\n * @default -\n */\n overlayStyle?: React.CSSProperties;\n /**\n * @description 下拉框内层 surface 的内联样式。\n * 用于覆盖 surface 默认约束(默认 min-width:160px、max-width:320px);\n * 自定义 dropdownRender 内容若需大于 320px 宽,传 `{ width: 400, maxWidth: 'none' }` 即可。\n * @default -\n */\n overlayInnerStyle?: React.CSSProperties;\n\n /**\n * @description 自定义下拉框内容\n * @default -\n */\n dropdownRender?: (menus: React.ReactNode) => React.ReactNode;\n /**\n * @description 是否禁用\n * @default false\n */\n // 透传给子元素,antd的dropdown用cloneElement生成dropdown的子元素,劫持了disabled属性,因此如果Dropdown上没有disabled属性,子元素不能获得该属性\n disabled?: boolean;\n /**\n * @description 鼠标移入后延迟显示下拉框的时间,单位为毫秒\n * @default 0\n */\n delay?: UseHoverProps['delay'];\n /**\n * @description 是否在下拉框变化的时候自动更新位置\n * @default false\n */\n autoUpdatePos?: boolean;\n /**\n * @description 初始化焦点,参照:https://floating-ui.com/docs/floatingfocusmanager#initialfocus\n */\n initialFocus?: FloatingFocusManagerProps['initialFocus'];\n\n /**\n * @description 菜单是否跟随触发元素宽度\n * @default false\n */\n popupMatchTriggerWidth?: boolean | number;\n /**\n * @description 空间不足时自动计算菜单最大高度并启用滚动,启用后 offset 固定为 0\n * @default false\n */\n allowOverlap?: boolean;\n}\n\nfunction hasTrigger(\n trigger: ActionType | ActionType[],\n action: ActionType,\n): boolean {\n return Array.isArray(trigger) ? trigger.includes(action) : trigger === action;\n}\n\nexport default function Dropdown(props: IDropdownProps) {\n const {\n children,\n destroyPopupOnHide = true,\n getPopupContainer,\n menu,\n overlayClassName,\n placement = 'bottom-start',\n trigger = 'click',\n open,\n onOpenChange = () => {},\n closeOnFocusOut = true,\n overlayStyle,\n overlayInnerStyle,\n dropdownRender,\n disabled,\n offset: offsetProps = 4,\n delay = 0,\n autoUpdatePos = false,\n // 默认不自动 focus\n initialFocus = -1,\n popupMatchTriggerWidth = false,\n allowOverlap = false,\n } = props;\n const [isOpen, setIsOpen] = useState<boolean>(open || false);\n const [isAnimatingOut, setIsAnimatingOut] = useState(false);\n const closeAnimationTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const lastResolvedFloatingStylesRef = useRef<React.CSSProperties | null>(\n null,\n );\n const lastResolvedSideRef = useRef<'top' | 'bottom' | 'left' | 'right'>(\n resolvePlacementSide(placement),\n );\n const currentFloatingStylesRef = useRef<React.CSSProperties | null>(null);\n const currentFloatingSideRef = useRef<'top' | 'bottom' | 'left' | 'right'>(\n resolvePlacementSide(placement),\n );\n const [targetElement, setTargetElement] = useState<HTMLElement | null>(null);\n const popupMatchTriggerWidthNumber = parsePopupMatchWidth(\n popupMatchTriggerWidth,\n );\n const [matchedTriggerWidth, setMatchedTriggerWidth] = useState<\n number | undefined\n >(popupMatchTriggerWidthNumber);\n const popupZIndex = useFloatingPopupZIndex();\n\n const onOpenChangeFn = useMemoizedFn(onOpenChange);\n const isOpenControlled = open !== undefined;\n\n const clearCloseAnimationTimer = useCallback(() => {\n if (closeAnimationTimerRef.current) {\n clearTimeout(closeAnimationTimerRef.current);\n closeAnimationTimerRef.current = null;\n }\n }, []);\n\n const stopCloseAnimation = useCallback(() => {\n clearCloseAnimationTimer();\n document.body.classList.remove('ald-dropdown-root-closing');\n setIsAnimatingOut(false);\n }, [clearCloseAnimationTimer]);\n\n const markRootClosing = useCallback(() => {\n document.body.classList.add('ald-dropdown-root-closing');\n lastResolvedFloatingStylesRef.current =\n currentFloatingStylesRef.current ?? lastResolvedFloatingStylesRef.current;\n lastResolvedSideRef.current =\n currentFloatingSideRef.current ?? lastResolvedSideRef.current;\n }, []);\n\n const startCloseAnimation = useCallback(() => {\n clearCloseAnimationTimer();\n markRootClosing();\n setIsAnimatingOut(true);\n closeAnimationTimerRef.current = setTimeout(() => {\n document.body.classList.remove('ald-dropdown-root-closing');\n setIsAnimatingOut(false);\n closeAnimationTimerRef.current = null;\n }, OVERLAY_EXIT_ANIMATION_MS);\n }, [clearCloseAnimationTimer, markRootClosing]);\n\n useLayoutEffect(() => {\n if (!isOpenControlled) {\n return;\n }\n\n if (open) {\n stopCloseAnimation();\n setIsOpen(true);\n return;\n }\n\n if (isOpen) {\n startCloseAnimation();\n }\n setIsOpen(false);\n }, [isOpen, isOpenControlled, open, startCloseAnimation, stopCloseAnimation]);\n\n useEffect(() => {\n return () => {\n clearCloseAnimationTimer();\n };\n }, [clearCloseAnimationTimer]);\n\n useEffect(() => {\n return () => {\n document.body.classList.remove('ald-dropdown-root-closing');\n };\n }, []);\n\n const onChangeOpen = useCallback(\n (newOpen: boolean) => {\n if (newOpen) {\n stopCloseAnimation();\n } else {\n startCloseAnimation();\n }\n\n if (!isOpenControlled) {\n setIsOpen(newOpen);\n }\n onOpenChangeFn(newOpen);\n },\n [isOpenControlled, onOpenChangeFn, startCloseAnimation, stopCloseAnimation],\n );\n\n const nodeId = useFloatingNodeId();\n const {\n refs,\n floatingStyles,\n context,\n placement: floatingPlacement,\n x,\n y,\n } = useFloating({\n nodeId,\n placement: placement as any,\n open: isOpen,\n onOpenChange: onChangeOpen,\n middleware: [\n offset(allowOverlap ? 0 : offsetProps),\n flip({\n fallbackAxisSideDirection: 'end',\n ...(allowOverlap && { fallbackStrategy: 'bestFit' }),\n }),\n shift(allowOverlap ? { mainAxis: true } : undefined),\n size({\n ...(allowOverlap && { padding: 8 }),\n apply({ availableHeight, elements }) {\n if (!allowOverlap) {\n return;\n }\n\n Object.assign(elements.floating.style, {\n maxHeight: `${Math.max(100, availableHeight)}px`,\n overflowY: 'auto',\n });\n },\n }),\n ],\n whileElementsMounted: autoUpdatePos ? autoUpdate : undefined,\n });\n\n const click = useClick(context, {\n enabled: hasTrigger(trigger, 'click'),\n });\n const hover = useHover(context, {\n enabled: hasTrigger(trigger, 'hover'),\n handleClose: safePolygon({}),\n delay: delay,\n });\n const dismiss = useDismiss(context, {});\n const role = useRole(context);\n\n const propsList = useMemo(() => {\n const res = [dismiss, role];\n\n if (hasTrigger(trigger, 'hover')) {\n res.unshift(hover);\n }\n if (hasTrigger(trigger, 'click')) {\n res.unshift(click);\n }\n return res;\n }, [trigger, click, dismiss, role, hover]);\n\n const { getReferenceProps, getFloatingProps } = useInteractions(propsList);\n\n const headingId = useId();\n\n useLayoutEffect(() => {\n if (!popupMatchTriggerWidth || !isOpen) {\n setMatchedTriggerWidth(undefined);\n return;\n }\n\n if (popupMatchTriggerWidthNumber !== undefined) {\n setMatchedTriggerWidth(popupMatchTriggerWidthNumber);\n return;\n }\n\n const referenceElement = targetElement;\n if (!referenceElement) {\n return;\n }\n\n const updateMatchedWidth = () => {\n const nextWidth = referenceElement.getBoundingClientRect().width;\n setMatchedTriggerWidth((currentWidth) =>\n currentWidth === nextWidth ? currentWidth : nextWidth,\n );\n };\n\n updateMatchedWidth();\n\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', updateMatchedWidth);\n return () => {\n window.removeEventListener('resize', updateMatchedWidth);\n };\n }\n\n let resizeAnimationFrame: number | undefined;\n const scheduleMatchedWidthUpdate = () => {\n if (resizeAnimationFrame !== undefined) {\n cancelAnimationFrame(resizeAnimationFrame);\n }\n resizeAnimationFrame = requestAnimationFrame(updateMatchedWidth);\n };\n\n const observer = new ResizeObserver(scheduleMatchedWidthUpdate);\n observer.observe(referenceElement);\n\n return () => {\n if (resizeAnimationFrame !== undefined) {\n cancelAnimationFrame(resizeAnimationFrame);\n }\n observer.disconnect();\n };\n }, [\n isOpen,\n popupMatchTriggerWidth,\n popupMatchTriggerWidthNumber,\n targetElement,\n ]);\n\n const child = children as React.ReactElement;\n const childProps = child.props || {};\n const referenceProps = getReferenceProps();\n const updateMatchedWidthFromElement = useCallback(\n (element: HTMLElement) => {\n if (!popupMatchTriggerWidth) {\n return;\n }\n\n setMatchedTriggerWidth((currentWidth) => {\n const nextWidth =\n popupMatchTriggerWidthNumber !== undefined\n ? popupMatchTriggerWidthNumber\n : element.getBoundingClientRect().width;\n return currentWidth === nextWidth ? currentWidth : nextWidth;\n });\n },\n [popupMatchTriggerWidth, popupMatchTriggerWidthNumber],\n );\n const modifiedChild = cloneElement(child, {\n ...childProps,\n disabled,\n // ref: (node: HTMLDivElement) => refs.setReference(node),\n ...referenceProps,\n onClick: (event: React.MouseEvent<HTMLElement>) => {\n updateMatchedWidthFromElement(event.currentTarget);\n childProps.onClick?.(event);\n const { onClick: referenceOnClick } = referenceProps;\n if (typeof referenceOnClick === 'function') {\n referenceOnClick(event);\n }\n },\n });\n\n const onMenuItemClick = useCallback(\n (info: MenuInfo) => {\n if (menu?.onClick) {\n menu.onClick(info);\n }\n if (info.keepOpen) {\n document.body.classList.remove('ald-dropdown-root-closing');\n return;\n }\n onChangeOpen(false);\n },\n [menu, onChangeOpen],\n );\n\n const menuInstance = useMemo(() => {\n const menuProps = {\n ...menu,\n items: menu?.items || [],\n menuStyle: {\n ...(popupMatchTriggerWidth\n ? {\n width: '100%',\n minWidth: 0,\n maxWidth: 'none',\n }\n : undefined),\n ...menu?.menuStyle,\n },\n onBeforeLeafItemClick: markRootClosing,\n rootClosing: isAnimatingOut,\n };\n return (\n <Menu\n {...menuProps}\n onClick={onMenuItemClick}\n externalOverflow={allowOverlap}\n />\n );\n }, [\n allowOverlap,\n isAnimatingOut,\n markRootClosing,\n menu,\n onMenuItemClick,\n popupMatchTriggerWidth,\n ]);\n\n const popupElement = useMemo(() => {\n return typeof dropdownRender === 'function'\n ? dropdownRender(menuInstance)\n : menuInstance;\n }, [dropdownRender, menuInstance]);\n\n const mergedMatchedTriggerWidth =\n popupMatchTriggerWidthNumber ?? matchedTriggerWidth;\n const matchedOverlayStyle =\n popupMatchTriggerWidth && mergedMatchedTriggerWidth !== undefined\n ? ({\n width: `${mergedMatchedTriggerWidth}px`,\n minWidth: 0,\n } satisfies React.CSSProperties)\n : undefined;\n\n const matchedSurfaceStyle = popupMatchTriggerWidth\n ? ({\n width: '100%',\n minWidth: 0,\n maxWidth: 'none',\n } satisfies React.CSSProperties)\n : undefined;\n\n const floatingSide = resolvePlacementSide(String(floatingPlacement));\n const shouldKeepMounted = !destroyPopupOnHide || isOpen || isAnimatingOut;\n const isPositionReady = x !== null && y !== null;\n const overlayHidden =\n (!isOpen && !isAnimatingOut) || (isOpen && !isPositionReady);\n const resolvedFloatingStyles = isAnimatingOut\n ? lastResolvedFloatingStylesRef.current ?? floatingStyles\n : floatingStyles;\n const resolvedFloatingSide = isAnimatingOut\n ? lastResolvedSideRef.current\n : floatingSide;\n\n if (isOpen && isPositionReady) {\n currentFloatingStylesRef.current = { ...floatingStyles };\n currentFloatingSideRef.current = floatingSide;\n lastResolvedFloatingStylesRef.current = { ...floatingStyles };\n lastResolvedSideRef.current = floatingSide;\n }\n\n // 渲染浮动内容到自定义容器\n const renderFloatingContent = useCallback(() => {\n const surface = (\n <div\n {...(isAnimatingOut ? {} : getFloatingProps())}\n className={cn(\n 'ald-dropdown-overlay',\n // tw-outline-none:FloatingFocusManager 打开时会聚焦浮层容器,不抑制 outline 会渲染出蓝色焦点框\n 'tw-pointer-events-auto tw-z-[1001] tw-max-w-none tw-outline-none',\n overlayClassName,\n { 'ald-dropdown-overlay-hidden': overlayHidden },\n )}\n ref={refs.setFloating}\n style={{\n zIndex: popupZIndex,\n ...resolvedFloatingStyles,\n ...matchedOverlayStyle,\n ...overlayStyle,\n }}\n aria-labelledby={headingId}\n >\n <div\n className={cn(\n 'ald-dropdown-surface',\n 'tw-flex tw-flex-col tw-items-start tw-text-sm',\n )}\n style={{\n ...matchedSurfaceStyle,\n ...overlayInnerStyle,\n }}\n data-state={isOpen ? 'open' : 'closed'}\n data-side={resolvedFloatingSide}\n >\n {popupElement}\n </div>\n </div>\n );\n\n const popupElem =\n isAnimatingOut && !isOpen ? (\n surface\n ) : (\n <FloatingFocusManager\n context={context}\n modal={false}\n initialFocus={initialFocus}\n closeOnFocusOut={closeOnFocusOut}\n >\n {surface}\n </FloatingFocusManager>\n );\n\n const popupContainer =\n typeof getPopupContainer === 'function'\n ? getPopupContainer()\n : document.body;\n return ReactDOM.createPortal(popupElem, popupContainer);\n }, [\n context,\n getFloatingProps,\n getPopupContainer,\n headingId,\n popupElement,\n refs.setFloating,\n overlayClassName,\n overlayStyle,\n overlayInnerStyle,\n matchedOverlayStyle,\n matchedSurfaceStyle,\n popupZIndex,\n overlayHidden,\n isAnimatingOut,\n isOpen,\n initialFocus,\n closeOnFocusOut,\n resolvedFloatingSide,\n resolvedFloatingStyles,\n ]);\n\n const popup = shouldKeepMounted ? renderFloatingContent() : null;\n const { setReference } = refs;\n\n const setTargetRef = useCallback(\n (node: HTMLElement | null) => {\n if (node) {\n // display: contents 元素没有 box model,getBoundingClientRect() 返回零值\n // 需要获取实际的第一个子元素作为 floating-ui 的参考元素\n const target =\n node.style.display === 'contents'\n ? (node.firstElementChild as HTMLElement) || node\n : node;\n setTargetElement((currentTarget) =>\n currentTarget === target ? currentTarget : target,\n );\n setReference(target);\n } else {\n setTargetElement(null);\n setReference(null);\n }\n },\n [setReference],\n );\n\n const content = (\n <>\n <span ref={setTargetRef} style={{ display: 'contents' }}>\n {modifiedChild}\n </span>\n <FloatingNode id={nodeId}>{popup}</FloatingNode>\n </>\n );\n\n const parentId = useFloatingParentNodeId();\n if (!parentId) {\n return <FloatingTree>{content}</FloatingTree>;\n }\n\n return content;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Dropdown/index.tsx"],"sourcesContent":["import './dropdown.css';\nimport {\n FloatingFocusManager,\n FloatingFocusManagerProps,\n FloatingNode,\n FloatingTree,\n OffsetOptions,\n UseHoverProps,\n autoUpdate,\n flip,\n offset,\n safePolygon,\n shift,\n size,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingParentNodeId,\n useHover,\n useId,\n useInteractions,\n useRole,\n} from '@floating-ui/react';\nimport { useMemoizedFn } from 'ahooks';\nimport { cn } from '../lib/utils';\nimport React, {\n cloneElement,\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport ReactDOM from 'react-dom';\nimport Menu, { MenuInfo, MenuProps } from '../Menu';\nimport { useFloatingPopupZIndex } from '../_utils/floatingLayer';\nimport { ensureWeakRefFallback } from '../_utils/weakRefFallback';\n\nconst OVERLAY_EXIT_ANIMATION_MS = 200;\n\nensureWeakRefFallback();\n\nfunction resolvePlacementSide(\n currentPlacement: string,\n): 'top' | 'bottom' | 'left' | 'right' {\n const [side] = currentPlacement.split('-');\n if (\n side === 'top' ||\n side === 'bottom' ||\n side === 'left' ||\n side === 'right'\n ) {\n return side;\n }\n if (currentPlacement.startsWith('top')) {\n return 'top';\n }\n if (currentPlacement.startsWith('bottom')) {\n return 'bottom';\n }\n if (currentPlacement.startsWith('left')) {\n return 'left';\n }\n if (currentPlacement.startsWith('right')) {\n return 'right';\n }\n return 'bottom';\n}\n\nfunction parsePopupMatchWidth(value: unknown): number | undefined {\n if (typeof value === 'number') {\n return value;\n }\n\n if (typeof value === 'string' && value.trim() !== '') {\n const parsedValue = Number(value);\n return Number.isNaN(parsedValue) ? undefined : parsedValue;\n }\n\n return undefined;\n}\n\nexport type ActionType = 'hover' | 'click';\nexport type PlacementType =\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'top-start'\n | 'top-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'left-start'\n | 'left-end'\n | 'right-start'\n | 'right-end'\n // Legacy antd-style placement names\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight';\nexport interface IDropdownProps {\n children: React.ReactNode;\n /**\n * @description 菜单弹出位置的偏移量\n */\n offset?: OffsetOptions;\n /**\n * @description 关闭后是否销毁 Dropdown\n * @default false\n */\n destroyPopupOnHide?: boolean;\n /**\n * @description 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位\n * @default () => document.body\n */\n getPopupContainer?: () => HTMLElement;\n /**\n * @description 菜单\n * @type Menu | () => Menu\n * @default -\n */\n menu?: MenuProps;\n // /**\n // * @description 菜单\n // * @type Menu | () => Menu\n // * @default -\n // */\n // menu?: ReactElement | (() => ReactElement);\n /**\n * @description 下拉根元素的类名称\n * @default -\n */\n overlayClassName?: string;\n /**\n * @description 菜单弹出位置\n * @default bottomLeft\n */\n placement?: PlacementType;\n /**\n * @description 触发下拉的行为\n * @type ActionType, 其中 ActionType 为 'hover' | 'click' | 'contextMenu';\n * @default click\n */\n trigger?: ActionType | ActionType[];\n /**\n * @description 菜单是否显示\n * @default -\n */\n open?: boolean;\n /**\n * @description 菜单显示状态改变时调用,参数为 open,点击菜单按钮导致的消失不会触发\n * @default -\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * @description 焦点移出触发元素和浮层时是否关闭 Dropdown\n * @default true\n */\n closeOnFocusOut?: boolean;\n /**\n * @description 下拉框外层 overlay 的内联样式(与定位 transform 合并)\n * @default -\n */\n overlayStyle?: React.CSSProperties;\n /**\n * @description 下拉框内层 surface 的内联样式。\n * 用于覆盖 surface 默认约束(默认 min-width:160px、max-width:320px);\n * 自定义 dropdownRender 内容若需大于 320px 宽,传 `{ width: 400, maxWidth: 'none' }` 即可。\n * @default -\n */\n overlayInnerStyle?: React.CSSProperties;\n\n /**\n * @description 自定义下拉框内容\n * @default -\n */\n dropdownRender?: (menus: React.ReactNode) => React.ReactNode;\n /**\n * @description 是否禁用\n * @default false\n */\n // 透传给子元素,antd的dropdown用cloneElement生成dropdown的子元素,劫持了disabled属性,因此如果Dropdown上没有disabled属性,子元素不能获得该属性\n disabled?: boolean;\n /**\n * @description 鼠标移入后延迟显示下拉框的时间,单位为毫秒\n * @default 0\n */\n delay?: UseHoverProps['delay'];\n /**\n * @description 是否在下拉框变化的时候自动更新位置\n * @default false\n */\n autoUpdatePos?: boolean;\n /**\n * @description 初始化焦点,参照:https://floating-ui.com/docs/floatingfocusmanager#initialfocus\n */\n initialFocus?: FloatingFocusManagerProps['initialFocus'];\n\n /**\n * @description 菜单是否跟随触发元素宽度\n * @default false\n */\n popupMatchTriggerWidth?: boolean | number;\n /**\n * @description 空间不足时自动计算菜单最大高度并启用滚动,启用后 offset 固定为 0\n * @default false\n */\n allowOverlap?: boolean;\n}\n\nfunction hasTrigger(\n trigger: ActionType | ActionType[],\n action: ActionType,\n): boolean {\n return Array.isArray(trigger) ? trigger.includes(action) : trigger === action;\n}\n\nexport default function Dropdown(props: IDropdownProps) {\n const {\n children,\n destroyPopupOnHide = true,\n getPopupContainer,\n menu,\n overlayClassName,\n placement = 'bottom-start',\n trigger = 'click',\n open,\n onOpenChange = () => {},\n closeOnFocusOut = true,\n overlayStyle,\n overlayInnerStyle,\n dropdownRender,\n disabled,\n offset: offsetProps = 4,\n delay = 0,\n autoUpdatePos = false,\n // 默认不自动 focus\n initialFocus = -1,\n popupMatchTriggerWidth = false,\n allowOverlap = false,\n } = props;\n const [isOpen, setIsOpen] = useState<boolean>(open || false);\n const [isAnimatingOut, setIsAnimatingOut] = useState(false);\n const closeAnimationTimerRef = useRef<ReturnType<typeof setTimeout> | null>(\n null,\n );\n const lastResolvedFloatingStylesRef = useRef<React.CSSProperties | null>(\n null,\n );\n const lastResolvedSideRef = useRef<'top' | 'bottom' | 'left' | 'right'>(\n resolvePlacementSide(placement),\n );\n const currentFloatingStylesRef = useRef<React.CSSProperties | null>(null);\n const currentFloatingSideRef = useRef<'top' | 'bottom' | 'left' | 'right'>(\n resolvePlacementSide(placement),\n );\n const [targetElement, setTargetElement] = useState<HTMLElement | null>(null);\n const popupMatchTriggerWidthNumber = parsePopupMatchWidth(\n popupMatchTriggerWidth,\n );\n const [matchedTriggerWidth, setMatchedTriggerWidth] = useState<\n number | undefined\n >(popupMatchTriggerWidthNumber);\n const popupZIndex = useFloatingPopupZIndex();\n\n const onOpenChangeFn = useMemoizedFn(onOpenChange);\n const isOpenControlled = open !== undefined;\n\n const clearCloseAnimationTimer = useCallback(() => {\n if (closeAnimationTimerRef.current) {\n clearTimeout(closeAnimationTimerRef.current);\n closeAnimationTimerRef.current = null;\n }\n }, []);\n\n const stopCloseAnimation = useCallback(() => {\n clearCloseAnimationTimer();\n document.body.classList.remove('ald-dropdown-root-closing');\n setIsAnimatingOut(false);\n }, [clearCloseAnimationTimer]);\n\n const markRootClosing = useCallback(() => {\n document.body.classList.add('ald-dropdown-root-closing');\n lastResolvedFloatingStylesRef.current =\n currentFloatingStylesRef.current ?? lastResolvedFloatingStylesRef.current;\n lastResolvedSideRef.current =\n currentFloatingSideRef.current ?? lastResolvedSideRef.current;\n }, []);\n\n const startCloseAnimation = useCallback(() => {\n clearCloseAnimationTimer();\n markRootClosing();\n setIsAnimatingOut(true);\n closeAnimationTimerRef.current = setTimeout(() => {\n document.body.classList.remove('ald-dropdown-root-closing');\n setIsAnimatingOut(false);\n closeAnimationTimerRef.current = null;\n }, OVERLAY_EXIT_ANIMATION_MS);\n }, [clearCloseAnimationTimer, markRootClosing]);\n\n useLayoutEffect(() => {\n if (!isOpenControlled) {\n return;\n }\n\n if (open) {\n stopCloseAnimation();\n setIsOpen(true);\n return;\n }\n\n if (isOpen) {\n startCloseAnimation();\n }\n setIsOpen(false);\n }, [isOpen, isOpenControlled, open, startCloseAnimation, stopCloseAnimation]);\n\n useEffect(() => {\n return () => {\n clearCloseAnimationTimer();\n };\n }, [clearCloseAnimationTimer]);\n\n useEffect(() => {\n return () => {\n document.body.classList.remove('ald-dropdown-root-closing');\n };\n }, []);\n\n const onChangeOpen = useCallback(\n (newOpen: boolean) => {\n if (!isOpenControlled) {\n if (newOpen) {\n stopCloseAnimation();\n } else {\n startCloseAnimation();\n }\n setIsOpen(newOpen);\n }\n onOpenChangeFn(newOpen);\n },\n [isOpenControlled, onOpenChangeFn, startCloseAnimation, stopCloseAnimation],\n );\n\n const nodeId = useFloatingNodeId();\n const {\n refs,\n floatingStyles,\n context,\n placement: floatingPlacement,\n x,\n y,\n } = useFloating({\n nodeId,\n placement: placement as any,\n open: isOpen,\n onOpenChange: onChangeOpen,\n middleware: [\n offset(allowOverlap ? 0 : offsetProps),\n flip({\n fallbackAxisSideDirection: 'end',\n ...(allowOverlap && { fallbackStrategy: 'bestFit' }),\n }),\n shift(allowOverlap ? { mainAxis: true } : undefined),\n size({\n ...(allowOverlap && { padding: 8 }),\n apply({ availableHeight, elements }) {\n if (!allowOverlap) {\n return;\n }\n\n Object.assign(elements.floating.style, {\n maxHeight: `${Math.max(100, availableHeight)}px`,\n overflowY: 'auto',\n });\n },\n }),\n ],\n whileElementsMounted: autoUpdatePos ? autoUpdate : undefined,\n });\n\n const click = useClick(context, {\n enabled: hasTrigger(trigger, 'click'),\n });\n const hover = useHover(context, {\n enabled: hasTrigger(trigger, 'hover'),\n handleClose: safePolygon({}),\n delay: delay,\n });\n const dismiss = useDismiss(context, {});\n const role = useRole(context);\n\n const propsList = useMemo(() => {\n const res = [dismiss, role];\n\n if (hasTrigger(trigger, 'hover')) {\n res.unshift(hover);\n }\n if (hasTrigger(trigger, 'click')) {\n res.unshift(click);\n }\n return res;\n }, [trigger, click, dismiss, role, hover]);\n\n const { getReferenceProps, getFloatingProps } = useInteractions(propsList);\n\n const headingId = useId();\n\n useLayoutEffect(() => {\n if (!popupMatchTriggerWidth || !isOpen) {\n setMatchedTriggerWidth(undefined);\n return;\n }\n\n if (popupMatchTriggerWidthNumber !== undefined) {\n setMatchedTriggerWidth(popupMatchTriggerWidthNumber);\n return;\n }\n\n const referenceElement = targetElement;\n if (!referenceElement) {\n return;\n }\n\n const updateMatchedWidth = () => {\n const nextWidth = referenceElement.getBoundingClientRect().width;\n setMatchedTriggerWidth((currentWidth) =>\n currentWidth === nextWidth ? currentWidth : nextWidth,\n );\n };\n\n updateMatchedWidth();\n\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', updateMatchedWidth);\n return () => {\n window.removeEventListener('resize', updateMatchedWidth);\n };\n }\n\n let resizeAnimationFrame: number | undefined;\n const scheduleMatchedWidthUpdate = () => {\n if (resizeAnimationFrame !== undefined) {\n cancelAnimationFrame(resizeAnimationFrame);\n }\n resizeAnimationFrame = requestAnimationFrame(updateMatchedWidth);\n };\n\n const observer = new ResizeObserver(scheduleMatchedWidthUpdate);\n observer.observe(referenceElement);\n\n return () => {\n if (resizeAnimationFrame !== undefined) {\n cancelAnimationFrame(resizeAnimationFrame);\n }\n observer.disconnect();\n };\n }, [\n isOpen,\n popupMatchTriggerWidth,\n popupMatchTriggerWidthNumber,\n targetElement,\n ]);\n\n const child = children as React.ReactElement;\n const childProps = child.props || {};\n const referenceProps = getReferenceProps();\n const updateMatchedWidthFromElement = useCallback(\n (element: HTMLElement) => {\n if (!popupMatchTriggerWidth) {\n return;\n }\n\n setMatchedTriggerWidth((currentWidth) => {\n const nextWidth =\n popupMatchTriggerWidthNumber !== undefined\n ? popupMatchTriggerWidthNumber\n : element.getBoundingClientRect().width;\n return currentWidth === nextWidth ? currentWidth : nextWidth;\n });\n },\n [popupMatchTriggerWidth, popupMatchTriggerWidthNumber],\n );\n const modifiedChild = cloneElement(child, {\n ...childProps,\n disabled,\n // ref: (node: HTMLDivElement) => refs.setReference(node),\n ...referenceProps,\n onClick: (event: React.MouseEvent<HTMLElement>) => {\n updateMatchedWidthFromElement(event.currentTarget);\n childProps.onClick?.(event);\n const { onClick: referenceOnClick } = referenceProps;\n if (typeof referenceOnClick === 'function') {\n referenceOnClick(event);\n }\n },\n });\n\n const onMenuItemClick = useCallback(\n (info: MenuInfo) => {\n if (menu?.onClick) {\n menu.onClick(info);\n }\n if (info.keepOpen) {\n document.body.classList.remove('ald-dropdown-root-closing');\n return;\n }\n onChangeOpen(false);\n },\n [menu, onChangeOpen],\n );\n\n const menuInstance = useMemo(() => {\n const menuProps = {\n ...menu,\n items: menu?.items || [],\n menuStyle: {\n ...(popupMatchTriggerWidth\n ? {\n width: '100%',\n minWidth: 0,\n maxWidth: 'none',\n }\n : undefined),\n ...menu?.menuStyle,\n },\n onBeforeLeafItemClick: isOpenControlled ? undefined : markRootClosing,\n rootClosing: isAnimatingOut,\n };\n return (\n <Menu\n {...menuProps}\n onClick={onMenuItemClick}\n externalOverflow={allowOverlap}\n />\n );\n }, [\n allowOverlap,\n isAnimatingOut,\n isOpenControlled,\n markRootClosing,\n menu,\n onMenuItemClick,\n popupMatchTriggerWidth,\n ]);\n\n const popupElement = useMemo(() => {\n return typeof dropdownRender === 'function'\n ? dropdownRender(menuInstance)\n : menuInstance;\n }, [dropdownRender, menuInstance]);\n\n const mergedMatchedTriggerWidth =\n popupMatchTriggerWidthNumber ?? matchedTriggerWidth;\n const matchedOverlayStyle =\n popupMatchTriggerWidth && mergedMatchedTriggerWidth !== undefined\n ? ({\n width: `${mergedMatchedTriggerWidth}px`,\n minWidth: 0,\n } satisfies React.CSSProperties)\n : undefined;\n\n const matchedSurfaceStyle = popupMatchTriggerWidth\n ? ({\n width: '100%',\n minWidth: 0,\n maxWidth: 'none',\n } satisfies React.CSSProperties)\n : undefined;\n\n const floatingSide = resolvePlacementSide(String(floatingPlacement));\n const shouldKeepMounted = !destroyPopupOnHide || isOpen || isAnimatingOut;\n const isPositionReady = x !== null && y !== null;\n const overlayHidden =\n (!isOpen && !isAnimatingOut) || (isOpen && !isPositionReady);\n const resolvedFloatingStyles = isAnimatingOut\n ? lastResolvedFloatingStylesRef.current ?? floatingStyles\n : floatingStyles;\n const resolvedFloatingSide = isAnimatingOut\n ? lastResolvedSideRef.current\n : floatingSide;\n\n if (isOpen && isPositionReady) {\n currentFloatingStylesRef.current = { ...floatingStyles };\n currentFloatingSideRef.current = floatingSide;\n lastResolvedFloatingStylesRef.current = { ...floatingStyles };\n lastResolvedSideRef.current = floatingSide;\n }\n\n // 渲染浮动内容到自定义容器\n const renderFloatingContent = useCallback(() => {\n const surface = (\n <div\n {...(isAnimatingOut ? {} : getFloatingProps())}\n className={cn(\n 'ald-dropdown-overlay',\n // tw-outline-none:FloatingFocusManager 打开时会聚焦浮层容器,不抑制 outline 会渲染出蓝色焦点框\n 'tw-pointer-events-auto tw-z-[1001] tw-max-w-none tw-outline-none',\n overlayClassName,\n { 'ald-dropdown-overlay-hidden': overlayHidden },\n )}\n ref={refs.setFloating}\n style={{\n zIndex: popupZIndex,\n ...resolvedFloatingStyles,\n ...matchedOverlayStyle,\n ...overlayStyle,\n }}\n aria-labelledby={headingId}\n >\n <div\n className={cn(\n 'ald-dropdown-surface',\n 'tw-flex tw-flex-col tw-items-start tw-text-sm',\n )}\n style={{\n ...matchedSurfaceStyle,\n ...overlayInnerStyle,\n }}\n data-state={isOpen ? 'open' : 'closed'}\n data-side={resolvedFloatingSide}\n >\n {popupElement}\n </div>\n </div>\n );\n\n const popupElem =\n isAnimatingOut && !isOpen ? (\n surface\n ) : (\n <FloatingFocusManager\n context={context}\n modal={false}\n initialFocus={initialFocus}\n closeOnFocusOut={closeOnFocusOut}\n >\n {surface}\n </FloatingFocusManager>\n );\n\n const popupContainer =\n typeof getPopupContainer === 'function'\n ? getPopupContainer()\n : document.body;\n return ReactDOM.createPortal(popupElem, popupContainer);\n }, [\n context,\n getFloatingProps,\n getPopupContainer,\n headingId,\n popupElement,\n refs.setFloating,\n overlayClassName,\n overlayStyle,\n overlayInnerStyle,\n matchedOverlayStyle,\n matchedSurfaceStyle,\n popupZIndex,\n overlayHidden,\n isAnimatingOut,\n isOpen,\n initialFocus,\n closeOnFocusOut,\n resolvedFloatingSide,\n resolvedFloatingStyles,\n ]);\n\n const popup = shouldKeepMounted ? renderFloatingContent() : null;\n const { setReference } = refs;\n\n const setTargetRef = useCallback(\n (node: HTMLElement | null) => {\n if (node) {\n // display: contents 元素没有 box model,getBoundingClientRect() 返回零值\n // 需要获取实际的第一个子元素作为 floating-ui 的参考元素\n const target =\n node.style.display === 'contents'\n ? (node.firstElementChild as HTMLElement) || node\n : node;\n setTargetElement((currentTarget) =>\n currentTarget === target ? currentTarget : target,\n );\n setReference(target);\n } else {\n setTargetElement(null);\n setReference(null);\n }\n },\n [setReference],\n );\n\n const content = (\n <>\n <span ref={setTargetRef} style={{ display: 'contents' }}>\n {modifiedChild}\n </span>\n <FloatingNode id={nodeId}>{popup}</FloatingNode>\n </>\n );\n\n const parentId = useFloatingParentNodeId();\n if (!parentId) {\n return <FloatingTree>{content}</FloatingTree>;\n }\n\n return content;\n}\n"],"mappings":"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"}
@@ -126,7 +126,7 @@ function FormItemLayout({ label, children, meta, help, extra, required, rules, h
126
126
  className: cn("ald-form-item-label ant-form-item-label", layout === "vertical" && "tw-mb-1 tw-block", layout === "horizontal" && "tw-mr-3 tw-shrink-0"),
127
127
  style: useGridLayout ? colStyle(resolvedLabelCol) : void 0,
128
128
  children: /* @__PURE__ */ jsxs("label", {
129
- className: cn("tw-text-sm tw-font-medium tw-text-[var(--content-secondary)]", !showColon && "ant-form-item-no-colon"),
129
+ className: cn("tw-text-[var(--content-secondary)] tw-text-typography-label", !showColon && "ant-form-item-no-colon"),
130
130
  children: [
131
131
  showRequired && /* @__PURE__ */ jsx("span", {
132
132
  className: "tw-mr-1 tw-text-[var(--content-negative-primary)]",
@@ -134,7 +134,7 @@ function FormItemLayout({ label, children, meta, help, extra, required, rules, h
134
134
  }),
135
135
  label,
136
136
  showOptional && /* @__PURE__ */ jsx("span", {
137
- className: "tw-ml-1 tw-text-xs tw-font-normal tw-text-[var(--content-secondary)]",
137
+ className: "tw-ml-1 tw-text-[var(--content-secondary)] tw-text-typography-caption",
138
138
  children: "(optional)"
139
139
  }),
140
140
  showColon && label ? ":" : null
@@ -156,12 +156,12 @@ function FormItemLayout({ label, children, meta, help, extra, required, rules, h
156
156
  })
157
157
  }),
158
158
  /* @__PURE__ */ jsx("div", {
159
- className: cn("ald-form-item-explain ant-form-item-explain tw-text-xs tw-transition-all tw-duration-200", displayMessages.length > 0 && "tw-mt-1", hasError && "tw-text-[var(--content-negative-secondary)]", hasWarning && !hasError && "tw-text-[var(--content-warning-primary)]", !hasError && !hasWarning && help !== null && help !== void 0 && "tw-text-[var(--content-secondary)]"),
159
+ className: cn("ald-form-item-explain ant-form-item-explain tw-transition-all tw-duration-200 tw-text-typography-caption", displayMessages.length > 0 && "tw-mt-1", hasError && "tw-text-[var(--content-negative-secondary)]", hasWarning && !hasError && "tw-text-[var(--content-warning-primary)]", !hasError && !hasWarning && help !== null && help !== void 0 && "tw-text-[var(--content-secondary)]"),
160
160
  style: displayMessages.length === 0 ? { display: "none" } : void 0,
161
161
  children: displayMessages.map((msg, i) => /* @__PURE__ */ jsx("div", { children: msg }, i))
162
162
  }),
163
163
  extra && /* @__PURE__ */ jsx("div", {
164
- className: "ald-form-item-extra tw-mt-1 tw-text-xs tw-text-[var(--content-secondary)]",
164
+ className: "ald-form-item-extra tw-mt-1 tw-text-[var(--content-secondary)] tw-text-typography-caption",
165
165
  children: extra
166
166
  })
167
167
  ]
@@ -273,7 +273,7 @@ function ErrorListComponent(props) {
273
273
  return /* @__PURE__ */ jsx("div", {
274
274
  className: cn("ald-form-error-list", className),
275
275
  children: errors.map((err, i) => /* @__PURE__ */ jsx("div", {
276
- className: "tw-text-xs tw-text-[var(--content-negative-secondary)]",
276
+ className: "tw-text-[var(--content-negative-secondary)] tw-text-typography-caption",
277
277
  children: err
278
278
  }, i))
279
279
  });