@aloudata/aloudata-design 3.0.22 → 3.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App/index.js +5 -2
- package/dist/App/index.js.map +1 -1
- package/dist/Button/index.d.ts +1 -1
- package/dist/Button/index.js +9 -9
- package/dist/Button/index.js.map +1 -1
- package/dist/Checkbox/index.js +23 -13
- package/dist/Checkbox/index.js.map +1 -1
- package/dist/Drawer/index.d.ts +1 -1
- package/dist/Drawer/index.js +29 -20
- package/dist/Drawer/index.js.map +1 -1
- package/dist/Dropdown/index.js +14 -6
- package/dist/Dropdown/index.js.map +1 -1
- package/dist/Form/index.js +8 -8
- package/dist/Form/index.js.map +1 -1
- package/dist/Input/components/Input/index.js +5 -5
- package/dist/Input/components/Input/index.js.map +1 -1
- package/dist/Input/components/TextArea/index.js +2 -2
- package/dist/Input/components/TextArea/index.js.map +1 -1
- package/dist/InputNumber/index.js +1 -1
- package/dist/InputNumber/index.js.map +1 -1
- package/dist/Menu/index.js +9 -7
- package/dist/Menu/index.js.map +1 -1
- package/dist/Modal/index.d.ts +4 -1
- package/dist/Modal/index.js +63 -22
- package/dist/Modal/index.js.map +1 -1
- package/dist/Popconfirm/index.js +1 -1
- package/dist/Radio/components/Radio/index.js +2 -2
- package/dist/Radio/components/Radio/index.js.map +1 -1
- package/dist/Select/BaseSelect.js +1 -1
- package/dist/Select/BaseSelect.js.map +1 -1
- package/dist/Select/hooks/useOptions.js +4 -1
- package/dist/Select/hooks/useOptions.js.map +1 -1
- package/dist/Select/index.js +1 -1
- package/dist/Select/index.js.map +1 -1
- package/dist/Select/interface.d.ts +1 -0
- package/dist/Switch/index.js +1 -0
- package/dist/Switch/index.js.map +1 -1
- package/dist/Table/components/Cell.js +8 -3
- package/dist/Table/components/Cell.js.map +1 -1
- package/dist/Table/components/Footer/index.js +2 -1
- package/dist/Table/components/Footer/index.js.map +1 -1
- package/dist/Table/components/Header.js +1 -1
- package/dist/Table/components/Header.js.map +1 -1
- package/dist/Tabs/index.d.ts +1 -1
- package/dist/Tabs/index.js +85 -11
- package/dist/Tabs/index.js.map +1 -1
- package/dist/Tour/index.js +1 -1
- package/dist/Typography/index.js +5 -5
- package/dist/Typography/index.js.map +1 -1
- package/dist/_utils/floatingLayer.js +1 -1
- package/dist/_utils/overlayCoordinator.d.ts +14 -0
- package/dist/_utils/overlayCoordinator.js +151 -0
- package/dist/_utils/overlayCoordinator.js.map +1 -0
- package/dist/aloudata-design.css +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/theme/contract/tokenOutputContract.js +2 -45
- package/dist/theme/contract/tokenOutputContract.js.map +1 -1
- package/dist/theme/index.d.ts +2 -2
- package/dist/theme/typography/index.d.ts +75 -0
- package/dist/theme/typography/index.js +2 -0
- package/dist/theme/typography.d.ts +2 -0
- package/package.json +1 -1
package/dist/Menu/index.js
CHANGED
|
@@ -25,6 +25,7 @@ function Menu(props) {
|
|
|
25
25
|
const isSelected = selectedKeys?.includes(item.key);
|
|
26
26
|
if (isSubMenuItem(item)) {
|
|
27
27
|
const isLeafSubMenu = isLeafMenu(item.children);
|
|
28
|
+
const subMenuOverflow = isLeafSubMenu || menuStyle?.maxHeight !== void 0 ? "auto" : void 0;
|
|
28
29
|
return /* @__PURE__ */ jsx(SubMenu, {
|
|
29
30
|
label: /* @__PURE__ */ jsxs("div", {
|
|
30
31
|
className: "ald-menu-item-label",
|
|
@@ -35,7 +36,7 @@ function Menu(props) {
|
|
|
35
36
|
children: item.icon
|
|
36
37
|
}) : null,
|
|
37
38
|
/* @__PURE__ */ jsx("div", {
|
|
38
|
-
className: "ald-menu-item-label-text",
|
|
39
|
+
className: "ald-menu-item-label-text tw-text-typography-body-dense",
|
|
39
40
|
children: item.label
|
|
40
41
|
}),
|
|
41
42
|
/* @__PURE__ */ jsxs("div", {
|
|
@@ -52,8 +53,8 @@ function Menu(props) {
|
|
|
52
53
|
position: "anchor",
|
|
53
54
|
shift: 0,
|
|
54
55
|
menuStyle: { ...menuStyle },
|
|
55
|
-
menuClassName: cn("ald-menu-submenu-popup", isLeafSubMenu && "ald-menu-submenu-popup-leaf", item.popupClassName, rootClosing && "ald-menu-submenu-popup-root-closing"),
|
|
56
|
-
overflow:
|
|
56
|
+
menuClassName: cn("ald-menu-submenu-popup", isLeafSubMenu && "ald-menu-submenu-popup-leaf", !isLeafSubMenu && menuStyle?.maxHeight !== void 0 && "ald-menu-submenu-popup-scrollable", item.popupClassName, rootClosing && "ald-menu-submenu-popup-root-closing"),
|
|
57
|
+
overflow: subMenuOverflow,
|
|
57
58
|
children: getMenuItems(item.children, currPath)
|
|
58
59
|
}, item.key);
|
|
59
60
|
}
|
|
@@ -82,7 +83,7 @@ function Menu(props) {
|
|
|
82
83
|
children: item.icon
|
|
83
84
|
}) : null,
|
|
84
85
|
/* @__PURE__ */ jsx("div", {
|
|
85
|
-
className: "ald-menu-item-label-text",
|
|
86
|
+
className: "ald-menu-item-label-text tw-text-typography-body-dense",
|
|
86
87
|
children: item.label
|
|
87
88
|
}),
|
|
88
89
|
isSelectableGroup ? /* @__PURE__ */ jsx("div", {
|
|
@@ -98,7 +99,8 @@ function Menu(props) {
|
|
|
98
99
|
});
|
|
99
100
|
};
|
|
100
101
|
const ref = useRef(null);
|
|
101
|
-
const
|
|
102
|
+
const isLeafRootMenu = isLeafMenu(items);
|
|
103
|
+
const menuOverflow = isLeafRootMenu || menuStyle?.maxHeight !== void 0 ? "auto" : void 0;
|
|
102
104
|
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
|
|
103
105
|
style: { display: "none" },
|
|
104
106
|
ref
|
|
@@ -113,11 +115,11 @@ function Menu(props) {
|
|
|
113
115
|
submenuCloseDelay: 0,
|
|
114
116
|
menuStyle: { ...menuStyle },
|
|
115
117
|
anchorRef: ref,
|
|
116
|
-
className: cn(className, "ald-menu",
|
|
118
|
+
className: cn(className, "ald-menu", isLeafRootMenu && !externalOverflow && "ald-menu-leaf", !isLeafRootMenu && menuStyle?.maxHeight !== void 0 && !externalOverflow && "ald-menu-scrollable"),
|
|
117
119
|
position: externalOverflow ? "initial" : "auto",
|
|
118
120
|
captureFocus: false,
|
|
119
121
|
viewScroll: externalOverflow ? "initial" : "auto",
|
|
120
|
-
overflow: externalOverflow ? "visible" :
|
|
122
|
+
overflow: externalOverflow ? "visible" : menuOverflow,
|
|
121
123
|
children: getMenuItems(items || [])
|
|
122
124
|
})] });
|
|
123
125
|
}
|
package/dist/Menu/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Menu/index.tsx"],"sourcesContent":["import {\n ControlledMenu,\n MenuDivider,\n MenuHeader,\n MenuItem,\n SubMenu,\n} from '@szhsin/react-menu';\nimport { cn } from '../lib/utils';\nimport _ from 'lodash';\nimport React, { useRef } from 'react';\nimport { CheckLightLine, ChevronRightLine } from '../Icon';\nimport './menu.css';\n\nexport interface MenuProps {\n onClick?: (info: MenuInfo) => void;\n onBeforeLeafItemClick?: () => void;\n className?: string;\n items: MenuItemType[];\n selectedKeys?: string[];\n menuStyle?: React.CSSProperties;\n rootClosing?: boolean;\n /** @internal 由 Dropdown 注入,禁用内部定位/overflow 计算。不支持含 SubMenu 的菜单 */\n externalOverflow?: boolean;\n}\n\nexport default function Menu(props: MenuProps) {\n const {\n className,\n items,\n onClick: onMenuClick,\n onBeforeLeafItemClick,\n selectedKeys,\n menuStyle,\n rootClosing = false,\n externalOverflow,\n } = props;\n const selectedKeySet = new Set(selectedKeys || []);\n\n const hasDirectSelectedItem = (items: MenuItemType[]): boolean =>\n items.some((item) => {\n if (isSubMenuItem(item)) {\n return selectedKeySet.has(item.key);\n }\n if (isHeaderMenuItem(item) || isDivideMenuItem(item)) {\n return false;\n }\n return selectedKeySet.has(item.key);\n });\n\n const getMenuItems = (items: MenuItemType[], parentPath: string[] = []) => {\n const isSelectableGroup = hasDirectSelectedItem(items);\n\n return items.map((item, index) => {\n if (isDivideMenuItem(item)) {\n return <MenuDivider key={`divider_${index}`} />;\n }\n if (isHeaderMenuItem(item)) {\n return <MenuHeader key={`header_${index}`}>{item.label}</MenuHeader>;\n }\n const currPath = [...parentPath, item.key];\n const titleStr = _.isString(item.label) ? item.label : '';\n const isSelected = selectedKeys?.includes(item.key);\n\n if (isSubMenuItem(item)) {\n const isLeafSubMenu = isLeafMenu(item.children);\n const subMenuItemLabel = (\n <div className=\"ald-menu-item-label\" title={titleStr}>\n {item.icon ? (\n <div className=\"ald-menu-item-label-icon\">{item.icon}</div>\n ) : null}\n <div className=\"ald-menu-item-label-text\">{item.label}</div>\n <div className=\"ald-menu-item-right\">\n {isSelectableGroup ? (\n <div className=\"ald-menu-item-selection-slot\" />\n ) : null}\n <ChevronRightLine size={16} />\n </div>\n </div>\n );\n\n return (\n <SubMenu\n key={item.key}\n label={subMenuItemLabel}\n disabled={item.disabled}\n itemProps={{\n className: isLeafSubMenu\n ? 'ald-menu-submenu-leaf-trigger'\n : undefined,\n }}\n align=\"start\"\n direction=\"right\"\n gap={-8}\n position=\"anchor\"\n shift={0}\n menuStyle={{\n ...menuStyle,\n }}\n menuClassName={cn(\n 'ald-menu-submenu-popup',\n isLeafSubMenu && 'ald-menu-submenu-popup-leaf',\n item.popupClassName,\n rootClosing && 'ald-menu-submenu-popup-root-closing',\n )}\n overflow={isLeafSubMenu ? 'auto' : undefined}\n >\n {getMenuItems(item.children, currPath)}\n </SubMenu>\n );\n }\n\n return (\n <MenuItem\n key={item.key}\n className={cn(item.className, {\n 'ald-menu-item-danger': item.danger,\n 'ald-menu-item-selected': isSelected,\n })}\n disabled={item.disabled}\n onClick={({ syntheticEvent }) => {\n onBeforeLeafItemClick?.();\n const menuInfo = {\n key: item.key,\n keyPath: currPath,\n domEvent: syntheticEvent,\n };\n if (item.onClick) {\n item.onClick(menuInfo);\n }\n if (onMenuClick) {\n onMenuClick(menuInfo);\n }\n }}\n >\n <div className=\"ald-menu-item-label\" title={titleStr}>\n {item.icon ? (\n <div className=\"ald-menu-item-label-icon\">{item.icon}</div>\n ) : null}\n <div className=\"ald-menu-item-label-text\">{item.label}</div>\n {isSelectableGroup ? (\n <div className=\"ald-menu-item-right\">\n <div\n className={cn(\n 'ald-menu-item-selection-slot',\n isSelected &&\n 'ald-menu-item-selection-slot-selected ald-menu-item-selected-icon',\n )}\n >\n {isSelected ? <CheckLightLine /> : null}\n </div>\n </div>\n ) : null}\n </div>\n </MenuItem>\n );\n });\n };\n\n const ref = useRef(null);\n\n const leafOverflow = isLeafMenu(items) ? 'auto' : undefined;\n\n return (\n <>\n <div style={{ display: 'none' }} ref={ref} />\n <ControlledMenu\n state=\"open\"\n transition={{ open: true, close: true }}\n transitionTimeout={200}\n submenuOpenDelay={0}\n submenuCloseDelay={0}\n menuStyle={{\n ...menuStyle,\n }}\n anchorRef={ref}\n className={cn(\n className,\n 'ald-menu',\n leafOverflow && !externalOverflow && 'ald-menu-leaf',\n )}\n position={externalOverflow ? 'initial' : 'auto'}\n captureFocus={false}\n viewScroll={externalOverflow ? 'initial' : 'auto'}\n overflow={externalOverflow ? 'visible' : leafOverflow}\n >\n {getMenuItems(items || [])}\n </ControlledMenu>\n </>\n );\n}\n\nexport function isHeaderMenuItem(\n menuItem: MenuItemType,\n): menuItem is MenuHeaderType {\n return 'type' in menuItem && menuItem.type === 'header';\n}\n\nexport function isDivideMenuItem(\n menuItem: MenuItemType,\n): menuItem is MenuDividerType {\n return 'type' in menuItem && menuItem.type === 'divider';\n}\n\nexport function isSubMenuItem(menuItem: MenuItemType): menuItem is SubMenuType {\n return 'children' in menuItem && !!menuItem.children;\n}\n\nexport function isLeafMenu(menuItems: MenuItemType[]) {\n return !_.some(menuItems, (item) => isSubMenuItem(item));\n}\n\nexport type MenuItemType =\n | ItemType\n | MenuDividerType\n | SubMenuType\n | MenuHeaderType;\n\nexport interface ItemType {\n key: string;\n label: React.ReactNode;\n icon?: React.ReactNode;\n onClick?: (info: MenuInfo) => void;\n danger?: boolean;\n disabled?: boolean;\n className?: string;\n}\n\nexport interface MenuDividerType {\n key?: string;\n type: 'divider';\n}\n\nexport interface MenuHeaderType {\n key?: string;\n type: 'header';\n label: string;\n}\n\nexport interface SubMenuType {\n children: MenuItemType[];\n key: string;\n label: React.ReactNode;\n icon?: React.ReactNode;\n popupClassName?: string;\n disabled?: boolean;\n}\n\nexport interface MenuInfo {\n key: string;\n keyPath: string[];\n domEvent: MouseEvent | KeyboardEvent;\n // 阻止菜单关闭\n keepOpen?: boolean;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Menu/index.tsx"],"sourcesContent":["import {\n ControlledMenu,\n MenuDivider,\n MenuHeader,\n MenuItem,\n SubMenu,\n} from '@szhsin/react-menu';\nimport { cn } from '../lib/utils';\nimport _ from 'lodash';\nimport React, { useRef } from 'react';\nimport { CheckLightLine, ChevronRightLine } from '../Icon';\nimport './menu.css';\n\nexport interface MenuProps {\n onClick?: (info: MenuInfo) => void;\n onBeforeLeafItemClick?: () => void;\n className?: string;\n items: MenuItemType[];\n selectedKeys?: string[];\n menuStyle?: React.CSSProperties;\n rootClosing?: boolean;\n /** @internal 由 Dropdown 注入,禁用内部定位/overflow 计算。不支持含 SubMenu 的菜单 */\n externalOverflow?: boolean;\n}\n\nexport default function Menu(props: MenuProps) {\n const {\n className,\n items,\n onClick: onMenuClick,\n onBeforeLeafItemClick,\n selectedKeys,\n menuStyle,\n rootClosing = false,\n externalOverflow,\n } = props;\n const selectedKeySet = new Set(selectedKeys || []);\n\n const hasDirectSelectedItem = (items: MenuItemType[]): boolean =>\n items.some((item) => {\n if (isSubMenuItem(item)) {\n return selectedKeySet.has(item.key);\n }\n if (isHeaderMenuItem(item) || isDivideMenuItem(item)) {\n return false;\n }\n return selectedKeySet.has(item.key);\n });\n\n const getMenuItems = (items: MenuItemType[], parentPath: string[] = []) => {\n const isSelectableGroup = hasDirectSelectedItem(items);\n\n return items.map((item, index) => {\n if (isDivideMenuItem(item)) {\n return <MenuDivider key={`divider_${index}`} />;\n }\n if (isHeaderMenuItem(item)) {\n return <MenuHeader key={`header_${index}`}>{item.label}</MenuHeader>;\n }\n const currPath = [...parentPath, item.key];\n const titleStr = _.isString(item.label) ? item.label : '';\n const isSelected = selectedKeys?.includes(item.key);\n\n if (isSubMenuItem(item)) {\n const isLeafSubMenu = isLeafMenu(item.children);\n const subMenuOverflow =\n isLeafSubMenu || menuStyle?.maxHeight !== undefined\n ? 'auto'\n : undefined;\n const subMenuItemLabel = (\n <div className=\"ald-menu-item-label\" title={titleStr}>\n {item.icon ? (\n <div className=\"ald-menu-item-label-icon\">{item.icon}</div>\n ) : null}\n <div className=\"ald-menu-item-label-text tw-text-typography-body-dense\">\n {item.label}\n </div>\n <div className=\"ald-menu-item-right\">\n {isSelectableGroup ? (\n <div className=\"ald-menu-item-selection-slot\" />\n ) : null}\n <ChevronRightLine size={16} />\n </div>\n </div>\n );\n\n return (\n <SubMenu\n key={item.key}\n label={subMenuItemLabel}\n disabled={item.disabled}\n itemProps={{\n className: isLeafSubMenu\n ? 'ald-menu-submenu-leaf-trigger'\n : undefined,\n }}\n align=\"start\"\n direction=\"right\"\n gap={-8}\n position=\"anchor\"\n shift={0}\n menuStyle={{\n ...menuStyle,\n }}\n menuClassName={cn(\n 'ald-menu-submenu-popup',\n isLeafSubMenu && 'ald-menu-submenu-popup-leaf',\n !isLeafSubMenu &&\n menuStyle?.maxHeight !== undefined &&\n 'ald-menu-submenu-popup-scrollable',\n item.popupClassName,\n rootClosing && 'ald-menu-submenu-popup-root-closing',\n )}\n overflow={subMenuOverflow}\n >\n {getMenuItems(item.children, currPath)}\n </SubMenu>\n );\n }\n\n return (\n <MenuItem\n key={item.key}\n className={cn(item.className, {\n 'ald-menu-item-danger': item.danger,\n 'ald-menu-item-selected': isSelected,\n })}\n disabled={item.disabled}\n onClick={({ syntheticEvent }) => {\n onBeforeLeafItemClick?.();\n const menuInfo = {\n key: item.key,\n keyPath: currPath,\n domEvent: syntheticEvent,\n };\n if (item.onClick) {\n item.onClick(menuInfo);\n }\n if (onMenuClick) {\n onMenuClick(menuInfo);\n }\n }}\n >\n <div className=\"ald-menu-item-label\" title={titleStr}>\n {item.icon ? (\n <div className=\"ald-menu-item-label-icon\">{item.icon}</div>\n ) : null}\n <div className=\"ald-menu-item-label-text tw-text-typography-body-dense\">\n {item.label}\n </div>\n {isSelectableGroup ? (\n <div className=\"ald-menu-item-right\">\n <div\n className={cn(\n 'ald-menu-item-selection-slot',\n isSelected &&\n 'ald-menu-item-selection-slot-selected ald-menu-item-selected-icon',\n )}\n >\n {isSelected ? <CheckLightLine /> : null}\n </div>\n </div>\n ) : null}\n </div>\n </MenuItem>\n );\n });\n };\n\n const ref = useRef(null);\n\n const isLeafRootMenu = isLeafMenu(items);\n const menuOverflow =\n isLeafRootMenu || menuStyle?.maxHeight !== undefined ? 'auto' : undefined;\n\n return (\n <>\n <div style={{ display: 'none' }} ref={ref} />\n <ControlledMenu\n state=\"open\"\n transition={{ open: true, close: true }}\n transitionTimeout={200}\n submenuOpenDelay={0}\n submenuCloseDelay={0}\n menuStyle={{\n ...menuStyle,\n }}\n anchorRef={ref}\n className={cn(\n className,\n 'ald-menu',\n isLeafRootMenu && !externalOverflow && 'ald-menu-leaf',\n !isLeafRootMenu &&\n menuStyle?.maxHeight !== undefined &&\n !externalOverflow &&\n 'ald-menu-scrollable',\n )}\n position={externalOverflow ? 'initial' : 'auto'}\n captureFocus={false}\n viewScroll={externalOverflow ? 'initial' : 'auto'}\n overflow={externalOverflow ? 'visible' : menuOverflow}\n >\n {getMenuItems(items || [])}\n </ControlledMenu>\n </>\n );\n}\n\nexport function isHeaderMenuItem(\n menuItem: MenuItemType,\n): menuItem is MenuHeaderType {\n return 'type' in menuItem && menuItem.type === 'header';\n}\n\nexport function isDivideMenuItem(\n menuItem: MenuItemType,\n): menuItem is MenuDividerType {\n return 'type' in menuItem && menuItem.type === 'divider';\n}\n\nexport function isSubMenuItem(menuItem: MenuItemType): menuItem is SubMenuType {\n return 'children' in menuItem && !!menuItem.children;\n}\n\nexport function isLeafMenu(menuItems: MenuItemType[]) {\n return !_.some(menuItems, (item) => isSubMenuItem(item));\n}\n\nexport type MenuItemType =\n | ItemType\n | MenuDividerType\n | SubMenuType\n | MenuHeaderType;\n\nexport interface ItemType {\n key: string;\n label: React.ReactNode;\n icon?: React.ReactNode;\n onClick?: (info: MenuInfo) => void;\n danger?: boolean;\n disabled?: boolean;\n className?: string;\n}\n\nexport interface MenuDividerType {\n key?: string;\n type: 'divider';\n}\n\nexport interface MenuHeaderType {\n key?: string;\n type: 'header';\n label: string;\n}\n\nexport interface SubMenuType {\n children: MenuItemType[];\n key: string;\n label: React.ReactNode;\n icon?: React.ReactNode;\n popupClassName?: string;\n disabled?: boolean;\n}\n\nexport interface MenuInfo {\n key: string;\n keyPath: string[];\n domEvent: MouseEvent | KeyboardEvent;\n // 阻止菜单关闭\n keepOpen?: boolean;\n}\n"],"mappings":";;;;;;;;;AAyBA,SAAwB,KAAK,OAAkB;CAC7C,MAAM,EACJ,WACA,OACA,SAAS,aACT,uBACA,cACA,WACA,cAAc,OACd,qBACE;CACJ,MAAM,iBAAiB,IAAI,IAAI,gBAAgB,EAAE,CAAC;CAElD,MAAM,yBAAyB,UAC7B,MAAM,MAAM,SAAS;AACnB,MAAI,cAAc,KAAK,CACrB,QAAO,eAAe,IAAI,KAAK,IAAI;AAErC,MAAI,iBAAiB,KAAK,IAAI,iBAAiB,KAAK,CAClD,QAAO;AAET,SAAO,eAAe,IAAI,KAAK,IAAI;GACnC;CAEJ,MAAM,gBAAgB,OAAuB,aAAuB,EAAE,KAAK;EACzE,MAAM,oBAAoB,sBAAsB,MAAM;AAEtD,SAAO,MAAM,KAAK,MAAM,UAAU;AAChC,OAAI,iBAAiB,KAAK,CACxB,QAAO,oBAAC,aAAD,EAAwC,EAAtB,WAAW,QAAW;AAEjD,OAAI,iBAAiB,KAAK,CACxB,QAAO,oBAAC,YAAD,EAAA,UAAqC,KAAK,OAAmB,EAA5C,UAAU,QAAkC;GAEtE,MAAM,WAAW,CAAC,GAAG,YAAY,KAAK,IAAI;GAC1C,MAAM,WAAW,EAAE,SAAS,KAAK,MAAM,GAAG,KAAK,QAAQ;GACvD,MAAM,aAAa,cAAc,SAAS,KAAK,IAAI;AAEnD,OAAI,cAAc,KAAK,EAAE;IACvB,MAAM,gBAAgB,WAAW,KAAK,SAAS;IAC/C,MAAM,kBACJ,iBAAiB,WAAW,cAAc,SACtC,SACA;AAkBN,WACE,oBAAC,SAAD;KAEE,OAnBF,qBAAC,OAAD;MAAK,WAAU;MAAsB,OAAO;gBAA5C;OACG,KAAK,OACJ,oBAAC,OAAD;QAAK,WAAU;kBAA4B,KAAK;QAAW,CAAA,GACzD;OACJ,oBAAC,OAAD;QAAK,WAAU;kBACZ,KAAK;QACF,CAAA;OACN,qBAAC,OAAD;QAAK,WAAU;kBAAf,CACG,oBACC,oBAAC,OAAD,EAAK,WAAU,gCAAiC,CAAA,GAC9C,MACJ,oBAAC,QAAD,EAAkB,MAAM,IAAM,CAAA,CAC1B;;OACF;;KAOJ,UAAU,KAAK;KACf,WAAW,EACT,WAAW,gBACP,kCACA,QACL;KACD,OAAM;KACN,WAAU;KACV,KAAK;KACL,UAAS;KACT,OAAO;KACP,WAAW,EACT,GAAG,WACJ;KACD,eAAe,GACb,0BACA,iBAAiB,+BACjB,CAAC,iBACC,WAAW,cAAc,UACzB,qCACF,KAAK,gBACL,eAAe,sCAChB;KACD,UAAU;eAET,aAAa,KAAK,UAAU,SAAS;KAC9B,EA5BH,KAAK,IA4BF;;AAId,UACE,oBAAC,UAAD;IAEE,WAAW,GAAG,KAAK,WAAW;KAC5B,wBAAwB,KAAK;KAC7B,0BAA0B;KAC3B,CAAC;IACF,UAAU,KAAK;IACf,UAAU,EAAE,qBAAqB;AAC/B,8BAAyB;KACzB,MAAM,WAAW;MACf,KAAK,KAAK;MACV,SAAS;MACT,UAAU;MACX;AACD,SAAI,KAAK,QACP,MAAK,QAAQ,SAAS;AAExB,SAAI,YACF,aAAY,SAAS;;cAIzB,qBAAC,OAAD;KAAK,WAAU;KAAsB,OAAO;eAA5C;MACG,KAAK,OACJ,oBAAC,OAAD;OAAK,WAAU;iBAA4B,KAAK;OAAW,CAAA,GACzD;MACJ,oBAAC,OAAD;OAAK,WAAU;iBACZ,KAAK;OACF,CAAA;MACL,oBACC,oBAAC,OAAD;OAAK,WAAU;iBACb,oBAAC,OAAD;QACE,WAAW,GACT,gCACA,cACE,oEACH;kBAEA,aAAa,oBAAC,MAAD,EAAkB,CAAA,GAAG;QAC/B,CAAA;OACF,CAAA,GACJ;MACA;;IACG,EA1CJ,KAAK,IA0CD;IAEb;;CAGJ,MAAM,MAAM,OAAO,KAAK;CAExB,MAAM,iBAAiB,WAAW,MAAM;CACxC,MAAM,eACJ,kBAAkB,WAAW,cAAc,SAAY,SAAS;AAElE,QACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,OAAD;EAAK,OAAO,EAAE,SAAS,QAAQ;EAAO;EAAO,CAAA,EAC7C,oBAAC,gBAAD;EACE,OAAM;EACN,YAAY;GAAE,MAAM;GAAM,OAAO;GAAM;EACvC,mBAAmB;EACnB,kBAAkB;EAClB,mBAAmB;EACnB,WAAW,EACT,GAAG,WACJ;EACD,WAAW;EACX,WAAW,GACT,WACA,YACA,kBAAkB,CAAC,oBAAoB,iBACvC,CAAC,kBACC,WAAW,cAAc,UACzB,CAAC,oBACD,sBACH;EACD,UAAU,mBAAmB,YAAY;EACzC,cAAc;EACd,YAAY,mBAAmB,YAAY;EAC3C,UAAU,mBAAmB,YAAY;YAExC,aAAa,SAAS,EAAE,CAAC;EACX,CAAA,CAChB,EAAA,CAAA;;AAIP,SAAgB,iBACd,UAC4B;AAC5B,QAAO,UAAU,YAAY,SAAS,SAAS;;AAGjD,SAAgB,iBACd,UAC6B;AAC7B,QAAO,UAAU,YAAY,SAAS,SAAS;;AAGjD,SAAgB,cAAc,UAAiD;AAC7E,QAAO,cAAc,YAAY,CAAC,CAAC,SAAS;;AAG9C,SAAgB,WAAW,WAA2B;AACpD,QAAO,CAAC,EAAE,KAAK,YAAY,SAAS,cAAc,KAAK,CAAC"}
|
package/dist/Modal/index.d.ts
CHANGED
|
@@ -44,6 +44,9 @@ export interface ModalProps {
|
|
|
44
44
|
/** @internal used by static methods to pass modal type for icon styling */
|
|
45
45
|
_modalType?: string;
|
|
46
46
|
}
|
|
47
|
+
interface OriginModalProps extends ModalProps {
|
|
48
|
+
onTopChange?: (isTop: boolean) => void;
|
|
49
|
+
}
|
|
47
50
|
export interface ModalFuncProps {
|
|
48
51
|
title?: React.ReactNode;
|
|
49
52
|
subTitle?: React.ReactNode;
|
|
@@ -65,7 +68,7 @@ export interface ModalFuncProps {
|
|
|
65
68
|
centered?: boolean;
|
|
66
69
|
maskClosable?: boolean;
|
|
67
70
|
}
|
|
68
|
-
declare function OriginModal(props:
|
|
71
|
+
declare function OriginModal(props: OriginModalProps): import("react/jsx-runtime").JSX.Element;
|
|
69
72
|
type ModalFunc = (props: ModalFuncProps) => {
|
|
70
73
|
destroy: () => void;
|
|
71
74
|
update: (props: Partial<ModalFuncProps>) => void;
|
package/dist/Modal/index.js
CHANGED
|
@@ -3,12 +3,13 @@ import Memo from "../Icon/components/AttentionTriangleLightLine.js";
|
|
|
3
3
|
import Memo$1 from "../Icon/components/CheckCircleLightLine.js";
|
|
4
4
|
import Memo$2 from "../Icon/components/CloseLLine.js";
|
|
5
5
|
import Memo$3 from "../Icon/components/InformationCircleLightLine.js";
|
|
6
|
+
import { FLOATING_LAYER_BASE_Z_INDEX, FloatingLayerProvider } from "../_utils/floatingLayer.js";
|
|
7
|
+
import { ModalLayerProvider, useModalLayer } from "../_utils/overlayCoordinator.js";
|
|
6
8
|
import Button_default from "../Button/index.js";
|
|
7
|
-
import { FloatingLayerProvider, useFloatingLayer } from "../_utils/floatingLayer.js";
|
|
8
9
|
import { LocaleContext, getTranslator } from "../locale/default.js";
|
|
9
10
|
import IconButton from "../IconButton/index.js";
|
|
10
11
|
import ScrollArea_default from "../ScrollArea/index.js";
|
|
11
|
-
import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
12
|
+
import { useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
12
13
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
13
14
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
14
15
|
import { hideOthers } from "aria-hidden";
|
|
@@ -16,6 +17,19 @@ import { createRoot } from "react-dom/client";
|
|
|
16
17
|
//#region src/Modal/index.tsx
|
|
17
18
|
var destroyFns = [];
|
|
18
19
|
var DEFAULT_WIDTH = 552;
|
|
20
|
+
var modalEscapeEvents = /* @__PURE__ */ new WeakSet();
|
|
21
|
+
function shouldCancelTopModal(event) {
|
|
22
|
+
return !event.cancelBubble && (!event.defaultPrevented || modalEscapeEvents.has(event));
|
|
23
|
+
}
|
|
24
|
+
function ModalContentProviders({ layerId, floatingLevel, children }) {
|
|
25
|
+
return /* @__PURE__ */ jsx(ModalLayerProvider, {
|
|
26
|
+
id: layerId,
|
|
27
|
+
children: /* @__PURE__ */ jsx(FloatingLayerProvider, {
|
|
28
|
+
value: floatingLevel,
|
|
29
|
+
children
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
}
|
|
19
33
|
var ModalTitle = ({ icon, title, subTitle }, type) => /* @__PURE__ */ jsxs("div", {
|
|
20
34
|
className: "ald-modal-title-container tw-flex tw-items-center tw-gap-4",
|
|
21
35
|
children: [icon && /* @__PURE__ */ jsx("div", {
|
|
@@ -55,9 +69,14 @@ function getIcon(type) {
|
|
|
55
69
|
function OriginModal(props) {
|
|
56
70
|
const { locale } = useContext(LocaleContext);
|
|
57
71
|
const t = getTranslator(locale);
|
|
58
|
-
const { className, "data-testid": dataTestId, "aria-label": ariaLabel, children, okType = "primary", width, closeIcon, subTitle, okButtonProps = {}, cancelButtonProps = {}, okText = t.Modal.sure, cancelText = t.Modal.cancel, icon, title, paddingLess, responsiveBounds, hideHeaderBottomBorder, virtualScrollBar, style, maskClosable = false, fullscreen, open = false, onOk, onCancel, footer, confirmLoading, closable = true, zIndex = 1e3, bodyStyle, keyboard = true, afterOpenChange, wrapClassName, _modalType } = props;
|
|
72
|
+
const { className, "data-testid": dataTestId, "aria-label": ariaLabel, children, okType = "primary", width, closeIcon, subTitle, okButtonProps = {}, cancelButtonProps = {}, okText = t.Modal.sure, cancelText = t.Modal.cancel, icon, title, paddingLess, responsiveBounds, hideHeaderBottomBorder, virtualScrollBar, style, maskClosable = false, fullscreen, open = false, onOk, onCancel, footer, confirmLoading, closable = true, zIndex = 1e3, bodyStyle, keyboard = true, afterOpenChange, wrapClassName, _modalType, onTopChange } = props;
|
|
59
73
|
const prevOpenRef = useRef(open);
|
|
60
74
|
const contentRef = useRef(null);
|
|
75
|
+
const { id: modalLayerId, maskZIndex, contentZIndex, isTop } = useModalLayer(open, zIndex);
|
|
76
|
+
const nextFloatingLevel = (maskZIndex - FLOATING_LAYER_BASE_Z_INDEX) / 10 + 1;
|
|
77
|
+
useLayoutEffect(() => {
|
|
78
|
+
onTopChange?.(isTop);
|
|
79
|
+
}, [isTop, onTopChange]);
|
|
61
80
|
useEffect(() => {
|
|
62
81
|
if (prevOpenRef.current !== open) {
|
|
63
82
|
prevOpenRef.current = open;
|
|
@@ -65,19 +84,11 @@ function OriginModal(props) {
|
|
|
65
84
|
}
|
|
66
85
|
}, [open, afterOpenChange]);
|
|
67
86
|
useEffect(() => {
|
|
68
|
-
if (!open) return;
|
|
69
|
-
const prev = document.body.style.overflow;
|
|
70
|
-
document.body.style.overflow = "hidden";
|
|
71
|
-
return () => {
|
|
72
|
-
document.body.style.overflow = prev;
|
|
73
|
-
};
|
|
74
|
-
}, [open]);
|
|
75
|
-
useEffect(() => {
|
|
76
|
-
if (!open || !contentRef.current) return;
|
|
87
|
+
if (!open || !isTop || !contentRef.current) return;
|
|
77
88
|
return hideOthers(contentRef.current);
|
|
78
|
-
}, [open]);
|
|
89
|
+
}, [isTop, open]);
|
|
79
90
|
useEffect(() => {
|
|
80
|
-
if (!open || !contentRef.current) return;
|
|
91
|
+
if (!open || !isTop || !contentRef.current) return;
|
|
81
92
|
const container = contentRef.current;
|
|
82
93
|
const handleKeyDown = (e) => {
|
|
83
94
|
if (e.key !== "Tab") return;
|
|
@@ -97,7 +108,23 @@ function OriginModal(props) {
|
|
|
97
108
|
};
|
|
98
109
|
document.addEventListener("keydown", handleKeyDown);
|
|
99
110
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
100
|
-
}, [open]);
|
|
111
|
+
}, [isTop, open]);
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (!open || !isTop || !keyboard) return;
|
|
114
|
+
const handleEscape = (event) => {
|
|
115
|
+
if (event.key !== "Escape") return;
|
|
116
|
+
queueMicrotask(() => {
|
|
117
|
+
if (shouldCancelTopModal(event)) onCancel?.({});
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
window.addEventListener("keydown", handleEscape, true);
|
|
121
|
+
return () => window.removeEventListener("keydown", handleEscape, true);
|
|
122
|
+
}, [
|
|
123
|
+
isTop,
|
|
124
|
+
keyboard,
|
|
125
|
+
onCancel,
|
|
126
|
+
open
|
|
127
|
+
]);
|
|
101
128
|
const responsiveBoundsStyle = useMemo(() => {
|
|
102
129
|
if (!responsiveBounds) return {};
|
|
103
130
|
return {
|
|
@@ -113,7 +140,6 @@ function OriginModal(props) {
|
|
|
113
140
|
loading: confirmLoading,
|
|
114
141
|
...okButtonProps
|
|
115
142
|
};
|
|
116
|
-
const { maskZIndex, contentZIndex, nextLevel } = useFloatingLayer(zIndex);
|
|
117
143
|
const renderFooter = () => {
|
|
118
144
|
if (footer === null) return null;
|
|
119
145
|
if (footer) return /* @__PURE__ */ jsx("div", {
|
|
@@ -140,7 +166,7 @@ function OriginModal(props) {
|
|
|
140
166
|
return /* @__PURE__ */ jsx(DialogPrimitive.Root, {
|
|
141
167
|
open,
|
|
142
168
|
modal: false,
|
|
143
|
-
children: /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [/* @__PURE__ */ jsx("div", {
|
|
169
|
+
children: /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [isTop && /* @__PURE__ */ jsx("div", {
|
|
144
170
|
className: "ald-modal-mask tw-animate-in tw-fade-in-0 tw-fixed tw-inset-0 tw-bg-[var(--background-inverted)] tw-opacity-45",
|
|
145
171
|
style: { zIndex: maskZIndex },
|
|
146
172
|
onPointerDown: () => {
|
|
@@ -148,6 +174,8 @@ function OriginModal(props) {
|
|
|
148
174
|
}
|
|
149
175
|
}), /* @__PURE__ */ jsx("div", {
|
|
150
176
|
ref: contentRef,
|
|
177
|
+
...!isTop ? { inert: "" } : {},
|
|
178
|
+
"aria-hidden": !isTop || void 0,
|
|
151
179
|
className: cn("ald-modal-wrap ant-modal-wrap tw-pointer-events-none tw-fixed tw-inset-0 tw-flex tw-items-center tw-justify-center", wrapClassName),
|
|
152
180
|
style: { zIndex: contentZIndex },
|
|
153
181
|
children: /* @__PURE__ */ jsx(DialogPrimitive.Content, {
|
|
@@ -161,9 +189,9 @@ function OriginModal(props) {
|
|
|
161
189
|
},
|
|
162
190
|
...style
|
|
163
191
|
},
|
|
164
|
-
onEscapeKeyDown: (
|
|
165
|
-
if (
|
|
166
|
-
|
|
192
|
+
onEscapeKeyDown: (event) => {
|
|
193
|
+
if (!event.defaultPrevented) modalEscapeEvents.add(event);
|
|
194
|
+
event.preventDefault();
|
|
167
195
|
},
|
|
168
196
|
onPointerDownOutside: (e) => {
|
|
169
197
|
if (maskClosable) onCancel?.({});
|
|
@@ -174,8 +202,9 @@ function OriginModal(props) {
|
|
|
174
202
|
},
|
|
175
203
|
children: /* @__PURE__ */ jsx("div", {
|
|
176
204
|
className: "ant-modal-content tw-flex tw-h-full tw-flex-col",
|
|
177
|
-
children: /* @__PURE__ */ jsxs(
|
|
178
|
-
|
|
205
|
+
children: /* @__PURE__ */ jsxs(ModalContentProviders, {
|
|
206
|
+
layerId: modalLayerId,
|
|
207
|
+
floatingLevel: nextFloatingLevel,
|
|
179
208
|
children: [
|
|
180
209
|
!fullscreen && /* @__PURE__ */ jsxs("div", {
|
|
181
210
|
className: cn("ald-modal-header ant-modal-header tw-flex tw-items-start tw-justify-between tw-bg-[var(--background-default)] tw-px-6 tw-py-4", !hideHeaderBottomBorder && "tw-border-b tw-border-solid tw-border-[var(--border-default)]"),
|
|
@@ -223,15 +252,24 @@ function OriginModal(props) {
|
|
|
223
252
|
});
|
|
224
253
|
}
|
|
225
254
|
function createStaticModal(type, props) {
|
|
255
|
+
const focusTarget = document.activeElement;
|
|
226
256
|
const container = document.createElement("div");
|
|
227
257
|
document.body.appendChild(container);
|
|
228
258
|
const root = createRoot(container);
|
|
229
259
|
let currentProps = { ...props };
|
|
260
|
+
let destroyed = false;
|
|
261
|
+
let isTop = true;
|
|
230
262
|
const destroy = () => {
|
|
263
|
+
if (destroyed) return;
|
|
264
|
+
destroyed = true;
|
|
265
|
+
const shouldRestoreFocus = isTop;
|
|
231
266
|
root.unmount();
|
|
232
267
|
container.remove();
|
|
233
268
|
const idx = destroyFns.indexOf(destroy);
|
|
234
269
|
if (idx >= 0) destroyFns.splice(idx, 1);
|
|
270
|
+
queueMicrotask(() => {
|
|
271
|
+
if (shouldRestoreFocus && focusTarget?.isConnected) focusTarget.focus();
|
|
272
|
+
});
|
|
235
273
|
};
|
|
236
274
|
const update = (newProps) => {
|
|
237
275
|
currentProps = {
|
|
@@ -267,6 +305,9 @@ function createStaticModal(type, props) {
|
|
|
267
305
|
closable: p.closable,
|
|
268
306
|
maskClosable: p.maskClosable,
|
|
269
307
|
_modalType: type,
|
|
308
|
+
onTopChange: (nextIsTop) => {
|
|
309
|
+
isTop = nextIsTop;
|
|
310
|
+
},
|
|
270
311
|
footer: isConfirm ? void 0 : /* @__PURE__ */ jsx(Button_default, {
|
|
271
312
|
type: "primary",
|
|
272
313
|
size: "middle",
|
package/dist/Modal/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Modal/index.tsx"],"sourcesContent":["import * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { hideOthers } from 'aria-hidden';\nimport React, {\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { createRoot } from 'react-dom/client';\nimport Button, { ButtonType, IButtonProps } from '../Button';\nimport {\n AttentionTriangleLightLine,\n CheckCircleLightLine,\n CloseLLine,\n InformationCircleLightLine,\n} from '../Icon';\nimport IconButton from '../IconButton';\nimport ScrollArea from '../ScrollArea';\nimport {\n FloatingLayerProvider,\n useFloatingLayer,\n} from '../_utils/floatingLayer';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport { cn } from '../lib/utils';\n\nexport const destroyFns: Array<() => void> = [];\n\nexport interface ModalProps {\n open?: boolean;\n onOk?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n onCancel?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n afterClose?: () => void;\n title?: React.ReactNode;\n subTitle?: React.ReactNode;\n icon?: React.ReactElement;\n width?: number | string;\n footer?: React.ReactNode | null;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n confirmLoading?: boolean;\n maskClosable?: boolean;\n closable?: boolean;\n closeIcon?: React.ReactNode;\n centered?: boolean;\n destroyOnClose?: boolean;\n className?: string;\n /** Pass through to the modal content root for automated testing. */\n 'data-testid'?: string;\n /** Pass through to the modal content root for accessibility and automated testing. */\n 'aria-label'?: string;\n /** Applied to the outer wrap layer (matches antd wrapClassName behavior) */\n wrapClassName?: string;\n style?: React.CSSProperties;\n bodyStyle?: React.CSSProperties;\n zIndex?: number;\n children?: React.ReactNode;\n paddingLess?: boolean;\n virtualScrollBar?: boolean;\n hideHeaderBottomBorder?: boolean;\n responsiveBounds?: boolean;\n fullscreen?: boolean;\n keyboard?: boolean;\n afterOpenChange?: (open: boolean) => void;\n getContainer?: (() => HTMLElement) | false;\n /** @internal used by static methods to pass modal type for icon styling */\n _modalType?: string;\n}\n\nexport interface ModalFuncProps {\n title?: React.ReactNode;\n subTitle?: React.ReactNode;\n content?: React.ReactNode;\n icon?: React.ReactElement;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n onOk?: (...args: any[]) => any;\n onCancel?: (...args: any[]) => any;\n width?: number | string;\n className?: string;\n /** @deprecated Use `className` instead. Preserved for antd v4 compat. */\n wrapClassName?: string;\n closable?: boolean;\n type?: 'info' | 'success' | 'error' | 'warn' | 'warning' | 'confirm';\n centered?: boolean;\n maskClosable?: boolean;\n}\n\nconst DEFAULT_WIDTH = 552;\n\nconst ModalTitle = (\n { icon, title, subTitle }: Pick<ModalProps, 'icon' | 'title' | 'subTitle'>,\n type?: string,\n) => (\n <div className=\"ald-modal-title-container tw-flex tw-items-center tw-gap-4\">\n {icon && (\n <div\n className={cn(\n 'ald-modal-icon-container tw-grid tw-size-10 tw-shrink-0 tw-place-items-center tw-rounded-[var(--global-grid-250)]',\n type === 'info' &&\n 'ald-modal-cion-info-container tw-bg-[var(--background-informative-muted)]',\n type === 'success' &&\n 'ald-modal-cion-success-container tw-bg-[var(--background-positive-muted)]',\n type === 'warning' &&\n 'ald-modal-cion-warning-container tw-bg-[var(--background-warning-muted)]',\n type === 'warn' &&\n 'ald-modal-cion-warning-container tw-bg-[var(--background-warning-muted)]',\n type === 'error' &&\n 'ald-modal-cion-error-container tw-bg-[var(--background-negative-muted)]',\n type === 'confirm' &&\n 'ald-modal-cion-confirm-container tw-bg-[var(--background-brand-muted)]',\n )}\n >\n {icon}\n </div>\n )}\n <div className=\"ald-modal-text-container\">\n {title && (\n <div\n className={cn(\n 'ald-modal-text-title tw-text-lg tw-font-semibold tw-leading-7 tw-text-[var(--content-primary)]',\n !subTitle && 'ald-modal-text-title-only tw-text-xl',\n )}\n >\n {title}\n </div>\n )}\n {subTitle && (\n <div className=\"ald-modal-text-sub-title tw-mt-1 tw-text-xs tw-leading-4 tw-text-[var(--content-secondary)]\">\n {subTitle}\n </div>\n )}\n </div>\n </div>\n);\n\nfunction getIcon(\n type: 'info' | 'success' | 'error' | 'warn' | 'warning' | 'confirm',\n) {\n if (type === 'success')\n return (\n <CheckCircleLightLine\n fill=\"var(--content-inverted-primary)\"\n color=\"var(--background-positive-strong)\"\n size={24}\n />\n );\n if (type === 'error')\n return (\n <AttentionTriangleLightLine\n color=\"var(--background-negative-strong)\"\n fill=\"var(--content-inverted-primary)\"\n size={24}\n />\n );\n if (type === 'warning' || type === 'warn')\n return (\n <AttentionTriangleLightLine\n color=\"var(--background-warning-strong)\"\n size={24}\n />\n );\n return (\n <InformationCircleLightLine\n size={24}\n color=\"var(--action-primary-normal)\"\n />\n );\n}\n\nfunction OriginModal(props: ModalProps) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n const {\n className,\n 'data-testid': dataTestId,\n 'aria-label': ariaLabel,\n children,\n okType = 'primary',\n width,\n closeIcon,\n subTitle,\n okButtonProps = {},\n cancelButtonProps = {},\n okText = t.Modal.sure,\n cancelText = t.Modal.cancel,\n icon,\n title,\n paddingLess,\n responsiveBounds,\n hideHeaderBottomBorder,\n virtualScrollBar,\n style,\n maskClosable = false,\n fullscreen,\n open = false,\n onOk,\n onCancel,\n footer,\n confirmLoading,\n closable = true,\n zIndex = 1000,\n bodyStyle,\n keyboard = true,\n afterOpenChange,\n wrapClassName,\n _modalType,\n } = props;\n\n const prevOpenRef = useRef(open);\n const contentRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (prevOpenRef.current !== open) {\n prevOpenRef.current = open;\n afterOpenChange?.(open);\n }\n }, [open, afterOpenChange]);\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 焦点循环 ----\n useEffect(() => {\n if (!open || !contentRef.current) return;\n const container = contentRef.current;\n\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\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\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [open]);\n\n const responsiveBoundsStyle = useMemo(() => {\n if (!responsiveBounds) return {};\n return {\n width: 'calc(100% - 160px)',\n maxWidth: '1680px',\n minWidth: '1280px',\n height: 'calc(100% - 48px)',\n maxHeight: '900px',\n minHeight: '640px',\n };\n }, [responsiveBounds]);\n\n const mergedOkProps = { loading: confirmLoading, ...okButtonProps };\n const { maskZIndex, contentZIndex, nextLevel } = useFloatingLayer(zIndex);\n\n const renderFooter = () => {\n if (footer === null) return null;\n if (footer)\n return (\n // antd 兼容:antd .ant-modal-footer 使用 text-align:right 让 inline 按钮右对齐,\n // 即使消费方传入 width:100% 的子容器,内部 inline 元素仍能右对齐。\n // 此处同时使用 tw-flex tw-justify-end(flexbox 对齐)和 tw-text-right(继承式对齐)保持兼容。\n <div className=\"ald-modal-footer ant-modal-footer tw-flex tw-items-center tw-justify-end tw-gap-2 tw-border-t tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-px-6 tw-py-3 tw-text-right\">\n {footer}\n </div>\n );\n return (\n <div className=\"ald-modal-footer ant-modal-footer tw-flex tw-justify-end tw-gap-2 tw-border-t tw-border-solid tw-border-[var(--border-default)] tw-px-6 tw-py-4\">\n <Button\n type=\"secondary\"\n size=\"middle\"\n {...cancelButtonProps}\n onClick={onCancel}\n >\n {cancelText}\n </Button>\n <Button type={okType} size=\"middle\" {...mergedOkProps} onClick={onOk}>\n {okText}\n </Button>\n </div>\n );\n };\n\n return (\n <DialogPrimitive.Root open={open} modal={false}>\n <DialogPrimitive.Portal>\n {/* modal={false} 时 DialogPrimitive.Overlay 不渲染,用普通 div 替代 */}\n <div\n className=\"ald-modal-mask tw-animate-in tw-fade-in-0 tw-fixed tw-inset-0 tw-bg-[var(--background-inverted)] tw-opacity-45\"\n style={{ zIndex: maskZIndex }}\n onPointerDown={() => {\n if (maskClosable) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n }\n }}\n />\n {/* Centering wrapper — replaces transform centering so consumer CSS (top/left overrides) works */}\n <div\n ref={contentRef}\n className={cn(\n // antd 兼容:保留 ant-modal-wrap class,消费方 CSS 通过 wrapClassName + :global(.ant-modal) 控制弹窗宽高\n 'ald-modal-wrap ant-modal-wrap tw-pointer-events-none tw-fixed tw-inset-0 tw-flex tw-items-center tw-justify-center',\n wrapClassName,\n )}\n style={{ zIndex: contentZIndex }}\n >\n <DialogPrimitive.Content\n data-testid={dataTestId}\n aria-label={ariaLabel}\n className={cn(\n // antd 兼容:保留 ant-modal class,消费方 CSS 通过 .ant-modal 选择器控制弹窗宽高等样式\n // tw-outline-none:Radix 打开时会聚焦 Content,不抑制 outline 会渲染出蓝色焦点框\n 'ald-modal ant-modal tw-pointer-events-auto tw-box-border tw-flex tw-flex-col tw-overflow-hidden tw-bg-[var(--background-default)] tw-shadow-[var(--elevation-bottom-bottom-lg)] tw-outline-none',\n fullscreen\n ? 'ald-modal-fullscreen tw-fixed tw-inset-0 tw-size-full tw-rounded-none'\n : 'tw-rounded-r-75',\n !fullscreen &&\n 'tw-border tw-border-solid tw-border-[var(--border-default)]',\n paddingLess && 'ald-modal-padding-less',\n virtualScrollBar && 'ald-modal-virtual-scroll-bar',\n hideHeaderBottomBorder && 'ald-modal-hide-header-bottom-border',\n responsiveBounds && 'ald-modal-responsive-bounds',\n className,\n )}\n style={{\n ...(fullscreen\n ? {}\n : {\n width: responsiveBounds\n ? responsiveBoundsStyle.width\n : width || DEFAULT_WIDTH,\n ...responsiveBoundsStyle,\n }),\n ...style,\n }}\n onEscapeKeyDown={(e) => {\n if (keyboard) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n } else {\n e.preventDefault();\n }\n }}\n onPointerDownOutside={(e) => {\n if (maskClosable) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n } else {\n e.preventDefault();\n }\n }}\n onInteractOutside={(e) => {\n if (!maskClosable) {\n e.preventDefault();\n }\n }}\n >\n {/* ant-modal-content compat wrapper — matches antd DOM nesting for consumer CSS */}\n <div className=\"ant-modal-content tw-flex tw-h-full tw-flex-col\">\n <FloatingLayerProvider value={nextLevel}>\n {!fullscreen && (\n <div\n className={cn(\n 'ald-modal-header ant-modal-header tw-flex tw-items-start tw-justify-between tw-bg-[var(--background-default)] tw-px-6 tw-py-4',\n !hideHeaderBottomBorder &&\n 'tw-border-b tw-border-solid tw-border-[var(--border-default)]',\n )}\n >\n <DialogPrimitive.Title asChild>\n <div className=\"tw-flex-1\">\n {ModalTitle({ icon, title, subTitle }, _modalType)}\n </div>\n </DialogPrimitive.Title>\n {closable && (\n <DialogPrimitive.Close asChild>\n <span className=\"ant-modal-close\" onClick={onCancel}>\n {closeIcon || (\n <IconButton\n icon={<CloseLLine size={20} />}\n size=\"middle\"\n />\n )}\n </span>\n </DialogPrimitive.Close>\n )}\n </div>\n )}\n {/* Hidden title for accessibility when fullscreen hides the header */}\n {fullscreen && (\n <DialogPrimitive.Title className=\"tw-sr-only\">\n {title}\n </DialogPrimitive.Title>\n )}\n <div\n className={cn(\n 'ald-modal-body ant-modal-body tw-flex-1 tw-text-sm tw-leading-5',\n fullscreen\n ? 'tw-h-full tw-overflow-auto tw-p-0'\n : 'tw-min-h-[130px]',\n !fullscreen &&\n (virtualScrollBar\n ? 'tw-overflow-hidden tw-p-0'\n : 'tw-overflow-auto'),\n !fullscreen &&\n !responsiveBounds &&\n !virtualScrollBar &&\n 'tw-max-h-[68vh]',\n !fullscreen &&\n !paddingLess &&\n !virtualScrollBar &&\n 'tw-p-6',\n )}\n style={bodyStyle}\n >\n {virtualScrollBar ? (\n <ScrollArea\n className=\"ald-modal-body-wrap !tw-h-auto\"\n innerClassName={cn(\n 'ald-modal-body-wrap-inner tw-max-h-[68vh]',\n paddingLess ? 'tw-p-0' : 'tw-px-[23px] tw-py-0',\n )}\n >\n {children}\n </ScrollArea>\n ) : (\n children\n )}\n </div>\n {!fullscreen && renderFooter()}\n </FloatingLayerProvider>\n </div>\n </DialogPrimitive.Content>\n </div>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n\n// Static method helper\nfunction createStaticModal(\n type: ModalFuncProps['type'],\n props: ModalFuncProps,\n) {\n const container = document.createElement('div');\n document.body.appendChild(container);\n const root = createRoot(container);\n\n let currentProps = { ...props };\n\n const destroy = () => {\n root.unmount();\n container.remove();\n const idx = destroyFns.indexOf(destroy);\n if (idx >= 0) destroyFns.splice(idx, 1);\n };\n\n const update = (newProps: Partial<ModalFuncProps>) => {\n currentProps = { ...currentProps, ...newProps };\n render(currentProps);\n };\n\n const isConfirm = type === 'confirm';\n\n const render = (p: ModalFuncProps) => {\n const handleOk = () => {\n p.onOk?.();\n destroy();\n };\n const handleCancel = () => {\n p.onCancel?.();\n destroy();\n };\n\n root.render(\n <OriginModal\n open={true}\n title={p.title}\n subTitle={p.subTitle}\n icon={p.icon || getIcon(type || 'info')}\n onOk={handleOk}\n onCancel={handleCancel}\n okText={p.okText}\n cancelText={p.cancelText}\n okButtonProps={p.okButtonProps}\n cancelButtonProps={p.cancelButtonProps}\n okType={p.okType || (isConfirm ? 'dangerous' : 'primary')}\n width={p.width || DEFAULT_WIDTH}\n className={cn('ald-modal', p.className)}\n closable={p.closable}\n maskClosable={p.maskClosable}\n _modalType={type}\n footer={\n isConfirm ? undefined : (\n <Button\n type=\"primary\"\n size=\"middle\"\n {...(p.okButtonProps || {})}\n onClick={handleOk}\n >\n {p.okText || 'OK'}\n </Button>\n )\n }\n >\n {p.content}\n </OriginModal>,\n );\n };\n\n destroyFns.push(destroy);\n render(currentProps);\n\n return { destroy, update };\n}\n\n// Attach static methods\ntype ModalFunc = (props: ModalFuncProps) => {\n destroy: () => void;\n update: (props: Partial<ModalFuncProps>) => void;\n};\n\n// ---------- useModal hook ----------\n\ninterface ModalInstance {\n id: number;\n type: ModalFuncProps['type'];\n props: ModalFuncProps;\n open: boolean;\n}\n\nexport interface ModalApiInstance {\n destroy: () => void;\n update: (newProps: Partial<ModalFuncProps>) => void;\n}\n\nexport interface ModalStaticFunctions {\n info: (props: ModalFuncProps) => ModalApiInstance;\n success: (props: ModalFuncProps) => ModalApiInstance;\n error: (props: ModalFuncProps) => ModalApiInstance;\n warning: (props: ModalFuncProps) => ModalApiInstance;\n confirm: (props: ModalFuncProps) => ModalApiInstance;\n}\n\nfunction useModal(): [ModalStaticFunctions, React.ReactElement] {\n const [modals, setModals] = useState<ModalInstance[]>([]);\n const idCounter = useRef(0);\n\n const removeModal = useCallback((id: number) => {\n setModals((prev) =>\n prev.map((m) => (m.id === id ? { ...m, open: false } : m)),\n );\n // Remove from DOM after animation\n setTimeout(() => {\n setModals((prev) => prev.filter((m) => m.id !== id));\n }, 300);\n }, []);\n\n const updateModal = useCallback(\n (id: number, newProps: Partial<ModalFuncProps>) => {\n setModals((prev) =>\n prev.map((m) =>\n m.id === id ? { ...m, props: { ...m.props, ...newProps } } : m,\n ),\n );\n },\n [],\n );\n\n const openModal = useCallback(\n (type: ModalFuncProps['type'], props: ModalFuncProps): ModalApiInstance => {\n const id = ++idCounter.current;\n const instance: ModalInstance = { id, type, props, open: true };\n setModals((prev) => [...prev, instance]);\n\n return {\n destroy: () => removeModal(id),\n update: (newProps: Partial<ModalFuncProps>) =>\n updateModal(id, newProps),\n };\n },\n [removeModal, updateModal],\n );\n\n const api = useMemo<ModalStaticFunctions>(\n () => ({\n info: (props) => openModal('info', props),\n success: (props) => openModal('success', props),\n error: (props) => openModal('error', props),\n warning: (props) => openModal('warning', props),\n confirm: (props) =>\n openModal('confirm', { ...props, type: props.type || 'confirm' }),\n }),\n [openModal],\n );\n\n const contextHolder = (\n <>\n {modals.map((m) => {\n const isConfirmType = m.type === 'confirm';\n const handleOk = () => {\n m.props.onOk?.();\n removeModal(m.id);\n };\n const handleCancel = () => {\n m.props.onCancel?.();\n removeModal(m.id);\n };\n return (\n <OriginModal\n key={m.id}\n open={m.open}\n title={m.props.title}\n subTitle={m.props.subTitle}\n icon={m.props.icon || getIcon(m.type || 'info')}\n onOk={handleOk}\n onCancel={handleCancel}\n okText={m.props.okText}\n cancelText={m.props.cancelText}\n okButtonProps={m.props.okButtonProps}\n cancelButtonProps={m.props.cancelButtonProps}\n okType={m.props.okType || (isConfirmType ? 'dangerous' : 'primary')}\n width={m.props.width || DEFAULT_WIDTH}\n className={cn('ald-modal', m.props.className)}\n closable={m.props.closable}\n maskClosable={m.props.maskClosable}\n _modalType={m.type}\n footer={\n isConfirmType ? undefined : (\n <Button\n type=\"primary\"\n size=\"middle\"\n {...(m.props.okButtonProps || {})}\n onClick={handleOk}\n >\n {m.props.okText || 'OK'}\n </Button>\n )\n }\n >\n {m.props.content}\n </OriginModal>\n );\n })}\n </>\n );\n\n return [api, contextHolder];\n}\n\n// ---------- end useModal ----------\n\nconst Modal = OriginModal as typeof OriginModal & {\n info: ModalFunc;\n success: ModalFunc;\n error: ModalFunc;\n warning: ModalFunc;\n confirm: ModalFunc;\n destroyAll: () => void;\n useModal: typeof useModal;\n config: (config: any) => void;\n};\n\nModal.info = (props) => createStaticModal('info', props);\nModal.success = (props) => createStaticModal('success', props);\nModal.error = (props) => createStaticModal('error', props);\nModal.warning = (props) => createStaticModal('warning', props);\nModal.confirm = (props) =>\n createStaticModal('confirm', { ...props, type: props.type || 'confirm' });\n\nModal.destroyAll = () => {\n while (destroyFns.length) {\n const close = destroyFns.pop();\n if (close) close();\n }\n};\n\nModal.useModal = useModal;\nModal.config = () => {};\n\nexport default Modal;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Modal/index.tsx"],"sourcesContent":["import * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { hideOthers } from 'aria-hidden';\nimport React, {\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { createRoot } from 'react-dom/client';\nimport Button, { ButtonType, IButtonProps } from '../Button';\nimport {\n AttentionTriangleLightLine,\n CheckCircleLightLine,\n CloseLLine,\n InformationCircleLightLine,\n} from '../Icon';\nimport IconButton from '../IconButton';\nimport ScrollArea from '../ScrollArea';\nimport {\n FLOATING_LAYER_BASE_Z_INDEX,\n FLOATING_LAYER_STEP,\n FloatingLayerProvider,\n} from '../_utils/floatingLayer';\nimport {\n ModalLayerProvider,\n useModalLayer,\n} from '../_utils/overlayCoordinator';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport { cn } from '../lib/utils';\n\nexport const destroyFns: Array<() => void> = [];\n\nexport interface ModalProps {\n open?: boolean;\n onOk?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n onCancel?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n afterClose?: () => void;\n title?: React.ReactNode;\n subTitle?: React.ReactNode;\n icon?: React.ReactElement;\n width?: number | string;\n footer?: React.ReactNode | null;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n confirmLoading?: boolean;\n maskClosable?: boolean;\n closable?: boolean;\n closeIcon?: React.ReactNode;\n centered?: boolean;\n destroyOnClose?: boolean;\n className?: string;\n /** Pass through to the modal content root for automated testing. */\n 'data-testid'?: string;\n /** Pass through to the modal content root for accessibility and automated testing. */\n 'aria-label'?: string;\n /** Applied to the outer wrap layer (matches antd wrapClassName behavior) */\n wrapClassName?: string;\n style?: React.CSSProperties;\n bodyStyle?: React.CSSProperties;\n zIndex?: number;\n children?: React.ReactNode;\n paddingLess?: boolean;\n virtualScrollBar?: boolean;\n hideHeaderBottomBorder?: boolean;\n responsiveBounds?: boolean;\n fullscreen?: boolean;\n keyboard?: boolean;\n afterOpenChange?: (open: boolean) => void;\n getContainer?: (() => HTMLElement) | false;\n /** @internal used by static methods to pass modal type for icon styling */\n _modalType?: string;\n}\n\ninterface OriginModalProps extends ModalProps {\n onTopChange?: (isTop: boolean) => void;\n}\n\nexport interface ModalFuncProps {\n title?: React.ReactNode;\n subTitle?: React.ReactNode;\n content?: React.ReactNode;\n icon?: React.ReactElement;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n onOk?: (...args: any[]) => any;\n onCancel?: (...args: any[]) => any;\n width?: number | string;\n className?: string;\n /** @deprecated Use `className` instead. Preserved for antd v4 compat. */\n wrapClassName?: string;\n closable?: boolean;\n type?: 'info' | 'success' | 'error' | 'warn' | 'warning' | 'confirm';\n centered?: boolean;\n maskClosable?: boolean;\n}\n\nconst DEFAULT_WIDTH = 552;\nconst modalEscapeEvents = new WeakSet<KeyboardEvent>();\n\nfunction shouldCancelTopModal(event: KeyboardEvent) {\n return (\n !event.cancelBubble &&\n (!event.defaultPrevented || modalEscapeEvents.has(event))\n );\n}\n\nfunction ModalContentProviders({\n layerId,\n floatingLevel,\n children,\n}: {\n layerId: number;\n floatingLevel: number;\n children: React.ReactNode;\n}) {\n return (\n <ModalLayerProvider id={layerId}>\n <FloatingLayerProvider value={floatingLevel}>\n {children}\n </FloatingLayerProvider>\n </ModalLayerProvider>\n );\n}\n\nconst ModalTitle = (\n { icon, title, subTitle }: Pick<ModalProps, 'icon' | 'title' | 'subTitle'>,\n type?: string,\n) => (\n <div className=\"ald-modal-title-container tw-flex tw-items-center tw-gap-4\">\n {icon && (\n <div\n className={cn(\n 'ald-modal-icon-container tw-grid tw-size-10 tw-shrink-0 tw-place-items-center tw-rounded-[var(--global-grid-250)]',\n type === 'info' &&\n 'ald-modal-cion-info-container tw-bg-[var(--background-informative-muted)]',\n type === 'success' &&\n 'ald-modal-cion-success-container tw-bg-[var(--background-positive-muted)]',\n type === 'warning' &&\n 'ald-modal-cion-warning-container tw-bg-[var(--background-warning-muted)]',\n type === 'warn' &&\n 'ald-modal-cion-warning-container tw-bg-[var(--background-warning-muted)]',\n type === 'error' &&\n 'ald-modal-cion-error-container tw-bg-[var(--background-negative-muted)]',\n type === 'confirm' &&\n 'ald-modal-cion-confirm-container tw-bg-[var(--background-brand-muted)]',\n )}\n >\n {icon}\n </div>\n )}\n <div className=\"ald-modal-text-container\">\n {title && (\n <div\n className={cn(\n 'ald-modal-text-title tw-text-lg tw-font-semibold tw-leading-7 tw-text-[var(--content-primary)]',\n !subTitle && 'ald-modal-text-title-only tw-text-xl',\n )}\n >\n {title}\n </div>\n )}\n {subTitle && (\n <div className=\"ald-modal-text-sub-title tw-mt-1 tw-text-xs tw-leading-4 tw-text-[var(--content-secondary)]\">\n {subTitle}\n </div>\n )}\n </div>\n </div>\n);\n\nfunction getIcon(\n type: 'info' | 'success' | 'error' | 'warn' | 'warning' | 'confirm',\n) {\n if (type === 'success')\n return (\n <CheckCircleLightLine\n fill=\"var(--content-inverted-primary)\"\n color=\"var(--background-positive-strong)\"\n size={24}\n />\n );\n if (type === 'error')\n return (\n <AttentionTriangleLightLine\n color=\"var(--background-negative-strong)\"\n fill=\"var(--content-inverted-primary)\"\n size={24}\n />\n );\n if (type === 'warning' || type === 'warn')\n return (\n <AttentionTriangleLightLine\n color=\"var(--background-warning-strong)\"\n size={24}\n />\n );\n return (\n <InformationCircleLightLine\n size={24}\n color=\"var(--action-primary-normal)\"\n />\n );\n}\n\nfunction OriginModal(props: OriginModalProps) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n const {\n className,\n 'data-testid': dataTestId,\n 'aria-label': ariaLabel,\n children,\n okType = 'primary',\n width,\n closeIcon,\n subTitle,\n okButtonProps = {},\n cancelButtonProps = {},\n okText = t.Modal.sure,\n cancelText = t.Modal.cancel,\n icon,\n title,\n paddingLess,\n responsiveBounds,\n hideHeaderBottomBorder,\n virtualScrollBar,\n style,\n maskClosable = false,\n fullscreen,\n open = false,\n onOk,\n onCancel,\n footer,\n confirmLoading,\n closable = true,\n zIndex = 1000,\n bodyStyle,\n keyboard = true,\n afterOpenChange,\n wrapClassName,\n _modalType,\n onTopChange,\n } = props;\n\n const prevOpenRef = useRef(open);\n const contentRef = useRef<HTMLDivElement>(null);\n const modalLayer = useModalLayer(open, zIndex);\n const { id: modalLayerId, maskZIndex, contentZIndex, isTop } = modalLayer;\n const nextFloatingLevel =\n (maskZIndex - FLOATING_LAYER_BASE_Z_INDEX) / FLOATING_LAYER_STEP + 1;\n\n useLayoutEffect(() => {\n onTopChange?.(isTop);\n }, [isTop, onTopChange]);\n\n useEffect(() => {\n if (prevOpenRef.current !== open) {\n prevOpenRef.current = open;\n afterOpenChange?.(open);\n }\n }, [open, afterOpenChange]);\n\n // ---- modal={false} 补偿:aria-hidden(屏幕阅读器只感知弹窗) ----\n useEffect(() => {\n if (!open || !isTop || !contentRef.current) return;\n return hideOthers(contentRef.current);\n }, [isTop, open]);\n\n // ---- modal={false} 补偿:Tab 焦点循环 ----\n useEffect(() => {\n if (!open || !isTop || !contentRef.current) return;\n const container = contentRef.current;\n\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\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\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isTop, open]);\n\n useEffect(() => {\n if (!open || !isTop || !keyboard) return;\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key !== 'Escape') return;\n // Radix observes Escape during document capture, so child overlays can\n // only finish their own propagation handling later in the event cycle.\n queueMicrotask(() => {\n if (shouldCancelTopModal(event)) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n }\n });\n };\n\n window.addEventListener('keydown', handleEscape, true);\n return () => window.removeEventListener('keydown', handleEscape, true);\n }, [isTop, keyboard, onCancel, open]);\n\n const responsiveBoundsStyle = useMemo(() => {\n if (!responsiveBounds) return {};\n return {\n width: 'calc(100% - 160px)',\n maxWidth: '1680px',\n minWidth: '1280px',\n height: 'calc(100% - 48px)',\n maxHeight: '900px',\n minHeight: '640px',\n };\n }, [responsiveBounds]);\n\n const mergedOkProps = { loading: confirmLoading, ...okButtonProps };\n\n const renderFooter = () => {\n if (footer === null) return null;\n if (footer)\n return (\n // antd 兼容:antd .ant-modal-footer 使用 text-align:right 让 inline 按钮右对齐,\n // 即使消费方传入 width:100% 的子容器,内部 inline 元素仍能右对齐。\n // 此处同时使用 tw-flex tw-justify-end(flexbox 对齐)和 tw-text-right(继承式对齐)保持兼容。\n <div className=\"ald-modal-footer ant-modal-footer tw-flex tw-items-center tw-justify-end tw-gap-2 tw-border-t tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-px-6 tw-py-3 tw-text-right\">\n {footer}\n </div>\n );\n return (\n <div className=\"ald-modal-footer ant-modal-footer tw-flex tw-justify-end tw-gap-2 tw-border-t tw-border-solid tw-border-[var(--border-default)] tw-px-6 tw-py-4\">\n <Button\n type=\"secondary\"\n size=\"middle\"\n {...cancelButtonProps}\n onClick={onCancel}\n >\n {cancelText}\n </Button>\n <Button type={okType} size=\"middle\" {...mergedOkProps} onClick={onOk}>\n {okText}\n </Button>\n </div>\n );\n };\n\n return (\n <DialogPrimitive.Root open={open} modal={false}>\n <DialogPrimitive.Portal>\n {/* modal={false} 时 DialogPrimitive.Overlay 不渲染,用普通 div 替代 */}\n {isTop && (\n <div\n className=\"ald-modal-mask tw-animate-in tw-fade-in-0 tw-fixed tw-inset-0 tw-bg-[var(--background-inverted)] tw-opacity-45\"\n style={{ zIndex: maskZIndex }}\n onPointerDown={() => {\n if (maskClosable) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n }\n }}\n />\n )}\n {/* Centering wrapper — replaces transform centering so consumer CSS (top/left overrides) works */}\n <div\n ref={contentRef}\n {...(!isTop ? { inert: '' } : {})}\n aria-hidden={!isTop || undefined}\n className={cn(\n // antd 兼容:保留 ant-modal-wrap class,消费方 CSS 通过 wrapClassName + :global(.ant-modal) 控制弹窗宽高\n 'ald-modal-wrap ant-modal-wrap tw-pointer-events-none tw-fixed tw-inset-0 tw-flex tw-items-center tw-justify-center',\n wrapClassName,\n )}\n style={{ zIndex: contentZIndex }}\n >\n <DialogPrimitive.Content\n data-testid={dataTestId}\n aria-label={ariaLabel}\n className={cn(\n // antd 兼容:保留 ant-modal class,消费方 CSS 通过 .ant-modal 选择器控制弹窗宽高等样式\n // tw-outline-none:Radix 打开时会聚焦 Content,不抑制 outline 会渲染出蓝色焦点框\n 'ald-modal ant-modal tw-pointer-events-auto tw-box-border tw-flex tw-flex-col tw-overflow-hidden tw-bg-[var(--background-default)] tw-shadow-[var(--elevation-bottom-bottom-lg)] tw-outline-none',\n fullscreen\n ? 'ald-modal-fullscreen tw-fixed tw-inset-0 tw-size-full tw-rounded-none'\n : 'tw-rounded-r-75',\n !fullscreen &&\n 'tw-border tw-border-solid tw-border-[var(--border-default)]',\n paddingLess && 'ald-modal-padding-less',\n virtualScrollBar && 'ald-modal-virtual-scroll-bar',\n hideHeaderBottomBorder && 'ald-modal-hide-header-bottom-border',\n responsiveBounds && 'ald-modal-responsive-bounds',\n className,\n )}\n style={{\n ...(fullscreen\n ? {}\n : {\n width: responsiveBounds\n ? responsiveBoundsStyle.width\n : width || DEFAULT_WIDTH,\n ...responsiveBoundsStyle,\n }),\n ...style,\n }}\n onEscapeKeyDown={(event) => {\n if (!event.defaultPrevented) modalEscapeEvents.add(event);\n event.preventDefault();\n }}\n onPointerDownOutside={(e) => {\n if (maskClosable) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n } else {\n e.preventDefault();\n }\n }}\n onInteractOutside={(e) => {\n if (!maskClosable) {\n e.preventDefault();\n }\n }}\n >\n {/* ant-modal-content compat wrapper — matches antd DOM nesting for consumer CSS */}\n <div className=\"ant-modal-content tw-flex tw-h-full tw-flex-col\">\n <ModalContentProviders\n layerId={modalLayerId}\n floatingLevel={nextFloatingLevel}\n >\n {!fullscreen && (\n <div\n className={cn(\n 'ald-modal-header ant-modal-header tw-flex tw-items-start tw-justify-between tw-bg-[var(--background-default)] tw-px-6 tw-py-4',\n !hideHeaderBottomBorder &&\n 'tw-border-b tw-border-solid tw-border-[var(--border-default)]',\n )}\n >\n <DialogPrimitive.Title asChild>\n <div className=\"tw-flex-1\">\n {ModalTitle({ icon, title, subTitle }, _modalType)}\n </div>\n </DialogPrimitive.Title>\n {closable && (\n <DialogPrimitive.Close asChild>\n <span className=\"ant-modal-close\" onClick={onCancel}>\n {closeIcon || (\n <IconButton\n icon={<CloseLLine size={20} />}\n size=\"middle\"\n />\n )}\n </span>\n </DialogPrimitive.Close>\n )}\n </div>\n )}\n {/* Hidden title for accessibility when fullscreen hides the header */}\n {fullscreen && (\n <DialogPrimitive.Title className=\"tw-sr-only\">\n {title}\n </DialogPrimitive.Title>\n )}\n <div\n className={cn(\n 'ald-modal-body ant-modal-body tw-flex-1 tw-text-sm tw-leading-5',\n fullscreen\n ? 'tw-h-full tw-overflow-auto tw-p-0'\n : 'tw-min-h-[130px]',\n !fullscreen &&\n (virtualScrollBar\n ? 'tw-overflow-hidden tw-p-0'\n : 'tw-overflow-auto'),\n !fullscreen &&\n !responsiveBounds &&\n !virtualScrollBar &&\n 'tw-max-h-[68vh]',\n !fullscreen &&\n !paddingLess &&\n !virtualScrollBar &&\n 'tw-p-6',\n )}\n style={bodyStyle}\n >\n {virtualScrollBar ? (\n <ScrollArea\n className=\"ald-modal-body-wrap !tw-h-auto\"\n innerClassName={cn(\n 'ald-modal-body-wrap-inner tw-max-h-[68vh]',\n paddingLess ? 'tw-p-0' : 'tw-px-[23px] tw-py-0',\n )}\n >\n {children}\n </ScrollArea>\n ) : (\n children\n )}\n </div>\n {!fullscreen && renderFooter()}\n </ModalContentProviders>\n </div>\n </DialogPrimitive.Content>\n </div>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n\n// Static method helper\nfunction createStaticModal(\n type: ModalFuncProps['type'],\n props: ModalFuncProps,\n) {\n const focusTarget = document.activeElement as HTMLElement | null;\n const container = document.createElement('div');\n document.body.appendChild(container);\n const root = createRoot(container);\n\n let currentProps = { ...props };\n let destroyed = false;\n let isTop = true;\n\n const destroy = () => {\n if (destroyed) return;\n destroyed = true;\n const shouldRestoreFocus = isTop;\n root.unmount();\n container.remove();\n const idx = destroyFns.indexOf(destroy);\n if (idx >= 0) destroyFns.splice(idx, 1);\n queueMicrotask(() => {\n if (shouldRestoreFocus && focusTarget?.isConnected) focusTarget.focus();\n });\n };\n\n const update = (newProps: Partial<ModalFuncProps>) => {\n currentProps = { ...currentProps, ...newProps };\n render(currentProps);\n };\n\n const isConfirm = type === 'confirm';\n\n const render = (p: ModalFuncProps) => {\n const handleOk = () => {\n p.onOk?.();\n destroy();\n };\n const handleCancel = () => {\n p.onCancel?.();\n destroy();\n };\n\n root.render(\n <OriginModal\n open={true}\n title={p.title}\n subTitle={p.subTitle}\n icon={p.icon || getIcon(type || 'info')}\n onOk={handleOk}\n onCancel={handleCancel}\n okText={p.okText}\n cancelText={p.cancelText}\n okButtonProps={p.okButtonProps}\n cancelButtonProps={p.cancelButtonProps}\n okType={p.okType || (isConfirm ? 'dangerous' : 'primary')}\n width={p.width || DEFAULT_WIDTH}\n className={cn('ald-modal', p.className)}\n closable={p.closable}\n maskClosable={p.maskClosable}\n _modalType={type}\n onTopChange={(nextIsTop) => {\n isTop = nextIsTop;\n }}\n footer={\n isConfirm ? undefined : (\n <Button\n type=\"primary\"\n size=\"middle\"\n {...(p.okButtonProps || {})}\n onClick={handleOk}\n >\n {p.okText || 'OK'}\n </Button>\n )\n }\n >\n {p.content}\n </OriginModal>,\n );\n };\n\n destroyFns.push(destroy);\n render(currentProps);\n\n return { destroy, update };\n}\n\n// Attach static methods\ntype ModalFunc = (props: ModalFuncProps) => {\n destroy: () => void;\n update: (props: Partial<ModalFuncProps>) => void;\n};\n\n// ---------- useModal hook ----------\n\ninterface ModalInstance {\n id: number;\n type: ModalFuncProps['type'];\n props: ModalFuncProps;\n open: boolean;\n}\n\nexport interface ModalApiInstance {\n destroy: () => void;\n update: (newProps: Partial<ModalFuncProps>) => void;\n}\n\nexport interface ModalStaticFunctions {\n info: (props: ModalFuncProps) => ModalApiInstance;\n success: (props: ModalFuncProps) => ModalApiInstance;\n error: (props: ModalFuncProps) => ModalApiInstance;\n warning: (props: ModalFuncProps) => ModalApiInstance;\n confirm: (props: ModalFuncProps) => ModalApiInstance;\n}\n\nfunction useModal(): [ModalStaticFunctions, React.ReactElement] {\n const [modals, setModals] = useState<ModalInstance[]>([]);\n const idCounter = useRef(0);\n\n const removeModal = useCallback((id: number) => {\n setModals((prev) =>\n prev.map((m) => (m.id === id ? { ...m, open: false } : m)),\n );\n // Remove from DOM after animation\n setTimeout(() => {\n setModals((prev) => prev.filter((m) => m.id !== id));\n }, 300);\n }, []);\n\n const updateModal = useCallback(\n (id: number, newProps: Partial<ModalFuncProps>) => {\n setModals((prev) =>\n prev.map((m) =>\n m.id === id ? { ...m, props: { ...m.props, ...newProps } } : m,\n ),\n );\n },\n [],\n );\n\n const openModal = useCallback(\n (type: ModalFuncProps['type'], props: ModalFuncProps): ModalApiInstance => {\n const id = ++idCounter.current;\n const instance: ModalInstance = { id, type, props, open: true };\n setModals((prev) => [...prev, instance]);\n\n return {\n destroy: () => removeModal(id),\n update: (newProps: Partial<ModalFuncProps>) =>\n updateModal(id, newProps),\n };\n },\n [removeModal, updateModal],\n );\n\n const api = useMemo<ModalStaticFunctions>(\n () => ({\n info: (props) => openModal('info', props),\n success: (props) => openModal('success', props),\n error: (props) => openModal('error', props),\n warning: (props) => openModal('warning', props),\n confirm: (props) =>\n openModal('confirm', { ...props, type: props.type || 'confirm' }),\n }),\n [openModal],\n );\n\n const contextHolder = (\n <>\n {modals.map((m) => {\n const isConfirmType = m.type === 'confirm';\n const handleOk = () => {\n m.props.onOk?.();\n removeModal(m.id);\n };\n const handleCancel = () => {\n m.props.onCancel?.();\n removeModal(m.id);\n };\n return (\n <OriginModal\n key={m.id}\n open={m.open}\n title={m.props.title}\n subTitle={m.props.subTitle}\n icon={m.props.icon || getIcon(m.type || 'info')}\n onOk={handleOk}\n onCancel={handleCancel}\n okText={m.props.okText}\n cancelText={m.props.cancelText}\n okButtonProps={m.props.okButtonProps}\n cancelButtonProps={m.props.cancelButtonProps}\n okType={m.props.okType || (isConfirmType ? 'dangerous' : 'primary')}\n width={m.props.width || DEFAULT_WIDTH}\n className={cn('ald-modal', m.props.className)}\n closable={m.props.closable}\n maskClosable={m.props.maskClosable}\n _modalType={m.type}\n footer={\n isConfirmType ? undefined : (\n <Button\n type=\"primary\"\n size=\"middle\"\n {...(m.props.okButtonProps || {})}\n onClick={handleOk}\n >\n {m.props.okText || 'OK'}\n </Button>\n )\n }\n >\n {m.props.content}\n </OriginModal>\n );\n })}\n </>\n );\n\n return [api, contextHolder];\n}\n\n// ---------- end useModal ----------\n\nconst Modal = OriginModal as typeof OriginModal & {\n info: ModalFunc;\n success: ModalFunc;\n error: ModalFunc;\n warning: ModalFunc;\n confirm: ModalFunc;\n destroyAll: () => void;\n useModal: typeof useModal;\n config: (config: any) => void;\n};\n\nModal.info = (props) => createStaticModal('info', props);\nModal.success = (props) => createStaticModal('success', props);\nModal.error = (props) => createStaticModal('error', props);\nModal.warning = (props) => createStaticModal('warning', props);\nModal.confirm = (props) =>\n createStaticModal('confirm', { ...props, type: props.type || 'confirm' });\n\nModal.destroyAll = () => {\n while (destroyFns.length) {\n const close = destroyFns.pop();\n if (close) close();\n }\n};\n\nModal.useModal = useModal;\nModal.config = () => {};\n\nexport default Modal;\n"],"mappings":"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"}
|
package/dist/Popconfirm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cn } from "../lib/utils.js";
|
|
2
2
|
import Memo from "../Icon/components/AttentionTriangleFill.js";
|
|
3
|
-
import Button_default from "../Button/index.js";
|
|
4
3
|
import { useFloatingPopupZIndex } from "../_utils/floatingLayer.js";
|
|
4
|
+
import Button_default from "../Button/index.js";
|
|
5
5
|
import React, { useState } from "react";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
@@ -14,7 +14,7 @@ function Radio(props) {
|
|
|
14
14
|
const isControlled = "checked" in props;
|
|
15
15
|
const [innerChecked, setInnerChecked] = useState(props.defaultChecked ?? false);
|
|
16
16
|
if (inGroup) radioProps.disabled = groupContext.disabled || props.disabled;
|
|
17
|
-
const checked = inGroup ?
|
|
17
|
+
const checked = inGroup ? groupContext.value === props.value : !isControlled ? innerChecked : radioProps.checked;
|
|
18
18
|
const aldRadioClass = cn("ald-radio", {
|
|
19
19
|
"ald-radio-checked": checked,
|
|
20
20
|
"ald-radio-disabled": radioProps.disabled
|
|
@@ -68,7 +68,7 @@ function Radio(props) {
|
|
|
68
68
|
}
|
|
69
69
|
}), /* @__PURE__ */ jsx("span", { className: "ald-radio-inner" })]
|
|
70
70
|
}), props.children && /* @__PURE__ */ jsx("span", {
|
|
71
|
-
className: "ald-radio-desc",
|
|
71
|
+
className: "ald-radio-desc tw-text-typography-label",
|
|
72
72
|
children: props.children
|
|
73
73
|
})]
|
|
74
74
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/Radio/components/Radio/index.tsx"],"sourcesContent":["import { cn } from '../../../lib/utils';\nimport _ from 'lodash';\nimport React, { useContext, useRef, useState } from 'react';\n\nimport { getUUID } from '../../../_utils/hooks/useId';\nimport { IRadioProps } from '../../interface/radio';\nimport { RadioGroupContext } from '../Group';\n\nexport default function Radio(props: IRadioProps) {\n const groupContext = useContext(RadioGroupContext);\n const labelRef = useRef<HTMLLabelElement>(null);\n const [id] = useState(() => getUUID().toString());\n\n const radioProps = { ...props };\n const inGroup = !_.isEmpty(groupContext);\n const isControlled = 'checked' in props;\n const [innerChecked, setInnerChecked] = useState(\n props.defaultChecked ?? false,\n );\n\n if (inGroup) {\n radioProps.disabled = groupContext.disabled || props.disabled;\n }\n\n // checked 直接从 groupContext 或 props 派生,不使用 useState + useEffect,\n // 避免双重渲染导致切换时视觉抖动。\n const checked = inGroup\n ?
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/Radio/components/Radio/index.tsx"],"sourcesContent":["import { cn } from '../../../lib/utils';\nimport _ from 'lodash';\nimport React, { useContext, useRef, useState } from 'react';\n\nimport { getUUID } from '../../../_utils/hooks/useId';\nimport { IRadioProps } from '../../interface/radio';\nimport { RadioGroupContext } from '../Group';\n\nexport default function Radio(props: IRadioProps) {\n const groupContext = useContext(RadioGroupContext);\n const labelRef = useRef<HTMLLabelElement>(null);\n const [id] = useState(() => getUUID().toString());\n\n const radioProps = { ...props };\n const inGroup = !_.isEmpty(groupContext);\n const isControlled = 'checked' in props;\n const [innerChecked, setInnerChecked] = useState(\n props.defaultChecked ?? false,\n );\n\n if (inGroup) {\n radioProps.disabled = groupContext.disabled || props.disabled;\n }\n\n // checked 直接从 groupContext 或 props 派生,不使用 useState + useEffect,\n // 避免双重渲染导致切换时视觉抖动。\n const checked = inGroup\n ? groupContext.value === props.value\n : !isControlled\n ? innerChecked\n : radioProps.checked;\n\n // 设置input外层盒子的class\n const aldRadioClass = cn('ald-radio', {\n 'ald-radio-checked': checked,\n 'ald-radio-disabled': radioProps.disabled,\n });\n\n // 根据属性设置最外层的class\n const getWrapperClass = () => {\n let otherClass = '';\n if (groupContext.type === 'button') {\n if (groupContext.radioGroupStyle === 'filled') {\n otherClass = 'ald-radio-button-wrapper-filled';\n } else if (groupContext.radioGroupStyle === 'border') {\n otherClass = 'ald-radio-button-wrapper-border';\n } else if (groupContext.radioGroupStyle === 'filter') {\n otherClass = 'ald-radio-button-wrapper-filter';\n } else {\n otherClass = 'ald-radio-button-wrapper-border-primary';\n }\n } else if (groupContext.type === 'iconButton') {\n if (groupContext.radioGroupStyle === 'filled') {\n otherClass = 'ald-radio-icon-button-wrapper-filled';\n } else if (groupContext.radioGroupStyle === 'border') {\n otherClass = 'ald-radio-icon-button-wrapper-border';\n } else if (groupContext.radioGroupStyle === 'filter') {\n otherClass = 'ald-radio-icon-button-wrapper-filter';\n } else {\n otherClass = 'ald-radio-icon-button-wrapper-border-primary';\n }\n } else {\n // 当type未设置或者是radio时\n otherClass = 'ald-radio-wrapper';\n if (props.indeterminate) {\n otherClass = otherClass + ' ald-radio-wrapper-indeterminate';\n }\n }\n return cn('ald-radio-label', otherClass, props.className, {\n 'ald-radio-wrapper-checked': checked,\n 'ald-radio-wrapper-disabled': radioProps.disabled,\n });\n };\n\n // button / iconButton 模式下,radio 圆圈需要完全隐藏\n const isButtonMode =\n groupContext.type === 'button' || groupContext.type === 'iconButton';\n const radioHideStyle: React.CSSProperties | undefined = isButtonMode\n ? { width: 0, height: 0, overflow: 'hidden' }\n : undefined;\n\n return (\n <label className={getWrapperClass()} htmlFor={id} ref={labelRef}>\n <span className={aldRadioClass} style={radioHideStyle}>\n <input\n id={id}\n type=\"radio\"\n className=\"ald-radio-input\"\n // 同步派生的 checked 到原生 input,对齐 v2/antd 行为(仅有 class 不更新 input.checked)\n checked={!!checked}\n disabled={radioProps.disabled}\n value={props.value}\n onChange={(e) => {\n if (radioProps.disabled) return;\n if (!inGroup && !isControlled) {\n setInnerChecked(e.target.checked);\n }\n props.onChange?.(e);\n }}\n onClick={(e) => {\n props.onClick?.(e);\n\n if (inGroup && groupContext?.onChange) {\n // input事件的value会被toString,所以此处进行一个覆盖\n groupContext.onChange(props.value);\n }\n }}\n />\n <span className=\"ald-radio-inner\" />\n </span>\n {props.children && (\n <span className=\"ald-radio-desc tw-text-typography-label\">\n {props.children}\n </span>\n )}\n </label>\n );\n}\n"],"mappings":";;;;;;;AAQA,SAAwB,MAAM,OAAoB;CAChD,MAAM,eAAe,WAAW,kBAAkB;CAClD,MAAM,WAAW,OAAyB,KAAK;CAC/C,MAAM,CAAC,MAAM,eAAe,SAAS,CAAC,UAAU,CAAC;CAEjD,MAAM,aAAa,EAAE,GAAG,OAAO;CAC/B,MAAM,UAAU,CAAC,EAAE,QAAQ,aAAa;CACxC,MAAM,eAAe,aAAa;CAClC,MAAM,CAAC,cAAc,mBAAmB,SACtC,MAAM,kBAAkB,MACzB;AAED,KAAI,QACF,YAAW,WAAW,aAAa,YAAY,MAAM;CAKvD,MAAM,UAAU,UACZ,aAAa,UAAU,MAAM,QAC7B,CAAC,eACD,eACA,WAAW;CAGf,MAAM,gBAAgB,GAAG,aAAa;EACpC,qBAAqB;EACrB,sBAAsB,WAAW;EAClC,CAAC;CAGF,MAAM,wBAAwB;EAC5B,IAAI,aAAa;AACjB,MAAI,aAAa,SAAS,SACxB,KAAI,aAAa,oBAAoB,SACnC,cAAa;WACJ,aAAa,oBAAoB,SAC1C,cAAa;WACJ,aAAa,oBAAoB,SAC1C,cAAa;MAEb,cAAa;WAEN,aAAa,SAAS,aAC/B,KAAI,aAAa,oBAAoB,SACnC,cAAa;WACJ,aAAa,oBAAoB,SAC1C,cAAa;WACJ,aAAa,oBAAoB,SAC1C,cAAa;MAEb,cAAa;OAEV;AAEL,gBAAa;AACb,OAAI,MAAM,cACR,cAAa,aAAa;;AAG9B,SAAO,GAAG,mBAAmB,YAAY,MAAM,WAAW;GACxD,6BAA6B;GAC7B,8BAA8B,WAAW;GAC1C,CAAC;;CAMJ,MAAM,iBADJ,aAAa,SAAS,YAAY,aAAa,SAAS,eAEtD;EAAE,OAAO;EAAG,QAAQ;EAAG,UAAU;EAAU,GAC3C;AAEJ,QACE,qBAAC,SAAD;EAAO,WAAW,iBAAiB;EAAE,SAAS;EAAI,KAAK;YAAvD,CACE,qBAAC,QAAD;GAAM,WAAW;GAAe,OAAO;aAAvC,CACE,oBAAC,SAAD;IACM;IACJ,MAAK;IACL,WAAU;IAEV,SAAS,CAAC,CAAC;IACX,UAAU,WAAW;IACrB,OAAO,MAAM;IACb,WAAW,MAAM;AACf,SAAI,WAAW,SAAU;AACzB,SAAI,CAAC,WAAW,CAAC,aACf,iBAAgB,EAAE,OAAO,QAAQ;AAEnC,WAAM,WAAW,EAAE;;IAErB,UAAU,MAAM;AACd,WAAM,UAAU,EAAE;AAElB,SAAI,WAAW,cAAc,SAE3B,cAAa,SAAS,MAAM,MAAM;;IAGtC,CAAA,EACF,oBAAC,QAAD,EAAM,WAAU,mBAAoB,CAAA,CAC/B;MACN,MAAM,YACL,oBAAC,QAAD;GAAM,WAAU;aACb,MAAM;GACF,CAAA,CAEH"}
|
|
@@ -129,7 +129,7 @@ var BaseSelect = React$1.forwardRef((props, ref) => {
|
|
|
129
129
|
"multiple-responsive": isResponsiveMode,
|
|
130
130
|
"multiple-default": isMultipleMode && !isResponsiveMode,
|
|
131
131
|
"overflow-collapsed": overflowCollapsed && width === "auto" && !_.isEmpty(displayValues)
|
|
132
|
-
}), className, compactItemClassnames);
|
|
132
|
+
}), "tw-text-typography-body-dense", className, compactItemClassnames);
|
|
133
133
|
const showMenu = React$1.useMemo(() => {
|
|
134
134
|
if (!displayMenu) return;
|
|
135
135
|
return {
|