@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
@@ -118,6 +118,9 @@ function Table(props, ref) {
118
118
  const showResizer = columnSizing && !(!!rowSelectionInfo.isRowSelectionEnabled && index === 0);
119
119
  const { className: fixedClassName, style: fixedStyle } = getColumnFixedInfo(index, true);
120
120
  return /* @__PURE__ */ jsxs("div", {
121
+ role: "columnheader",
122
+ "aria-label": typeof header.column.columnDef.meta.title === "string" ? header.column.columnDef.meta.title : void 0,
123
+ "aria-sort": header.column.columnDef.meta.sortOrder === "ascend" ? "ascending" : header.column.columnDef.meta.sortOrder === "descend" ? "descending" : header.column.columnDef.meta.sortOrder !== void 0 ? "none" : void 0,
121
124
  className: cn(prefixCls("th"), fixedClassName),
122
125
  style: {
123
126
  width: header.getSize(),
@@ -150,6 +153,7 @@ function Table(props, ref) {
150
153
  virtualPaddingRight = columnVirtualizer.getTotalSize() - (virtualColumns[virtualColumns.length - 1]?.end ?? 0);
151
154
  }
152
155
  const headerContent = /* @__PURE__ */ jsx("div", {
156
+ role: "rowgroup",
153
157
  className: cn(prefixCls("header"), {
154
158
  [prefixCls("overflow-x")]: true,
155
159
  [prefixCls("sticky")]: isStickyWork,
@@ -204,6 +208,7 @@ function Table(props, ref) {
204
208
  } else content = _.map(allHeaderCells, (header, index) => renderHeaderCell(header, index));
205
209
  return /* @__PURE__ */ jsxs("div", {
206
210
  className: prefixCls("tr"),
211
+ role: "row",
207
212
  style: { width: totalColumnsWidth },
208
213
  children: [content, y !== void 0 && /* @__PURE__ */ jsx("div", {
209
214
  className: prefixCls("header-scroll-placeholder"),
@@ -234,6 +239,7 @@ function Table(props, ref) {
234
239
  const { className: fixedClassName, style: fixedStyle } = getColumnFixedInfo(colIndex);
235
240
  const tdContent = flexRender(cell.column.columnDef.cell, cell.getContext());
236
241
  return /* @__PURE__ */ jsx("div", {
242
+ role: "cell",
237
243
  className: cn(prefixCls("td"), fixedClassName),
238
244
  style: {
239
245
  width: cell.column.getSize(),
@@ -255,6 +261,7 @@ function Table(props, ref) {
255
261
  rowSelectionInfo.isRowSelectionEnabled
256
262
  ]);
257
263
  const bodyContent = /* @__PURE__ */ jsx("div", {
264
+ role: "rowgroup",
258
265
  className: prefixCls("body"),
259
266
  style: {
260
267
  width: totalColumnsWidth,
@@ -272,6 +279,8 @@ function Table(props, ref) {
272
279
  })
273
280
  })
274
281
  }), /* @__PURE__ */ jsx("div", {
282
+ role: "status",
283
+ "aria-live": "polite",
275
284
  "aria-invalid": "true",
276
285
  style: {
277
286
  position: "absolute",
@@ -339,6 +348,8 @@ function Table(props, ref) {
339
348
  const isRowSelected = rowSelectionInfo.isRowSelectionEnabled && rowSelectionInfo.selectedRowKeys.includes(rowId);
340
349
  const isRowSelectionDisabled = rowSelectionInfo.isRowSelectionEnabled && !!rowSelection?.getCheckboxProps?.(row.original).disabled;
341
350
  const rowNode = /* @__PURE__ */ jsx("div", {
351
+ role: "row",
352
+ "aria-rowindex": rowIndex + 2,
342
353
  "data-index": virtual ? rowData.index : rowIndex,
343
354
  className: cn(prefixCls("tr"), {
344
355
  [prefixCls("row-hover")]: rowDndInfo.draggingRowId ? void 0 : hoverRowId === rowId,
@@ -377,6 +388,7 @@ function Table(props, ref) {
377
388
  if (expandItem?.isExpanded !== true) return rowList;
378
389
  const customRow = /* @__PURE__ */ jsx("div", {
379
390
  className: cn(prefixCls("tr")),
391
+ role: "row",
380
392
  onClick: onClickRow(row.original, rowIndex),
381
393
  children: expandedRowRender(row.original, expandItem.level + 1)
382
394
  }, customExpandRowKey);
@@ -392,35 +404,38 @@ function Table(props, ref) {
392
404
  totalSize,
393
405
  isShowFooter
394
406
  ]);
395
- const tableContent = /* @__PURE__ */ jsx(CustomSpin, {
396
- spinning: !!loading,
397
- children: /* @__PURE__ */ jsxs("div", {
398
- className: prefixCls("content"),
399
- children: [
400
- headerContent,
401
- /* @__PURE__ */ jsx("div", {
402
- style: {
403
- height: tableContentHeight,
404
- position: virtual ? "relative" : void 0
405
- },
406
- className: cn(prefixCls("body-scroll"), {
407
- [prefixCls("scroll-y")]: y !== void 0,
408
- [prefixCls("scroll-hidden")]: isEmpty
409
- }),
410
- ref: bodyRef,
411
- onScroll: onBodyScroll,
412
- children: bodyContent
407
+ const tableContentBody = /* @__PURE__ */ jsxs("div", {
408
+ className: prefixCls("content"),
409
+ role: "table",
410
+ "aria-label": "Data table",
411
+ children: [
412
+ headerContent,
413
+ /* @__PURE__ */ jsx("div", {
414
+ style: {
415
+ height: tableContentHeight,
416
+ position: virtual ? "relative" : void 0
417
+ },
418
+ className: cn(prefixCls("body-scroll"), {
419
+ [prefixCls("scroll-y")]: y !== void 0,
420
+ [prefixCls("scroll-hidden")]: isEmpty
413
421
  }),
414
- isShowFooter && /* @__PURE__ */ jsx(TableFooter, {
415
- rowSelectionInfo,
416
- isShowPagination,
417
- pagination,
418
- scroll,
419
- scrollToFirstRow
420
- })
421
- ]
422
- })
422
+ ref: bodyRef,
423
+ onScroll: onBodyScroll,
424
+ children: bodyContent
425
+ }),
426
+ isShowFooter && /* @__PURE__ */ jsx(TableFooter, {
427
+ rowSelectionInfo,
428
+ isShowPagination,
429
+ pagination,
430
+ scroll,
431
+ scrollToFirstRow
432
+ })
433
+ ]
423
434
  });
435
+ const tableContent = loading ? /* @__PURE__ */ jsx(CustomSpin, {
436
+ spinning: true,
437
+ children: tableContentBody
438
+ }) : tableContentBody;
424
439
  const tableStyle = {};
425
440
  if (y) tableStyle.height = y;
426
441
  return /* @__PURE__ */ jsx("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Table/index.tsx"],"sourcesContent":["import {\n Cell,\n Header,\n Row,\n flexRender,\n getCoreRowModel,\n useReactTable,\n} from '@tanstack/react-table';\nimport { VirtualItem, useVirtualizer } from '@tanstack/react-virtual';\nimport { cn } from '../lib/utils';\nimport './table.css';\nimport _ from 'lodash';\nimport React, {\n CSSProperties,\n ForwardedRef,\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Empty, Spin } from '..';\nimport ExpandCell from './components/ExpandCell';\nimport Footer from './components/Footer';\nimport DndWrapper from './components/DndWrapper';\nimport { getRowKey, getTableColumns, prefixCls } from './helper';\nimport useExpandable, { getExpandableConfig } from './hooks/useExpandable';\nimport useFixed from './hooks/useFixed';\nimport useRowSelection from './hooks/useRowSelection';\nimport useScroll from './hooks/useScroll';\nimport { ITableProps, ITableRef } from './types';\nimport useRowDnd from './hooks/useRowDnd';\n\nconst HEADER_HEIGHT = 41;\nconst FOOTER_HEIGHT = 52;\n\nfunction TableResizeWrapper({\n children,\n onResize,\n}: {\n children: React.ReactNode;\n onResize: (width: number, height: number) => void;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const onResizeRef = useRef(onResize);\n onResizeRef.current = onResize;\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n let prevW = 0;\n let prevH = 0;\n const ro = new window.ResizeObserver(() => {\n const w = el.offsetWidth;\n const h = el.offsetHeight;\n if (w === prevW && h === prevH) return;\n prevW = w;\n prevH = h;\n onResizeRef.current(w, h);\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, []);\n return (\n <div ref={ref} style={{ height: '100%' }}>\n {children}\n </div>\n );\n}\n\nfunction Table<TDataItem extends object>(\n props: ITableProps<TDataItem>,\n ref: ForwardedRef<ITableRef>,\n) {\n const {\n data,\n bordered,\n rowKey,\n columnSizing,\n sticky,\n loading,\n pagination,\n scroll = {},\n empty: emptyComponent,\n virtual = false,\n rowClassName = () => '',\n onRowClick,\n onError,\n onSort,\n expandable,\n rowDnd,\n rowSelection,\n } = props;\n const [totalSize, setTotalSize] = useState<{\n width: number;\n height: number;\n } | null>(null);\n\n const [hoverRowId, setHoverRowId] = useState<string | null>(null);\n\n const { y } = scroll;\n const {\n containerWidth,\n onBodyScroll,\n headerRef,\n bodyRef,\n isPingLeft,\n isPingRight,\n scrollbarWidth,\n changeIsPing,\n } = useScroll({\n totalSize,\n scroll,\n });\n\n const scrollToFirstRow = useCallback(() => {\n if (!bodyRef.current) {\n return;\n }\n bodyRef.current.scrollTop = 0;\n }, [bodyRef]);\n\n useImperativeHandle(ref, () => ({\n scrollToFirstRow,\n }));\n\n const expandableInfo = useExpandable({\n expandable,\n data,\n rowKey,\n });\n const expandableConfig = getExpandableConfig(expandable);\n\n const rowSelectionInfo = useRowSelection({\n ...props,\n data: expandableInfo.data,\n isExpandable: expandableInfo.isExpandable,\n flattenData: expandableInfo.flattenData,\n });\n\n const rowDndInfo = useRowDnd({\n ...props,\n columns: rowSelectionInfo.columns,\n data: expandableInfo.data,\n });\n\n const tableColumns = useMemo(() => {\n return getTableColumns<TDataItem>({\n columns: rowDndInfo.columns,\n containerWidth: containerWidth || 0,\n onError,\n onSort,\n });\n }, [containerWidth, onError, onSort, rowDndInfo.columns]);\n\n const tableInstance = useReactTable<TDataItem>({\n columns: tableColumns,\n // 排除掉被折叠的行\n data: rowDndInfo.tableData,\n getCoreRowModel: getCoreRowModel(),\n getRowId: (row, index) => {\n return getRowKey(row, rowKey, index);\n },\n columnResizeMode: 'onChange',\n });\n\n const headerGroups = tableInstance.getHeaderGroups();\n\n const columnWidths = headerGroups[0].headers.map((header) =>\n header.getSize(),\n );\n const getColumnFixedInfo = useFixed<TDataItem>({\n columnWidths,\n tableColumns,\n y,\n scrollbarWidth,\n });\n\n // 渲染 header\n const { rows } = tableInstance.getRowModel();\n\n const isStickyWork = !!sticky && y === undefined;\n const headerStyle: CSSProperties = {};\n if (isStickyWork && _.get(sticky, 'offsetHeader')) {\n headerStyle.top = _.get(sticky, 'offsetHeader', 0);\n }\n\n const totalColumnsWidth = _.sum(columnWidths);\n\n useEffect(() => {\n // 总列宽改变时,重新计算是否需要显示固定列的阴影\n changeIsPing(totalColumnsWidth);\n }, [changeIsPing, totalColumnsWidth]);\n\n const renderHeaderCell = useCallback(\n (header: Header<TDataItem, unknown>, index: number) => {\n // 选择行的列不能拖动宽度\n const showResizer =\n columnSizing &&\n !(!!rowSelectionInfo.isRowSelectionEnabled && index === 0);\n const { className: fixedClassName, style: fixedStyle } =\n getColumnFixedInfo(index, true);\n return (\n <div\n className={cn(prefixCls('th'), fixedClassName)}\n style={{ width: header.getSize(), ...fixedStyle }}\n key={header.id}\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n {showResizer && (\n <div\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n className={cn(prefixCls('resizer'), {\n [prefixCls('self-resizing')]: header.column.getIsResizing(),\n })}\n />\n )}\n </div>\n );\n },\n [columnSizing, rowSelectionInfo, getColumnFixedInfo],\n );\n\n const visibleColumns = tableInstance.getVisibleLeafColumns();\n\n const columnVirtualizer = useVirtualizer({\n count: tableColumns.length,\n estimateSize: (index: number) => visibleColumns[index].getSize(),\n getScrollElement: () => bodyRef.current,\n horizontal: true,\n overscan: 5,\n });\n\n const virtualColumns = columnVirtualizer.getVirtualItems();\n\n //different virtualization strategy for columns - instead of absolute and translateY, we add empty columns to the left and right\n let virtualPaddingLeft: number | undefined;\n let virtualPaddingRight: number | undefined;\n\n if (columnVirtualizer && virtualColumns?.length) {\n virtualPaddingLeft = virtualColumns[0]?.start ?? 0;\n virtualPaddingRight =\n columnVirtualizer.getTotalSize() -\n (virtualColumns[virtualColumns.length - 1]?.end ?? 0);\n }\n\n const headerContent = (\n <div\n className={cn(prefixCls('header'), {\n [prefixCls('overflow-x')]: true,\n [prefixCls('sticky')]: isStickyWork,\n [prefixCls('resizing')]:\n tableInstance.getState().columnSizingInfo.isResizingColumn,\n })}\n ref={headerRef}\n style={headerStyle}\n >\n {_.map(headerGroups, (headerGroup) => {\n const allHeaderCells = headerGroup.headers;\n const virtualColumns = columnVirtualizer.getVirtualItems();\n\n const middleVirtualColumns: VirtualItem[] = [];\n // 将固定列单独拎出来,固定列不受列虚拟化影响,必须要渲染\n const leftFixedColumns: {\n header: Header<TDataItem, unknown>;\n index: number;\n }[] = [];\n const rightFixedColumns: {\n header: Header<TDataItem, unknown>;\n index: number;\n }[] = [];\n let content: React.ReactNode | null = null;\n if (virtual) {\n _.forEach(allHeaderCells, (header, index) => {\n const fixedInfo = getColumnFixedInfo(index);\n if (fixedInfo.fixed === 'left') {\n leftFixedColumns.push({ header, index });\n }\n if (fixedInfo.fixed === 'right') {\n rightFixedColumns.push({ header, index });\n }\n });\n\n _.forEach(virtualColumns, (virtualColumn) => {\n const colIndex = virtualColumn.index;\n const fixedInfo = getColumnFixedInfo(colIndex);\n if (fixedInfo.fixed !== 'left' && fixedInfo.fixed !== 'right') {\n middleVirtualColumns.push(virtualColumn);\n }\n });\n content = (\n <>\n {virtualPaddingLeft ? (\n //fake empty column to the left for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-left')}\n style={{ width: virtualPaddingLeft }}\n />\n ) : null}\n {leftFixedColumns.map(({ header, index }) => {\n return renderHeaderCell(header, index);\n })}\n {_.map(middleVirtualColumns, (virtualColumn) => {\n const header = allHeaderCells[virtualColumn.index];\n return renderHeaderCell(header, virtualColumn.index);\n })}\n {rightFixedColumns.map(({ header, index }) => {\n return renderHeaderCell(header, index);\n })}\n {virtualPaddingRight ? (\n //fake empty column to the right for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-right')}\n style={{ width: virtualPaddingRight }}\n />\n ) : null}\n </>\n );\n } else {\n content = _.map(allHeaderCells, (header, index) =>\n renderHeaderCell(header, index),\n );\n }\n\n return (\n <div\n className={prefixCls('tr')}\n key={headerGroup.id}\n style={{ width: totalColumnsWidth }}\n >\n {content}\n {y !== undefined && (\n <div\n className={prefixCls('header-scroll-placeholder')}\n style={{ flexBasis: scrollbarWidth }}\n />\n )}\n </div>\n );\n })}\n </div>\n );\n\n const onClickRow = useCallback(\n (rowData: TDataItem, rowIndex: number) => () => {\n if (typeof onRowClick !== 'function') {\n return;\n }\n if (window.getSelection()?.toString().length !== 0) {\n // 防止选择文本时触发 onRowClick\n return;\n }\n onRowClick(rowData, rowIndex);\n },\n [onRowClick],\n );\n\n const isShowPagination = !!(\n pagination &&\n (pagination.total > pagination.pageSize || pagination.showSizeChanger)\n );\n const isShowRowSelection = rowSelectionInfo.isShowRowSelectionInFooter;\n\n const isShowFooter = isShowPagination || isShowRowSelection;\n\n // 空态切换 size 的阈值\n const EMPTY_SMALL_SIZE_HEIGHT = 436;\n const isSmallEmpty = totalSize && totalSize.height < EMPTY_SMALL_SIZE_HEIGHT;\n\n const isEmpty = rows.length === 0 && !loading;\n\n const rowVirtualizer = useVirtualizer({\n count: rows.length,\n estimateSize: () => 48, // estimate row height for accurate scrollbar dragging\n // 没有测量出 bodyRef.current 的高度时,返回 null,避免虚拟化器从 DOM 获取异常高度\n getScrollElement: () => (totalSize ? bodyRef.current : null),\n // measure dynamic row height, except in firefox because it measures table border height incorrectly\n measureElement:\n typeof window !== 'undefined' &&\n navigator.userAgent.indexOf('Firefox') === -1\n ? (element) => element?.getBoundingClientRect().height\n : undefined,\n overscan: 5,\n });\n\n const tableRows = virtual ? rowVirtualizer.getVirtualItems() : rows;\n\n const renderBodyCell = useCallback(\n (row: Row<TDataItem>, cell: Cell<TDataItem, unknown>, colIndex: number) => {\n const { className: fixedClassName, style: fixedStyle } =\n getColumnFixedInfo(colIndex);\n const tdContent = flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n );\n return (\n <div\n className={cn(prefixCls('td'), fixedClassName)}\n key={cell.id}\n style={{ width: cell.column.getSize(), ...fixedStyle }}\n >\n {expandableInfo.isExpandable &&\n colIndex === (rowSelectionInfo.isRowSelectionEnabled ? 1 : 0) ? (\n <ExpandCell\n expandableInfo={expandableInfo}\n expandable={expandable}\n data={row.original}\n rowKey={rowKey}\n >\n {tdContent}\n </ExpandCell>\n ) : (\n tdContent\n )}\n </div>\n );\n },\n [\n expandableInfo,\n expandable,\n rowKey,\n getColumnFixedInfo,\n rowSelectionInfo.isRowSelectionEnabled,\n ],\n );\n\n // 渲染 body\n const bodyContent = (\n <div\n className={prefixCls('body')}\n style={{\n width: totalColumnsWidth,\n height: virtual\n ? totalSize\n ? rowVirtualizer.getTotalSize()\n : 0\n : 'auto',\n }}\n >\n {isEmpty ? (\n <div style={{ width: totalSize?.width }}>\n <div style={{ visibility: 'hidden' }}>\n {emptyComponent || (\n <div\n className={cn(prefixCls('empty'), {\n [prefixCls('empty-small')]: isSmallEmpty,\n })}\n >\n <Empty\n image={isSmallEmpty ? null : Empty.PRESENTED_IMAGE_SEARCH}\n size={isSmallEmpty ? 'small' : undefined}\n />\n </div>\n )}\n </div>\n <div\n aria-invalid=\"true\"\n style={{\n position: 'absolute',\n top: 40,\n left: 0,\n right: 0,\n bottom: 0,\n }}\n >\n {emptyComponent || (\n <div\n className={cn(prefixCls('empty'), {\n [prefixCls('empty-small')]: isSmallEmpty,\n })}\n >\n <Empty\n image={isSmallEmpty ? null : Empty.PRESENTED_IMAGE_SEARCH}\n size={isSmallEmpty ? 'small' : undefined}\n />\n </div>\n )}\n </div>\n </div>\n ) : (\n _.reduce<Row<TDataItem> | VirtualItem, React.ReactNode[]>(\n tableRows,\n (rowList, rowData, rowIndex) => {\n const row = virtual\n ? rows[rowData.index]\n : (rowData as Row<TDataItem>);\n const allRowCells = row.getVisibleCells();\n\n let content: React.ReactNode | null = null;\n // 将固定列单独拎出来,固定列不受列虚拟化影响,必须要渲染\n const leftFixedColumns: {\n cell: Cell<TDataItem, unknown>;\n index: number;\n }[] = [];\n const rightFixedColumns: {\n cell: Cell<TDataItem, unknown>;\n index: number;\n }[] = [];\n\n if (virtual) {\n const virtualColumns = columnVirtualizer.getVirtualItems();\n\n const middleVirtualColumns: VirtualItem[] = [];\n\n _.forEach(allRowCells, (cell, index) => {\n const fixedInfo = getColumnFixedInfo(index);\n if (fixedInfo.fixed === 'left') {\n leftFixedColumns.push({ cell, index });\n }\n if (fixedInfo.fixed === 'right') {\n rightFixedColumns.push({ cell, index });\n }\n });\n\n _.forEach(virtualColumns, (virtualColumn) => {\n const colIndex = virtualColumn.index;\n const fixedInfo = getColumnFixedInfo(colIndex);\n if (fixedInfo.fixed !== 'left' && fixedInfo.fixed !== 'right') {\n middleVirtualColumns.push(virtualColumn);\n }\n });\n content = (\n <>\n {virtualPaddingLeft ? (\n //fake empty column to the left for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-left')}\n style={{ width: virtualPaddingLeft }}\n />\n ) : null}\n {leftFixedColumns.map(({ cell, index }) => {\n return renderBodyCell(row, cell, index);\n })}\n {middleVirtualColumns.map((virtualColumn) => {\n const colIndex = virtualColumn.index;\n const cell = allRowCells[colIndex];\n return renderBodyCell(row, cell, colIndex);\n })}\n {rightFixedColumns.map(({ cell, index }) => {\n return renderBodyCell(row, cell, index);\n })}\n {virtualPaddingRight ? (\n //fake empty column to the right for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-right')}\n style={{ width: virtualPaddingRight }}\n />\n ) : null}\n </>\n );\n } else {\n content = allRowCells.map((cell, index) =>\n renderBodyCell(row, cell, index),\n );\n }\n const rowId = row.id;\n const isRowSelected =\n rowSelectionInfo.isRowSelectionEnabled &&\n rowSelectionInfo.selectedRowKeys.includes(rowId);\n const isRowSelectionDisabled =\n rowSelectionInfo.isRowSelectionEnabled &&\n !!rowSelection?.getCheckboxProps?.(row.original).disabled;\n\n const rowNode = (\n <div\n key={rowId}\n data-index={virtual ? (rowData as VirtualItem).index : rowIndex}\n className={cn(\n prefixCls('tr'),\n {\n // 需要用 state 的原因是,存在固定列的情况,左右侧的固定列在 dom 结构上不在同一个 tr 上,所以不能用 css 的 :hover 来实现\n // 当拖拽行时,不显示 hover 状态\n [prefixCls('row-hover')]: rowDndInfo.draggingRowId\n ? undefined\n : hoverRowId === rowId,\n [prefixCls('row-dragging')]:\n rowDndInfo.draggingRowId === rowId,\n [prefixCls('row-selected')]: isRowSelected,\n [prefixCls('row-selection-disabled')]:\n isRowSelectionDisabled,\n [prefixCls('no-border-tr')]:\n isShowPagination && rowIndex === rows.length - 1,\n },\n rowClassName(row.original, rowIndex),\n )}\n ref={(node) => {\n // 只在虚拟滚动模式下才测量行高度,避免非虚拟模式下的不必要重渲染\n if (virtual) {\n rowVirtualizer.measureElement(node);\n }\n\n // 如果启用了行拖拽,则设置行引用\n if (rowDnd && node) {\n const rowRef = rowDndInfo.getRowRef(row.original, rowIndex);\n if (rowRef) {\n rowRef.current = node;\n }\n }\n }}\n onClick={onClickRow(row.original, rowIndex)}\n onMouseEnter={() => {\n if (!isRowSelectionDisabled) {\n setHoverRowId(rowId);\n }\n }}\n onMouseLeave={() => setHoverRowId(null)}\n style={\n virtual\n ? {\n position: 'absolute',\n transform: `translateY(${\n (rowData as VirtualItem).start\n }px)`,\n }\n : {}\n }\n >\n {content}\n </div>\n );\n rowList.push(rowNode);\n\n // 渲染额外展开的行\n const expandItem = expandableInfo.expandItemMap[rowId];\n const customExpandRowKey =\n expandableInfo.isExpandable && expandItem?.customExpandRowKey;\n const hasCustomExpandRowKey = !!customExpandRowKey;\n if (hasCustomExpandRowKey) {\n // 在该行的下面追加自定义展开行\n const expandedRowRender = expandableConfig.expandedRowRender;\n if (typeof expandedRowRender !== 'function') {\n console.error('expandedRowRender must be a function');\n return rowList;\n }\n if (expandItem?.isExpanded !== true) {\n return rowList;\n }\n const customRow = (\n <div\n key={customExpandRowKey}\n className={cn(prefixCls('tr'))}\n onClick={onClickRow(row.original, rowIndex)}\n >\n {expandedRowRender(row.original, expandItem.level + 1)}\n </div>\n );\n rowList.push(customRow);\n }\n return rowList;\n },\n [],\n )\n )}\n </div>\n );\n\n const tableContentHeight = useMemo(() => {\n return y && totalSize\n ? totalSize.height - HEADER_HEIGHT - (isShowFooter ? FOOTER_HEIGHT : 0)\n : 'auto';\n }, [y, totalSize, isShowFooter]);\n\n const tableContent = (\n <Spin spinning={!!loading}>\n <div className={prefixCls('content')}>\n {headerContent}\n <div\n style={{\n height: tableContentHeight,\n position: virtual ? 'relative' : undefined,\n }}\n className={cn(prefixCls('body-scroll'), {\n [prefixCls('scroll-y')]: y !== undefined,\n [prefixCls('scroll-hidden')]: isEmpty,\n })}\n ref={bodyRef}\n onScroll={onBodyScroll}\n >\n {bodyContent}\n </div>\n {isShowFooter && (\n <Footer\n rowSelectionInfo={rowSelectionInfo}\n isShowPagination={isShowPagination}\n pagination={pagination}\n scroll={scroll}\n scrollToFirstRow={scrollToFirstRow}\n />\n )}\n </div>\n </Spin>\n );\n\n const tableStyle: CSSProperties = {};\n if (y) {\n tableStyle.height = y;\n }\n\n return (\n <div\n className={cn(prefixCls('container'), {\n [prefixCls('bordered')]: bordered,\n })}\n style={tableStyle}\n >\n <TableResizeWrapper\n onResize={(w, h) =>\n setTotalSize((prev) => {\n if (prev && prev.width === w && prev.height === h) return prev;\n return { width: w, height: h };\n })\n }\n >\n <div\n className={cn(prefixCls('main'), {\n [prefixCls('overflow-hidden')]: !!y,\n [prefixCls('ping-left')]: isPingLeft,\n [prefixCls('ping-right')]: isPingRight,\n })}\n >\n {rowDnd ? <DndWrapper>{tableContent}</DndWrapper> : tableContent}\n </div>\n </TableResizeWrapper>\n </div>\n );\n}\n\nexport default forwardRef(Table) as <TDataItem extends object>(\n props: ITableProps<TDataItem> & {\n ref?: React.ForwardedRef<ITableRef>;\n },\n) => ReturnType<typeof Table>;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAmCA,IAAM,gBAAgB;AACtB,IAAM,gBAAgB;AAEtB,SAAS,mBAAmB,EAC1B,UACA,YAIC;CACD,MAAM,MAAM,OAAuB,KAAK;CACxC,MAAM,cAAc,OAAO,SAAS;AACpC,aAAY,UAAU;AACtB,iBAAgB;EACd,MAAM,KAAK,IAAI;AACf,MAAI,CAAC,GAAI;EACT,IAAI,QAAQ;EACZ,IAAI,QAAQ;EACZ,MAAM,KAAK,IAAI,OAAO,qBAAqB;GACzC,MAAM,IAAI,GAAG;GACb,MAAM,IAAI,GAAG;AACb,OAAI,MAAM,SAAS,MAAM,MAAO;AAChC,WAAQ;AACR,WAAQ;AACR,eAAY,QAAQ,GAAG,EAAE;IACzB;AACF,KAAG,QAAQ,GAAG;AACd,eAAa,GAAG,YAAY;IAC3B,EAAE,CAAC;AACN,QACE,oBAAC,OAAD;EAAU;EAAK,OAAO,EAAE,QAAQ,QAAQ;EACrC;EACG,CAAA;;AAIV,SAAS,MACP,OACA,KACA;CACA,MAAM,EACJ,MACA,UACA,QACA,cACA,QACA,SACA,YACA,SAAS,EAAE,EACX,OAAO,gBACP,UAAU,OACV,qBAAqB,IACrB,YACA,SACA,QACA,YACA,QACA,iBACE;CACJ,MAAM,CAAC,WAAW,gBAAgB,SAGxB,KAAK;CAEf,MAAM,CAAC,YAAY,iBAAiB,SAAwB,KAAK;CAEjE,MAAM,EAAE,MAAM;CACd,MAAM,EACJ,gBACA,cACA,WACA,SACA,YACA,aACA,gBACA,iBACE,UAAU;EACZ;EACA;EACD,CAAC;CAEF,MAAM,mBAAmB,kBAAkB;AACzC,MAAI,CAAC,QAAQ,QACX;AAEF,UAAQ,QAAQ,YAAY;IAC3B,CAAC,QAAQ,CAAC;AAEb,qBAAoB,YAAY,EAC9B,kBACD,EAAE;CAEH,MAAM,iBAAiB,cAAc;EACnC;EACA;EACA;EACD,CAAC;CACF,MAAM,mBAAmB,oBAAoB,WAAW;CAExD,MAAM,mBAAmB,gBAAgB;EACvC,GAAG;EACH,MAAM,eAAe;EACrB,cAAc,eAAe;EAC7B,aAAa,eAAe;EAC7B,CAAC;CAEF,MAAM,aAAa,UAAU;EAC3B,GAAG;EACH,SAAS,iBAAiB;EAC1B,MAAM,eAAe;EACtB,CAAC;CAEF,MAAM,eAAe,cAAc;AACjC,SAAO,gBAA2B;GAChC,SAAS,WAAW;GACpB,gBAAgB,kBAAkB;GAClC;GACA;GACD,CAAC;IACD;EAAC;EAAgB;EAAS;EAAQ,WAAW;EAAQ,CAAC;CAEzD,MAAM,gBAAgB,cAAyB;EAC7C,SAAS;EAET,MAAM,WAAW;EACjB,iBAAiB,iBAAiB;EAClC,WAAW,KAAK,UAAU;AACxB,UAAO,UAAU,KAAK,QAAQ,MAAM;;EAEtC,kBAAkB;EACnB,CAAC;CAEF,MAAM,eAAe,cAAc,iBAAiB;CAEpD,MAAM,eAAe,aAAa,GAAG,QAAQ,KAAK,WAChD,OAAO,SAAS,CACjB;CACD,MAAM,qBAAqB,SAAoB;EAC7C;EACA;EACA;EACA;EACD,CAAC;CAGF,MAAM,EAAE,SAAS,cAAc,aAAa;CAE5C,MAAM,eAAe,CAAC,CAAC,UAAU,MAAM;CACvC,MAAM,cAA6B,EAAE;AACrC,KAAI,gBAAgB,EAAE,IAAI,QAAQ,eAAe,CAC/C,aAAY,MAAM,EAAE,IAAI,QAAQ,gBAAgB,EAAE;CAGpD,MAAM,oBAAoB,EAAE,IAAI,aAAa;AAE7C,iBAAgB;AAEd,eAAa,kBAAkB;IAC9B,CAAC,cAAc,kBAAkB,CAAC;CAErC,MAAM,mBAAmB,aACtB,QAAoC,UAAkB;EAErD,MAAM,cACJ,gBACA,EAAE,CAAC,CAAC,iBAAiB,yBAAyB,UAAU;EAC1D,MAAM,EAAE,WAAW,gBAAgB,OAAO,eACxC,mBAAmB,OAAO,KAAK;AACjC,SACE,qBAAC,OAAD;GACE,WAAW,GAAG,UAAU,KAAK,EAAE,eAAe;GAC9C,OAAO;IAAE,OAAO,OAAO,SAAS;IAAE,GAAG;IAAY;aAFnD,CAKG,WAAW,OAAO,OAAO,UAAU,QAAQ,OAAO,YAAY,CAAC,EAC/D,eACC,oBAAC,OAAD;IACE,aAAa,OAAO,kBAAkB;IACtC,cAAc,OAAO,kBAAkB;IACvC,WAAW,GAAG,UAAU,UAAU,EAAE,GACjC,UAAU,gBAAgB,GAAG,OAAO,OAAO,eAAe,EAC5D,CAAC;IACF,CAAA,CAEA;KAZC,OAAO,GAYR;IAGV;EAAC;EAAc;EAAkB;EAAmB,CACrD;CAED,MAAM,iBAAiB,cAAc,uBAAuB;CAE5D,MAAM,oBAAoB,eAAe;EACvC,OAAO,aAAa;EACpB,eAAe,UAAkB,eAAe,OAAO,SAAS;EAChE,wBAAwB,QAAQ;EAChC,YAAY;EACZ,UAAU;EACX,CAAC;CAEF,MAAM,iBAAiB,kBAAkB,iBAAiB;CAG1D,IAAI;CACJ,IAAI;AAEJ,KAAI,qBAAqB,gBAAgB,QAAQ;AAC/C,uBAAqB,eAAe,IAAI,SAAS;AACjD,wBACE,kBAAkB,cAAc,IAC/B,eAAe,eAAe,SAAS,IAAI,OAAO;;CAGvD,MAAM,gBACJ,oBAAC,OAAD;EACE,WAAW,GAAG,UAAU,SAAS,EAAE;IAChC,UAAU,aAAa,GAAG;IAC1B,UAAU,SAAS,GAAG;IACtB,UAAU,WAAW,GACpB,cAAc,UAAU,CAAC,iBAAiB;GAC7C,CAAC;EACF,KAAK;EACL,OAAO;YAEN,EAAE,IAAI,eAAe,gBAAgB;GACpC,MAAM,iBAAiB,YAAY;GACnC,MAAM,iBAAiB,kBAAkB,iBAAiB;GAE1D,MAAM,uBAAsC,EAAE;GAE9C,MAAM,mBAGA,EAAE;GACR,MAAM,oBAGA,EAAE;GACR,IAAI,UAAkC;AACtC,OAAI,SAAS;AACX,MAAE,QAAQ,iBAAiB,QAAQ,UAAU;KAC3C,MAAM,YAAY,mBAAmB,MAAM;AAC3C,SAAI,UAAU,UAAU,OACtB,kBAAiB,KAAK;MAAE;MAAQ;MAAO,CAAC;AAE1C,SAAI,UAAU,UAAU,QACtB,mBAAkB,KAAK;MAAE;MAAQ;MAAO,CAAC;MAE3C;AAEF,MAAE,QAAQ,iBAAiB,kBAAkB;KAC3C,MAAM,WAAW,cAAc;KAC/B,MAAM,YAAY,mBAAmB,SAAS;AAC9C,SAAI,UAAU,UAAU,UAAU,UAAU,UAAU,QACpD,sBAAqB,KAAK,cAAc;MAE1C;AACF,cACE,qBAAA,UAAA,EAAA,UAAA;KACG,qBAEC,oBAAC,OAAD;MACE,WAAW,UAAU,uBAAuB;MAC5C,OAAO,EAAE,OAAO,oBAAoB;MACpC,CAAA,GACA;KACH,iBAAiB,KAAK,EAAE,QAAQ,YAAY;AAC3C,aAAO,iBAAiB,QAAQ,MAAM;OACtC;KACD,EAAE,IAAI,uBAAuB,kBAAkB;MAC9C,MAAM,SAAS,eAAe,cAAc;AAC5C,aAAO,iBAAiB,QAAQ,cAAc,MAAM;OACpD;KACD,kBAAkB,KAAK,EAAE,QAAQ,YAAY;AAC5C,aAAO,iBAAiB,QAAQ,MAAM;OACtC;KACD,sBAEC,oBAAC,OAAD;MACE,WAAW,UAAU,wBAAwB;MAC7C,OAAO,EAAE,OAAO,qBAAqB;MACrC,CAAA,GACA;KACH,EAAA,CAAA;SAGL,WAAU,EAAE,IAAI,iBAAiB,QAAQ,UACvC,iBAAiB,QAAQ,MAAM,CAChC;AAGH,UACE,qBAAC,OAAD;IACE,WAAW,UAAU,KAAK;IAE1B,OAAO,EAAE,OAAO,mBAAmB;cAHrC,CAKG,SACA,MAAM,UACL,oBAAC,OAAD;KACE,WAAW,UAAU,4BAA4B;KACjD,OAAO,EAAE,WAAW,gBAAgB;KACpC,CAAA,CAEA;MAVC,YAAY,GAUb;IAER;EACE,CAAA;CAGR,MAAM,aAAa,aAChB,SAAoB,mBAA2B;AAC9C,MAAI,OAAO,eAAe,WACxB;AAEF,MAAI,OAAO,cAAc,EAAE,UAAU,CAAC,WAAW,EAE/C;AAEF,aAAW,SAAS,SAAS;IAE/B,CAAC,WAAW,CACb;CAED,MAAM,mBAAmB,CAAC,EACxB,eACC,WAAW,QAAQ,WAAW,YAAY,WAAW;CAExD,MAAM,qBAAqB,iBAAiB;CAE5C,MAAM,eAAe,oBAAoB;CAIzC,MAAM,eAAe,aAAa,UAAU,SADZ;CAGhC,MAAM,UAAU,KAAK,WAAW,KAAK,CAAC;CAEtC,MAAM,iBAAiB,eAAe;EACpC,OAAO,KAAK;EACZ,oBAAoB;EAEpB,wBAAyB,YAAY,QAAQ,UAAU;EAEvD,gBACE,OAAO,WAAW,eAClB,UAAU,UAAU,QAAQ,UAAU,KAAK,MACtC,YAAY,SAAS,uBAAuB,CAAC,SAC9C;EACN,UAAU;EACX,CAAC;CAEF,MAAM,YAAY,UAAU,eAAe,iBAAiB,GAAG;CAE/D,MAAM,iBAAiB,aACpB,KAAqB,MAAgC,aAAqB;EACzE,MAAM,EAAE,WAAW,gBAAgB,OAAO,eACxC,mBAAmB,SAAS;EAC9B,MAAM,YAAY,WAChB,KAAK,OAAO,UAAU,MACtB,KAAK,YAAY,CAClB;AACD,SACE,oBAAC,OAAD;GACE,WAAW,GAAG,UAAU,KAAK,EAAE,eAAe;GAE9C,OAAO;IAAE,OAAO,KAAK,OAAO,SAAS;IAAE,GAAG;IAAY;aAErD,eAAe,gBAChB,cAAc,iBAAiB,wBAAwB,IAAI,KACzD,oBAAC,YAAD;IACkB;IACJ;IACZ,MAAM,IAAI;IACF;cAEP;IACU,CAAA,GAEb;GAEE,EAhBC,KAAK,GAgBN;IAGV;EACE;EACA;EACA;EACA;EACA,iBAAiB;EAClB,CACF;CAGD,MAAM,cACJ,oBAAC,OAAD;EACE,WAAW,UAAU,OAAO;EAC5B,OAAO;GACL,OAAO;GACP,QAAQ,UACJ,YACE,eAAe,cAAc,GAC7B,IACF;GACL;YAEA,UACC,qBAAC,OAAD;GAAK,OAAO,EAAE,OAAO,WAAW,OAAO;aAAvC,CACE,oBAAC,OAAD;IAAK,OAAO,EAAE,YAAY,UAAU;cACjC,kBACC,oBAAC,OAAD;KACE,WAAW,GAAG,UAAU,QAAQ,EAAE,GAC/B,UAAU,cAAc,GAAG,cAC7B,CAAC;eAEF,oBAAC,OAAD;MACE,OAAO,eAAe,OAAO,MAAM;MACnC,MAAM,eAAe,UAAU;MAC/B,CAAA;KACE,CAAA;IAEJ,CAAA,EACN,oBAAC,OAAD;IACE,gBAAa;IACb,OAAO;KACL,UAAU;KACV,KAAK;KACL,MAAM;KACN,OAAO;KACP,QAAQ;KACT;cAEA,kBACC,oBAAC,OAAD;KACE,WAAW,GAAG,UAAU,QAAQ,EAAE,GAC/B,UAAU,cAAc,GAAG,cAC7B,CAAC;eAEF,oBAAC,OAAD;MACE,OAAO,eAAe,OAAO,MAAM;MACnC,MAAM,eAAe,UAAU;MAC/B,CAAA;KACE,CAAA;IAEJ,CAAA,CACF;OAEN,EAAE,OACA,YACC,SAAS,SAAS,aAAa;GAC9B,MAAM,MAAM,UACR,KAAK,QAAQ,SACZ;GACL,MAAM,cAAc,IAAI,iBAAiB;GAEzC,IAAI,UAAkC;GAEtC,MAAM,mBAGA,EAAE;GACR,MAAM,oBAGA,EAAE;AAER,OAAI,SAAS;IACX,MAAM,iBAAiB,kBAAkB,iBAAiB;IAE1D,MAAM,uBAAsC,EAAE;AAE9C,MAAE,QAAQ,cAAc,MAAM,UAAU;KACtC,MAAM,YAAY,mBAAmB,MAAM;AAC3C,SAAI,UAAU,UAAU,OACtB,kBAAiB,KAAK;MAAE;MAAM;MAAO,CAAC;AAExC,SAAI,UAAU,UAAU,QACtB,mBAAkB,KAAK;MAAE;MAAM;MAAO,CAAC;MAEzC;AAEF,MAAE,QAAQ,iBAAiB,kBAAkB;KAC3C,MAAM,WAAW,cAAc;KAC/B,MAAM,YAAY,mBAAmB,SAAS;AAC9C,SAAI,UAAU,UAAU,UAAU,UAAU,UAAU,QACpD,sBAAqB,KAAK,cAAc;MAE1C;AACF,cACE,qBAAA,UAAA,EAAA,UAAA;KACG,qBAEC,oBAAC,OAAD;MACE,WAAW,UAAU,uBAAuB;MAC5C,OAAO,EAAE,OAAO,oBAAoB;MACpC,CAAA,GACA;KACH,iBAAiB,KAAK,EAAE,MAAM,YAAY;AACzC,aAAO,eAAe,KAAK,MAAM,MAAM;OACvC;KACD,qBAAqB,KAAK,kBAAkB;MAC3C,MAAM,WAAW,cAAc;MAC/B,MAAM,OAAO,YAAY;AACzB,aAAO,eAAe,KAAK,MAAM,SAAS;OAC1C;KACD,kBAAkB,KAAK,EAAE,MAAM,YAAY;AAC1C,aAAO,eAAe,KAAK,MAAM,MAAM;OACvC;KACD,sBAEC,oBAAC,OAAD;MACE,WAAW,UAAU,wBAAwB;MAC7C,OAAO,EAAE,OAAO,qBAAqB;MACrC,CAAA,GACA;KACH,EAAA,CAAA;SAGL,WAAU,YAAY,KAAK,MAAM,UAC/B,eAAe,KAAK,MAAM,MAAM,CACjC;GAEH,MAAM,QAAQ,IAAI;GAClB,MAAM,gBACJ,iBAAiB,yBACjB,iBAAiB,gBAAgB,SAAS,MAAM;GAClD,MAAM,yBACJ,iBAAiB,yBACjB,CAAC,CAAC,cAAc,mBAAmB,IAAI,SAAS,CAAC;GAEnD,MAAM,UACJ,oBAAC,OAAD;IAEE,cAAY,UAAW,QAAwB,QAAQ;IACvD,WAAW,GACT,UAAU,KAAK,EACf;MAGG,UAAU,YAAY,GAAG,WAAW,gBACjC,SACA,eAAe;MAClB,UAAU,eAAe,GACxB,WAAW,kBAAkB;MAC9B,UAAU,eAAe,GAAG;MAC5B,UAAU,yBAAyB,GAClC;MACD,UAAU,eAAe,GACxB,oBAAoB,aAAa,KAAK,SAAS;KAClD,EACD,aAAa,IAAI,UAAU,SAAS,CACrC;IACD,MAAM,SAAS;AAEb,SAAI,QACF,gBAAe,eAAe,KAAK;AAIrC,SAAI,UAAU,MAAM;MAClB,MAAM,SAAS,WAAW,UAAU,IAAI,UAAU,SAAS;AAC3D,UAAI,OACF,QAAO,UAAU;;;IAIvB,SAAS,WAAW,IAAI,UAAU,SAAS;IAC3C,oBAAoB;AAClB,SAAI,CAAC,uBACH,eAAc,MAAM;;IAGxB,oBAAoB,cAAc,KAAK;IACvC,OACE,UACI;KACE,UAAU;KACV,WAAW,cACR,QAAwB,MAC1B;KACF,GACD,EAAE;cAGP;IACG,EArDC,MAqDD;AAER,WAAQ,KAAK,QAAQ;GAGrB,MAAM,aAAa,eAAe,cAAc;GAChD,MAAM,qBACJ,eAAe,gBAAgB,YAAY;AAE7C,OAD8B,CAAC,CAAC,oBACL;IAEzB,MAAM,oBAAoB,iBAAiB;AAC3C,QAAI,OAAO,sBAAsB,YAAY;AAC3C,aAAQ,MAAM,uCAAuC;AACrD,YAAO;;AAET,QAAI,YAAY,eAAe,KAC7B,QAAO;IAET,MAAM,YACJ,oBAAC,OAAD;KAEE,WAAW,GAAG,UAAU,KAAK,CAAC;KAC9B,SAAS,WAAW,IAAI,UAAU,SAAS;eAE1C,kBAAkB,IAAI,UAAU,WAAW,QAAQ,EAAE;KAClD,EALC,mBAKD;AAER,YAAQ,KAAK,UAAU;;AAEzB,UAAO;KAET,EAAE,CACH;EAEC,CAAA;CAGR,MAAM,qBAAqB,cAAc;AACvC,SAAO,KAAK,YACR,UAAU,SAAS,iBAAiB,eAAe,gBAAgB,KACnE;IACH;EAAC;EAAG;EAAW;EAAa,CAAC;CAEhC,MAAM,eACJ,oBAAC,YAAD;EAAM,UAAU,CAAC,CAAC;YAChB,qBAAC,OAAD;GAAK,WAAW,UAAU,UAAU;aAApC;IACG;IACD,oBAAC,OAAD;KACE,OAAO;MACL,QAAQ;MACR,UAAU,UAAU,aAAa;MAClC;KACD,WAAW,GAAG,UAAU,cAAc,EAAE;OACrC,UAAU,WAAW,GAAG,MAAM;OAC9B,UAAU,gBAAgB,GAAG;MAC/B,CAAC;KACF,KAAK;KACL,UAAU;eAET;KACG,CAAA;IACL,gBACC,oBAAC,aAAD;KACoB;KACA;KACN;KACJ;KACU;KAClB,CAAA;IAEA;;EACD,CAAA;CAGT,MAAM,aAA4B,EAAE;AACpC,KAAI,EACF,YAAW,SAAS;AAGtB,QACE,oBAAC,OAAD;EACE,WAAW,GAAG,UAAU,YAAY,EAAE,GACnC,UAAU,WAAW,GAAG,UAC1B,CAAC;EACF,OAAO;YAEP,oBAAC,oBAAD;GACE,WAAW,GAAG,MACZ,cAAc,SAAS;AACrB,QAAI,QAAQ,KAAK,UAAU,KAAK,KAAK,WAAW,EAAG,QAAO;AAC1D,WAAO;KAAE,OAAO;KAAG,QAAQ;KAAG;KAC9B;aAGJ,oBAAC,OAAD;IACE,WAAW,GAAG,UAAU,OAAO,EAAE;MAC9B,UAAU,kBAAkB,GAAG,CAAC,CAAC;MACjC,UAAU,YAAY,GAAG;MACzB,UAAU,aAAa,GAAG;KAC5B,CAAC;cAED,SAAS,oBAAC,YAAD,EAAA,UAAa,cAA0B,CAAA,GAAG;IAChD,CAAA;GACa,CAAA;EACjB,CAAA;;AAIV,IAAA,gBAAe,WAAW,MAAM"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Table/index.tsx"],"sourcesContent":["import {\n Cell,\n Header,\n Row,\n flexRender,\n getCoreRowModel,\n useReactTable,\n} from '@tanstack/react-table';\nimport { VirtualItem, useVirtualizer } from '@tanstack/react-virtual';\nimport { cn } from '../lib/utils';\nimport './table.css';\nimport _ from 'lodash';\nimport React, {\n CSSProperties,\n ForwardedRef,\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Empty, Spin } from '..';\nimport ExpandCell from './components/ExpandCell';\nimport Footer from './components/Footer';\nimport DndWrapper from './components/DndWrapper';\nimport { getRowKey, getTableColumns, prefixCls } from './helper';\nimport useExpandable, { getExpandableConfig } from './hooks/useExpandable';\nimport useFixed from './hooks/useFixed';\nimport useRowSelection from './hooks/useRowSelection';\nimport useScroll from './hooks/useScroll';\nimport { ITableColumn, ITableProps, ITableRef } from './types';\nimport useRowDnd from './hooks/useRowDnd';\n\nconst HEADER_HEIGHT = 41;\nconst FOOTER_HEIGHT = 52;\n\nfunction TableResizeWrapper({\n children,\n onResize,\n}: {\n children: React.ReactNode;\n onResize: (width: number, height: number) => void;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const onResizeRef = useRef(onResize);\n onResizeRef.current = onResize;\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n let prevW = 0;\n let prevH = 0;\n const ro = new window.ResizeObserver(() => {\n const w = el.offsetWidth;\n const h = el.offsetHeight;\n if (w === prevW && h === prevH) return;\n prevW = w;\n prevH = h;\n onResizeRef.current(w, h);\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, []);\n return (\n <div ref={ref} style={{ height: '100%' }}>\n {children}\n </div>\n );\n}\n\nfunction Table<TDataItem extends object>(\n props: ITableProps<TDataItem>,\n ref: ForwardedRef<ITableRef>,\n) {\n const {\n data,\n bordered,\n rowKey,\n columnSizing,\n sticky,\n loading,\n pagination,\n scroll = {},\n empty: emptyComponent,\n virtual = false,\n rowClassName = () => '',\n onRowClick,\n onError,\n onSort,\n expandable,\n rowDnd,\n rowSelection,\n } = props;\n const [totalSize, setTotalSize] = useState<{\n width: number;\n height: number;\n } | null>(null);\n\n const [hoverRowId, setHoverRowId] = useState<string | null>(null);\n\n const { y } = scroll;\n const {\n containerWidth,\n onBodyScroll,\n headerRef,\n bodyRef,\n isPingLeft,\n isPingRight,\n scrollbarWidth,\n changeIsPing,\n } = useScroll({\n totalSize,\n scroll,\n });\n\n const scrollToFirstRow = useCallback(() => {\n if (!bodyRef.current) {\n return;\n }\n bodyRef.current.scrollTop = 0;\n }, [bodyRef]);\n\n useImperativeHandle(ref, () => ({\n scrollToFirstRow,\n }));\n\n const expandableInfo = useExpandable({\n expandable,\n data,\n rowKey,\n });\n const expandableConfig = getExpandableConfig(expandable);\n\n const rowSelectionInfo = useRowSelection({\n ...props,\n data: expandableInfo.data,\n isExpandable: expandableInfo.isExpandable,\n flattenData: expandableInfo.flattenData,\n });\n\n const rowDndInfo = useRowDnd({\n ...props,\n columns: rowSelectionInfo.columns,\n data: expandableInfo.data,\n });\n\n const tableColumns = useMemo(() => {\n return getTableColumns<TDataItem>({\n columns: rowDndInfo.columns,\n containerWidth: containerWidth || 0,\n onError,\n onSort,\n });\n }, [containerWidth, onError, onSort, rowDndInfo.columns]);\n\n const tableInstance = useReactTable<TDataItem>({\n columns: tableColumns,\n // 排除掉被折叠的行\n data: rowDndInfo.tableData,\n getCoreRowModel: getCoreRowModel(),\n getRowId: (row, index) => {\n return getRowKey(row, rowKey, index);\n },\n columnResizeMode: 'onChange',\n });\n\n const headerGroups = tableInstance.getHeaderGroups();\n\n const columnWidths = headerGroups[0].headers.map((header) =>\n header.getSize(),\n );\n const getColumnFixedInfo = useFixed<TDataItem>({\n columnWidths,\n tableColumns,\n y,\n scrollbarWidth,\n });\n\n // 渲染 header\n const { rows } = tableInstance.getRowModel();\n\n const isStickyWork = !!sticky && y === undefined;\n const headerStyle: CSSProperties = {};\n if (isStickyWork && _.get(sticky, 'offsetHeader')) {\n headerStyle.top = _.get(sticky, 'offsetHeader', 0);\n }\n\n const totalColumnsWidth = _.sum(columnWidths);\n\n useEffect(() => {\n // 总列宽改变时,重新计算是否需要显示固定列的阴影\n changeIsPing(totalColumnsWidth);\n }, [changeIsPing, totalColumnsWidth]);\n\n const renderHeaderCell = useCallback(\n (header: Header<TDataItem, unknown>, index: number) => {\n // 选择行的列不能拖动宽度\n const showResizer =\n columnSizing &&\n !(!!rowSelectionInfo.isRowSelectionEnabled && index === 0);\n const { className: fixedClassName, style: fixedStyle } =\n getColumnFixedInfo(index, true);\n return (\n <div\n role=\"columnheader\"\n aria-label={\n typeof (header.column.columnDef.meta as ITableColumn).title ===\n 'string'\n ? ((header.column.columnDef.meta as ITableColumn).title as string)\n : undefined\n }\n aria-sort={\n (header.column.columnDef.meta as ITableColumn).sortOrder ===\n 'ascend'\n ? 'ascending'\n : (header.column.columnDef.meta as ITableColumn).sortOrder ===\n 'descend'\n ? 'descending'\n : (header.column.columnDef.meta as ITableColumn).sortOrder !==\n undefined\n ? 'none'\n : undefined\n }\n className={cn(prefixCls('th'), fixedClassName)}\n style={{ width: header.getSize(), ...fixedStyle }}\n key={header.id}\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n {showResizer && (\n <div\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n className={cn(prefixCls('resizer'), {\n [prefixCls('self-resizing')]: header.column.getIsResizing(),\n })}\n />\n )}\n </div>\n );\n },\n [columnSizing, rowSelectionInfo, getColumnFixedInfo],\n );\n\n const visibleColumns = tableInstance.getVisibleLeafColumns();\n\n const columnVirtualizer = useVirtualizer({\n count: tableColumns.length,\n estimateSize: (index: number) => visibleColumns[index].getSize(),\n getScrollElement: () => bodyRef.current,\n horizontal: true,\n overscan: 5,\n });\n\n const virtualColumns = columnVirtualizer.getVirtualItems();\n\n //different virtualization strategy for columns - instead of absolute and translateY, we add empty columns to the left and right\n let virtualPaddingLeft: number | undefined;\n let virtualPaddingRight: number | undefined;\n\n if (columnVirtualizer && virtualColumns?.length) {\n virtualPaddingLeft = virtualColumns[0]?.start ?? 0;\n virtualPaddingRight =\n columnVirtualizer.getTotalSize() -\n (virtualColumns[virtualColumns.length - 1]?.end ?? 0);\n }\n\n const headerContent = (\n <div\n role=\"rowgroup\"\n className={cn(prefixCls('header'), {\n [prefixCls('overflow-x')]: true,\n [prefixCls('sticky')]: isStickyWork,\n [prefixCls('resizing')]:\n tableInstance.getState().columnSizingInfo.isResizingColumn,\n })}\n ref={headerRef}\n style={headerStyle}\n >\n {_.map(headerGroups, (headerGroup) => {\n const allHeaderCells = headerGroup.headers;\n const virtualColumns = columnVirtualizer.getVirtualItems();\n\n const middleVirtualColumns: VirtualItem[] = [];\n // 将固定列单独拎出来,固定列不受列虚拟化影响,必须要渲染\n const leftFixedColumns: {\n header: Header<TDataItem, unknown>;\n index: number;\n }[] = [];\n const rightFixedColumns: {\n header: Header<TDataItem, unknown>;\n index: number;\n }[] = [];\n let content: React.ReactNode | null = null;\n if (virtual) {\n _.forEach(allHeaderCells, (header, index) => {\n const fixedInfo = getColumnFixedInfo(index);\n if (fixedInfo.fixed === 'left') {\n leftFixedColumns.push({ header, index });\n }\n if (fixedInfo.fixed === 'right') {\n rightFixedColumns.push({ header, index });\n }\n });\n\n _.forEach(virtualColumns, (virtualColumn) => {\n const colIndex = virtualColumn.index;\n const fixedInfo = getColumnFixedInfo(colIndex);\n if (fixedInfo.fixed !== 'left' && fixedInfo.fixed !== 'right') {\n middleVirtualColumns.push(virtualColumn);\n }\n });\n content = (\n <>\n {virtualPaddingLeft ? (\n //fake empty column to the left for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-left')}\n style={{ width: virtualPaddingLeft }}\n />\n ) : null}\n {leftFixedColumns.map(({ header, index }) => {\n return renderHeaderCell(header, index);\n })}\n {_.map(middleVirtualColumns, (virtualColumn) => {\n const header = allHeaderCells[virtualColumn.index];\n return renderHeaderCell(header, virtualColumn.index);\n })}\n {rightFixedColumns.map(({ header, index }) => {\n return renderHeaderCell(header, index);\n })}\n {virtualPaddingRight ? (\n //fake empty column to the right for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-right')}\n style={{ width: virtualPaddingRight }}\n />\n ) : null}\n </>\n );\n } else {\n content = _.map(allHeaderCells, (header, index) =>\n renderHeaderCell(header, index),\n );\n }\n\n return (\n <div\n className={prefixCls('tr')}\n role=\"row\"\n key={headerGroup.id}\n style={{ width: totalColumnsWidth }}\n >\n {content}\n {y !== undefined && (\n <div\n className={prefixCls('header-scroll-placeholder')}\n style={{ flexBasis: scrollbarWidth }}\n />\n )}\n </div>\n );\n })}\n </div>\n );\n\n const onClickRow = useCallback(\n (rowData: TDataItem, rowIndex: number) => () => {\n if (typeof onRowClick !== 'function') {\n return;\n }\n if (window.getSelection()?.toString().length !== 0) {\n // 防止选择文本时触发 onRowClick\n return;\n }\n onRowClick(rowData, rowIndex);\n },\n [onRowClick],\n );\n\n const isShowPagination = !!(\n pagination &&\n (pagination.total > pagination.pageSize || pagination.showSizeChanger)\n );\n const isShowRowSelection = rowSelectionInfo.isShowRowSelectionInFooter;\n\n const isShowFooter = isShowPagination || isShowRowSelection;\n\n // 空态切换 size 的阈值\n const EMPTY_SMALL_SIZE_HEIGHT = 436;\n const isSmallEmpty = totalSize && totalSize.height < EMPTY_SMALL_SIZE_HEIGHT;\n\n const isEmpty = rows.length === 0 && !loading;\n\n const rowVirtualizer = useVirtualizer({\n count: rows.length,\n estimateSize: () => 48, // estimate row height for accurate scrollbar dragging\n // 没有测量出 bodyRef.current 的高度时,返回 null,避免虚拟化器从 DOM 获取异常高度\n getScrollElement: () => (totalSize ? bodyRef.current : null),\n // measure dynamic row height, except in firefox because it measures table border height incorrectly\n measureElement:\n typeof window !== 'undefined' &&\n navigator.userAgent.indexOf('Firefox') === -1\n ? (element) => element?.getBoundingClientRect().height\n : undefined,\n overscan: 5,\n });\n\n const tableRows = virtual ? rowVirtualizer.getVirtualItems() : rows;\n\n const renderBodyCell = useCallback(\n (row: Row<TDataItem>, cell: Cell<TDataItem, unknown>, colIndex: number) => {\n const { className: fixedClassName, style: fixedStyle } =\n getColumnFixedInfo(colIndex);\n const tdContent = flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n );\n return (\n <div\n role=\"cell\"\n className={cn(prefixCls('td'), fixedClassName)}\n key={cell.id}\n style={{ width: cell.column.getSize(), ...fixedStyle }}\n >\n {expandableInfo.isExpandable &&\n colIndex === (rowSelectionInfo.isRowSelectionEnabled ? 1 : 0) ? (\n <ExpandCell\n expandableInfo={expandableInfo}\n expandable={expandable}\n data={row.original}\n rowKey={rowKey}\n >\n {tdContent}\n </ExpandCell>\n ) : (\n tdContent\n )}\n </div>\n );\n },\n [\n expandableInfo,\n expandable,\n rowKey,\n getColumnFixedInfo,\n rowSelectionInfo.isRowSelectionEnabled,\n ],\n );\n\n // 渲染 body\n const bodyContent = (\n <div\n role=\"rowgroup\"\n className={prefixCls('body')}\n style={{\n width: totalColumnsWidth,\n height: virtual\n ? totalSize\n ? rowVirtualizer.getTotalSize()\n : 0\n : 'auto',\n }}\n >\n {isEmpty ? (\n <div style={{ width: totalSize?.width }}>\n <div style={{ visibility: 'hidden' }}>\n {emptyComponent || (\n <div\n className={cn(prefixCls('empty'), {\n [prefixCls('empty-small')]: isSmallEmpty,\n })}\n >\n <Empty\n image={isSmallEmpty ? null : Empty.PRESENTED_IMAGE_SEARCH}\n size={isSmallEmpty ? 'small' : undefined}\n />\n </div>\n )}\n </div>\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-invalid=\"true\"\n style={{\n position: 'absolute',\n top: 40,\n left: 0,\n right: 0,\n bottom: 0,\n }}\n >\n {emptyComponent || (\n <div\n className={cn(prefixCls('empty'), {\n [prefixCls('empty-small')]: isSmallEmpty,\n })}\n >\n <Empty\n image={isSmallEmpty ? null : Empty.PRESENTED_IMAGE_SEARCH}\n size={isSmallEmpty ? 'small' : undefined}\n />\n </div>\n )}\n </div>\n </div>\n ) : (\n _.reduce<Row<TDataItem> | VirtualItem, React.ReactNode[]>(\n tableRows,\n (rowList, rowData, rowIndex) => {\n const row = virtual\n ? rows[rowData.index]\n : (rowData as Row<TDataItem>);\n const allRowCells = row.getVisibleCells();\n\n let content: React.ReactNode | null = null;\n // 将固定列单独拎出来,固定列不受列虚拟化影响,必须要渲染\n const leftFixedColumns: {\n cell: Cell<TDataItem, unknown>;\n index: number;\n }[] = [];\n const rightFixedColumns: {\n cell: Cell<TDataItem, unknown>;\n index: number;\n }[] = [];\n\n if (virtual) {\n const virtualColumns = columnVirtualizer.getVirtualItems();\n\n const middleVirtualColumns: VirtualItem[] = [];\n\n _.forEach(allRowCells, (cell, index) => {\n const fixedInfo = getColumnFixedInfo(index);\n if (fixedInfo.fixed === 'left') {\n leftFixedColumns.push({ cell, index });\n }\n if (fixedInfo.fixed === 'right') {\n rightFixedColumns.push({ cell, index });\n }\n });\n\n _.forEach(virtualColumns, (virtualColumn) => {\n const colIndex = virtualColumn.index;\n const fixedInfo = getColumnFixedInfo(colIndex);\n if (fixedInfo.fixed !== 'left' && fixedInfo.fixed !== 'right') {\n middleVirtualColumns.push(virtualColumn);\n }\n });\n content = (\n <>\n {virtualPaddingLeft ? (\n //fake empty column to the left for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-left')}\n style={{ width: virtualPaddingLeft }}\n />\n ) : null}\n {leftFixedColumns.map(({ cell, index }) => {\n return renderBodyCell(row, cell, index);\n })}\n {middleVirtualColumns.map((virtualColumn) => {\n const colIndex = virtualColumn.index;\n const cell = allRowCells[colIndex];\n return renderBodyCell(row, cell, colIndex);\n })}\n {rightFixedColumns.map(({ cell, index }) => {\n return renderBodyCell(row, cell, index);\n })}\n {virtualPaddingRight ? (\n //fake empty column to the right for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-right')}\n style={{ width: virtualPaddingRight }}\n />\n ) : null}\n </>\n );\n } else {\n content = allRowCells.map((cell, index) =>\n renderBodyCell(row, cell, index),\n );\n }\n const rowId = row.id;\n const isRowSelected =\n rowSelectionInfo.isRowSelectionEnabled &&\n rowSelectionInfo.selectedRowKeys.includes(rowId);\n const isRowSelectionDisabled =\n rowSelectionInfo.isRowSelectionEnabled &&\n !!rowSelection?.getCheckboxProps?.(row.original).disabled;\n\n const rowNode = (\n <div\n key={rowId}\n role=\"row\"\n aria-rowindex={rowIndex + 2}\n data-index={virtual ? (rowData as VirtualItem).index : rowIndex}\n className={cn(\n prefixCls('tr'),\n {\n // 需要用 state 的原因是,存在固定列的情况,左右侧的固定列在 dom 结构上不在同一个 tr 上,所以不能用 css 的 :hover 来实现\n // 当拖拽行时,不显示 hover 状态\n [prefixCls('row-hover')]: rowDndInfo.draggingRowId\n ? undefined\n : hoverRowId === rowId,\n [prefixCls('row-dragging')]:\n rowDndInfo.draggingRowId === rowId,\n [prefixCls('row-selected')]: isRowSelected,\n [prefixCls('row-selection-disabled')]:\n isRowSelectionDisabled,\n [prefixCls('no-border-tr')]:\n isShowPagination && rowIndex === rows.length - 1,\n },\n rowClassName(row.original, rowIndex),\n )}\n ref={(node) => {\n // 只在虚拟滚动模式下才测量行高度,避免非虚拟模式下的不必要重渲染\n if (virtual) {\n rowVirtualizer.measureElement(node);\n }\n\n // 如果启用了行拖拽,则设置行引用\n if (rowDnd && node) {\n const rowRef = rowDndInfo.getRowRef(row.original, rowIndex);\n if (rowRef) {\n rowRef.current = node;\n }\n }\n }}\n onClick={onClickRow(row.original, rowIndex)}\n onMouseEnter={() => {\n if (!isRowSelectionDisabled) {\n setHoverRowId(rowId);\n }\n }}\n onMouseLeave={() => setHoverRowId(null)}\n style={\n virtual\n ? {\n position: 'absolute',\n transform: `translateY(${\n (rowData as VirtualItem).start\n }px)`,\n }\n : {}\n }\n >\n {content}\n </div>\n );\n rowList.push(rowNode);\n\n // 渲染额外展开的行\n const expandItem = expandableInfo.expandItemMap[rowId];\n const customExpandRowKey =\n expandableInfo.isExpandable && expandItem?.customExpandRowKey;\n const hasCustomExpandRowKey = !!customExpandRowKey;\n if (hasCustomExpandRowKey) {\n // 在该行的下面追加自定义展开行\n const expandedRowRender = expandableConfig.expandedRowRender;\n if (typeof expandedRowRender !== 'function') {\n console.error('expandedRowRender must be a function');\n return rowList;\n }\n if (expandItem?.isExpanded !== true) {\n return rowList;\n }\n const customRow = (\n <div\n key={customExpandRowKey}\n className={cn(prefixCls('tr'))}\n role=\"row\"\n onClick={onClickRow(row.original, rowIndex)}\n >\n {expandedRowRender(row.original, expandItem.level + 1)}\n </div>\n );\n rowList.push(customRow);\n }\n return rowList;\n },\n [],\n )\n )}\n </div>\n );\n\n const tableContentHeight = useMemo(() => {\n return y && totalSize\n ? totalSize.height - HEADER_HEIGHT - (isShowFooter ? FOOTER_HEIGHT : 0)\n : 'auto';\n }, [y, totalSize, isShowFooter]);\n\n const tableContentBody = (\n <div className={prefixCls('content')} role=\"table\" aria-label=\"Data table\">\n {headerContent}\n <div\n style={{\n height: tableContentHeight,\n position: virtual ? 'relative' : undefined,\n }}\n className={cn(prefixCls('body-scroll'), {\n [prefixCls('scroll-y')]: y !== undefined,\n [prefixCls('scroll-hidden')]: isEmpty,\n })}\n ref={bodyRef}\n onScroll={onBodyScroll}\n >\n {bodyContent}\n </div>\n {isShowFooter && (\n <Footer\n rowSelectionInfo={rowSelectionInfo}\n isShowPagination={isShowPagination}\n pagination={pagination}\n scroll={scroll}\n scrollToFirstRow={scrollToFirstRow}\n />\n )}\n </div>\n );\n\n const tableContent = loading ? (\n <Spin spinning>{tableContentBody}</Spin>\n ) : (\n tableContentBody\n );\n\n const tableStyle: CSSProperties = {};\n if (y) {\n tableStyle.height = y;\n }\n\n return (\n <div\n className={cn(prefixCls('container'), {\n [prefixCls('bordered')]: bordered,\n })}\n style={tableStyle}\n >\n <TableResizeWrapper\n onResize={(w, h) =>\n setTotalSize((prev) => {\n if (prev && prev.width === w && prev.height === h) return prev;\n return { width: w, height: h };\n })\n }\n >\n <div\n className={cn(prefixCls('main'), {\n [prefixCls('overflow-hidden')]: !!y,\n [prefixCls('ping-left')]: isPingLeft,\n [prefixCls('ping-right')]: isPingRight,\n })}\n >\n {rowDnd ? <DndWrapper>{tableContent}</DndWrapper> : tableContent}\n </div>\n </TableResizeWrapper>\n </div>\n );\n}\n\nexport default forwardRef(Table) as <TDataItem extends object>(\n props: ITableProps<TDataItem> & {\n ref?: React.ForwardedRef<ITableRef>;\n },\n) => ReturnType<typeof Table>;\n"],"mappings":"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"}
@@ -276,6 +276,7 @@ function Tabs(props) {
276
276
  role: "tabpanel",
277
277
  id: getPanelId(item.key),
278
278
  "aria-labelledby": getTabId(item.key),
279
+ "aria-hidden": !isActive || void 0,
279
280
  children: item.children
280
281
  }, item.key);
281
282
  })
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Tabs/index.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../lib/utils';\nimport { ChevronLeftLine, ChevronRightLine, CloseLightLine } from '../Icon';\nimport TabPane from './TabPane';\n\nexport type TabsSize = 'default' | 'small';\n\ninterface TabItem {\n key: string;\n label: React.ReactNode;\n children?: React.ReactNode;\n disabled?: boolean;\n closable?: boolean;\n icon?: React.ReactNode;\n forceRender?: boolean;\n className?: string;\n}\n\nexport interface ITabsProps {\n size?: TabsSize;\n activeKey?: string;\n defaultActiveKey?: string;\n onChange?: (activeKey: string) => void;\n onTabClick?: (activeKey: string, e: React.MouseEvent) => void;\n destroyInactiveTabPane?: boolean;\n centered?: boolean;\n adaptHeight?: boolean;\n tabPosition?: 'left' | 'right' | 'top' | 'bottom';\n className?: string;\n children?: React.ReactNode;\n headerBackgroundColor?: string;\n monospace?: boolean;\n padding?: boolean | number;\n compact?: boolean;\n hasDividing?: boolean;\n items?: TabItem[];\n type?: 'line' | 'card' | 'editable-card';\n tabBarExtraContent?:\n | React.ReactNode\n | { left?: React.ReactNode; right?: React.ReactNode };\n onEdit?: (\n targetKey: string | React.MouseEvent | React.KeyboardEvent,\n action: 'add' | 'remove',\n ) => void;\n hideAdd?: boolean;\n style?: React.CSSProperties;\n tabBarStyle?: React.CSSProperties;\n popupClassName?: string;\n tabBarGutter?: number;\n moreIcon?: React.ReactNode;\n /** 透传到 Tabs 根容器的 data-testid,用于自动化测试定位 */\n 'data-testid'?: string;\n /** 透传到 tablist 的 aria-label,用于可访问性与自动化测试定位 */\n 'aria-label'?: string;\n}\n\nexport default function Tabs(props: ITabsProps) {\n const {\n size,\n className,\n adaptHeight,\n style = {},\n monospace: propsMonospace,\n tabPosition = 'top',\n padding: propsPadding = false,\n compact,\n hasDividing = true,\n items,\n activeKey: controlledActiveKey,\n defaultActiveKey,\n onChange,\n onTabClick,\n destroyInactiveTabPane,\n centered,\n tabBarExtraContent,\n headerBackgroundColor,\n children,\n type,\n onEdit,\n hideAdd,\n tabBarStyle,\n 'data-testid': dataTestId,\n 'aria-label': ariaLabel,\n } = props;\n\n const isEditable = type === 'editable-card';\n const isCard = type === 'card' || type === 'editable-card';\n\n // Derive items from children if not provided\n const resolvedItems: TabItem[] = useMemo(() => {\n if (items) return items;\n return React.Children.toArray(children)\n .filter(React.isValidElement)\n .map((child: any) => ({\n key: child.key || child.props.key || '',\n label: child.props.tab,\n children: child.props.children,\n disabled: child.props.disabled,\n closable: child.props.closable,\n forceRender: child.props.forceRender,\n }));\n }, [items, children]);\n\n const firstKey = resolvedItems[0]?.key || '';\n const [innerActiveKey, setInnerActiveKey] = useState(\n defaultActiveKey || firstKey,\n );\n const mergedActiveKey =\n controlledActiveKey !== undefined ? controlledActiveKey : innerActiveKey;\n const activeKey = resolvedItems.some((item) => item.key === mergedActiveKey)\n ? mergedActiveKey\n : firstKey;\n\n const tabsId = React.useId();\n const tabRefs = useRef<Record<string, HTMLDivElement | null>>({});\n const pendingFocusKeyRef = useRef<string | null>(null);\n const getPreferredFocusKey = useCallback(\n (items: TabItem[] = resolvedItems) =>\n items.find((item) => item.key === activeKey && !item.disabled)?.key ||\n items.find((item) => !item.disabled)?.key ||\n '',\n [activeKey, resolvedItems],\n );\n const [focusedKey, setFocusedKey] = useState(() => getPreferredFocusKey());\n\n const getTabId = (key: string) => `${tabsId}-tab-${key}`;\n const getPanelId = (key: string) => `${tabsId}-panel-${key}`;\n\n const focusTab = useCallback((key: string) => {\n setFocusedKey(key);\n tabRefs.current[key]?.focus();\n }, []);\n\n useEffect(() => {\n const pendingFocusKey = pendingFocusKeyRef.current;\n if (\n pendingFocusKey &&\n resolvedItems.some(\n (item) => item.key === pendingFocusKey && !item.disabled,\n )\n ) {\n pendingFocusKeyRef.current = null;\n focusTab(pendingFocusKey);\n return;\n }\n\n setFocusedKey((currentFocusedKey) => {\n const focusedItem = resolvedItems.find(\n (item) => item.key === currentFocusedKey,\n );\n return focusedItem && !focusedItem.disabled\n ? currentFocusedKey\n : getPreferredFocusKey();\n });\n }, [focusTab, getPreferredFocusKey, resolvedItems]);\n\n const activateTab = useCallback(\n (key: string) => {\n if (controlledActiveKey === undefined) {\n setInnerActiveKey(key);\n }\n onChange?.(key);\n },\n [controlledActiveKey, onChange],\n );\n\n const handleTabClick = (key: string, e: React.MouseEvent) => {\n setFocusedKey(key);\n activateTab(key);\n onTabClick?.(key, e);\n };\n\n const handleRemove = (key: string, e: React.MouseEvent) => {\n e.stopPropagation();\n const itemIndex = resolvedItems.findIndex((item) => item.key === key);\n const nextFocusableItem = [\n ...resolvedItems.slice(itemIndex + 1),\n ...resolvedItems.slice(0, itemIndex).reverse(),\n ].find((item) => !item.disabled);\n pendingFocusKeyRef.current = nextFocusableItem?.key || null;\n onEdit?.(key, 'remove');\n };\n\n const handleTabKeyDown = (\n item: TabItem,\n e: React.KeyboardEvent<HTMLDivElement>,\n ) => {\n const enabledItems = resolvedItems.filter(\n (candidate) => !candidate.disabled,\n );\n const currentIndex = enabledItems.findIndex(\n (candidate) => candidate.key === item.key,\n );\n if (currentIndex === -1) return;\n\n let nextIndex: number | undefined;\n if (\n (!isVertical && e.key === 'ArrowRight') ||\n (isVertical && e.key === 'ArrowDown')\n ) {\n nextIndex = (currentIndex + 1) % enabledItems.length;\n } else if (\n (!isVertical && e.key === 'ArrowLeft') ||\n (isVertical && e.key === 'ArrowUp')\n ) {\n nextIndex =\n (currentIndex - 1 + enabledItems.length) % enabledItems.length;\n } else if (e.key === 'Home') {\n nextIndex = 0;\n } else if (e.key === 'End') {\n nextIndex = enabledItems.length - 1;\n }\n\n if (nextIndex !== undefined) {\n e.preventDefault();\n focusTab(enabledItems[nextIndex].key);\n return;\n }\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n activateTab(item.key);\n }\n };\n\n const handleAdd = (e: React.MouseEvent) => {\n onEdit?.(e, 'add');\n };\n\n const monospace = tabPosition !== 'top' ? false : propsMonospace;\n const paddingVal = useMemo(() => {\n if (tabPosition !== 'top') return 0;\n if (typeof propsPadding === 'number') return propsPadding;\n if (typeof propsPadding === 'boolean' && propsPadding) return 20;\n return 0;\n }, [propsPadding, tabPosition]);\n\n const isTop = tabPosition === 'top';\n const isBottom = tabPosition === 'bottom';\n const isLeft = tabPosition === 'left';\n const isRight = tabPosition === 'right';\n const isVertical = tabPosition === 'left' || tabPosition === 'right';\n const rootDirectionClass = isRight\n ? 'tw-flex-row-reverse'\n : isLeft\n ? 'tw-flex-row'\n : isBottom\n ? 'tw-flex-col-reverse'\n : 'tw-flex-col';\n\n const extraLeft =\n tabBarExtraContent &&\n typeof tabBarExtraContent === 'object' &&\n 'left' in tabBarExtraContent\n ? tabBarExtraContent.left\n : null;\n const extraRight = tabBarExtraContent\n ? typeof tabBarExtraContent === 'object' && 'right' in tabBarExtraContent\n ? tabBarExtraContent.right\n : React.isValidElement(tabBarExtraContent)\n ? tabBarExtraContent\n : null\n : null;\n\n // Scroll state for overflow\n const navListRef = useRef<HTMLDivElement>(null);\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const checkScroll = useCallback(() => {\n const el = navListRef.current;\n if (!el || isVertical) {\n setCanScrollLeft(false);\n setCanScrollRight(false);\n return;\n }\n const { scrollLeft, scrollWidth, clientWidth } = el;\n setCanScrollLeft(scrollLeft > 1);\n setCanScrollRight(scrollLeft + clientWidth < scrollWidth - 1);\n }, [isVertical]);\n\n useEffect(() => {\n checkScroll();\n const el = navListRef.current;\n if (!el) return;\n // Use ResizeObserver to detect size changes\n let ro: ResizeObserver | undefined;\n if (typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(() => checkScroll());\n ro.observe(el);\n }\n el.addEventListener('scroll', checkScroll, { passive: true });\n return () => {\n el.removeEventListener('scroll', checkScroll);\n ro?.disconnect();\n };\n }, [checkScroll, resolvedItems.length]);\n\n const scrollBy = (delta: number) => {\n const el = navListRef.current;\n if (el) {\n el.scrollBy({ left: delta, behavior: 'smooth' });\n }\n };\n\n const showScrollButtons = canScrollLeft || canScrollRight;\n\n return (\n <div\n data-testid={dataTestId}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs ant-tabs tw-flex',\n rootDirectionClass,\n adaptHeight && 'ald-adapt-height tw-h-full',\n size !== 'small' && 'ald-tabs-default',\n monospace && 'ald-tabs-monospace',\n compact && 'ald-tabs-compact',\n !hasDividing && 'ald-tabs-no-dividing',\n className,\n )}\n style={\n {\n ...style,\n '--header-bg-color': headerBackgroundColor,\n '--tabs-padding': `${paddingVal}px`,\n } as React.CSSProperties\n }\n >\n {/* Tab nav */}\n <div\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-nav ant-tabs-nav tw-flex',\n isVertical ? 'tw-shrink-0 tw-items-stretch' : 'tw-items-center',\n isTop && 'tw-mb-5',\n isBottom && 'tw-mt-5',\n isTop &&\n hasDividing &&\n 'tw-border-0 tw-border-b tw-border-solid tw-border-b-[var(--border-default)]',\n isBottom &&\n hasDividing &&\n 'tw-border-0 tw-border-t tw-border-solid tw-border-t-[var(--border-default)]',\n isTop && compact && '!tw-mb-0',\n isBottom && compact && '!tw-mt-0',\n isLeft &&\n 'tw-flex-col tw-border-0 tw-border-r tw-border-solid tw-border-r-[var(--border-default)]',\n isRight &&\n 'tw-flex-col tw-border-0 tw-border-l tw-border-solid tw-border-l-[var(--border-default)]',\n )}\n style={\n headerBackgroundColor || tabBarStyle\n ? {\n ...tabBarStyle,\n ...(headerBackgroundColor\n ? { backgroundColor: headerBackgroundColor }\n : {}),\n }\n : undefined\n }\n >\n {extraLeft}\n\n {/* Scroll left button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-[var(--action-ghost-normal)] tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollLeft && 'tw-invisible',\n )}\n onClick={() => scrollBy(-200)}\n aria-label=\"Scroll tabs left\"\n >\n <ChevronLeftLine size={16} />\n </button>\n )}\n\n <div\n className={cn(\n 'ald-tabs-nav-wrap ant-tabs-nav-wrap',\n isVertical\n ? 'tw-w-full tw-shrink-0 tw-self-stretch'\n : 'tw-min-w-0 tw-flex-1',\n )}\n style={paddingVal ? { margin: `0 ${paddingVal}px` } : undefined}\n >\n <div\n ref={navListRef}\n role=\"tablist\"\n aria-label={ariaLabel}\n aria-orientation={isVertical ? 'vertical' : 'horizontal'}\n onBlur={(e) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) {\n setFocusedKey(getPreferredFocusKey());\n }\n }}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-nav-list ant-tabs-nav-list tw-flex tw-overflow-hidden',\n isVertical && 'tw-w-full tw-shrink-0 tw-flex-col tw-self-stretch',\n centered && !isVertical && 'tw-justify-center',\n monospace && '[&>*]:tw-flex-1',\n isCard ? 'tw-gap-1' : !isVertical && !monospace && 'tw-gap-8',\n )}\n style={\n !isVertical\n ? { scrollbarWidth: 'none', msOverflowStyle: 'none' }\n : undefined\n }\n >\n {resolvedItems.map((item) => {\n const isActive = activeKey === item.key;\n // For editable-card, closable defaults to true unless explicitly set to false\n const showClose = isEditable && item.closable !== false;\n const closeLabel =\n typeof item.label === 'string' || typeof item.label === 'number'\n ? `Remove ${item.label}`\n : 'Remove tab';\n\n return (\n <div\n key={item.key}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-tab ant-tabs-tab tw-relative tw-flex tw-shrink-0 tw-items-center tw-gap-2 tw-whitespace-nowrap tw-transition-colors',\n isVertical && 'tw-w-full tw-self-stretch',\n // Card / editable-card styling\n isCard\n ? cn(\n 'tw-h-10 tw-rounded-t-[6px] tw-border tw-border-b-0 tw-border-solid tw-px-4 tw-text-sm tw-leading-5',\n 'tw-gap-sp-75',\n isActive\n ? 'tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-font-medium tw-text-[var(--content-brand-primary)]'\n : 'tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-text-[var(--content-secondary)] hover:tw-text-inherit',\n )\n : cn(\n size === 'small'\n ? 'tw-py-2 tw-text-xs tw-leading-4'\n : 'tw-py-2.5 tw-text-sm tw-leading-5',\n monospace && 'tw-justify-center',\n isActive\n ? 'tw-font-medium tw-text-[var(--content-brand-primary)]'\n : 'tw-font-medium tw-text-[var(--content-secondary)] hover:tw-text-inherit',\n ),\n item.disabled &&\n 'tw-pointer-events-none tw-cursor-default tw-opacity-50',\n // Focus belongs to the roving tab trigger, not to the\n // selected/active state. Render it on the tab envelope so\n // card and line tab geometry remain unchanged.\n !item.disabled && [\n 'has-[.ald-tabs-tab-trigger:focus-visible]:tw-shadow-[0_0_0_2px_var(--focus-ring)]',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-2',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-offset-2',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-[Highlight]',\n ],\n )}\n >\n <div\n ref={(node) => {\n tabRefs.current[item.key] = node;\n }}\n id={getTabId(item.key)}\n role=\"tab\"\n aria-selected={isActive}\n aria-controls={getPanelId(item.key)}\n aria-disabled={item.disabled || undefined}\n tabIndex={\n !item.disabled && focusedKey === item.key ? 0 : -1\n }\n className={cn(\n 'ald-tabs-tab-trigger tw-flex tw-min-w-0 tw-flex-1 tw-cursor-pointer tw-items-center tw-whitespace-nowrap',\n isCard ? 'tw-gap-sp-75' : 'tw-gap-2',\n monospace && 'tw-justify-center',\n )}\n onClick={\n item.disabled\n ? undefined\n : (e) => handleTabClick(item.key, e)\n }\n onFocus={() => setFocusedKey(item.key)}\n onKeyDown={(e) => handleTabKeyDown(item, e)}\n >\n {item.icon}\n {/* antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器 */}\n <span className=\"ant-tabs-tab-btn\">{item.label}</span>\n </div>\n {/* Close button for editable-card */}\n {showClose && (\n <button\n type=\"button\"\n className=\"ald-tabs-tab-remove tw-m-0 tw-grid tw-size-4 tw-cursor-pointer tw-place-items-center tw-border-0 tw-bg-transparent tw-p-0 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]\"\n onClick={(e) => handleRemove(item.key, e)}\n aria-label={closeLabel}\n >\n <CloseLightLine size={12} />\n </button>\n )}\n {/* Active indicator for non-card line tabs */}\n {/* antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器 */}\n {!isCard && isActive && isTop && (\n <div className=\"ant-tabs-ink-bar tw-absolute tw-inset-x-0 tw--bottom-px tw-h-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n {!isCard && isActive && isBottom && (\n <div className=\"ant-tabs-ink-bar tw-absolute tw-inset-x-0 tw--top-px tw-h-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n {!isCard && isActive && isLeft && (\n <div className=\"tw-absolute tw-inset-y-0 tw--right-px tw-w-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n {!isCard && isActive && isRight && (\n <div className=\"tw-absolute tw-inset-y-0 tw--left-px tw-w-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n </div>\n );\n })}\n </div>\n </div>\n\n {/* Scroll right button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-[var(--action-ghost-normal)] tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollRight && 'tw-invisible',\n )}\n onClick={() => scrollBy(200)}\n aria-label=\"Scroll tabs right\"\n >\n <ChevronRightLine size={16} />\n </button>\n )}\n\n {/* Add button for editable-card */}\n {isEditable && !hideAdd && (\n <button\n type=\"button\"\n className=\"ald-tabs-nav-add tw-ml-1 tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-justify-center tw-rounded tw-border tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-px-2 tw-py-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]\"\n onClick={handleAdd}\n aria-label=\"Add tab\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </button>\n )}\n\n {extraRight}\n </div>\n\n {/* Tab content */}\n {/* antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器 */}\n <div\n className={cn(\n 'ald-tabs-content ant-tabs-content ant-tabs-content-holder tw-min-h-0 tw-flex-1',\n adaptHeight && 'tw-h-full',\n )}\n style={\n paddingVal\n ? { padding: `0 ${paddingVal}px ${paddingVal}px` }\n : undefined\n }\n >\n {resolvedItems.map((item) => {\n const isActive = item.key === activeKey;\n if (!isActive && destroyInactiveTabPane && !item.forceRender) {\n return null;\n }\n return (\n <div\n key={item.key}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-tabpane ant-tabs-tabpane',\n // v2 行为:adaptHeight 时 tabpane 撑满内容区,子元素的百分比高度才能解析\n adaptHeight && 'tw-h-full tw-overflow-y-auto',\n isActive ? 'ant-tabs-tabpane-active tw-block' : 'tw-hidden',\n )}\n role=\"tabpanel\"\n id={getPanelId(item.key)}\n aria-labelledby={getTabId(item.key)}\n >\n {item.children}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nTabs.TabPane = TabPane;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Tabs/index.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../lib/utils';\nimport { ChevronLeftLine, ChevronRightLine, CloseLightLine } from '../Icon';\nimport TabPane from './TabPane';\n\nexport type TabsSize = 'default' | 'small';\n\ninterface TabItem {\n key: string;\n label: React.ReactNode;\n children?: React.ReactNode;\n disabled?: boolean;\n closable?: boolean;\n icon?: React.ReactNode;\n forceRender?: boolean;\n className?: string;\n}\n\nexport interface ITabsProps {\n size?: TabsSize;\n activeKey?: string;\n defaultActiveKey?: string;\n onChange?: (activeKey: string) => void;\n onTabClick?: (activeKey: string, e: React.MouseEvent) => void;\n destroyInactiveTabPane?: boolean;\n centered?: boolean;\n adaptHeight?: boolean;\n tabPosition?: 'left' | 'right' | 'top' | 'bottom';\n className?: string;\n children?: React.ReactNode;\n headerBackgroundColor?: string;\n monospace?: boolean;\n padding?: boolean | number;\n compact?: boolean;\n hasDividing?: boolean;\n items?: TabItem[];\n type?: 'line' | 'card' | 'editable-card';\n tabBarExtraContent?:\n | React.ReactNode\n | { left?: React.ReactNode; right?: React.ReactNode };\n onEdit?: (\n targetKey: string | React.MouseEvent | React.KeyboardEvent,\n action: 'add' | 'remove',\n ) => void;\n hideAdd?: boolean;\n style?: React.CSSProperties;\n tabBarStyle?: React.CSSProperties;\n popupClassName?: string;\n tabBarGutter?: number;\n moreIcon?: React.ReactNode;\n /** 透传到 Tabs 根容器的 data-testid,用于自动化测试定位 */\n 'data-testid'?: string;\n /** 透传到 tablist 的 aria-label,用于可访问性与自动化测试定位 */\n 'aria-label'?: string;\n}\n\nexport default function Tabs(props: ITabsProps) {\n const {\n size,\n className,\n adaptHeight,\n style = {},\n monospace: propsMonospace,\n tabPosition = 'top',\n padding: propsPadding = false,\n compact,\n hasDividing = true,\n items,\n activeKey: controlledActiveKey,\n defaultActiveKey,\n onChange,\n onTabClick,\n destroyInactiveTabPane,\n centered,\n tabBarExtraContent,\n headerBackgroundColor,\n children,\n type,\n onEdit,\n hideAdd,\n tabBarStyle,\n 'data-testid': dataTestId,\n 'aria-label': ariaLabel,\n } = props;\n\n const isEditable = type === 'editable-card';\n const isCard = type === 'card' || type === 'editable-card';\n\n // Derive items from children if not provided\n const resolvedItems: TabItem[] = useMemo(() => {\n if (items) return items;\n return React.Children.toArray(children)\n .filter(React.isValidElement)\n .map((child: any) => ({\n key: child.key || child.props.key || '',\n label: child.props.tab,\n children: child.props.children,\n disabled: child.props.disabled,\n closable: child.props.closable,\n forceRender: child.props.forceRender,\n }));\n }, [items, children]);\n\n const firstKey = resolvedItems[0]?.key || '';\n const [innerActiveKey, setInnerActiveKey] = useState(\n defaultActiveKey || firstKey,\n );\n const mergedActiveKey =\n controlledActiveKey !== undefined ? controlledActiveKey : innerActiveKey;\n const activeKey = resolvedItems.some((item) => item.key === mergedActiveKey)\n ? mergedActiveKey\n : firstKey;\n\n const tabsId = React.useId();\n const tabRefs = useRef<Record<string, HTMLDivElement | null>>({});\n const pendingFocusKeyRef = useRef<string | null>(null);\n const getPreferredFocusKey = useCallback(\n (items: TabItem[] = resolvedItems) =>\n items.find((item) => item.key === activeKey && !item.disabled)?.key ||\n items.find((item) => !item.disabled)?.key ||\n '',\n [activeKey, resolvedItems],\n );\n const [focusedKey, setFocusedKey] = useState(() => getPreferredFocusKey());\n\n const getTabId = (key: string) => `${tabsId}-tab-${key}`;\n const getPanelId = (key: string) => `${tabsId}-panel-${key}`;\n\n const focusTab = useCallback((key: string) => {\n setFocusedKey(key);\n tabRefs.current[key]?.focus();\n }, []);\n\n useEffect(() => {\n const pendingFocusKey = pendingFocusKeyRef.current;\n if (\n pendingFocusKey &&\n resolvedItems.some(\n (item) => item.key === pendingFocusKey && !item.disabled,\n )\n ) {\n pendingFocusKeyRef.current = null;\n focusTab(pendingFocusKey);\n return;\n }\n\n setFocusedKey((currentFocusedKey) => {\n const focusedItem = resolvedItems.find(\n (item) => item.key === currentFocusedKey,\n );\n return focusedItem && !focusedItem.disabled\n ? currentFocusedKey\n : getPreferredFocusKey();\n });\n }, [focusTab, getPreferredFocusKey, resolvedItems]);\n\n const activateTab = useCallback(\n (key: string) => {\n if (controlledActiveKey === undefined) {\n setInnerActiveKey(key);\n }\n onChange?.(key);\n },\n [controlledActiveKey, onChange],\n );\n\n const handleTabClick = (key: string, e: React.MouseEvent) => {\n setFocusedKey(key);\n activateTab(key);\n onTabClick?.(key, e);\n };\n\n const handleRemove = (key: string, e: React.MouseEvent) => {\n e.stopPropagation();\n const itemIndex = resolvedItems.findIndex((item) => item.key === key);\n const nextFocusableItem = [\n ...resolvedItems.slice(itemIndex + 1),\n ...resolvedItems.slice(0, itemIndex).reverse(),\n ].find((item) => !item.disabled);\n pendingFocusKeyRef.current = nextFocusableItem?.key || null;\n onEdit?.(key, 'remove');\n };\n\n const handleTabKeyDown = (\n item: TabItem,\n e: React.KeyboardEvent<HTMLDivElement>,\n ) => {\n const enabledItems = resolvedItems.filter(\n (candidate) => !candidate.disabled,\n );\n const currentIndex = enabledItems.findIndex(\n (candidate) => candidate.key === item.key,\n );\n if (currentIndex === -1) return;\n\n let nextIndex: number | undefined;\n if (\n (!isVertical && e.key === 'ArrowRight') ||\n (isVertical && e.key === 'ArrowDown')\n ) {\n nextIndex = (currentIndex + 1) % enabledItems.length;\n } else if (\n (!isVertical && e.key === 'ArrowLeft') ||\n (isVertical && e.key === 'ArrowUp')\n ) {\n nextIndex =\n (currentIndex - 1 + enabledItems.length) % enabledItems.length;\n } else if (e.key === 'Home') {\n nextIndex = 0;\n } else if (e.key === 'End') {\n nextIndex = enabledItems.length - 1;\n }\n\n if (nextIndex !== undefined) {\n e.preventDefault();\n focusTab(enabledItems[nextIndex].key);\n return;\n }\n\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n activateTab(item.key);\n }\n };\n\n const handleAdd = (e: React.MouseEvent) => {\n onEdit?.(e, 'add');\n };\n\n const monospace = tabPosition !== 'top' ? false : propsMonospace;\n const paddingVal = useMemo(() => {\n if (tabPosition !== 'top') return 0;\n if (typeof propsPadding === 'number') return propsPadding;\n if (typeof propsPadding === 'boolean' && propsPadding) return 20;\n return 0;\n }, [propsPadding, tabPosition]);\n\n const isTop = tabPosition === 'top';\n const isBottom = tabPosition === 'bottom';\n const isLeft = tabPosition === 'left';\n const isRight = tabPosition === 'right';\n const isVertical = tabPosition === 'left' || tabPosition === 'right';\n const rootDirectionClass = isRight\n ? 'tw-flex-row-reverse'\n : isLeft\n ? 'tw-flex-row'\n : isBottom\n ? 'tw-flex-col-reverse'\n : 'tw-flex-col';\n\n const extraLeft =\n tabBarExtraContent &&\n typeof tabBarExtraContent === 'object' &&\n 'left' in tabBarExtraContent\n ? tabBarExtraContent.left\n : null;\n const extraRight = tabBarExtraContent\n ? typeof tabBarExtraContent === 'object' && 'right' in tabBarExtraContent\n ? tabBarExtraContent.right\n : React.isValidElement(tabBarExtraContent)\n ? tabBarExtraContent\n : null\n : null;\n\n // Scroll state for overflow\n const navListRef = useRef<HTMLDivElement>(null);\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const checkScroll = useCallback(() => {\n const el = navListRef.current;\n if (!el || isVertical) {\n setCanScrollLeft(false);\n setCanScrollRight(false);\n return;\n }\n const { scrollLeft, scrollWidth, clientWidth } = el;\n setCanScrollLeft(scrollLeft > 1);\n setCanScrollRight(scrollLeft + clientWidth < scrollWidth - 1);\n }, [isVertical]);\n\n useEffect(() => {\n checkScroll();\n const el = navListRef.current;\n if (!el) return;\n // Use ResizeObserver to detect size changes\n let ro: ResizeObserver | undefined;\n if (typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(() => checkScroll());\n ro.observe(el);\n }\n el.addEventListener('scroll', checkScroll, { passive: true });\n return () => {\n el.removeEventListener('scroll', checkScroll);\n ro?.disconnect();\n };\n }, [checkScroll, resolvedItems.length]);\n\n const scrollBy = (delta: number) => {\n const el = navListRef.current;\n if (el) {\n el.scrollBy({ left: delta, behavior: 'smooth' });\n }\n };\n\n const showScrollButtons = canScrollLeft || canScrollRight;\n\n return (\n <div\n data-testid={dataTestId}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs ant-tabs tw-flex',\n rootDirectionClass,\n adaptHeight && 'ald-adapt-height tw-h-full',\n size !== 'small' && 'ald-tabs-default',\n monospace && 'ald-tabs-monospace',\n compact && 'ald-tabs-compact',\n !hasDividing && 'ald-tabs-no-dividing',\n className,\n )}\n style={\n {\n ...style,\n '--header-bg-color': headerBackgroundColor,\n '--tabs-padding': `${paddingVal}px`,\n } as React.CSSProperties\n }\n >\n {/* Tab nav */}\n <div\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-nav ant-tabs-nav tw-flex',\n isVertical ? 'tw-shrink-0 tw-items-stretch' : 'tw-items-center',\n isTop && 'tw-mb-5',\n isBottom && 'tw-mt-5',\n isTop &&\n hasDividing &&\n 'tw-border-0 tw-border-b tw-border-solid tw-border-b-[var(--border-default)]',\n isBottom &&\n hasDividing &&\n 'tw-border-0 tw-border-t tw-border-solid tw-border-t-[var(--border-default)]',\n isTop && compact && '!tw-mb-0',\n isBottom && compact && '!tw-mt-0',\n isLeft &&\n 'tw-flex-col tw-border-0 tw-border-r tw-border-solid tw-border-r-[var(--border-default)]',\n isRight &&\n 'tw-flex-col tw-border-0 tw-border-l tw-border-solid tw-border-l-[var(--border-default)]',\n )}\n style={\n headerBackgroundColor || tabBarStyle\n ? {\n ...tabBarStyle,\n ...(headerBackgroundColor\n ? { backgroundColor: headerBackgroundColor }\n : {}),\n }\n : undefined\n }\n >\n {extraLeft}\n\n {/* Scroll left button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-[var(--action-ghost-normal)] tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollLeft && 'tw-invisible',\n )}\n onClick={() => scrollBy(-200)}\n aria-label=\"Scroll tabs left\"\n >\n <ChevronLeftLine size={16} />\n </button>\n )}\n\n <div\n className={cn(\n 'ald-tabs-nav-wrap ant-tabs-nav-wrap',\n isVertical\n ? 'tw-w-full tw-shrink-0 tw-self-stretch'\n : 'tw-min-w-0 tw-flex-1',\n )}\n style={paddingVal ? { margin: `0 ${paddingVal}px` } : undefined}\n >\n <div\n ref={navListRef}\n role=\"tablist\"\n aria-label={ariaLabel}\n aria-orientation={isVertical ? 'vertical' : 'horizontal'}\n onBlur={(e) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) {\n setFocusedKey(getPreferredFocusKey());\n }\n }}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-nav-list ant-tabs-nav-list tw-flex tw-overflow-hidden',\n isVertical && 'tw-w-full tw-shrink-0 tw-flex-col tw-self-stretch',\n centered && !isVertical && 'tw-justify-center',\n monospace && '[&>*]:tw-flex-1',\n isCard ? 'tw-gap-1' : !isVertical && !monospace && 'tw-gap-8',\n )}\n style={\n !isVertical\n ? { scrollbarWidth: 'none', msOverflowStyle: 'none' }\n : undefined\n }\n >\n {resolvedItems.map((item) => {\n const isActive = activeKey === item.key;\n // For editable-card, closable defaults to true unless explicitly set to false\n const showClose = isEditable && item.closable !== false;\n const closeLabel =\n typeof item.label === 'string' || typeof item.label === 'number'\n ? `Remove ${item.label}`\n : 'Remove tab';\n\n return (\n <div\n key={item.key}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-tab ant-tabs-tab tw-relative tw-flex tw-shrink-0 tw-items-center tw-gap-2 tw-whitespace-nowrap tw-transition-colors',\n isVertical && 'tw-w-full tw-self-stretch',\n // Card / editable-card styling\n isCard\n ? cn(\n 'tw-h-10 tw-rounded-t-[6px] tw-border tw-border-b-0 tw-border-solid tw-px-4 tw-text-sm tw-leading-5',\n 'tw-gap-sp-75',\n isActive\n ? 'tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-font-medium tw-text-[var(--content-brand-primary)]'\n : 'tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-text-[var(--content-secondary)] hover:tw-text-inherit',\n )\n : cn(\n size === 'small'\n ? 'tw-py-2 tw-text-xs tw-leading-4'\n : 'tw-py-2.5 tw-text-sm tw-leading-5',\n monospace && 'tw-justify-center',\n isActive\n ? 'tw-font-medium tw-text-[var(--content-brand-primary)]'\n : 'tw-font-medium tw-text-[var(--content-secondary)] hover:tw-text-inherit',\n ),\n item.disabled &&\n 'tw-pointer-events-none tw-cursor-default tw-opacity-50',\n // Focus belongs to the roving tab trigger, not to the\n // selected/active state. Render it on the tab envelope so\n // card and line tab geometry remain unchanged.\n !item.disabled && [\n 'has-[.ald-tabs-tab-trigger:focus-visible]:tw-shadow-[0_0_0_2px_var(--focus-ring)]',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-2',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-offset-2',\n 'forced-colors:has-[.ald-tabs-tab-trigger:focus-visible]:tw-outline-[Highlight]',\n ],\n )}\n >\n <div\n ref={(node) => {\n tabRefs.current[item.key] = node;\n }}\n id={getTabId(item.key)}\n role=\"tab\"\n aria-selected={isActive}\n aria-controls={getPanelId(item.key)}\n aria-disabled={item.disabled || undefined}\n tabIndex={\n !item.disabled && focusedKey === item.key ? 0 : -1\n }\n className={cn(\n 'ald-tabs-tab-trigger tw-flex tw-min-w-0 tw-flex-1 tw-cursor-pointer tw-items-center tw-whitespace-nowrap',\n isCard ? 'tw-gap-sp-75' : 'tw-gap-2',\n monospace && 'tw-justify-center',\n )}\n onClick={\n item.disabled\n ? undefined\n : (e) => handleTabClick(item.key, e)\n }\n onFocus={() => setFocusedKey(item.key)}\n onKeyDown={(e) => handleTabKeyDown(item, e)}\n >\n {item.icon}\n {/* antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器 */}\n <span className=\"ant-tabs-tab-btn\">{item.label}</span>\n </div>\n {/* Close button for editable-card */}\n {showClose && (\n <button\n type=\"button\"\n className=\"ald-tabs-tab-remove tw-m-0 tw-grid tw-size-4 tw-cursor-pointer tw-place-items-center tw-border-0 tw-bg-transparent tw-p-0 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]\"\n onClick={(e) => handleRemove(item.key, e)}\n aria-label={closeLabel}\n >\n <CloseLightLine size={12} />\n </button>\n )}\n {/* Active indicator for non-card line tabs */}\n {/* antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器 */}\n {!isCard && isActive && isTop && (\n <div className=\"ant-tabs-ink-bar tw-absolute tw-inset-x-0 tw--bottom-px tw-h-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n {!isCard && isActive && isBottom && (\n <div className=\"ant-tabs-ink-bar tw-absolute tw-inset-x-0 tw--top-px tw-h-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n {!isCard && isActive && isLeft && (\n <div className=\"tw-absolute tw-inset-y-0 tw--right-px tw-w-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n {!isCard && isActive && isRight && (\n <div className=\"tw-absolute tw-inset-y-0 tw--left-px tw-w-[2px] tw-rounded-[2px] tw-bg-[var(--border-brand-strong)]\" />\n )}\n </div>\n );\n })}\n </div>\n </div>\n\n {/* Scroll right button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-[var(--action-ghost-normal)] tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollRight && 'tw-invisible',\n )}\n onClick={() => scrollBy(200)}\n aria-label=\"Scroll tabs right\"\n >\n <ChevronRightLine size={16} />\n </button>\n )}\n\n {/* Add button for editable-card */}\n {isEditable && !hideAdd && (\n <button\n type=\"button\"\n className=\"ald-tabs-nav-add tw-ml-1 tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-justify-center tw-rounded tw-border tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-px-2 tw-py-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]\"\n onClick={handleAdd}\n aria-label=\"Add tab\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </button>\n )}\n\n {extraRight}\n </div>\n\n {/* Tab content */}\n {/* antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器 */}\n <div\n className={cn(\n 'ald-tabs-content ant-tabs-content ant-tabs-content-holder tw-min-h-0 tw-flex-1',\n adaptHeight && 'tw-h-full',\n )}\n style={\n paddingVal\n ? { padding: `0 ${paddingVal}px ${paddingVal}px` }\n : undefined\n }\n >\n {resolvedItems.map((item) => {\n const isActive = item.key === activeKey;\n if (!isActive && destroyInactiveTabPane && !item.forceRender) {\n return null;\n }\n return (\n <div\n key={item.key}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-tabpane ant-tabs-tabpane',\n // v2 行为:adaptHeight 时 tabpane 撑满内容区,子元素的百分比高度才能解析\n adaptHeight && 'tw-h-full tw-overflow-y-auto',\n isActive ? 'ant-tabs-tabpane-active tw-block' : 'tw-hidden',\n )}\n role=\"tabpanel\"\n id={getPanelId(item.key)}\n aria-labelledby={getTabId(item.key)}\n aria-hidden={!isActive || undefined}\n >\n {item.children}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nTabs.TabPane = TabPane;\n"],"mappings":"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"}
package/dist/Tag/index.js CHANGED
@@ -50,6 +50,15 @@ function Tag(props) {
50
50
  maxWidth: maxWidth || DEFAULT_MAX_WIDTH
51
51
  },
52
52
  onClick: onTagClick,
53
+ role: onClick ? "button" : void 0,
54
+ tabIndex: onClick && !disabled ? 0 : void 0,
55
+ "aria-disabled": disabled || void 0,
56
+ onKeyDown: (e) => {
57
+ if (onClick && !disabled && (e.key === "Enter" || e.key === " ")) {
58
+ e.preventDefault();
59
+ onTagClick(e);
60
+ }
61
+ },
53
62
  children: [
54
63
  icon && /* @__PURE__ */ jsx("span", {
55
64
  className: cn(prefixCls("icon"), "tw-inline-flex tw-flex-none tw-items-center"),
@@ -67,9 +76,19 @@ function Tag(props) {
67
76
  closable ? /* @__PURE__ */ jsx("span", {
68
77
  className: cn(prefixCls("close-btn"), "tw-inline-flex tw-flex-none tw-items-center", disabled ? "tw-cursor-default" : "tw-cursor-pointer"),
69
78
  onClick: onCloseBtnClick,
79
+ role: "button",
80
+ tabIndex: disabled ? -1 : 0,
81
+ "aria-label": `Remove ${domTitle}`,
82
+ onKeyDown: (e) => {
83
+ if (!disabled && (e.key === "Enter" || e.key === " ")) {
84
+ e.preventDefault();
85
+ onCloseBtnClick(e);
86
+ }
87
+ },
70
88
  children: /* @__PURE__ */ jsx(Memo, {
71
89
  color: textColor,
72
- size: 16
90
+ size: 16,
91
+ "aria-hidden": "true"
73
92
  })
74
93
  }) : null
75
94
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Tag/index.tsx"],"sourcesContent":["import React, { MouseEventHandler, useCallback } from 'react';\nimport { CloseLightLine } from '../Icon';\nimport { cn } from '../lib/utils';\n\nexport interface TagProps {\n children: React.ReactNode;\n onClick?: MouseEventHandler;\n /**\n * 是否可关闭\n */\n closable?: boolean;\n /**\n * 关闭回调\n */\n onClose?: MouseEventHandler;\n status?: 'default' | 'info' | 'success' | 'warning' | 'error';\n /**\n * 自定义颜色\n */\n color?: string;\n /**\n * 前置 icon 图标\n */\n icon?: React.ReactNode;\n /**\n * 后置 icon 图标\n */\n suffixIcon?: React.ReactNode;\n /**\n * 大小\n */\n size?: 'large' | 'default' | 'middle' | 'small';\n /**\n * 风格,填充、默认、线框\n */\n mode?: 'fill' | 'default' | 'border';\n /**\n * 是否禁用\n */\n disabled?: boolean;\n /**\n * 最大宽度\n */\n maxWidth?: number;\n /**\n * hover 上去后显示的 title\n */\n title?: string;\n className?: string;\n}\n\nexport default function Tag(props: TagProps) {\n const {\n children,\n onClick,\n closable,\n onClose,\n color,\n icon,\n suffixIcon,\n size = 'middle',\n status,\n mode,\n disabled,\n maxWidth,\n className,\n title,\n } = props;\n const tokens = getStatusTokens(status);\n const providedIsHex = isHexColor(color);\n const providedColor = color;\n\n // background color\n const bgColor = (() => {\n if (mode === 'border') {\n return 'var(--background-default)';\n }\n if (providedColor) {\n if (providedIsHex)\n return addHexAlpha(\n providedColor as string,\n mode === 'fill' ? 0.16 : 0.06,\n );\n return `color-mix(in srgb, ${providedColor} ${\n mode === 'fill' ? 16 : 6\n }%, transparent)`;\n }\n return mode === 'fill' ? tokens.bgSubtle : tokens.bgOnSubtle;\n })();\n // text color\n const textColor = (() => {\n if (providedColor) {\n if (providedIsHex) return addHexAlpha(providedColor as string, 1);\n return providedColor;\n }\n return tokens.text;\n })();\n // border color\n const borderColor = (() => {\n if (mode === 'fill') return 'transparent';\n if (providedColor) {\n if (providedIsHex) return addHexAlpha(providedColor as string, 0.32);\n return `color-mix(in srgb, ${providedColor} 32%, transparent)`;\n }\n return tokens.borderSubtle;\n })();\n\n const onTagClick = useCallback<MouseEventHandler>(\n (e) => {\n if (disabled) {\n return;\n }\n onClick?.(e);\n },\n [disabled, onClick],\n );\n const onCloseBtnClick = useCallback<MouseEventHandler>(\n (e) => {\n if (disabled) {\n return;\n }\n onClose?.(e);\n },\n [disabled, onClose],\n );\n\n const DEFAULT_MAX_WIDTH = 400;\n\n const domTitle =\n title !== undefined ? title : typeof children === 'string' ? children : '';\n\n return (\n <span\n className={cn(\n prefixCls('container'),\n 'tw-inline-flex tw-cursor-default tw-items-center tw-overflow-hidden tw-border tw-border-solid',\n // Size variants\n size === 'small' &&\n `${prefixCls(\n 'small',\n )} tw-gap-sp-50 tw-rounded-[2px] tw-px-[3px] tw-py-px tw-text-xs tw-leading-4`,\n size === 'large' &&\n `${prefixCls(\n 'large',\n )} tw-gap-sp-50 tw-rounded-[6px] tw-px-[7px] tw-py-px tw-text-base tw-leading-6`,\n size !== 'small' &&\n size !== 'large' &&\n 'tw-gap-sp-50 tw-rounded-r-50 tw-px-[5px] tw-py-px tw-text-sm tw-leading-5',\n // Disabled\n disabled && `${prefixCls('disabled')} tw-cursor-default tw-opacity-40`,\n className || '',\n )}\n style={{\n backgroundColor: bgColor,\n color: textColor,\n borderColor: borderColor,\n maxWidth: maxWidth || DEFAULT_MAX_WIDTH,\n }}\n onClick={onTagClick}\n >\n {icon && (\n <span\n className={cn(\n prefixCls('icon'),\n 'tw-inline-flex tw-flex-none tw-items-center',\n )}\n >\n {icon}\n </span>\n )}\n <span\n className={cn(prefixCls('content'), 'tw-flex-1 tw-truncate')}\n title={domTitle}\n >\n {children}\n </span>\n {suffixIcon && (\n <span\n className={cn(\n prefixCls('suffix-icon'),\n 'tw-inline-flex tw-flex-none tw-items-center',\n )}\n >\n {suffixIcon}\n </span>\n )}\n {closable ? (\n <span\n className={cn(\n prefixCls('close-btn'),\n 'tw-inline-flex tw-flex-none tw-items-center',\n disabled ? 'tw-cursor-default' : 'tw-cursor-pointer',\n )}\n onClick={onCloseBtnClick}\n >\n <CloseLightLine color={textColor} size={16} />\n </span>\n ) : null}\n </span>\n );\n}\n\nconst ALD_PREFIX = 'ald-tag';\nexport function prefixCls(className: string) {\n return `${ALD_PREFIX}-${className}`;\n}\n\nfunction addHexAlpha(hex: string, opacity: number) {\n const rawHex = hex.startsWith('#') ? hex.slice(1) : hex;\n const normalizedHex =\n rawHex.length === 3\n ? rawHex\n .split('')\n .map((char) => `${char}${char}`)\n .join('')\n : rawHex.slice(0, 6);\n const alpha = Math.round(opacity * 255)\n .toString(16)\n .padStart(2, '0');\n\n return `#${normalizedHex}${alpha}`;\n}\n\nfunction isHexColor(value?: string): boolean {\n return (\n !!value && /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value)\n );\n}\n\nfunction getStatusTokens(status?: TagProps['status']) {\n switch (status) {\n case 'success':\n return {\n text: 'var(--content-positive-secondary)',\n bgSubtle: 'var(--background-positive-subtle)',\n bgOnSubtle: 'var(--background-positive-on-subtle)',\n borderSubtle: 'var(--border-positive-subtle)',\n } as const;\n case 'warning':\n return {\n text: 'var(--content-warning-secondary)',\n bgSubtle: 'var(--background-warning-subtle)',\n bgOnSubtle: 'var(--background-warning-on-subtle)',\n borderSubtle: 'var(--border-warning-subtle)',\n } as const;\n case 'error':\n return {\n text: 'var(--content-negative-secondary)',\n bgSubtle: 'var(--background-negative-subtle)',\n bgOnSubtle: 'var(--background-negative-on-subtle)',\n borderSubtle: 'var(--border-negative-subtle)',\n } as const;\n case 'default':\n return {\n text: 'var(--content-primary)',\n bgSubtle: 'var(--background-neutral-subtle)',\n bgOnSubtle: 'var(--background-neutral-on-subtle)',\n borderSubtle: 'var(--border-neutral-subtle)',\n } as const;\n case 'info':\n default:\n return {\n text: 'var(--content-informative-secondary)',\n bgSubtle: 'var(--background-informative-subtle)',\n bgOnSubtle: 'var(--background-informative-on-subtle)',\n borderSubtle: 'var(--border-informative-subtle)',\n } as const;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Tag/index.tsx"],"sourcesContent":["import React, { MouseEventHandler, useCallback } from 'react';\nimport { CloseLightLine } from '../Icon';\nimport { cn } from '../lib/utils';\n\nexport interface TagProps {\n children: React.ReactNode;\n onClick?: MouseEventHandler;\n /**\n * 是否可关闭\n */\n closable?: boolean;\n /**\n * 关闭回调\n */\n onClose?: MouseEventHandler;\n status?: 'default' | 'info' | 'success' | 'warning' | 'error';\n /**\n * 自定义颜色\n */\n color?: string;\n /**\n * 前置 icon 图标\n */\n icon?: React.ReactNode;\n /**\n * 后置 icon 图标\n */\n suffixIcon?: React.ReactNode;\n /**\n * 大小\n */\n size?: 'large' | 'default' | 'middle' | 'small';\n /**\n * 风格,填充、默认、线框\n */\n mode?: 'fill' | 'default' | 'border';\n /**\n * 是否禁用\n */\n disabled?: boolean;\n /**\n * 最大宽度\n */\n maxWidth?: number;\n /**\n * hover 上去后显示的 title\n */\n title?: string;\n className?: string;\n}\n\nexport default function Tag(props: TagProps) {\n const {\n children,\n onClick,\n closable,\n onClose,\n color,\n icon,\n suffixIcon,\n size = 'middle',\n status,\n mode,\n disabled,\n maxWidth,\n className,\n title,\n } = props;\n const tokens = getStatusTokens(status);\n const providedIsHex = isHexColor(color);\n const providedColor = color;\n\n // background color\n const bgColor = (() => {\n if (mode === 'border') {\n return 'var(--background-default)';\n }\n if (providedColor) {\n if (providedIsHex)\n return addHexAlpha(\n providedColor as string,\n mode === 'fill' ? 0.16 : 0.06,\n );\n return `color-mix(in srgb, ${providedColor} ${\n mode === 'fill' ? 16 : 6\n }%, transparent)`;\n }\n return mode === 'fill' ? tokens.bgSubtle : tokens.bgOnSubtle;\n })();\n // text color\n const textColor = (() => {\n if (providedColor) {\n if (providedIsHex) return addHexAlpha(providedColor as string, 1);\n return providedColor;\n }\n return tokens.text;\n })();\n // border color\n const borderColor = (() => {\n if (mode === 'fill') return 'transparent';\n if (providedColor) {\n if (providedIsHex) return addHexAlpha(providedColor as string, 0.32);\n return `color-mix(in srgb, ${providedColor} 32%, transparent)`;\n }\n return tokens.borderSubtle;\n })();\n\n const onTagClick = useCallback<MouseEventHandler>(\n (e) => {\n if (disabled) {\n return;\n }\n onClick?.(e);\n },\n [disabled, onClick],\n );\n const onCloseBtnClick = useCallback<MouseEventHandler>(\n (e) => {\n if (disabled) {\n return;\n }\n onClose?.(e);\n },\n [disabled, onClose],\n );\n\n const DEFAULT_MAX_WIDTH = 400;\n\n const domTitle =\n title !== undefined ? title : typeof children === 'string' ? children : '';\n\n return (\n <span\n className={cn(\n prefixCls('container'),\n 'tw-inline-flex tw-cursor-default tw-items-center tw-overflow-hidden tw-border tw-border-solid',\n // Size variants\n size === 'small' &&\n `${prefixCls(\n 'small',\n )} tw-gap-sp-50 tw-rounded-[2px] tw-px-[3px] tw-py-px tw-text-xs tw-leading-4`,\n size === 'large' &&\n `${prefixCls(\n 'large',\n )} tw-gap-sp-50 tw-rounded-[6px] tw-px-[7px] tw-py-px tw-text-base tw-leading-6`,\n size !== 'small' &&\n size !== 'large' &&\n 'tw-gap-sp-50 tw-rounded-r-50 tw-px-[5px] tw-py-px tw-text-sm tw-leading-5',\n // Disabled\n disabled && `${prefixCls('disabled')} tw-cursor-default tw-opacity-40`,\n className || '',\n )}\n style={{\n backgroundColor: bgColor,\n color: textColor,\n borderColor: borderColor,\n maxWidth: maxWidth || DEFAULT_MAX_WIDTH,\n }}\n onClick={onTagClick}\n role={onClick ? 'button' : undefined}\n tabIndex={onClick && !disabled ? 0 : undefined}\n aria-disabled={disabled || undefined}\n onKeyDown={(e) => {\n if (onClick && !disabled && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n onTagClick(e as unknown as React.MouseEvent);\n }\n }}\n >\n {icon && (\n <span\n className={cn(\n prefixCls('icon'),\n 'tw-inline-flex tw-flex-none tw-items-center',\n )}\n >\n {icon}\n </span>\n )}\n <span\n className={cn(prefixCls('content'), 'tw-flex-1 tw-truncate')}\n title={domTitle}\n >\n {children}\n </span>\n {suffixIcon && (\n <span\n className={cn(\n prefixCls('suffix-icon'),\n 'tw-inline-flex tw-flex-none tw-items-center',\n )}\n >\n {suffixIcon}\n </span>\n )}\n {closable ? (\n <span\n className={cn(\n prefixCls('close-btn'),\n 'tw-inline-flex tw-flex-none tw-items-center',\n disabled ? 'tw-cursor-default' : 'tw-cursor-pointer',\n )}\n onClick={onCloseBtnClick}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-label={`Remove ${domTitle}`}\n onKeyDown={(e) => {\n if (!disabled && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n onCloseBtnClick(e as unknown as React.MouseEvent);\n }\n }}\n >\n <CloseLightLine color={textColor} size={16} aria-hidden=\"true\" />\n </span>\n ) : null}\n </span>\n );\n}\n\nconst ALD_PREFIX = 'ald-tag';\nexport function prefixCls(className: string) {\n return `${ALD_PREFIX}-${className}`;\n}\n\nfunction addHexAlpha(hex: string, opacity: number) {\n const rawHex = hex.startsWith('#') ? hex.slice(1) : hex;\n const normalizedHex =\n rawHex.length === 3\n ? rawHex\n .split('')\n .map((char) => `${char}${char}`)\n .join('')\n : rawHex.slice(0, 6);\n const alpha = Math.round(opacity * 255)\n .toString(16)\n .padStart(2, '0');\n\n return `#${normalizedHex}${alpha}`;\n}\n\nfunction isHexColor(value?: string): boolean {\n return (\n !!value && /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value)\n );\n}\n\nfunction getStatusTokens(status?: TagProps['status']) {\n switch (status) {\n case 'success':\n return {\n text: 'var(--content-positive-secondary)',\n bgSubtle: 'var(--background-positive-subtle)',\n bgOnSubtle: 'var(--background-positive-on-subtle)',\n borderSubtle: 'var(--border-positive-subtle)',\n } as const;\n case 'warning':\n return {\n text: 'var(--content-warning-secondary)',\n bgSubtle: 'var(--background-warning-subtle)',\n bgOnSubtle: 'var(--background-warning-on-subtle)',\n borderSubtle: 'var(--border-warning-subtle)',\n } as const;\n case 'error':\n return {\n text: 'var(--content-negative-secondary)',\n bgSubtle: 'var(--background-negative-subtle)',\n bgOnSubtle: 'var(--background-negative-on-subtle)',\n borderSubtle: 'var(--border-negative-subtle)',\n } as const;\n case 'default':\n return {\n text: 'var(--content-primary)',\n bgSubtle: 'var(--background-neutral-subtle)',\n bgOnSubtle: 'var(--background-neutral-on-subtle)',\n borderSubtle: 'var(--border-neutral-subtle)',\n } as const;\n case 'info':\n default:\n return {\n text: 'var(--content-informative-secondary)',\n bgSubtle: 'var(--background-informative-subtle)',\n bgOnSubtle: 'var(--background-informative-on-subtle)',\n borderSubtle: 'var(--border-informative-subtle)',\n } as const;\n }\n}\n"],"mappings":"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"}