@aloudata/aloudata-design 3.1.0 → 3.1.2

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 (196) hide show
  1. package/dist/AProgress/index.js +10 -0
  2. package/dist/AProgress/index.js.map +1 -1
  3. package/dist/Alert/index.js +3 -1
  4. package/dist/Alert/index.js.map +1 -1
  5. package/dist/Badge/index.js +37 -11
  6. package/dist/Badge/index.js.map +1 -1
  7. package/dist/Breadcrumb/index.js +12 -2
  8. package/dist/Breadcrumb/index.js.map +1 -1
  9. package/dist/Button/index.d.ts +1 -1
  10. package/dist/Button/index.js +20 -6
  11. package/dist/Button/index.js.map +1 -1
  12. package/dist/Card/index.js +1 -1
  13. package/dist/Card/index.js.map +1 -1
  14. package/dist/Carousel/index.js +9 -1
  15. package/dist/Carousel/index.js.map +1 -1
  16. package/dist/Checkbox/index.js +17 -2
  17. package/dist/Checkbox/index.js.map +1 -1
  18. package/dist/Checkbox/type.d.ts +10 -2
  19. package/dist/ColorPicker/index.js +112 -46
  20. package/dist/ColorPicker/index.js.map +1 -1
  21. package/dist/DataPreviewTable/components/Body/Cell.d.ts +2 -0
  22. package/dist/DataPreviewTable/components/Body/Cell.js +9 -1
  23. package/dist/DataPreviewTable/components/Body/Cell.js.map +1 -1
  24. package/dist/DataPreviewTable/components/Body/index.d.ts +1 -0
  25. package/dist/DataPreviewTable/components/Body/index.js +35 -23
  26. package/dist/DataPreviewTable/components/Body/index.js.map +1 -1
  27. package/dist/DataPreviewTable/components/Header/index.d.ts +1 -0
  28. package/dist/DataPreviewTable/components/Header/index.js +36 -28
  29. package/dist/DataPreviewTable/components/Header/index.js.map +1 -1
  30. package/dist/DataPreviewTable/index.js +19 -2
  31. package/dist/DataPreviewTable/index.js.map +1 -1
  32. package/dist/Drawer/index.d.ts +4 -0
  33. package/dist/Drawer/index.js +93 -79
  34. package/dist/Drawer/index.js.map +1 -1
  35. package/dist/Dropdown/index.d.ts +1 -1
  36. package/dist/Dropdown/index.js +64 -13
  37. package/dist/Dropdown/index.js.map +1 -1
  38. package/dist/Form/FormItemContext.d.ts +1 -1
  39. package/dist/Form/FormItemContext.js.map +1 -1
  40. package/dist/Form/index.js +50 -7
  41. package/dist/Form/index.js.map +1 -1
  42. package/dist/IconButton/index.d.ts +2 -2
  43. package/dist/IconButton/index.js +9 -3
  44. package/dist/IconButton/index.js.map +1 -1
  45. package/dist/Input/components/Input/index.js +18 -8
  46. package/dist/Input/components/Input/index.js.map +1 -1
  47. package/dist/Input/components/TextArea/index.js +18 -7
  48. package/dist/Input/components/TextArea/index.js.map +1 -1
  49. package/dist/Input/privateSemanticOwner.d.ts +2 -0
  50. package/dist/Input/privateSemanticOwner.js +1 -0
  51. package/dist/InputNumber/index.js +16 -9
  52. package/dist/InputNumber/index.js.map +1 -1
  53. package/dist/InputNumber/type.d.ts +2 -2
  54. package/dist/LogicTree/components/LogicItem/index.d.ts +2 -1
  55. package/dist/LogicTree/components/LogicItem/index.js +13 -2
  56. package/dist/LogicTree/components/LogicItem/index.js.map +1 -1
  57. package/dist/LogicTree/index.js +2 -0
  58. package/dist/LogicTree/index.js.map +1 -1
  59. package/dist/MemberPicker/components/MemberSelection.d.ts +2 -0
  60. package/dist/MemberPicker/components/MemberSelection.js +15 -13
  61. package/dist/MemberPicker/components/MemberSelection.js.map +1 -1
  62. package/dist/MemberPicker/components/MultipleOption.js +12 -0
  63. package/dist/MemberPicker/components/MultipleOption.js.map +1 -1
  64. package/dist/MemberPicker/components/Panel.d.ts +2 -0
  65. package/dist/MemberPicker/components/Panel.js +11 -1
  66. package/dist/MemberPicker/components/Panel.js.map +1 -1
  67. package/dist/MemberPicker/components/PanelWrapper.js +2 -0
  68. package/dist/MemberPicker/components/PanelWrapper.js.map +1 -1
  69. package/dist/MemberPicker/components/SelectedMemberTags.js +14 -6
  70. package/dist/MemberPicker/components/SelectedMemberTags.js.map +1 -1
  71. package/dist/MemberPicker/components/SingleOption.js +12 -0
  72. package/dist/MemberPicker/components/SingleOption.js.map +1 -1
  73. package/dist/MemberPicker/components/UserGroupSelection.d.ts +3 -1
  74. package/dist/MemberPicker/components/UserGroupSelection.js +65 -42
  75. package/dist/MemberPicker/components/UserGroupSelection.js.map +1 -1
  76. package/dist/MemberPicker/index.js +134 -108
  77. package/dist/MemberPicker/index.js.map +1 -1
  78. package/dist/Menu/index.d.ts +8 -0
  79. package/dist/Menu/index.js +33 -3
  80. package/dist/Menu/index.js.map +1 -1
  81. package/dist/Modal/index.d.ts +4 -0
  82. package/dist/Modal/index.js +55 -66
  83. package/dist/Modal/index.js.map +1 -1
  84. package/dist/OverflowCount/index.js +10 -0
  85. package/dist/OverflowCount/index.js.map +1 -1
  86. package/dist/Pagination/index.js +1 -0
  87. package/dist/Pagination/index.js.map +1 -1
  88. package/dist/Popconfirm/index.js +9 -1
  89. package/dist/Popconfirm/index.js.map +1 -1
  90. package/dist/Popover/index.js +52 -1
  91. package/dist/Popover/index.js.map +1 -1
  92. package/dist/Progress/index.js +4 -0
  93. package/dist/Progress/index.js.map +1 -1
  94. package/dist/Radio/components/Group/index.d.ts +5 -1
  95. package/dist/Radio/components/Group/index.js +7 -2
  96. package/dist/Radio/components/Group/index.js.map +1 -1
  97. package/dist/Radio/components/Radio/index.js +26 -0
  98. package/dist/Radio/components/Radio/index.js.map +1 -1
  99. package/dist/Radio/interface/radio.d.ts +7 -0
  100. package/dist/Radio/interface/radioGroup.d.ts +2 -0
  101. package/dist/RenameInput/index.js +11 -0
  102. package/dist/RenameInput/index.js.map +1 -1
  103. package/dist/Select/BaseSelect.d.ts +3 -0
  104. package/dist/Select/BaseSelect.js +229 -32
  105. package/dist/Select/BaseSelect.js.map +1 -1
  106. package/dist/Select/SelectTrigger.d.ts +2 -0
  107. package/dist/Select/SelectTrigger.js +13 -5
  108. package/dist/Select/SelectTrigger.js.map +1 -1
  109. package/dist/Select/components/OptionCollection.d.ts +41 -0
  110. package/dist/Select/components/OptionCollection.js +124 -0
  111. package/dist/Select/components/OptionCollection.js.map +1 -0
  112. package/dist/Select/index.js +45 -3
  113. package/dist/Select/index.js.map +1 -1
  114. package/dist/Select/interface.d.ts +1 -1
  115. package/dist/Skeleton/index.js +1 -1
  116. package/dist/Skeleton/index.js.map +1 -1
  117. package/dist/Spin/index.d.ts +1 -1
  118. package/dist/Spin/index.js +22 -7
  119. package/dist/Spin/index.js.map +1 -1
  120. package/dist/Switch/index.d.ts +5 -0
  121. package/dist/Switch/index.js +15 -5
  122. package/dist/Switch/index.js.map +1 -1
  123. package/dist/Table/components/Header.js +0 -1
  124. package/dist/Table/components/Header.js.map +1 -1
  125. package/dist/Table/index.js +42 -27
  126. package/dist/Table/index.js.map +1 -1
  127. package/dist/Tabs/index.js +1 -0
  128. package/dist/Tabs/index.js.map +1 -1
  129. package/dist/Tag/index.js +20 -1
  130. package/dist/Tag/index.js.map +1 -1
  131. package/dist/Tooltip/index.js +34 -5
  132. package/dist/Tooltip/index.js.map +1 -1
  133. package/dist/Tour/index.js +13 -1
  134. package/dist/Tour/index.js.map +1 -1
  135. package/dist/Tree/Tree2.js +2 -0
  136. package/dist/Tree/Tree2.js.map +1 -1
  137. package/dist/_utils/dialogAccessibility.d.ts +17 -0
  138. package/dist/_utils/dialogAccessibility.js +110 -0
  139. package/dist/_utils/dialogAccessibility.js.map +1 -0
  140. package/dist/_utils/formControlSemanticOwner.d.ts +3 -0
  141. package/dist/_utils/formControlSemanticOwner.js +17 -0
  142. package/dist/_utils/formControlSemanticOwner.js.map +1 -0
  143. package/dist/_utils/overlayCoordinator.js +1 -11
  144. package/dist/_utils/overlayCoordinator.js.map +1 -1
  145. package/dist/aloudata-design.css +1 -1
  146. package/dist/governance/semantic.d.ts +1 -0
  147. package/dist/governance/semantic.js +2 -0
  148. package/dist/governance/semantic.json +1737 -0
  149. package/dist/theme/contract/baselineResolvedTokenValueManifest.d.ts +1 -1
  150. package/dist/theme/contract/darkResolvedTokenValueManifest.d.ts +1 -1
  151. package/dist/theme/contract/tokenOutputContract.js +1 -0
  152. package/dist/theme/contract/tokenOutputContract.js.map +1 -1
  153. package/dist/theme/generator/acceptedColorValues.d.ts +2 -1
  154. package/dist/theme/generator/baselineTokenValueDelivery.d.ts +9 -1
  155. package/dist/theme/generator/minimalAcceptedColorValues.d.ts +2 -2
  156. package/dist/theme/generator/neutralSourceResolver.d.ts +28 -0
  157. package/dist/theme/generator/neutralSourceResolver.js +2 -0
  158. package/dist/theme/generator/neutralSourceValues.d.ts +28 -0
  159. package/dist/theme/generator/neutralSourceValues.js +2 -0
  160. package/dist/theme/governance/semanticGovernanceContract.d.ts +91 -0
  161. package/dist/theme/governance/semanticGovernanceContract.js +342 -0
  162. package/dist/theme/governance/semanticGovernanceContract.js.map +1 -0
  163. package/dist/theme/index.d.ts +2 -0
  164. package/dist/theme/index.js +1 -0
  165. package/dist/theme/neutralSourceContract.d.ts +3 -0
  166. package/dist/theme/neutralSourceContract.js +11 -0
  167. package/dist/theme/neutralSourceContract.js.map +1 -0
  168. package/dist/theme/runtime/colorValueMode/generated/darkBaselineDeclarations.d.ts +1 -1
  169. package/dist/theme/runtime/colorValueMode/generated/darkBaselineDeclarations.js +46 -45
  170. package/dist/theme/runtime/colorValueMode/generated/darkBaselineDeclarations.js.map +1 -1
  171. package/dist/theme/runtime/colorValueMode/generated/slateDarkDeclarations.d.ts +3 -0
  172. package/dist/theme/runtime/colorValueMode/generated/slateDarkDeclarations.js +2 -0
  173. package/dist/theme/runtime/colorValueMode/generated/slateLightDeclarations.d.ts +3 -0
  174. package/dist/theme/runtime/colorValueMode/generated/slateLightDeclarations.js +2 -0
  175. package/dist/theme/runtime/colorValueMode/generated/stoneDarkDeclarations.d.ts +3 -0
  176. package/dist/theme/runtime/colorValueMode/generated/stoneDarkDeclarations.js +2 -0
  177. package/dist/theme/runtime/colorValueMode/generated/stoneLightDeclarations.d.ts +3 -0
  178. package/dist/theme/runtime/colorValueMode/generated/stoneLightDeclarations.js +2 -0
  179. package/dist/theme/runtime/colorValueMode/generated/v3BaselineDeclarations.d.ts +1 -1
  180. package/dist/theme/runtime/colorValueMode/generated/v3BaselineDeclarations.js +42 -41
  181. package/dist/theme/runtime/colorValueMode/generated/v3BaselineDeclarations.js.map +1 -1
  182. package/dist/theme/runtime/colorValueMode/index.js +2 -12
  183. package/dist/theme/runtime/colorValueMode/index.js.map +1 -1
  184. package/dist/theme/runtime/colorValueMode/legacyNeutralCompatibility.d.ts +2 -0
  185. package/dist/theme/runtime/colorValueMode/legacyNeutralCompatibility.js +48 -0
  186. package/dist/theme/runtime/colorValueMode/legacyNeutralCompatibility.js.map +1 -0
  187. package/dist/theme/runtime/colorValueMode/registry.d.ts +1 -1
  188. package/dist/theme/runtime/colorValueMode/registry.js +2 -1
  189. package/dist/theme/runtime/colorValueMode/registry.js.map +1 -1
  190. package/dist/theme/runtime/initAldTheme.js +1 -3
  191. package/dist/theme/runtime/initAldTheme.js.map +1 -1
  192. package/dist/theme/runtime/neutralSource/index.d.ts +6 -0
  193. package/dist/theme/runtime/neutralSource/index.js +11 -0
  194. package/dist/theme/runtime/neutralSource/index.js.map +1 -0
  195. package/dist/theme/runtime/neutralSource.d.ts +2 -0
  196. package/package.json +12 -2
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/OverflowCount/index.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport Badge, { BadgeProps } from '../Badge';\nimport { cn } from '../lib/utils';\nimport Popover from '../Popover';\n\ninterface OverflowCountProps<T> {\n data: T[];\n renderItem: (item: T) => React.ReactNode;\n badge?: Omit<BadgeProps, 'count'>;\n popupClassName?: string;\n suffix?: React.ReactNode;\n size?: 'small' | 'default';\n}\n\nfunction OverflowCount<T = unknown>(props: OverflowCountProps<T>) {\n const {\n data,\n renderItem: propsRenderItem,\n popupClassName = '',\n badge,\n size,\n suffix,\n } = props;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [visibleCount, setVisibleCount] = useState(data.length);\n const [isPopupOpen, setIsPopupOpen] = useState(false);\n\n const itemClassName = cn(\n prefixCls('item'),\n 'tw-flex',\n size === 'small' ? [prefixCls('item-small'), 'tw-pr-1'] : 'tw-pr-1.5',\n );\n\n // Measure which items fit\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const measure = () => {\n const children = Array.from(\n container.querySelectorAll(`.${prefixCls('item')}`),\n );\n if (children.length === 0) {\n setVisibleCount(data.length);\n return;\n }\n const containerRight = container.getBoundingClientRect().right;\n let count = 0;\n for (const child of children) {\n const rect = (child as HTMLElement).getBoundingClientRect();\n if (rect.right <= containerRight - 40) {\n count++;\n } else {\n break;\n }\n }\n setVisibleCount(Math.max(1, count));\n };\n\n measure();\n const ro = new window.ResizeObserver(measure);\n ro.observe(container);\n return () => ro.disconnect();\n }, [data.length]);\n\n const visibleItems = data.slice(0, visibleCount);\n const omittedItems = data.slice(visibleCount);\n\n const renderRest = useCallback(() => {\n if (omittedItems.length === 0) return null;\n\n const itemNodes = omittedItems.map((item, index) => (\n <div key={index} className={itemClassName}>\n {propsRenderItem(item)}\n </div>\n ));\n\n return (\n <Popover\n content={\n <div\n className={cn(\n prefixCls('popup-container'),\n 'tw-flex tw-max-h-[300px] tw-w-[360px] tw-flex-wrap tw-overflow-y-auto',\n size === 'small'\n ? [prefixCls('popup-container-small'), 'tw-gap-y-1']\n : 'tw-gap-y-1.5',\n popupClassName,\n )}\n >\n {itemNodes}\n </div>\n }\n trigger=\"hover\"\n open={isPopupOpen}\n onOpenChange={(open) => setIsPopupOpen(open)}\n >\n <div\n className={cn(\n prefixCls('rest-btn'),\n 'tw-flex tw-cursor-pointer tw-items-center',\n )}\n >\n <Badge count={`+${omittedItems.length}`} status=\"info\" {...badge} />\n </div>\n </Popover>\n );\n }, [\n omittedItems,\n badge,\n popupClassName,\n propsRenderItem,\n itemClassName,\n size,\n isPopupOpen,\n ]);\n\n return (\n <div className={cn(prefixCls('container'), 'tw-w-full')}>\n <div\n ref={containerRef}\n className={cn(\n prefixCls('overflow'),\n 'tw-flex tw-flex-nowrap tw-items-center tw-overflow-hidden',\n )}\n >\n {visibleItems.map((item, i) => (\n <div key={i} className={itemClassName}>\n {propsRenderItem(item)}\n </div>\n ))}\n {renderRest()}\n {suffix}\n </div>\n </div>\n );\n}\n\nexport default OverflowCount;\n\nconst ALD_PREFIX = 'ald-overflow-count';\nexport function prefixCls(className: string) {\n return `${ALD_PREFIX}-${className}`;\n}\n"],"mappings":";;;;;;AAcA,SAAS,cAA2B,OAA8B;CAChE,MAAM,EACJ,MACA,YAAY,iBACZ,iBAAiB,IACjB,OACA,MACA,WACE;CAEJ,MAAM,eAAe,OAAuB,KAAK;CACjD,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK,OAAO;CAC7D,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;CAErD,MAAM,gBAAgB,GACpB,UAAU,OAAO,EACjB,WACA,SAAS,UAAU,CAAC,UAAU,aAAa,EAAE,UAAU,GAAG,YAC3D;AAGD,iBAAgB;EACd,MAAM,YAAY,aAAa;AAC/B,MAAI,CAAC,UAAW;EAEhB,MAAM,gBAAgB;GACpB,MAAM,WAAW,MAAM,KACrB,UAAU,iBAAiB,IAAI,UAAU,OAAO,GAAG,CACpD;AACD,OAAI,SAAS,WAAW,GAAG;AACzB,oBAAgB,KAAK,OAAO;AAC5B;;GAEF,MAAM,iBAAiB,UAAU,uBAAuB,CAAC;GACzD,IAAI,QAAQ;AACZ,QAAK,MAAM,SAAS,SAElB,KADc,MAAsB,uBAAuB,CAClD,SAAS,iBAAiB,GACjC;OAEA;AAGJ,mBAAgB,KAAK,IAAI,GAAG,MAAM,CAAC;;AAGrC,WAAS;EACT,MAAM,KAAK,IAAI,OAAO,eAAe,QAAQ;AAC7C,KAAG,QAAQ,UAAU;AACrB,eAAa,GAAG,YAAY;IAC3B,CAAC,KAAK,OAAO,CAAC;CAEjB,MAAM,eAAe,KAAK,MAAM,GAAG,aAAa;CAChD,MAAM,eAAe,KAAK,MAAM,aAAa;CAE7C,MAAM,aAAa,kBAAkB;AACnC,MAAI,aAAa,WAAW,EAAG,QAAO;EAEtC,MAAM,YAAY,aAAa,KAAK,MAAM,UACxC,oBAAC,OAAD;GAAiB,WAAW;aACzB,gBAAgB,KAAK;GAClB,EAFI,MAEJ,CACN;AAEF,SACE,oBAAC,SAAD;GACE,SACE,oBAAC,OAAD;IACE,WAAW,GACT,UAAU,kBAAkB,EAC5B,yEACA,SAAS,UACL,CAAC,UAAU,wBAAwB,EAAE,aAAa,GAClD,gBACJ,eACD;cAEA;IACG,CAAA;GAER,SAAQ;GACR,MAAM;GACN,eAAe,SAAS,eAAe,KAAK;aAE5C,oBAAC,OAAD;IACE,WAAW,GACT,UAAU,WAAW,EACrB,4CACD;cAED,oBAAC,OAAD;KAAO,OAAO,IAAI,aAAa;KAAU,QAAO;KAAO,GAAI;KAAS,CAAA;IAChE,CAAA;GACE,CAAA;IAEX;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,QACE,oBAAC,OAAD;EAAK,WAAW,GAAG,UAAU,YAAY,EAAE,YAAY;YACrD,qBAAC,OAAD;GACE,KAAK;GACL,WAAW,GACT,UAAU,WAAW,EACrB,4DACD;aALH;IAOG,aAAa,KAAK,MAAM,MACvB,oBAAC,OAAD;KAAa,WAAW;eACrB,gBAAgB,KAAK;KAClB,EAFI,EAEJ,CACN;IACD,YAAY;IACZ;IACG;;EACF,CAAA;;AAMV,IAAM,aAAa;AACnB,SAAgB,UAAU,WAAmB;AAC3C,QAAO,GAAG,WAAW,GAAG"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/OverflowCount/index.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport Badge, { BadgeProps } from '../Badge';\nimport { cn } from '../lib/utils';\nimport Popover from '../Popover';\n\ninterface OverflowCountProps<T> {\n data: T[];\n renderItem: (item: T) => React.ReactNode;\n badge?: Omit<BadgeProps, 'count'>;\n popupClassName?: string;\n suffix?: React.ReactNode;\n size?: 'small' | 'default';\n}\n\nfunction OverflowCount<T = unknown>(props: OverflowCountProps<T>) {\n const {\n data,\n renderItem: propsRenderItem,\n popupClassName = '',\n badge,\n size,\n suffix,\n } = props;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [visibleCount, setVisibleCount] = useState(data.length);\n const [isPopupOpen, setIsPopupOpen] = useState(false);\n\n const itemClassName = cn(\n prefixCls('item'),\n 'tw-flex',\n size === 'small' ? [prefixCls('item-small'), 'tw-pr-1'] : 'tw-pr-1.5',\n );\n\n // Measure which items fit\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const measure = () => {\n const children = Array.from(\n container.querySelectorAll(`.${prefixCls('item')}`),\n );\n if (children.length === 0) {\n setVisibleCount(data.length);\n return;\n }\n const containerRight = container.getBoundingClientRect().right;\n let count = 0;\n for (const child of children) {\n const rect = (child as HTMLElement).getBoundingClientRect();\n if (rect.right <= containerRight - 40) {\n count++;\n } else {\n break;\n }\n }\n setVisibleCount(Math.max(1, count));\n };\n\n measure();\n const ro = new window.ResizeObserver(measure);\n ro.observe(container);\n return () => ro.disconnect();\n }, [data.length]);\n\n const visibleItems = data.slice(0, visibleCount);\n const omittedItems = data.slice(visibleCount);\n\n const renderRest = useCallback(() => {\n if (omittedItems.length === 0) return null;\n\n const itemNodes = omittedItems.map((item, index) => (\n <div key={index} className={itemClassName}>\n {propsRenderItem(item)}\n </div>\n ));\n\n return (\n <Popover\n content={\n <div\n className={cn(\n prefixCls('popup-container'),\n 'tw-flex tw-max-h-[300px] tw-w-[360px] tw-flex-wrap tw-overflow-y-auto',\n size === 'small'\n ? [prefixCls('popup-container-small'), 'tw-gap-y-1']\n : 'tw-gap-y-1.5',\n popupClassName,\n )}\n >\n {itemNodes}\n </div>\n }\n trigger=\"hover\"\n open={isPopupOpen}\n onOpenChange={(open) => setIsPopupOpen(open)}\n >\n <div\n className={cn(\n prefixCls('rest-btn'),\n 'tw-flex tw-cursor-pointer tw-items-center',\n )}\n role=\"button\"\n tabIndex={0}\n aria-label={`Show ${omittedItems.length} more items`}\n aria-expanded={isPopupOpen}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n setIsPopupOpen((open) => !open);\n }\n }}\n >\n <Badge count={`+${omittedItems.length}`} status=\"info\" {...badge} />\n </div>\n </Popover>\n );\n }, [\n omittedItems,\n badge,\n popupClassName,\n propsRenderItem,\n itemClassName,\n size,\n isPopupOpen,\n ]);\n\n return (\n <div className={cn(prefixCls('container'), 'tw-w-full')}>\n <div\n ref={containerRef}\n className={cn(\n prefixCls('overflow'),\n 'tw-flex tw-flex-nowrap tw-items-center tw-overflow-hidden',\n )}\n >\n {visibleItems.map((item, i) => (\n <div key={i} className={itemClassName}>\n {propsRenderItem(item)}\n </div>\n ))}\n {renderRest()}\n {suffix}\n </div>\n </div>\n );\n}\n\nexport default OverflowCount;\n\nconst ALD_PREFIX = 'ald-overflow-count';\nexport function prefixCls(className: string) {\n return `${ALD_PREFIX}-${className}`;\n}\n"],"mappings":";;;;;;AAcA,SAAS,cAA2B,OAA8B;CAChE,MAAM,EACJ,MACA,YAAY,iBACZ,iBAAiB,IACjB,OACA,MACA,WACE;CAEJ,MAAM,eAAe,OAAuB,KAAK;CACjD,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK,OAAO;CAC7D,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;CAErD,MAAM,gBAAgB,GACpB,UAAU,OAAO,EACjB,WACA,SAAS,UAAU,CAAC,UAAU,aAAa,EAAE,UAAU,GAAG,YAC3D;AAGD,iBAAgB;EACd,MAAM,YAAY,aAAa;AAC/B,MAAI,CAAC,UAAW;EAEhB,MAAM,gBAAgB;GACpB,MAAM,WAAW,MAAM,KACrB,UAAU,iBAAiB,IAAI,UAAU,OAAO,GAAG,CACpD;AACD,OAAI,SAAS,WAAW,GAAG;AACzB,oBAAgB,KAAK,OAAO;AAC5B;;GAEF,MAAM,iBAAiB,UAAU,uBAAuB,CAAC;GACzD,IAAI,QAAQ;AACZ,QAAK,MAAM,SAAS,SAElB,KADc,MAAsB,uBAAuB,CAClD,SAAS,iBAAiB,GACjC;OAEA;AAGJ,mBAAgB,KAAK,IAAI,GAAG,MAAM,CAAC;;AAGrC,WAAS;EACT,MAAM,KAAK,IAAI,OAAO,eAAe,QAAQ;AAC7C,KAAG,QAAQ,UAAU;AACrB,eAAa,GAAG,YAAY;IAC3B,CAAC,KAAK,OAAO,CAAC;CAEjB,MAAM,eAAe,KAAK,MAAM,GAAG,aAAa;CAChD,MAAM,eAAe,KAAK,MAAM,aAAa;CAE7C,MAAM,aAAa,kBAAkB;AACnC,MAAI,aAAa,WAAW,EAAG,QAAO;EAEtC,MAAM,YAAY,aAAa,KAAK,MAAM,UACxC,oBAAC,OAAD;GAAiB,WAAW;aACzB,gBAAgB,KAAK;GAClB,EAFI,MAEJ,CACN;AAEF,SACE,oBAAC,SAAD;GACE,SACE,oBAAC,OAAD;IACE,WAAW,GACT,UAAU,kBAAkB,EAC5B,yEACA,SAAS,UACL,CAAC,UAAU,wBAAwB,EAAE,aAAa,GAClD,gBACJ,eACD;cAEA;IACG,CAAA;GAER,SAAQ;GACR,MAAM;GACN,eAAe,SAAS,eAAe,KAAK;aAE5C,oBAAC,OAAD;IACE,WAAW,GACT,UAAU,WAAW,EACrB,4CACD;IACD,MAAK;IACL,UAAU;IACV,cAAY,QAAQ,aAAa,OAAO;IACxC,iBAAe;IACf,YAAY,UAAU;AACpB,SAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;AAC9C,YAAM,gBAAgB;AACtB,sBAAgB,SAAS,CAAC,KAAK;;;cAInC,oBAAC,OAAD;KAAO,OAAO,IAAI,aAAa;KAAU,QAAO;KAAO,GAAI;KAAS,CAAA;IAChE,CAAA;GACE,CAAA;IAEX;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,QACE,oBAAC,OAAD;EAAK,WAAW,GAAG,UAAU,YAAY,EAAE,YAAY;YACrD,qBAAC,OAAD;GACE,KAAK;GACL,WAAW,GACT,UAAU,WAAW,EACrB,4DACD;aALH;IAOG,aAAa,KAAK,MAAM,MACvB,oBAAC,OAAD;KAAa,WAAW;eACrB,gBAAgB,KAAK;KAClB,EAFI,EAEJ,CACN;IACD,YAAY;IACZ;IACG;;EACF,CAAA;;AAMV,IAAM,aAAa;AACnB,SAAgB,UAAU,WAAmB;AAC3C,QAAO,GAAG,WAAW,GAAG"}
@@ -84,6 +84,7 @@ function Pagination(props) {
84
84
  _.map(pageRange, (page, index) => {
85
85
  if (page === "...") return /* @__PURE__ */ jsx("span", {
86
86
  className: prefixCls("ellipsis"),
87
+ "aria-hidden": "true",
87
88
  children: /* @__PURE__ */ jsx(Memo$2, { size: 20 })
88
89
  }, index);
89
90
  return /* @__PURE__ */ jsx(Button_default, {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Pagination/index.tsx"],"sourcesContent":["import { cn } from '../lib/utils';\nimport _ from 'lodash';\nimport React, { useCallback, useContext, useState } from 'react';\nimport Button from '../Button';\nimport { ChevronLeftLine, ChevronRightLine, Ellipsis } from '../Icon';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport { IPaginationProps } from './types';\nimport PageSizeChanger from './PageSizeChanger';\nimport './pagination.css';\n\nfunction Pagination(props: IPaginationProps) {\n const {\n current: controlledCurrent,\n defaultCurrent = 1,\n pageSize,\n total,\n onChange,\n hideOnSinglePage,\n showSizeChanger = false,\n pageSizeOptions = [10, 20, 30, 50],\n onShowSizeChange,\n showTotal = false,\n disabled = false,\n 'aria-label': ariaLabel,\n } = props;\n\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n const a11y = t.Pagination;\n const [uncontrolledCurrent, setUncontrolledCurrent] =\n useState(defaultCurrent);\n\n if (pageSize <= 0) {\n throw new Error('pageSize must be greater than 0');\n }\n\n const totalPage = getTotalPage(total, pageSize);\n const current = getSafeCurrent(\n totalPage,\n controlledCurrent ?? uncontrolledCurrent,\n );\n\n const onChangePage = useCallback(\n (page: number) => {\n return () => {\n if (disabled || page === current || page < 1 || page > totalPage) {\n return;\n }\n if (controlledCurrent === undefined) {\n setUncontrolledCurrent(page);\n }\n onChange(page, pageSize);\n };\n },\n [controlledCurrent, disabled, onChange, current, pageSize, totalPage],\n );\n\n const handlePageSizeChange = useCallback(\n (newPageSize: number) => {\n if (disabled || newPageSize <= 0 || newPageSize === pageSize) {\n return;\n }\n const newTotalPage = getTotalPage(total, newPageSize);\n const safeCurrent = getSafeCurrent(newTotalPage, current);\n\n if (controlledCurrent === undefined) {\n setUncontrolledCurrent(safeCurrent);\n }\n if (onShowSizeChange) {\n onShowSizeChange(safeCurrent, newPageSize);\n }\n\n onChange(safeCurrent, newPageSize);\n },\n [\n controlledCurrent,\n current,\n disabled,\n onChange,\n onShowSizeChange,\n pageSize,\n total,\n ],\n );\n\n const pageRange = getPaginationRange(totalPage, current);\n\n if (hideOnSinglePage) {\n if (totalPage <= 1 && !showSizeChanger && !showTotal) {\n return null;\n }\n }\n\n // 计算当前显示的数据范围\n const startIndex = (current - 1) * pageSize + 1;\n const endIndex = Math.min(current * pageSize, total);\n const range: [number, number] = [startIndex, endIndex];\n\n const containerClassName = prefixCls('container');\n\n // 获取显示总数的函数\n const getShowTotalContent = () => {\n if (typeof showTotal === 'function') {\n return showTotal(total, range);\n }\n if (showTotal === true) {\n return t.Pagination.totalItems(total, range);\n }\n return null;\n };\n\n return (\n <nav\n className={containerClassName}\n aria-label={ariaLabel ?? a11y.navigationLabel}\n >\n {/* 显示总数和当前范围 */}\n {showTotal && (\n <div className={prefixCls('total')}>{getShowTotalContent()}</div>\n )}\n\n {/* 主要的分页控件 */}\n <div className={prefixCls('main')}>\n <Button\n icon={<ChevronLeftLine size={16} />}\n onClick={onChangePage(current - 1)}\n disabled={disabled || current === 1}\n aria-label={a11y.previousPage}\n />\n {_.map(pageRange, (page, index: number) => {\n if (page === ELLIPSIS) {\n return (\n <span key={index} className={prefixCls('ellipsis')}>\n <Ellipsis size={20} />\n </span>\n );\n }\n return (\n <Button\n key={index}\n icon={<span>{page}</span>}\n className={cn(prefixCls('button'), {\n [prefixCls('active')]: page === current,\n })}\n onClick={onChangePage(page)}\n disabled={disabled}\n aria-label={\n page === current ? a11y.currentPage(page) : a11y.page(page)\n }\n {...(page === current\n ? ({ 'aria-current': 'page' } as React.AriaAttributes)\n : {})}\n />\n );\n })}\n <Button\n icon={<ChevronRightLine size={16} />}\n onClick={onChangePage(current + 1)}\n disabled={disabled || current >= totalPage}\n aria-label={a11y.nextPage}\n />\n </div>\n\n {/* 页面大小选择器 */}\n {showSizeChanger && (\n <PageSizeChanger\n pageSize={pageSize}\n pageSizeOptions={pageSizeOptions}\n onChange={handlePageSizeChange}\n disabled={disabled}\n ariaLabel={a11y.pageSize}\n />\n )}\n </nav>\n );\n}\n\nexport default Pagination;\n\n/**\n * 获取在安全范围内的当前页数\n */\nexport function getSafeCurrent(totalPage: number, current?: number) {\n if (current === undefined) {\n return 1;\n }\n return Math.max(1, Math.min(current, totalPage));\n}\n\nfunction getTotalPage(total: number, pageSize: number) {\n return Math.max(1, Math.ceil(total / pageSize));\n}\n\nexport const ELLIPSIS = '...';\n\nexport type PaginationItemType = number | typeof ELLIPSIS;\n\n/**\n * 获取分页组件需要显示的页码范围。\n *\n * @param totalPage 最大页码。\n * @param currentPage 当前所在的页码。\n *\n * 如果总页数不超过5页,直接返回所有页码。\n * 否则,在生成页码时,除了第一页和最后一页,还会显示以当前页为中心的连续页码,数量为 `surroundCount`*2 个,\n * 当当前页码距离边界过近时,会在页码前后添加省略号。\n * 当前页码 `currentPage` 的值必须介于 1 和总页数之间,如果超出这个范围,会自动修正。\n *\n * @returns 一个包含了所有要显示的页码和省略号的数组。\n */\nexport function getPaginationRange(\n totalPage: number,\n currentPage: number,\n): PaginationItemType[] {\n // 如果总页数不超过5页,直接返回所有页码\n if (totalPage <= 5) {\n return Array.from({ length: totalPage }, (_, i) => i + 1);\n }\n\n const surroundCount = 2;\n\n const current = Math.max(1, Math.min(currentPage, totalPage));\n\n let start = Math.max(2, current - surroundCount);\n let end = Math.min(totalPage - 1, current + surroundCount);\n\n // Adjust start and end based on current page\n if (current - start < surroundCount) {\n end = Math.min(end + (surroundCount - (current - start)), totalPage - 1);\n }\n if (end - current < surroundCount) {\n start = Math.max(start - (surroundCount - (end - current)), 2);\n }\n\n // Check if current page is out of range\n if (current < start || current > end) {\n start = Math.max(2, current - surroundCount);\n end = Math.min(totalPage - 1, current + surroundCount);\n }\n\n const range: PaginationItemType[] = [];\n for (let i = start; i <= end; i++) {\n range.push(i);\n }\n\n range.unshift(1);\n if (start > 2 && range[1] !== ELLIPSIS) {\n range.splice(1, 0, ELLIPSIS);\n }\n\n if (totalPage !== range[range.length - 1]) {\n if (end < totalPage - 1 && range[range.length - 1] !== ELLIPSIS) {\n range.splice(range.length, 0, ELLIPSIS);\n }\n range.push(totalPage);\n }\n\n return range;\n}\n\nfunction prefixCls(name: string) {\n return `ald-pagination-${name}`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Pagination/index.tsx"],"sourcesContent":["import { cn } from '../lib/utils';\nimport _ from 'lodash';\nimport React, { useCallback, useContext, useState } from 'react';\nimport Button from '../Button';\nimport { ChevronLeftLine, ChevronRightLine, Ellipsis } from '../Icon';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport { IPaginationProps } from './types';\nimport PageSizeChanger from './PageSizeChanger';\nimport './pagination.css';\n\nfunction Pagination(props: IPaginationProps) {\n const {\n current: controlledCurrent,\n defaultCurrent = 1,\n pageSize,\n total,\n onChange,\n hideOnSinglePage,\n showSizeChanger = false,\n pageSizeOptions = [10, 20, 30, 50],\n onShowSizeChange,\n showTotal = false,\n disabled = false,\n 'aria-label': ariaLabel,\n } = props;\n\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n const a11y = t.Pagination;\n const [uncontrolledCurrent, setUncontrolledCurrent] =\n useState(defaultCurrent);\n\n if (pageSize <= 0) {\n throw new Error('pageSize must be greater than 0');\n }\n\n const totalPage = getTotalPage(total, pageSize);\n const current = getSafeCurrent(\n totalPage,\n controlledCurrent ?? uncontrolledCurrent,\n );\n\n const onChangePage = useCallback(\n (page: number) => {\n return () => {\n if (disabled || page === current || page < 1 || page > totalPage) {\n return;\n }\n if (controlledCurrent === undefined) {\n setUncontrolledCurrent(page);\n }\n onChange(page, pageSize);\n };\n },\n [controlledCurrent, disabled, onChange, current, pageSize, totalPage],\n );\n\n const handlePageSizeChange = useCallback(\n (newPageSize: number) => {\n if (disabled || newPageSize <= 0 || newPageSize === pageSize) {\n return;\n }\n const newTotalPage = getTotalPage(total, newPageSize);\n const safeCurrent = getSafeCurrent(newTotalPage, current);\n\n if (controlledCurrent === undefined) {\n setUncontrolledCurrent(safeCurrent);\n }\n if (onShowSizeChange) {\n onShowSizeChange(safeCurrent, newPageSize);\n }\n\n onChange(safeCurrent, newPageSize);\n },\n [\n controlledCurrent,\n current,\n disabled,\n onChange,\n onShowSizeChange,\n pageSize,\n total,\n ],\n );\n\n const pageRange = getPaginationRange(totalPage, current);\n\n if (hideOnSinglePage) {\n if (totalPage <= 1 && !showSizeChanger && !showTotal) {\n return null;\n }\n }\n\n // 计算当前显示的数据范围\n const startIndex = (current - 1) * pageSize + 1;\n const endIndex = Math.min(current * pageSize, total);\n const range: [number, number] = [startIndex, endIndex];\n\n const containerClassName = prefixCls('container');\n\n // 获取显示总数的函数\n const getShowTotalContent = () => {\n if (typeof showTotal === 'function') {\n return showTotal(total, range);\n }\n if (showTotal === true) {\n return t.Pagination.totalItems(total, range);\n }\n return null;\n };\n\n return (\n <nav\n className={containerClassName}\n aria-label={ariaLabel ?? a11y.navigationLabel}\n >\n {/* 显示总数和当前范围 */}\n {showTotal && (\n <div className={prefixCls('total')}>{getShowTotalContent()}</div>\n )}\n\n {/* 主要的分页控件 */}\n <div className={prefixCls('main')}>\n <Button\n icon={<ChevronLeftLine size={16} />}\n onClick={onChangePage(current - 1)}\n disabled={disabled || current === 1}\n aria-label={a11y.previousPage}\n />\n {_.map(pageRange, (page, index: number) => {\n if (page === ELLIPSIS) {\n return (\n <span\n key={index}\n className={prefixCls('ellipsis')}\n aria-hidden=\"true\"\n >\n <Ellipsis size={20} />\n </span>\n );\n }\n return (\n <Button\n key={index}\n icon={<span>{page}</span>}\n className={cn(prefixCls('button'), {\n [prefixCls('active')]: page === current,\n })}\n onClick={onChangePage(page)}\n disabled={disabled}\n aria-label={\n page === current ? a11y.currentPage(page) : a11y.page(page)\n }\n {...(page === current\n ? ({ 'aria-current': 'page' } as React.AriaAttributes)\n : {})}\n />\n );\n })}\n <Button\n icon={<ChevronRightLine size={16} />}\n onClick={onChangePage(current + 1)}\n disabled={disabled || current >= totalPage}\n aria-label={a11y.nextPage}\n />\n </div>\n\n {/* 页面大小选择器 */}\n {showSizeChanger && (\n <PageSizeChanger\n pageSize={pageSize}\n pageSizeOptions={pageSizeOptions}\n onChange={handlePageSizeChange}\n disabled={disabled}\n ariaLabel={a11y.pageSize}\n />\n )}\n </nav>\n );\n}\n\nexport default Pagination;\n\n/**\n * 获取在安全范围内的当前页数\n */\nexport function getSafeCurrent(totalPage: number, current?: number) {\n if (current === undefined) {\n return 1;\n }\n return Math.max(1, Math.min(current, totalPage));\n}\n\nfunction getTotalPage(total: number, pageSize: number) {\n return Math.max(1, Math.ceil(total / pageSize));\n}\n\nexport const ELLIPSIS = '...';\n\nexport type PaginationItemType = number | typeof ELLIPSIS;\n\n/**\n * 获取分页组件需要显示的页码范围。\n *\n * @param totalPage 最大页码。\n * @param currentPage 当前所在的页码。\n *\n * 如果总页数不超过5页,直接返回所有页码。\n * 否则,在生成页码时,除了第一页和最后一页,还会显示以当前页为中心的连续页码,数量为 `surroundCount`*2 个,\n * 当当前页码距离边界过近时,会在页码前后添加省略号。\n * 当前页码 `currentPage` 的值必须介于 1 和总页数之间,如果超出这个范围,会自动修正。\n *\n * @returns 一个包含了所有要显示的页码和省略号的数组。\n */\nexport function getPaginationRange(\n totalPage: number,\n currentPage: number,\n): PaginationItemType[] {\n // 如果总页数不超过5页,直接返回所有页码\n if (totalPage <= 5) {\n return Array.from({ length: totalPage }, (_, i) => i + 1);\n }\n\n const surroundCount = 2;\n\n const current = Math.max(1, Math.min(currentPage, totalPage));\n\n let start = Math.max(2, current - surroundCount);\n let end = Math.min(totalPage - 1, current + surroundCount);\n\n // Adjust start and end based on current page\n if (current - start < surroundCount) {\n end = Math.min(end + (surroundCount - (current - start)), totalPage - 1);\n }\n if (end - current < surroundCount) {\n start = Math.max(start - (surroundCount - (end - current)), 2);\n }\n\n // Check if current page is out of range\n if (current < start || current > end) {\n start = Math.max(2, current - surroundCount);\n end = Math.min(totalPage - 1, current + surroundCount);\n }\n\n const range: PaginationItemType[] = [];\n for (let i = start; i <= end; i++) {\n range.push(i);\n }\n\n range.unshift(1);\n if (start > 2 && range[1] !== ELLIPSIS) {\n range.splice(1, 0, ELLIPSIS);\n }\n\n if (totalPage !== range[range.length - 1]) {\n if (end < totalPage - 1 && range[range.length - 1] !== ELLIPSIS) {\n range.splice(range.length, 0, ELLIPSIS);\n }\n range.push(totalPage);\n }\n\n return range;\n}\n\nfunction prefixCls(name: string) {\n return `ald-pagination-${name}`;\n}\n"],"mappings":"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"}
@@ -75,10 +75,14 @@ function Popconfirm(props) {
75
75
  const side = sideMap[placement] || "top";
76
76
  const align = alignMap[placement] || "center";
77
77
  const popupZIndex = useFloatingPopupZIndex();
78
- const triggerChild = React.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
78
+ const idBase = React.useId().replace(/:/g, "");
79
+ const contentId = `ald-popconfirm-${idBase}`;
80
+ const titleId = `ald-popconfirm-title-${idBase}`;
81
+ const triggerChild = React.isValidElement(children) ? React.cloneElement(children, { "aria-controls": contentId }) : /* @__PURE__ */ jsx("span", { children });
79
82
  return /* @__PURE__ */ jsxs(PopoverPrimitive.Root, {
80
83
  open: mergedOpen,
81
84
  onOpenChange: handleOpenChange,
85
+ modal: false,
82
86
  children: [/* @__PURE__ */ jsx(PopoverPrimitive.Trigger, {
83
87
  asChild: true,
84
88
  ref: setTriggerNode,
@@ -86,6 +90,9 @@ function Popconfirm(props) {
86
90
  }), /* @__PURE__ */ jsx(PopoverPrimitive.Portal, {
87
91
  container: popupContainer,
88
92
  children: /* @__PURE__ */ jsx(PopoverPrimitive.Content, {
93
+ id: contentId,
94
+ role: "region",
95
+ "aria-labelledby": title ? titleId : void 0,
89
96
  side,
90
97
  align,
91
98
  sideOffset: 4,
@@ -102,6 +109,7 @@ function Popconfirm(props) {
102
109
  }), /* @__PURE__ */ jsxs("div", {
103
110
  className: "tw-flex-1",
104
111
  children: [/* @__PURE__ */ jsx("div", {
112
+ id: titleId,
105
113
  className: "tw-mb-2 tw-break-all tw-text-xs tw-leading-4 tw-text-[var(--content-primary)]",
106
114
  children: title
107
115
  }), /* @__PURE__ */ jsxs("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Popconfirm/index.tsx"],"sourcesContent":["import * as PopoverPrimitive from '@radix-ui/react-popover';\nimport React, { useState } from 'react';\nimport Button, { ButtonType, IButtonProps } from '../Button';\nimport { AttentionTriangleFill } from '../Icon';\nimport { useFloatingPopupZIndex } from '../_utils/floatingLayer';\nimport { cn } from '../lib/utils';\n\nexport interface PopconfirmProps {\n title?: React.ReactNode;\n onConfirm?: (e?: React.MouseEvent) => void;\n onCancel?: (e?: React.MouseEvent) => void;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n icon?: React.ReactNode;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n placement?:\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight'\n | 'leftTop'\n | 'leftBottom'\n | 'rightTop'\n | 'rightBottom';\n rootClassName?: string;\n className?: string;\n overlayClassName?: string;\n getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;\n children?: React.ReactNode;\n disabled?: boolean;\n}\n\nconst sideMap: Record<string, PopoverPrimitive.PopoverContentProps['side']> = {\n top: 'top',\n bottom: 'bottom',\n left: 'left',\n right: 'right',\n topLeft: 'top',\n topRight: 'top',\n bottomLeft: 'bottom',\n bottomRight: 'bottom',\n leftTop: 'left',\n leftBottom: 'left',\n rightTop: 'right',\n rightBottom: 'right',\n};\n\nconst alignMap: Record<string, PopoverPrimitive.PopoverContentProps['align']> =\n {\n topLeft: 'start',\n topRight: 'end',\n bottomLeft: 'start',\n bottomRight: 'end',\n leftTop: 'start',\n leftBottom: 'end',\n rightTop: 'start',\n rightBottom: 'end',\n };\n\nfunction Popconfirm(props: PopconfirmProps) {\n const {\n title,\n onConfirm,\n onCancel,\n okText = 'OK',\n cancelText = 'Cancel',\n okButtonProps = {},\n cancelButtonProps = {},\n okType = 'dangerous',\n icon = (\n <AttentionTriangleFill\n size={16}\n color=\"var(--action-destructive-normal)\"\n fill=\"var(--action-inverted-normal)\"\n />\n ),\n open: controlledOpen,\n onOpenChange,\n placement = 'top',\n rootClassName,\n overlayClassName,\n getPopupContainer,\n children,\n disabled,\n } = props;\n\n const [innerOpen, setInnerOpen] = useState(false);\n const triggerRef = React.useRef<HTMLElement | null>(null);\n const getPopupContainerRef = React.useRef(getPopupContainer);\n const lastGetPopupContainerRef = React.useRef(getPopupContainer);\n const [popupContainer, setPopupContainer] = useState<\n HTMLElement | undefined\n >();\n getPopupContainerRef.current = getPopupContainer;\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : innerOpen;\n const mergedOpen = disabled ? false : isOpen;\n const updatePopupContainer = React.useCallback((node: HTMLElement | null) => {\n const nextContainer =\n node && getPopupContainerRef.current\n ? getPopupContainerRef.current(node)\n : undefined;\n setPopupContainer((prevContainer) =>\n prevContainer === nextContainer ? prevContainer : nextContainer,\n );\n }, []);\n const setTriggerNode = React.useCallback(\n (node: HTMLElement | null) => {\n if (!node) return;\n if (triggerRef.current === node) return;\n triggerRef.current = node;\n updatePopupContainer(node);\n },\n [updatePopupContainer],\n );\n\n React.useEffect(() => {\n if (lastGetPopupContainerRef.current === getPopupContainer) return;\n lastGetPopupContainerRef.current = getPopupContainer;\n updatePopupContainer(triggerRef.current);\n }, [getPopupContainer, updatePopupContainer]);\n\n const handleOpenChange = (val: boolean) => {\n if (disabled) return;\n if (!isControlled) setInnerOpen(val);\n onOpenChange?.(val);\n };\n\n const handleConfirm = (e?: React.MouseEvent) => {\n onConfirm?.(e);\n handleOpenChange(false);\n };\n\n const handleCancel = (e?: React.MouseEvent) => {\n onCancel?.(e);\n handleOpenChange(false);\n };\n\n const side = sideMap[placement] || 'top';\n const align = alignMap[placement] || 'center';\n const popupZIndex = useFloatingPopupZIndex();\n const triggerChild = React.isValidElement(children) ? (\n children\n ) : (\n <span>{children}</span>\n );\n\n return (\n <PopoverPrimitive.Root open={mergedOpen} onOpenChange={handleOpenChange}>\n <PopoverPrimitive.Trigger asChild ref={setTriggerNode}>\n {triggerChild}\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={popupContainer}>\n <PopoverPrimitive.Content\n side={side}\n align={align}\n sideOffset={4}\n className={cn(\n 'ald-pop-confirm tw-z-50 tw-w-[240px] tw-rounded-[6px] tw-border tw-border-solid tw-border-[var(--border-default-alpha)] tw-bg-[var(--background-default)] tw-p-3 tw-outline-none',\n rootClassName,\n overlayClassName,\n )}\n style={{\n zIndex: popupZIndex,\n boxShadow: 'var(--elevation-bottom-bottom-md)',\n }}\n >\n <div className=\"tw-flex tw-gap-2\">\n {icon && <span className=\"tw-mt-0.5 tw-shrink-0\">{icon}</span>}\n <div className=\"tw-flex-1\">\n <div className=\"tw-mb-2 tw-break-all tw-text-xs tw-leading-4 tw-text-[var(--content-primary)]\">\n {title}\n </div>\n <div className=\"tw-flex tw-justify-end tw-gap-2\">\n <Button\n type=\"secondary\"\n size=\"small\"\n {...cancelButtonProps}\n onClick={handleCancel}\n >\n {cancelText}\n </Button>\n <Button\n type={okType}\n size=\"small\"\n {...okButtonProps}\n onClick={handleConfirm}\n >\n {okText}\n </Button>\n </div>\n </div>\n </div>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n}\n\nexport default Popconfirm;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Popconfirm/index.tsx"],"sourcesContent":["import * as PopoverPrimitive from '@radix-ui/react-popover';\nimport React, { useState } from 'react';\nimport Button, { ButtonType, IButtonProps } from '../Button';\nimport { AttentionTriangleFill } from '../Icon';\nimport { useFloatingPopupZIndex } from '../_utils/floatingLayer';\nimport { cn } from '../lib/utils';\n\nexport interface PopconfirmProps {\n title?: React.ReactNode;\n onConfirm?: (e?: React.MouseEvent) => void;\n onCancel?: (e?: React.MouseEvent) => void;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n icon?: React.ReactNode;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n placement?:\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight'\n | 'leftTop'\n | 'leftBottom'\n | 'rightTop'\n | 'rightBottom';\n rootClassName?: string;\n className?: string;\n overlayClassName?: string;\n getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;\n children?: React.ReactNode;\n disabled?: boolean;\n}\n\nconst sideMap: Record<string, PopoverPrimitive.PopoverContentProps['side']> = {\n top: 'top',\n bottom: 'bottom',\n left: 'left',\n right: 'right',\n topLeft: 'top',\n topRight: 'top',\n bottomLeft: 'bottom',\n bottomRight: 'bottom',\n leftTop: 'left',\n leftBottom: 'left',\n rightTop: 'right',\n rightBottom: 'right',\n};\n\nconst alignMap: Record<string, PopoverPrimitive.PopoverContentProps['align']> =\n {\n topLeft: 'start',\n topRight: 'end',\n bottomLeft: 'start',\n bottomRight: 'end',\n leftTop: 'start',\n leftBottom: 'end',\n rightTop: 'start',\n rightBottom: 'end',\n };\n\nfunction Popconfirm(props: PopconfirmProps) {\n const {\n title,\n onConfirm,\n onCancel,\n okText = 'OK',\n cancelText = 'Cancel',\n okButtonProps = {},\n cancelButtonProps = {},\n okType = 'dangerous',\n icon = (\n <AttentionTriangleFill\n size={16}\n color=\"var(--action-destructive-normal)\"\n fill=\"var(--action-inverted-normal)\"\n />\n ),\n open: controlledOpen,\n onOpenChange,\n placement = 'top',\n rootClassName,\n overlayClassName,\n getPopupContainer,\n children,\n disabled,\n } = props;\n\n const [innerOpen, setInnerOpen] = useState(false);\n const triggerRef = React.useRef<HTMLElement | null>(null);\n const getPopupContainerRef = React.useRef(getPopupContainer);\n const lastGetPopupContainerRef = React.useRef(getPopupContainer);\n const [popupContainer, setPopupContainer] = useState<\n HTMLElement | undefined\n >();\n getPopupContainerRef.current = getPopupContainer;\n const isControlled = controlledOpen !== undefined;\n const isOpen = isControlled ? controlledOpen : innerOpen;\n const mergedOpen = disabled ? false : isOpen;\n const updatePopupContainer = React.useCallback((node: HTMLElement | null) => {\n const nextContainer =\n node && getPopupContainerRef.current\n ? getPopupContainerRef.current(node)\n : undefined;\n setPopupContainer((prevContainer) =>\n prevContainer === nextContainer ? prevContainer : nextContainer,\n );\n }, []);\n const setTriggerNode = React.useCallback(\n (node: HTMLElement | null) => {\n if (!node) return;\n if (triggerRef.current === node) return;\n triggerRef.current = node;\n updatePopupContainer(node);\n },\n [updatePopupContainer],\n );\n\n React.useEffect(() => {\n if (lastGetPopupContainerRef.current === getPopupContainer) return;\n lastGetPopupContainerRef.current = getPopupContainer;\n updatePopupContainer(triggerRef.current);\n }, [getPopupContainer, updatePopupContainer]);\n\n const handleOpenChange = (val: boolean) => {\n if (disabled) return;\n if (!isControlled) setInnerOpen(val);\n onOpenChange?.(val);\n };\n\n const handleConfirm = (e?: React.MouseEvent) => {\n onConfirm?.(e);\n handleOpenChange(false);\n };\n\n const handleCancel = (e?: React.MouseEvent) => {\n onCancel?.(e);\n handleOpenChange(false);\n };\n\n const side = sideMap[placement] || 'top';\n const align = alignMap[placement] || 'center';\n const popupZIndex = useFloatingPopupZIndex();\n const idBase = React.useId().replace(/:/g, '');\n const contentId = `ald-popconfirm-${idBase}`;\n const titleId = `ald-popconfirm-title-${idBase}`;\n const triggerChild = React.isValidElement(children) ? (\n React.cloneElement(children as React.ReactElement, {\n 'aria-controls': contentId,\n })\n ) : (\n <span>{children}</span>\n );\n\n return (\n <PopoverPrimitive.Root\n open={mergedOpen}\n onOpenChange={handleOpenChange}\n modal={false}\n >\n <PopoverPrimitive.Trigger asChild ref={setTriggerNode}>\n {triggerChild}\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={popupContainer}>\n <PopoverPrimitive.Content\n id={contentId}\n role=\"region\"\n aria-labelledby={title ? titleId : undefined}\n side={side}\n align={align}\n sideOffset={4}\n className={cn(\n 'ald-pop-confirm tw-z-50 tw-w-[240px] tw-rounded-[6px] tw-border tw-border-solid tw-border-[var(--border-default-alpha)] tw-bg-[var(--background-default)] tw-p-3 tw-outline-none',\n rootClassName,\n overlayClassName,\n )}\n style={{\n zIndex: popupZIndex,\n boxShadow: 'var(--elevation-bottom-bottom-md)',\n }}\n >\n <div className=\"tw-flex tw-gap-2\">\n {icon && <span className=\"tw-mt-0.5 tw-shrink-0\">{icon}</span>}\n <div className=\"tw-flex-1\">\n <div\n id={titleId}\n className=\"tw-mb-2 tw-break-all tw-text-xs tw-leading-4 tw-text-[var(--content-primary)]\"\n >\n {title}\n </div>\n <div className=\"tw-flex tw-justify-end tw-gap-2\">\n <Button\n type=\"secondary\"\n size=\"small\"\n {...cancelButtonProps}\n onClick={handleCancel}\n >\n {cancelText}\n </Button>\n <Button\n type={okType}\n size=\"small\"\n {...okButtonProps}\n onClick={handleConfirm}\n >\n {okText}\n </Button>\n </div>\n </div>\n </div>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n}\n\nexport default Popconfirm;\n"],"mappings":"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"}
@@ -4,6 +4,39 @@ import React from "react";
4
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
5
  import * as PopoverPrimitive from "@radix-ui/react-popover";
6
6
  //#region src/Popover/index.tsx
7
+ var interactiveRoles = new Set([
8
+ "button",
9
+ "checkbox",
10
+ "combobox",
11
+ "link",
12
+ "menuitem",
13
+ "option",
14
+ "radio",
15
+ "searchbox",
16
+ "slider",
17
+ "spinbutton",
18
+ "switch",
19
+ "tab",
20
+ "textbox"
21
+ ]);
22
+ function hasInteractiveContent(node) {
23
+ return React.Children.toArray(node).some((child) => {
24
+ if (!React.isValidElement(child)) return false;
25
+ if (typeof child.type === "string") {
26
+ if ([
27
+ "a",
28
+ "button",
29
+ "input",
30
+ "select",
31
+ "textarea",
32
+ "summary"
33
+ ].includes(child.type)) return true;
34
+ if (interactiveRoles.has(child.props.role)) return true;
35
+ if (typeof child.props.tabIndex === "number" && child.props.tabIndex >= 0) return true;
36
+ }
37
+ return hasInteractiveContent(child.props.children);
38
+ });
39
+ }
7
40
  var placementMap = {
8
41
  top: "top",
9
42
  bottom: "bottom",
@@ -64,6 +97,9 @@ function Popover(props) {
64
97
  const containerRef = React.useRef(getPopupContainer?.());
65
98
  const [hoverOpen, setHoverOpen] = React.useState(false);
66
99
  const triggers = normalizeTrigger(trigger);
100
+ const idBase = React.useId().replace(/:/g, "");
101
+ const contentId = `ald-popover-${idBase}`;
102
+ const titleId = `ald-popover-title-${idBase}`;
67
103
  const isControlled = open !== void 0;
68
104
  const isHoverTrigger = triggers.has("hover");
69
105
  const isOpen = isControlled ? open : isHoverTrigger ? hoverOpen : triggers.size === 0 ? false : void 0;
@@ -75,12 +111,20 @@ function Popover(props) {
75
111
  const align = alignMap[placement] || "center";
76
112
  const popupZIndex = useFloatingPopupZIndex(zIndex);
77
113
  const { alignOffset, sideOffset } = getPopoverOffsets(side, popupAlign?.offset);
78
- const triggerChild = React.isValidElement(children) ? children : /* @__PURE__ */ jsx("span", { children });
114
+ const triggerChild = React.isValidElement(children) ? React.cloneElement(children, {
115
+ "aria-controls": contentId,
116
+ "aria-haspopup": false
117
+ }) : /* @__PURE__ */ jsx("span", {
118
+ "aria-controls": contentId,
119
+ "aria-haspopup": false,
120
+ children
121
+ });
79
122
  if (triggers.size === 0 && !isControlled) return /* @__PURE__ */ jsx(Fragment, { children });
80
123
  return /* @__PURE__ */ jsxs(PopoverPrimitive.Root, {
81
124
  open: isOpen,
82
125
  defaultOpen,
83
126
  onOpenChange: handleOpenChange,
127
+ modal: false,
84
128
  children: [/* @__PURE__ */ jsx(PopoverPrimitive.Trigger, {
85
129
  asChild: true,
86
130
  children: isHoverTrigger ? /* @__PURE__ */ jsx("span", {
@@ -91,6 +135,9 @@ function Popover(props) {
91
135
  }), /* @__PURE__ */ jsx(PopoverPrimitive.Portal, {
92
136
  container: containerRef.current,
93
137
  children: /* @__PURE__ */ jsxs(PopoverPrimitive.Content, {
138
+ id: contentId,
139
+ role: "region",
140
+ "aria-labelledby": title ? titleId : void 0,
94
141
  side,
95
142
  align,
96
143
  sideOffset,
@@ -103,10 +150,14 @@ function Popover(props) {
103
150
  ...overlayStyle,
104
151
  ...overlayInnerStyle
105
152
  },
153
+ onOpenAutoFocus: (event) => {
154
+ if (!hasInteractiveContent(content)) event.preventDefault();
155
+ },
106
156
  onMouseEnter: isHoverTrigger ? () => handleOpenChange(true) : void 0,
107
157
  onMouseLeave: isHoverTrigger ? () => handleOpenChange(false) : void 0,
108
158
  children: [
109
159
  title && /* @__PURE__ */ jsx("div", {
160
+ id: titleId,
110
161
  className: "ald-popover-title tw-mb-2 tw-text-sm tw-font-medium tw-text-[var(--content-primary)]",
111
162
  children: title
112
163
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Popover/index.tsx"],"sourcesContent":["import * as PopoverPrimitive from '@radix-ui/react-popover';\nimport React from 'react';\nimport { useFloatingPopupZIndex } from '../_utils/floatingLayer';\nimport { cn } from '../lib/utils';\n\ntype TriggerType = 'hover' | 'click' | 'focus';\n\nexport interface PopoverProps {\n content?: React.ReactNode;\n title?: React.ReactNode;\n children?: React.ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: TriggerType | TriggerType[];\n rootClassName?: string;\n placement?:\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight'\n | 'leftTop'\n | 'leftBottom'\n | 'rightTop'\n | 'rightBottom';\n overlayClassName?: string;\n overlayStyle?: React.CSSProperties;\n overlayInnerStyle?: React.CSSProperties;\n color?: string;\n align?: {\n offset?: [number, number];\n [key: string]: any;\n };\n arrow?: boolean;\n mouseEnterDelay?: number;\n mouseLeaveDelay?: number;\n className?: string;\n style?: React.CSSProperties;\n getPopupContainer?: () => HTMLElement;\n zIndex?: number;\n}\n\nconst placementMap: Record<\n string,\n PopoverPrimitive.PopoverContentProps['side']\n> = {\n top: 'top',\n bottom: 'bottom',\n left: 'left',\n right: 'right',\n topLeft: 'top',\n topRight: 'top',\n bottomLeft: 'bottom',\n bottomRight: 'bottom',\n leftTop: 'left',\n leftBottom: 'left',\n rightTop: 'right',\n rightBottom: 'right',\n};\n\nconst alignMap: Record<string, PopoverPrimitive.PopoverContentProps['align']> =\n {\n topLeft: 'start',\n topRight: 'end',\n bottomLeft: 'start',\n bottomRight: 'end',\n leftTop: 'start',\n leftBottom: 'end',\n rightTop: 'start',\n rightBottom: 'end',\n };\n\nconst DEFAULT_SIDE_OFFSET = 4;\n\nfunction normalizeTrigger(trigger: PopoverProps['trigger']): Set<TriggerType> {\n if (Array.isArray(trigger)) return new Set(trigger);\n if (trigger) return new Set([trigger]);\n return new Set<TriggerType>(['hover']);\n}\n\nfunction getPopoverOffsets(\n side: PopoverPrimitive.PopoverContentProps['side'],\n offset?: [number, number],\n) {\n if (!offset) {\n return {\n alignOffset: undefined,\n sideOffset: DEFAULT_SIDE_OFFSET,\n };\n }\n\n const [x = 0, y = 0] = offset;\n switch (side) {\n case 'left':\n return {\n alignOffset: y,\n sideOffset: -x,\n };\n case 'right':\n return {\n alignOffset: y,\n sideOffset: x,\n };\n case 'bottom':\n return {\n alignOffset: x,\n sideOffset: y,\n };\n case 'top':\n default:\n return {\n alignOffset: x,\n sideOffset: -y,\n };\n }\n}\n\nfunction Popover(props: PopoverProps) {\n const {\n content,\n title,\n children,\n open,\n defaultOpen,\n onOpenChange,\n trigger = 'hover',\n placement = 'top',\n overlayClassName,\n overlayStyle,\n overlayInnerStyle,\n color,\n align: popupAlign,\n arrow = false,\n getPopupContainer,\n zIndex,\n } = props;\n\n const containerRef = React.useRef<HTMLElement | undefined>(\n getPopupContainer?.(),\n );\n\n const [hoverOpen, setHoverOpen] = React.useState(false);\n const triggers = normalizeTrigger(trigger);\n\n const isControlled = open !== undefined;\n const isHoverTrigger = triggers.has('hover');\n const isOpen = isControlled\n ? open\n : isHoverTrigger\n ? hoverOpen\n : triggers.size === 0\n ? false\n : undefined;\n\n const handleOpenChange = (val: boolean) => {\n if (!isControlled && isHoverTrigger) {\n setHoverOpen(val);\n }\n onOpenChange?.(val);\n };\n\n const side = placementMap[placement] || 'top';\n const align = alignMap[placement] || 'center';\n const popupZIndex = useFloatingPopupZIndex(zIndex);\n const { alignOffset, sideOffset } = getPopoverOffsets(\n side,\n popupAlign?.offset,\n );\n\n const triggerChild = React.isValidElement(children) ? (\n children\n ) : (\n <span>{children}</span>\n );\n\n if (triggers.size === 0 && !isControlled) {\n return <>{children}</>;\n }\n\n return (\n <PopoverPrimitive.Root\n open={isOpen}\n defaultOpen={defaultOpen}\n onOpenChange={handleOpenChange}\n >\n <PopoverPrimitive.Trigger asChild>\n {isHoverTrigger ? (\n <span\n onMouseEnter={() => handleOpenChange(true)}\n onMouseLeave={() => handleOpenChange(false)}\n >\n {triggerChild}\n </span>\n ) : (\n triggerChild\n )}\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={containerRef.current}>\n <PopoverPrimitive.Content\n side={side}\n align={align}\n sideOffset={sideOffset}\n alignOffset={alignOffset}\n // antd 兼容:保留 ant-popover-inner class,消费方 CSS 可能通过该选择器自定义内边距、背景等样式\n className={cn(\n 'ald-popover ant-popover-inner tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-default-alpha)] tw-bg-[var(--background-default)] tw-p-3 tw-outline-none',\n 'tw-animate-in tw-fade-in-0 tw-zoom-in-95',\n overlayClassName,\n )}\n style={{\n boxShadow: 'var(--elevation-bottom-bottom-sm)',\n backgroundColor: color,\n zIndex: popupZIndex,\n ...overlayStyle,\n ...overlayInnerStyle,\n }}\n onMouseEnter={\n isHoverTrigger ? () => handleOpenChange(true) : undefined\n }\n onMouseLeave={\n isHoverTrigger ? () => handleOpenChange(false) : undefined\n }\n >\n {title && (\n <div className=\"ald-popover-title tw-mb-2 tw-text-sm tw-font-medium tw-text-[var(--content-primary)]\">\n {title}\n </div>\n )}\n {content && (\n // antd 兼容:保留 ant-popover-inner-content class,消费方 CSS 可能通过该选择器自定义样式\n <div className=\"ald-popover-inner-content ant-popover-inner-content\">\n {content}\n </div>\n )}\n {arrow && (\n <PopoverPrimitive.Arrow\n style={{ fill: 'var(--background-default)' }}\n />\n )}\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n}\n\nexport default Popover;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Popover/index.tsx"],"sourcesContent":["import * as PopoverPrimitive from '@radix-ui/react-popover';\nimport React from 'react';\nimport { useFloatingPopupZIndex } from '../_utils/floatingLayer';\nimport { cn } from '../lib/utils';\n\ntype TriggerType = 'hover' | 'click' | 'focus';\n\nconst interactiveRoles = new Set([\n 'button',\n 'checkbox',\n 'combobox',\n 'link',\n 'menuitem',\n 'option',\n 'radio',\n 'searchbox',\n 'slider',\n 'spinbutton',\n 'switch',\n 'tab',\n 'textbox',\n]);\n\nfunction hasInteractiveContent(node: React.ReactNode): boolean {\n return React.Children.toArray(node).some((child) => {\n if (!React.isValidElement(child)) return false;\n\n if (typeof child.type === 'string') {\n if (\n ['a', 'button', 'input', 'select', 'textarea', 'summary'].includes(\n child.type,\n )\n ) {\n return true;\n }\n\n if (interactiveRoles.has(child.props.role)) return true;\n if (\n typeof child.props.tabIndex === 'number' &&\n child.props.tabIndex >= 0\n ) {\n return true;\n }\n }\n\n return hasInteractiveContent(child.props.children);\n });\n}\n\nexport interface PopoverProps {\n content?: React.ReactNode;\n title?: React.ReactNode;\n children?: React.ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: TriggerType | TriggerType[];\n rootClassName?: string;\n placement?:\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight'\n | 'leftTop'\n | 'leftBottom'\n | 'rightTop'\n | 'rightBottom';\n overlayClassName?: string;\n overlayStyle?: React.CSSProperties;\n overlayInnerStyle?: React.CSSProperties;\n color?: string;\n align?: {\n offset?: [number, number];\n [key: string]: any;\n };\n arrow?: boolean;\n mouseEnterDelay?: number;\n mouseLeaveDelay?: number;\n className?: string;\n style?: React.CSSProperties;\n getPopupContainer?: () => HTMLElement;\n zIndex?: number;\n}\n\nconst placementMap: Record<\n string,\n PopoverPrimitive.PopoverContentProps['side']\n> = {\n top: 'top',\n bottom: 'bottom',\n left: 'left',\n right: 'right',\n topLeft: 'top',\n topRight: 'top',\n bottomLeft: 'bottom',\n bottomRight: 'bottom',\n leftTop: 'left',\n leftBottom: 'left',\n rightTop: 'right',\n rightBottom: 'right',\n};\n\nconst alignMap: Record<string, PopoverPrimitive.PopoverContentProps['align']> =\n {\n topLeft: 'start',\n topRight: 'end',\n bottomLeft: 'start',\n bottomRight: 'end',\n leftTop: 'start',\n leftBottom: 'end',\n rightTop: 'start',\n rightBottom: 'end',\n };\n\nconst DEFAULT_SIDE_OFFSET = 4;\n\nfunction normalizeTrigger(trigger: PopoverProps['trigger']): Set<TriggerType> {\n if (Array.isArray(trigger)) return new Set(trigger);\n if (trigger) return new Set([trigger]);\n return new Set<TriggerType>(['hover']);\n}\n\nfunction getPopoverOffsets(\n side: PopoverPrimitive.PopoverContentProps['side'],\n offset?: [number, number],\n) {\n if (!offset) {\n return {\n alignOffset: undefined,\n sideOffset: DEFAULT_SIDE_OFFSET,\n };\n }\n\n const [x = 0, y = 0] = offset;\n switch (side) {\n case 'left':\n return {\n alignOffset: y,\n sideOffset: -x,\n };\n case 'right':\n return {\n alignOffset: y,\n sideOffset: x,\n };\n case 'bottom':\n return {\n alignOffset: x,\n sideOffset: y,\n };\n case 'top':\n default:\n return {\n alignOffset: x,\n sideOffset: -y,\n };\n }\n}\n\nfunction Popover(props: PopoverProps) {\n const {\n content,\n title,\n children,\n open,\n defaultOpen,\n onOpenChange,\n trigger = 'hover',\n placement = 'top',\n overlayClassName,\n overlayStyle,\n overlayInnerStyle,\n color,\n align: popupAlign,\n arrow = false,\n getPopupContainer,\n zIndex,\n } = props;\n\n const containerRef = React.useRef<HTMLElement | undefined>(\n getPopupContainer?.(),\n );\n\n const [hoverOpen, setHoverOpen] = React.useState(false);\n const triggers = normalizeTrigger(trigger);\n const idBase = React.useId().replace(/:/g, '');\n const contentId = `ald-popover-${idBase}`;\n const titleId = `ald-popover-title-${idBase}`;\n\n const isControlled = open !== undefined;\n const isHoverTrigger = triggers.has('hover');\n const isOpen = isControlled\n ? open\n : isHoverTrigger\n ? hoverOpen\n : triggers.size === 0\n ? false\n : undefined;\n\n const handleOpenChange = (val: boolean) => {\n if (!isControlled && isHoverTrigger) {\n setHoverOpen(val);\n }\n onOpenChange?.(val);\n };\n\n const side = placementMap[placement] || 'top';\n const align = alignMap[placement] || 'center';\n const popupZIndex = useFloatingPopupZIndex(zIndex);\n const { alignOffset, sideOffset } = getPopoverOffsets(\n side,\n popupAlign?.offset,\n );\n\n const triggerChild = React.isValidElement(children) ? (\n React.cloneElement(children as React.ReactElement, {\n 'aria-controls': contentId,\n 'aria-haspopup': false,\n })\n ) : (\n <span aria-controls={contentId} aria-haspopup={false}>\n {children}\n </span>\n );\n\n if (triggers.size === 0 && !isControlled) {\n return <>{children}</>;\n }\n\n return (\n <PopoverPrimitive.Root\n open={isOpen}\n defaultOpen={defaultOpen}\n onOpenChange={handleOpenChange}\n modal={false}\n >\n <PopoverPrimitive.Trigger asChild>\n {isHoverTrigger ? (\n <span\n onMouseEnter={() => handleOpenChange(true)}\n onMouseLeave={() => handleOpenChange(false)}\n >\n {triggerChild}\n </span>\n ) : (\n triggerChild\n )}\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={containerRef.current}>\n <PopoverPrimitive.Content\n id={contentId}\n role=\"region\"\n aria-labelledby={title ? titleId : undefined}\n side={side}\n align={align}\n sideOffset={sideOffset}\n alignOffset={alignOffset}\n // antd 兼容:保留 ant-popover-inner class,消费方 CSS 可能通过该选择器自定义内边距、背景等样式\n className={cn(\n 'ald-popover ant-popover-inner tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-default-alpha)] tw-bg-[var(--background-default)] tw-p-3 tw-outline-none',\n 'tw-animate-in tw-fade-in-0 tw-zoom-in-95',\n overlayClassName,\n )}\n style={{\n boxShadow: 'var(--elevation-bottom-bottom-sm)',\n backgroundColor: color,\n zIndex: popupZIndex,\n ...overlayStyle,\n ...overlayInnerStyle,\n }}\n onOpenAutoFocus={(event) => {\n if (!hasInteractiveContent(content)) {\n event.preventDefault();\n }\n }}\n onMouseEnter={\n isHoverTrigger ? () => handleOpenChange(true) : undefined\n }\n onMouseLeave={\n isHoverTrigger ? () => handleOpenChange(false) : undefined\n }\n >\n {title && (\n <div\n id={titleId}\n className=\"ald-popover-title tw-mb-2 tw-text-sm tw-font-medium tw-text-[var(--content-primary)]\"\n >\n {title}\n </div>\n )}\n {content && (\n // antd 兼容:保留 ant-popover-inner-content class,消费方 CSS 可能通过该选择器自定义样式\n <div className=\"ald-popover-inner-content ant-popover-inner-content\">\n {content}\n </div>\n )}\n {arrow && (\n <PopoverPrimitive.Arrow\n style={{ fill: 'var(--background-default)' }}\n />\n )}\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n );\n}\n\nexport default Popover;\n"],"mappings":"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"}
@@ -33,6 +33,10 @@ var Progress_default = forwardRef(function Progress(props, ref) {
33
33
  }, [loadingState]);
34
34
  return /* @__PURE__ */ jsx("div", {
35
35
  className: cn("ald-progress-bar tw-relative tw-h-[2px] tw-w-full tw-overflow-hidden", loadingState !== ELoadingState.IDLE && "ald-progress-bar-show-bg tw-bg-[var(--background-neutral-subtle)]", className),
36
+ role: "status",
37
+ "aria-live": "polite",
38
+ "aria-busy": loadingState === ELoadingState.LOADING,
39
+ "aria-label": "Loading",
36
40
  children: /* @__PURE__ */ jsx("div", {
37
41
  className: cn("ald-progress-bar-inner tw-absolute tw-left-0 tw-top-0 tw-h-full tw-w-0 tw-bg-[var(--action-primary-normal)]", loadingState === ELoadingState.LOADING && "ald-progress-bar-show-loading tw-animate-[progress-loading_2s_ease-in-out_forwards]", loadingState === ELoadingState.LOADED && "ald-progress-bar-hide-loading tw-animate-[progress-loaded_0.5s_ease-out_forwards]"),
38
42
  onAnimationEnd
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Progress/index.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useState,\n} from 'react';\nimport { cn } from '../lib/utils';\nimport './progress.css';\n\nenum ELoadingState {\n IDLE = 'IDLE',\n LOADING = 'LOADING',\n LOADED = 'LOADED',\n}\n\nexport default forwardRef(function Progress(props: IProps, ref) {\n const { loading, className } = props;\n const [loadingState, setLoadingState] = useState(ELoadingState.IDLE);\n const [key, setKey] = useState(0);\n\n useImperativeHandle(ref, () => ({\n restart() {\n setKey((prev) => prev + 1);\n },\n }));\n\n useEffect(() => {\n if (loadingState !== ELoadingState.IDLE) {\n if (loadingState === ELoadingState.LOADING && !loading) {\n setLoadingState(ELoadingState.LOADED);\n }\n return;\n }\n const DELAY_TIME = 200;\n const timer = setTimeout(() => {\n if (loading) {\n setLoadingState(ELoadingState.LOADING);\n }\n }, DELAY_TIME);\n\n return () => {\n if (timer) {\n clearTimeout(timer);\n }\n };\n }, [loading, loadingState]);\n\n const onAnimationEnd = useCallback(() => {\n if (loadingState === ELoadingState.LOADED) {\n setLoadingState(ELoadingState.IDLE);\n }\n }, [loadingState]);\n\n return (\n <div\n key={key}\n className={cn(\n 'ald-progress-bar tw-relative tw-h-[2px] tw-w-full tw-overflow-hidden',\n loadingState !== ELoadingState.IDLE &&\n 'ald-progress-bar-show-bg tw-bg-[var(--background-neutral-subtle)]',\n className,\n )}\n >\n <div\n className={cn(\n 'ald-progress-bar-inner tw-absolute tw-left-0 tw-top-0 tw-h-full tw-w-0 tw-bg-[var(--action-primary-normal)]',\n loadingState === ELoadingState.LOADING &&\n 'ald-progress-bar-show-loading tw-animate-[progress-loading_2s_ease-in-out_forwards]',\n loadingState === ELoadingState.LOADED &&\n 'ald-progress-bar-hide-loading tw-animate-[progress-loaded_0.5s_ease-out_forwards]',\n )}\n onAnimationEnd={onAnimationEnd}\n />\n </div>\n );\n});\n\nexport interface IProps {\n loading: boolean;\n className?: string;\n}\n\nexport interface IProgressRef {\n restart: () => void;\n}\n"],"mappings":";;;;;AAUA,IAAK,gBAAL,yBAAA,eAAA;AACE,eAAA,UAAA;AACA,eAAA,aAAA;AACA,eAAA,YAAA;;EAHG,iBAAA,EAAA,CAIJ;AAED,IAAA,mBAAe,WAAW,SAAS,SAAS,OAAe,KAAK;CAC9D,MAAM,EAAE,SAAS,cAAc;CAC/B,MAAM,CAAC,cAAc,mBAAmB,SAAS,cAAc,KAAK;CACpE,MAAM,CAAC,KAAK,UAAU,SAAS,EAAE;AAEjC,qBAAoB,YAAY,EAC9B,UAAU;AACR,UAAQ,SAAS,OAAO,EAAE;IAE7B,EAAE;AAEH,iBAAgB;AACd,MAAI,iBAAiB,cAAc,MAAM;AACvC,OAAI,iBAAiB,cAAc,WAAW,CAAC,QAC7C,iBAAgB,cAAc,OAAO;AAEvC;;EAGF,MAAM,QAAQ,iBAAiB;AAC7B,OAAI,QACF,iBAAgB,cAAc,QAAQ;KAHvB,IAKL;AAEd,eAAa;AACX,OAAI,MACF,cAAa,MAAM;;IAGtB,CAAC,SAAS,aAAa,CAAC;CAE3B,MAAM,iBAAiB,kBAAkB;AACvC,MAAI,iBAAiB,cAAc,OACjC,iBAAgB,cAAc,KAAK;IAEpC,CAAC,aAAa,CAAC;AAElB,QACE,oBAAC,OAAD;EAEE,WAAW,GACT,wEACA,iBAAiB,cAAc,QAC7B,qEACF,UACD;YAED,oBAAC,OAAD;GACE,WAAW,GACT,+GACA,iBAAiB,cAAc,WAC7B,uFACF,iBAAiB,cAAc,UAC7B,oFACH;GACe;GAChB,CAAA;EACE,EAlBC,IAkBD;EAER"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Progress/index.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useState,\n} from 'react';\nimport { cn } from '../lib/utils';\nimport './progress.css';\n\nenum ELoadingState {\n IDLE = 'IDLE',\n LOADING = 'LOADING',\n LOADED = 'LOADED',\n}\n\nexport default forwardRef(function Progress(props: IProps, ref) {\n const { loading, className } = props;\n const [loadingState, setLoadingState] = useState(ELoadingState.IDLE);\n const [key, setKey] = useState(0);\n\n useImperativeHandle(ref, () => ({\n restart() {\n setKey((prev) => prev + 1);\n },\n }));\n\n useEffect(() => {\n if (loadingState !== ELoadingState.IDLE) {\n if (loadingState === ELoadingState.LOADING && !loading) {\n setLoadingState(ELoadingState.LOADED);\n }\n return;\n }\n const DELAY_TIME = 200;\n const timer = setTimeout(() => {\n if (loading) {\n setLoadingState(ELoadingState.LOADING);\n }\n }, DELAY_TIME);\n\n return () => {\n if (timer) {\n clearTimeout(timer);\n }\n };\n }, [loading, loadingState]);\n\n const onAnimationEnd = useCallback(() => {\n if (loadingState === ELoadingState.LOADED) {\n setLoadingState(ELoadingState.IDLE);\n }\n }, [loadingState]);\n\n return (\n <div\n key={key}\n className={cn(\n 'ald-progress-bar tw-relative tw-h-[2px] tw-w-full tw-overflow-hidden',\n loadingState !== ELoadingState.IDLE &&\n 'ald-progress-bar-show-bg tw-bg-[var(--background-neutral-subtle)]',\n className,\n )}\n role=\"status\"\n aria-live=\"polite\"\n aria-busy={loadingState === ELoadingState.LOADING}\n aria-label=\"Loading\"\n >\n <div\n className={cn(\n 'ald-progress-bar-inner tw-absolute tw-left-0 tw-top-0 tw-h-full tw-w-0 tw-bg-[var(--action-primary-normal)]',\n loadingState === ELoadingState.LOADING &&\n 'ald-progress-bar-show-loading tw-animate-[progress-loading_2s_ease-in-out_forwards]',\n loadingState === ELoadingState.LOADED &&\n 'ald-progress-bar-hide-loading tw-animate-[progress-loaded_0.5s_ease-out_forwards]',\n )}\n onAnimationEnd={onAnimationEnd}\n />\n </div>\n );\n});\n\nexport interface IProps {\n loading: boolean;\n className?: string;\n}\n\nexport interface IProgressRef {\n restart: () => void;\n}\n"],"mappings":";;;;;AAUA,IAAK,gBAAL,yBAAA,eAAA;AACE,eAAA,UAAA;AACA,eAAA,aAAA;AACA,eAAA,YAAA;;EAHG,iBAAA,EAAA,CAIJ;AAED,IAAA,mBAAe,WAAW,SAAS,SAAS,OAAe,KAAK;CAC9D,MAAM,EAAE,SAAS,cAAc;CAC/B,MAAM,CAAC,cAAc,mBAAmB,SAAS,cAAc,KAAK;CACpE,MAAM,CAAC,KAAK,UAAU,SAAS,EAAE;AAEjC,qBAAoB,YAAY,EAC9B,UAAU;AACR,UAAQ,SAAS,OAAO,EAAE;IAE7B,EAAE;AAEH,iBAAgB;AACd,MAAI,iBAAiB,cAAc,MAAM;AACvC,OAAI,iBAAiB,cAAc,WAAW,CAAC,QAC7C,iBAAgB,cAAc,OAAO;AAEvC;;EAGF,MAAM,QAAQ,iBAAiB;AAC7B,OAAI,QACF,iBAAgB,cAAc,QAAQ;KAHvB,IAKL;AAEd,eAAa;AACX,OAAI,MACF,cAAa,MAAM;;IAGtB,CAAC,SAAS,aAAa,CAAC;CAE3B,MAAM,iBAAiB,kBAAkB;AACvC,MAAI,iBAAiB,cAAc,OACjC,iBAAgB,cAAc,KAAK;IAEpC,CAAC,aAAa,CAAC;AAElB,QACE,oBAAC,OAAD;EAEE,WAAW,GACT,wEACA,iBAAiB,cAAc,QAC7B,qEACF,UACD;EACD,MAAK;EACL,aAAU;EACV,aAAW,iBAAiB,cAAc;EAC1C,cAAW;YAEX,oBAAC,OAAD;GACE,WAAW,GACT,+GACA,iBAAiB,cAAc,WAC7B,uFACF,iBAAiB,cAAc,UAC7B,oFACH;GACe;GAChB,CAAA;EACE,EAtBC,IAsBD;EAER"}
@@ -1,4 +1,8 @@
1
1
  import { default as React } from 'react';
2
2
  import { IRadioGroupProps } from '../../interface/radioGroup';
3
- export declare const RadioGroupContext: React.Context<Omit<IRadioGroupProps, "className" | "children">>;
3
+ type RadioGroupContextValue = Omit<IRadioGroupProps, 'children' | 'className'> & {
4
+ name?: string;
5
+ };
6
+ export declare const RadioGroupContext: React.Context<RadioGroupContextValue>;
4
7
  export default function RadioGroup(props: IRadioGroupProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -5,7 +5,8 @@ import { jsx } from "react/jsx-runtime";
5
5
  //#region src/Radio/components/Group/index.tsx
6
6
  var RadioGroupContext = createContext({});
7
7
  function RadioGroup(props) {
8
- const { children, radioGroupStyle = "filled", size = "middle", type = "radio", className, disabled: customDisabled, "data-testid": dataTestId, "aria-label": ariaLabel } = props;
8
+ const { children, radioGroupStyle = "filled", size = "middle", type = "radio", className, disabled: customDisabled, "data-testid": dataTestId, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy } = props;
9
+ const groupName = React.useId();
9
10
  const isControlled = "value" in props && props.value !== void 0;
10
11
  const [innerValue, setInnerValue] = useState(props.defaultValue);
11
12
  useEffect(() => {
@@ -37,12 +38,16 @@ function RadioGroup(props) {
37
38
  radioGroupStyle,
38
39
  size,
39
40
  type,
40
- disabled: mergedDisabled
41
+ disabled: mergedDisabled,
42
+ name: groupName
41
43
  },
42
44
  children: /* @__PURE__ */ jsx("div", {
43
45
  className: getWrapperClass(),
44
46
  "data-testid": dataTestId,
47
+ role: "radiogroup",
45
48
  "aria-label": ariaLabel,
49
+ "aria-labelledby": ariaLabelledBy,
50
+ "aria-describedby": ariaDescribedBy,
46
51
  children
47
52
  })
48
53
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../src/Radio/components/Group/index.tsx"],"sourcesContent":["import { cn } from '../../../lib/utils';\nimport React, { createContext, useEffect, useState } from 'react';\nimport DisabledContext from '../../../ConfigProvider/DisabledContext';\nimport { IRadioGroupProps } from '../../interface/radioGroup';\n\nexport const RadioGroupContext = createContext<\n Omit<IRadioGroupProps, 'children' | 'className'>\n>({});\n\nexport default function RadioGroup(props: IRadioGroupProps) {\n const {\n children,\n radioGroupStyle = 'filled',\n size = 'middle',\n type = 'radio',\n className,\n disabled: customDisabled,\n 'data-testid': dataTestId,\n 'aria-label': ariaLabel,\n } = props;\n const isControlled = 'value' in props && props.value !== undefined;\n const [innerValue, setInnerValue] = useState(props.defaultValue);\n\n useEffect(() => {\n if (isControlled) {\n setInnerValue(props.value);\n }\n }, [props.value, isControlled]);\n\n const value = isControlled ? props.value : innerValue;\n const setValue = (v: any) => {\n if (!isControlled) {\n setInnerValue(v);\n }\n };\n // ===================== Disabled =====================\n const disabled = React.useContext(DisabledContext);\n const mergedDisabled = customDisabled ?? disabled;\n const onRadioChange = (selectedValue: any) => {\n const lastValue = value;\n\n setValue(selectedValue);\n const { onChange } = props;\n if (onChange && selectedValue !== lastValue) {\n onChange(selectedValue);\n }\n };\n\n const getWrapperClass = () => {\n const isButton = ['button', 'iconButton'].includes(type);\n const tempType = type === 'iconButton' ? 'icon-button' : type;\n return cn('ald-radio-group', className, `ald-radio-group-${tempType}`, {\n // 约束只能在type为button和iconbutton的时候才可以设置样式和大小\n [`ald-radio-group-${radioGroupStyle}`]: isButton,\n [`ald-radio-group-${size}`]: isButton,\n });\n };\n\n return (\n <RadioGroupContext.Provider\n value={{\n onChange: onRadioChange,\n value,\n radioGroupStyle,\n size,\n type,\n disabled: mergedDisabled,\n }}\n >\n <div\n className={getWrapperClass()}\n data-testid={dataTestId}\n aria-label={ariaLabel}\n >\n {children}\n </div>\n </RadioGroupContext.Provider>\n );\n}\n"],"mappings":";;;;;AAKA,IAAa,oBAAoB,cAE/B,EAAE,CAAC;AAEL,SAAwB,WAAW,OAAyB;CAC1D,MAAM,EACJ,UACA,kBAAkB,UAClB,OAAO,UACP,OAAO,SACP,WACA,UAAU,gBACV,eAAe,YACf,cAAc,cACZ;CACJ,MAAM,eAAe,WAAW,SAAS,MAAM,UAAU;CACzD,MAAM,CAAC,YAAY,iBAAiB,SAAS,MAAM,aAAa;AAEhE,iBAAgB;AACd,MAAI,aACF,eAAc,MAAM,MAAM;IAE3B,CAAC,MAAM,OAAO,aAAa,CAAC;CAE/B,MAAM,QAAQ,eAAe,MAAM,QAAQ;CAC3C,MAAM,YAAY,MAAW;AAC3B,MAAI,CAAC,aACH,eAAc,EAAE;;CAIpB,MAAM,WAAW,MAAM,WAAW,gBAAgB;CAClD,MAAM,iBAAiB,kBAAkB;CACzC,MAAM,iBAAiB,kBAAuB;EAC5C,MAAM,YAAY;AAElB,WAAS,cAAc;EACvB,MAAM,EAAE,aAAa;AACrB,MAAI,YAAY,kBAAkB,UAChC,UAAS,cAAc;;CAI3B,MAAM,wBAAwB;EAC5B,MAAM,WAAW,CAAC,UAAU,aAAa,CAAC,SAAS,KAAK;AAExD,SAAO,GAAG,mBAAmB,WAAW,mBADvB,SAAS,eAAe,gBAAgB,QACc;IAEpE,mBAAmB,oBAAoB;IACvC,mBAAmB,SAAS;GAC9B,CAAC;;AAGJ,QACE,oBAAC,kBAAkB,UAAnB;EACE,OAAO;GACL,UAAU;GACV;GACA;GACA;GACA;GACA,UAAU;GACX;YAED,oBAAC,OAAD;GACE,WAAW,iBAAiB;GAC5B,eAAa;GACb,cAAY;GAEX;GACG,CAAA;EACqB,CAAA"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/Radio/components/Group/index.tsx"],"sourcesContent":["import { cn } from '../../../lib/utils';\nimport React, { createContext, useEffect, useState } from 'react';\nimport DisabledContext from '../../../ConfigProvider/DisabledContext';\nimport { IRadioGroupProps } from '../../interface/radioGroup';\n\ntype RadioGroupContextValue = Omit<\n IRadioGroupProps,\n 'children' | 'className'\n> & {\n name?: string;\n};\n\nexport const RadioGroupContext = createContext<RadioGroupContextValue>({});\n\nexport default function RadioGroup(props: IRadioGroupProps) {\n const {\n children,\n radioGroupStyle = 'filled',\n size = 'middle',\n type = 'radio',\n className,\n disabled: customDisabled,\n 'data-testid': dataTestId,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n } = props;\n const groupName = React.useId();\n const isControlled = 'value' in props && props.value !== undefined;\n const [innerValue, setInnerValue] = useState(props.defaultValue);\n\n useEffect(() => {\n if (isControlled) {\n setInnerValue(props.value);\n }\n }, [props.value, isControlled]);\n\n const value = isControlled ? props.value : innerValue;\n const setValue = (v: any) => {\n if (!isControlled) {\n setInnerValue(v);\n }\n };\n // ===================== Disabled =====================\n const disabled = React.useContext(DisabledContext);\n const mergedDisabled = customDisabled ?? disabled;\n const onRadioChange = (selectedValue: any) => {\n const lastValue = value;\n\n setValue(selectedValue);\n const { onChange } = props;\n if (onChange && selectedValue !== lastValue) {\n onChange(selectedValue);\n }\n };\n\n const getWrapperClass = () => {\n const isButton = ['button', 'iconButton'].includes(type);\n const tempType = type === 'iconButton' ? 'icon-button' : type;\n return cn('ald-radio-group', className, `ald-radio-group-${tempType}`, {\n // 约束只能在type为button和iconbutton的时候才可以设置样式和大小\n [`ald-radio-group-${radioGroupStyle}`]: isButton,\n [`ald-radio-group-${size}`]: isButton,\n });\n };\n\n return (\n <RadioGroupContext.Provider\n value={{\n onChange: onRadioChange,\n value,\n radioGroupStyle,\n size,\n type,\n disabled: mergedDisabled,\n name: groupName,\n }}\n >\n <div\n className={getWrapperClass()}\n data-testid={dataTestId}\n role=\"radiogroup\"\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n >\n {children}\n </div>\n </RadioGroupContext.Provider>\n );\n}\n"],"mappings":";;;;;AAYA,IAAa,oBAAoB,cAAsC,EAAE,CAAC;AAE1E,SAAwB,WAAW,OAAyB;CAC1D,MAAM,EACJ,UACA,kBAAkB,UAClB,OAAO,UACP,OAAO,SACP,WACA,UAAU,gBACV,eAAe,YACf,cAAc,WACd,mBAAmB,gBACnB,oBAAoB,oBAClB;CACJ,MAAM,YAAY,MAAM,OAAO;CAC/B,MAAM,eAAe,WAAW,SAAS,MAAM,UAAU;CACzD,MAAM,CAAC,YAAY,iBAAiB,SAAS,MAAM,aAAa;AAEhE,iBAAgB;AACd,MAAI,aACF,eAAc,MAAM,MAAM;IAE3B,CAAC,MAAM,OAAO,aAAa,CAAC;CAE/B,MAAM,QAAQ,eAAe,MAAM,QAAQ;CAC3C,MAAM,YAAY,MAAW;AAC3B,MAAI,CAAC,aACH,eAAc,EAAE;;CAIpB,MAAM,WAAW,MAAM,WAAW,gBAAgB;CAClD,MAAM,iBAAiB,kBAAkB;CACzC,MAAM,iBAAiB,kBAAuB;EAC5C,MAAM,YAAY;AAElB,WAAS,cAAc;EACvB,MAAM,EAAE,aAAa;AACrB,MAAI,YAAY,kBAAkB,UAChC,UAAS,cAAc;;CAI3B,MAAM,wBAAwB;EAC5B,MAAM,WAAW,CAAC,UAAU,aAAa,CAAC,SAAS,KAAK;AAExD,SAAO,GAAG,mBAAmB,WAAW,mBADvB,SAAS,eAAe,gBAAgB,QACc;IAEpE,mBAAmB,oBAAoB;IACvC,mBAAmB,SAAS;GAC9B,CAAC;;AAGJ,QACE,oBAAC,kBAAkB,UAAnB;EACE,OAAO;GACL,UAAU;GACV;GACA;GACA;GACA;GACA,UAAU;GACV,MAAM;GACP;YAED,oBAAC,OAAD;GACE,WAAW,iBAAiB;GAC5B,eAAa;GACb,MAAK;GACL,cAAY;GACZ,mBAAiB;GACjB,oBAAkB;GAEjB;GACG,CAAA;EACqB,CAAA"}
@@ -1,4 +1,5 @@
1
1
  import { cn } from "../../../lib/utils.js";
2
+ import { getSemanticOwnerAriaProps } from "../../../_utils/formControlSemanticOwner.js";
2
3
  import { getUUID } from "../../../_utils/hooks/useId.js";
3
4
  import { RadioGroupContext } from "../Group/index.js";
4
5
  import { useContext, useRef, useState } from "react";
@@ -56,12 +57,37 @@ function Radio(props) {
56
57
  className: "ald-radio-input",
57
58
  checked: !!checked,
58
59
  disabled: radioProps.disabled,
60
+ name: groupContext.name,
61
+ required: props.required,
59
62
  value: props.value,
63
+ ...getSemanticOwnerAriaProps({
64
+ "aria-label": props["aria-label"],
65
+ "aria-labelledby": props["aria-labelledby"],
66
+ "aria-describedby": props["aria-describedby"],
67
+ "aria-invalid": props["aria-invalid"],
68
+ "aria-required": props["aria-required"],
69
+ "aria-disabled": props["aria-disabled"]
70
+ }),
60
71
  onChange: (e) => {
61
72
  if (radioProps.disabled) return;
62
73
  if (!inGroup && !isControlled) setInnerChecked(e.target.checked);
63
74
  props.onChange?.(e);
64
75
  },
76
+ onKeyDown: (e) => {
77
+ if (!inGroup || ![
78
+ "ArrowUp",
79
+ "ArrowDown",
80
+ "ArrowLeft",
81
+ "ArrowRight"
82
+ ].includes(e.key)) return;
83
+ const radios = Array.from(document.querySelectorAll("input[type=\"radio\"]")).filter((radio) => radio.name === groupContext.name && !radio.disabled);
84
+ const currentIndex = radios.indexOf(e.currentTarget);
85
+ if (currentIndex < 0 || radios.length < 2) return;
86
+ e.preventDefault();
87
+ const nextRadio = radios[(currentIndex + (e.key === "ArrowUp" || e.key === "ArrowLeft" ? -1 : 1) + radios.length) % radios.length];
88
+ nextRadio.focus();
89
+ nextRadio.click();
90
+ },
65
91
  onClick: (e) => {
66
92
  props.onClick?.(e);
67
93
  if (inGroup && groupContext?.onChange) groupContext.onChange(props.value);
@@ -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 ? 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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/Radio/components/Radio/index.tsx"],"sourcesContent":["import { cn } from '../../../lib/utils';\nimport { getSemanticOwnerAriaProps } from '../../../_utils/formControlSemanticOwner';\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 name={groupContext.name}\n required={props.required}\n value={props.value}\n {...getSemanticOwnerAriaProps({\n 'aria-label': props['aria-label'],\n 'aria-labelledby': props['aria-labelledby'],\n 'aria-describedby': props['aria-describedby'],\n 'aria-invalid': props['aria-invalid'],\n 'aria-required': props['aria-required'],\n 'aria-disabled': props['aria-disabled'],\n })}\n onChange={(e) => {\n if (radioProps.disabled) return;\n if (!inGroup && !isControlled) {\n setInnerChecked(e.target.checked);\n }\n props.onChange?.(e);\n }}\n onKeyDown={(e) => {\n if (\n !inGroup ||\n !['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(\n e.key,\n )\n ) {\n return;\n }\n\n const radios = Array.from(\n document.querySelectorAll<HTMLInputElement>(\n 'input[type=\"radio\"]',\n ),\n ).filter(\n (radio) => radio.name === groupContext.name && !radio.disabled,\n );\n const currentIndex = radios.indexOf(e.currentTarget);\n if (currentIndex < 0 || radios.length < 2) return;\n\n e.preventDefault();\n const direction =\n e.key === 'ArrowUp' || e.key === 'ArrowLeft' ? -1 : 1;\n const nextIndex =\n (currentIndex + direction + radios.length) % radios.length;\n const nextRadio = radios[nextIndex];\n nextRadio.focus();\n nextRadio.click();\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":";;;;;;;;AASA,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,MAAM,aAAa;IACnB,UAAU,MAAM;IAChB,OAAO,MAAM;IACb,GAAI,0BAA0B;KAC5B,cAAc,MAAM;KACpB,mBAAmB,MAAM;KACzB,oBAAoB,MAAM;KAC1B,gBAAgB,MAAM;KACtB,iBAAiB,MAAM;KACvB,iBAAiB,MAAM;KACxB,CAAC;IACF,WAAW,MAAM;AACf,SAAI,WAAW,SAAU;AACzB,SAAI,CAAC,WAAW,CAAC,aACf,iBAAgB,EAAE,OAAO,QAAQ;AAEnC,WAAM,WAAW,EAAE;;IAErB,YAAY,MAAM;AAChB,SACE,CAAC,WACD,CAAC;MAAC;MAAW;MAAa;MAAa;MAAa,CAAC,SACnD,EAAE,IACH,CAED;KAGF,MAAM,SAAS,MAAM,KACnB,SAAS,iBACP,wBACD,CACF,CAAC,QACC,UAAU,MAAM,SAAS,aAAa,QAAQ,CAAC,MAAM,SACvD;KACD,MAAM,eAAe,OAAO,QAAQ,EAAE,cAAc;AACpD,SAAI,eAAe,KAAK,OAAO,SAAS,EAAG;AAE3C,OAAE,gBAAgB;KAKlB,MAAM,YAAY,QADf,gBAFD,EAAE,QAAQ,aAAa,EAAE,QAAQ,cAAc,KAAK,KAExB,OAAO,UAAU,OAAO;AAEtD,eAAU,OAAO;AACjB,eAAU,OAAO;;IAEnB,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"}
@@ -20,6 +20,13 @@ export interface IRadioProps {
20
20
  * @default -
21
21
  */
22
22
  value?: any;
23
+ required?: boolean;
24
+ 'aria-label'?: string;
25
+ 'aria-labelledby'?: string;
26
+ 'aria-describedby'?: string;
27
+ 'aria-invalid'?: React.AriaAttributes['aria-invalid'];
28
+ 'aria-required'?: React.AriaAttributes['aria-required'];
29
+ 'aria-disabled'?: React.AriaAttributes['aria-disabled'];
23
30
  children?: ReactNode[] | ReactNode;
24
31
  onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
25
32
  onClick?: (e: React.MouseEvent<HTMLInputElement>) => void;
@@ -48,4 +48,6 @@ export interface IRadioGroupProps {
48
48
  'data-testid'?: string;
49
49
  /** 透传到 RadioGroup 根容器的 aria-label,用于可访问性与自动化测试定位 */
50
50
  'aria-label'?: string;
51
+ 'aria-labelledby'?: string;
52
+ 'aria-describedby'?: string;
51
53
  }
@@ -49,6 +49,7 @@ var RenameInput = ({ value: propsValue, onConfirm, className, width, fontStyle,
49
49
  width
50
50
  },
51
51
  value,
52
+ "aria-label": `Rename ${propsValue}`,
52
53
  ref: inputRef,
53
54
  onChange: (e) => setValue(e.target.value),
54
55
  onBlur: (e) => {
@@ -80,6 +81,9 @@ var RenameInput = ({ value: propsValue, onConfirm, className, width, fontStyle,
80
81
  return /* @__PURE__ */ jsx("div", {
81
82
  className: cn(className, "ald-rename-input-text tw-flex tw-h-[22px] tw-items-center tw-border tw-border-[var(--action-ghost-normal)] tw-p-[2px] tw-text-[13px]"),
82
83
  style: fontStyle,
84
+ role: !readonly ? "button" : void 0,
85
+ tabIndex: !readonly ? 0 : void 0,
86
+ "aria-label": !readonly ? `Edit ${propsValue}` : void 0,
83
87
  onMouseMove: () => {
84
88
  setIsEdit(true);
85
89
  setValue(propsValue);
@@ -87,6 +91,13 @@ var RenameInput = ({ value: propsValue, onConfirm, className, width, fontStyle,
87
91
  onClick: () => {
88
92
  inputRef.current?.select();
89
93
  },
94
+ onKeyDown: (e) => {
95
+ if (!readonly && (e.key === "Enter" || e.key === " ")) {
96
+ e.preventDefault();
97
+ setIsEdit(true);
98
+ setValue(propsValue);
99
+ }
100
+ },
90
101
  children: propsValue
91
102
  });
92
103
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/RenameInput/index.tsx"],"sourcesContent":["import React, {\n CSSProperties,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../lib/utils';\n\ninterface IProps {\n value: string;\n onConfirm?: (value: string) => void;\n onError?: (value: string) => void;\n className?: string;\n width?: number;\n fontStyle?: CSSProperties;\n /**\n * @deprecated 如果要控制编辑态请使用 isEdit\n */\n focus?: boolean;\n isEdit?: boolean;\n maxLength?: number;\n distance?: [left: number, right: number];\n validateValue?: (value: string) => boolean;\n readonly?: boolean;\n}\n\nconst defaultWidth = 20;\n\nconst PADDING_WIDTH = 4;\n\nconst RenameInput = ({\n value: propsValue,\n onConfirm,\n className,\n width,\n fontStyle,\n maxLength,\n validateValue,\n onError,\n readonly = false,\n isEdit: propsIsEdit = false,\n}: IProps) => {\n const [isEdit, setIsEdit] = useState<boolean>(propsIsEdit);\n const [value, setValue] = useState(propsValue);\n\n useEffect(() => {\n setValue(propsValue);\n }, [propsValue]);\n\n const divRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const handleBlur = useCallback(() => {\n onConfirm?.(value);\n inputRef.current?.blur();\n }, [onConfirm, value]);\n\n useEffect(() => {\n if (!width && divRef.current && inputRef.current) {\n const tempWidth = divRef.current?.offsetWidth || defaultWidth;\n inputRef.current.style.width = tempWidth + PADDING_WIDTH + 'px';\n }\n }, [width, value, isEdit]);\n\n useEffect(() => {\n if (isEdit) {\n setValue(propsValue);\n }\n }, [isEdit, propsValue]);\n\n useEffect(() => {\n if (propsIsEdit) {\n setIsEdit(true);\n setTimeout(() => {\n if (inputRef.current) {\n inputRef.current.focus();\n inputRef.current.select();\n }\n }, 100);\n } else {\n setIsEdit(false);\n }\n }, [propsIsEdit]);\n\n if (isEdit && !readonly) {\n return (\n <div className=\"ald-rename-input tw-flex tw-h-[22px] tw-min-w-[10px] tw-max-w-full tw-items-center tw-border tw-border-[var(--action-ghost-normal)]\">\n <input\n className={cn(\n className,\n 'ald-rename-input-wrapper tw-box-border tw-h-[22px] tw-max-w-full tw-border-0 tw-p-[2px] tw-text-[13px]',\n 'hover:tw-border hover:tw-border-solid hover:tw-border-[var(--border-neutral-strong)]',\n 'focus:tw-border focus:tw-border-solid focus:tw-border-[var(--border-brand-strong)] focus:tw-shadow-[0_0_0_1px_var(--border-brand-strong)]',\n )}\n style={{\n ...fontStyle,\n width,\n }}\n value={value}\n ref={inputRef}\n onChange={(e) => setValue(e.target.value)}\n onBlur={(e) => {\n if (!validateValue || validateValue(e.target.value.trim())) {\n handleBlur();\n } else {\n onError?.(value);\n setValue(propsValue);\n }\n setIsEdit(false);\n }}\n onFocus={() => {\n inputRef.current?.select();\n }}\n maxLength={maxLength}\n onKeyUp={(e) => {\n if (e.key === 'Enter') {\n if (\n !validateValue ||\n validateValue(inputRef.current?.value.trim() || '')\n ) {\n inputRef.current?.blur();\n } else {\n onError?.(inputRef.current?.value.trim() || '');\n setValue(propsValue);\n }\n }\n }}\n />\n <div\n ref={divRef}\n className=\"ald-rename-input-div tw-pointer-events-none tw-invisible tw-fixed tw-bottom-0 tw--ml-px tw-min-w-px tw-max-w-full tw-overflow-hidden tw-whitespace-pre tw-border tw-border-[var(--action-ghost-normal)] tw-p-0 tw-text-[13px] tw-font-normal\"\n style={fontStyle}\n >\n {value}\n </div>\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n className,\n 'ald-rename-input-text tw-flex tw-h-[22px] tw-items-center tw-border tw-border-[var(--action-ghost-normal)] tw-p-[2px] tw-text-[13px]',\n )}\n style={fontStyle}\n onMouseMove={() => {\n setIsEdit(true);\n setValue(propsValue);\n }}\n onClick={() => {\n inputRef.current?.select();\n }}\n >\n {propsValue}\n </div>\n );\n};\n\nexport default RenameInput;\n"],"mappings":";;;;AA2BA,IAAM,eAAe;AAErB,IAAM,gBAAgB;AAEtB,IAAM,eAAe,EACnB,OAAO,YACP,WACA,WACA,OACA,WACA,WACA,eACA,SACA,WAAW,OACX,QAAQ,cAAc,YACV;CACZ,MAAM,CAAC,QAAQ,aAAa,SAAkB,YAAY;CAC1D,MAAM,CAAC,OAAO,YAAY,SAAS,WAAW;AAE9C,iBAAgB;AACd,WAAS,WAAW;IACnB,CAAC,WAAW,CAAC;CAEhB,MAAM,SAAS,OAAuB,KAAK;CAC3C,MAAM,WAAW,OAAyB,KAAK;CAE/C,MAAM,aAAa,kBAAkB;AACnC,cAAY,MAAM;AAClB,WAAS,SAAS,MAAM;IACvB,CAAC,WAAW,MAAM,CAAC;AAEtB,iBAAgB;AACd,MAAI,CAAC,SAAS,OAAO,WAAW,SAAS,SAAS;GAChD,MAAM,YAAY,OAAO,SAAS,eAAe;AACjD,YAAS,QAAQ,MAAM,QAAQ,YAAY,gBAAgB;;IAE5D;EAAC;EAAO;EAAO;EAAO,CAAC;AAE1B,iBAAgB;AACd,MAAI,OACF,UAAS,WAAW;IAErB,CAAC,QAAQ,WAAW,CAAC;AAExB,iBAAgB;AACd,MAAI,aAAa;AACf,aAAU,KAAK;AACf,oBAAiB;AACf,QAAI,SAAS,SAAS;AACpB,cAAS,QAAQ,OAAO;AACxB,cAAS,QAAQ,QAAQ;;MAE1B,IAAI;QAEP,WAAU,MAAM;IAEjB,CAAC,YAAY,CAAC;AAEjB,KAAI,UAAU,CAAC,SACb,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,SAAD;GACE,WAAW,GACT,WACA,0GACA,wFACA,4IACD;GACD,OAAO;IACL,GAAG;IACH;IACD;GACM;GACP,KAAK;GACL,WAAW,MAAM,SAAS,EAAE,OAAO,MAAM;GACzC,SAAS,MAAM;AACb,QAAI,CAAC,iBAAiB,cAAc,EAAE,OAAO,MAAM,MAAM,CAAC,CACxD,aAAY;SACP;AACL,eAAU,MAAM;AAChB,cAAS,WAAW;;AAEtB,cAAU,MAAM;;GAElB,eAAe;AACb,aAAS,SAAS,QAAQ;;GAEjB;GACX,UAAU,MAAM;AACd,QAAI,EAAE,QAAQ,QACZ,KACE,CAAC,iBACD,cAAc,SAAS,SAAS,MAAM,MAAM,IAAI,GAAG,CAEnD,UAAS,SAAS,MAAM;SACnB;AACL,eAAU,SAAS,SAAS,MAAM,MAAM,IAAI,GAAG;AAC/C,cAAS,WAAW;;;GAI1B,CAAA,EACF,oBAAC,OAAD;GACE,KAAK;GACL,WAAU;GACV,OAAO;aAEN;GACG,CAAA,CACF;;AAIV,QACE,oBAAC,OAAD;EACE,WAAW,GACT,WACA,uIACD;EACD,OAAO;EACP,mBAAmB;AACjB,aAAU,KAAK;AACf,YAAS,WAAW;;EAEtB,eAAe;AACb,YAAS,SAAS,QAAQ;;YAG3B;EACG,CAAA"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/RenameInput/index.tsx"],"sourcesContent":["import React, {\n CSSProperties,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../lib/utils';\n\ninterface IProps {\n value: string;\n onConfirm?: (value: string) => void;\n onError?: (value: string) => void;\n className?: string;\n width?: number;\n fontStyle?: CSSProperties;\n /**\n * @deprecated 如果要控制编辑态请使用 isEdit\n */\n focus?: boolean;\n isEdit?: boolean;\n maxLength?: number;\n distance?: [left: number, right: number];\n validateValue?: (value: string) => boolean;\n readonly?: boolean;\n}\n\nconst defaultWidth = 20;\n\nconst PADDING_WIDTH = 4;\n\nconst RenameInput = ({\n value: propsValue,\n onConfirm,\n className,\n width,\n fontStyle,\n maxLength,\n validateValue,\n onError,\n readonly = false,\n isEdit: propsIsEdit = false,\n}: IProps) => {\n const [isEdit, setIsEdit] = useState<boolean>(propsIsEdit);\n const [value, setValue] = useState(propsValue);\n\n useEffect(() => {\n setValue(propsValue);\n }, [propsValue]);\n\n const divRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const handleBlur = useCallback(() => {\n onConfirm?.(value);\n inputRef.current?.blur();\n }, [onConfirm, value]);\n\n useEffect(() => {\n if (!width && divRef.current && inputRef.current) {\n const tempWidth = divRef.current?.offsetWidth || defaultWidth;\n inputRef.current.style.width = tempWidth + PADDING_WIDTH + 'px';\n }\n }, [width, value, isEdit]);\n\n useEffect(() => {\n if (isEdit) {\n setValue(propsValue);\n }\n }, [isEdit, propsValue]);\n\n useEffect(() => {\n if (propsIsEdit) {\n setIsEdit(true);\n setTimeout(() => {\n if (inputRef.current) {\n inputRef.current.focus();\n inputRef.current.select();\n }\n }, 100);\n } else {\n setIsEdit(false);\n }\n }, [propsIsEdit]);\n\n if (isEdit && !readonly) {\n return (\n <div className=\"ald-rename-input tw-flex tw-h-[22px] tw-min-w-[10px] tw-max-w-full tw-items-center tw-border tw-border-[var(--action-ghost-normal)]\">\n <input\n className={cn(\n className,\n 'ald-rename-input-wrapper tw-box-border tw-h-[22px] tw-max-w-full tw-border-0 tw-p-[2px] tw-text-[13px]',\n 'hover:tw-border hover:tw-border-solid hover:tw-border-[var(--border-neutral-strong)]',\n 'focus:tw-border focus:tw-border-solid focus:tw-border-[var(--border-brand-strong)] focus:tw-shadow-[0_0_0_1px_var(--border-brand-strong)]',\n )}\n style={{\n ...fontStyle,\n width,\n }}\n value={value}\n aria-label={`Rename ${propsValue}`}\n ref={inputRef}\n onChange={(e) => setValue(e.target.value)}\n onBlur={(e) => {\n if (!validateValue || validateValue(e.target.value.trim())) {\n handleBlur();\n } else {\n onError?.(value);\n setValue(propsValue);\n }\n setIsEdit(false);\n }}\n onFocus={() => {\n inputRef.current?.select();\n }}\n maxLength={maxLength}\n onKeyUp={(e) => {\n if (e.key === 'Enter') {\n if (\n !validateValue ||\n validateValue(inputRef.current?.value.trim() || '')\n ) {\n inputRef.current?.blur();\n } else {\n onError?.(inputRef.current?.value.trim() || '');\n setValue(propsValue);\n }\n }\n }}\n />\n <div\n ref={divRef}\n className=\"ald-rename-input-div tw-pointer-events-none tw-invisible tw-fixed tw-bottom-0 tw--ml-px tw-min-w-px tw-max-w-full tw-overflow-hidden tw-whitespace-pre tw-border tw-border-[var(--action-ghost-normal)] tw-p-0 tw-text-[13px] tw-font-normal\"\n style={fontStyle}\n >\n {value}\n </div>\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n className,\n 'ald-rename-input-text tw-flex tw-h-[22px] tw-items-center tw-border tw-border-[var(--action-ghost-normal)] tw-p-[2px] tw-text-[13px]',\n )}\n style={fontStyle}\n role={!readonly ? 'button' : undefined}\n tabIndex={!readonly ? 0 : undefined}\n aria-label={!readonly ? `Edit ${propsValue}` : undefined}\n onMouseMove={() => {\n setIsEdit(true);\n setValue(propsValue);\n }}\n onClick={() => {\n inputRef.current?.select();\n }}\n onKeyDown={(e) => {\n if (!readonly && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n setIsEdit(true);\n setValue(propsValue);\n }\n }}\n >\n {propsValue}\n </div>\n );\n};\n\nexport default RenameInput;\n"],"mappings":";;;;AA2BA,IAAM,eAAe;AAErB,IAAM,gBAAgB;AAEtB,IAAM,eAAe,EACnB,OAAO,YACP,WACA,WACA,OACA,WACA,WACA,eACA,SACA,WAAW,OACX,QAAQ,cAAc,YACV;CACZ,MAAM,CAAC,QAAQ,aAAa,SAAkB,YAAY;CAC1D,MAAM,CAAC,OAAO,YAAY,SAAS,WAAW;AAE9C,iBAAgB;AACd,WAAS,WAAW;IACnB,CAAC,WAAW,CAAC;CAEhB,MAAM,SAAS,OAAuB,KAAK;CAC3C,MAAM,WAAW,OAAyB,KAAK;CAE/C,MAAM,aAAa,kBAAkB;AACnC,cAAY,MAAM;AAClB,WAAS,SAAS,MAAM;IACvB,CAAC,WAAW,MAAM,CAAC;AAEtB,iBAAgB;AACd,MAAI,CAAC,SAAS,OAAO,WAAW,SAAS,SAAS;GAChD,MAAM,YAAY,OAAO,SAAS,eAAe;AACjD,YAAS,QAAQ,MAAM,QAAQ,YAAY,gBAAgB;;IAE5D;EAAC;EAAO;EAAO;EAAO,CAAC;AAE1B,iBAAgB;AACd,MAAI,OACF,UAAS,WAAW;IAErB,CAAC,QAAQ,WAAW,CAAC;AAExB,iBAAgB;AACd,MAAI,aAAa;AACf,aAAU,KAAK;AACf,oBAAiB;AACf,QAAI,SAAS,SAAS;AACpB,cAAS,QAAQ,OAAO;AACxB,cAAS,QAAQ,QAAQ;;MAE1B,IAAI;QAEP,WAAU,MAAM;IAEjB,CAAC,YAAY,CAAC;AAEjB,KAAI,UAAU,CAAC,SACb,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,SAAD;GACE,WAAW,GACT,WACA,0GACA,wFACA,4IACD;GACD,OAAO;IACL,GAAG;IACH;IACD;GACM;GACP,cAAY,UAAU;GACtB,KAAK;GACL,WAAW,MAAM,SAAS,EAAE,OAAO,MAAM;GACzC,SAAS,MAAM;AACb,QAAI,CAAC,iBAAiB,cAAc,EAAE,OAAO,MAAM,MAAM,CAAC,CACxD,aAAY;SACP;AACL,eAAU,MAAM;AAChB,cAAS,WAAW;;AAEtB,cAAU,MAAM;;GAElB,eAAe;AACb,aAAS,SAAS,QAAQ;;GAEjB;GACX,UAAU,MAAM;AACd,QAAI,EAAE,QAAQ,QACZ,KACE,CAAC,iBACD,cAAc,SAAS,SAAS,MAAM,MAAM,IAAI,GAAG,CAEnD,UAAS,SAAS,MAAM;SACnB;AACL,eAAU,SAAS,SAAS,MAAM,MAAM,IAAI,GAAG;AAC/C,cAAS,WAAW;;;GAI1B,CAAA,EACF,oBAAC,OAAD;GACE,KAAK;GACL,WAAU;GACV,OAAO;aAEN;GACG,CAAA,CACF;;AAIV,QACE,oBAAC,OAAD;EACE,WAAW,GACT,WACA,uIACD;EACD,OAAO;EACP,MAAM,CAAC,WAAW,WAAW;EAC7B,UAAU,CAAC,WAAW,IAAI;EAC1B,cAAY,CAAC,WAAW,QAAQ,eAAe;EAC/C,mBAAmB;AACjB,aAAU,KAAK;AACf,YAAS,WAAW;;EAEtB,eAAe;AACb,YAAS,SAAS,QAAQ;;EAE5B,YAAY,MAAM;AAChB,OAAI,CAAC,aAAa,EAAE,QAAQ,WAAW,EAAE,QAAQ,MAAM;AACrD,MAAE,gBAAgB;AAClB,cAAU,KAAK;AACf,aAAS,WAAW;;;YAIvB;EACG,CAAA"}