@rio-cloud/rio-uikit 2.3.0-beta.3 → 2.3.0

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 (83) hide show
  1. package/Table.js +10 -9
  2. package/TableNext.js +10 -9
  3. package/TableRowActionsDropdown.d.ts +2 -0
  4. package/TableRowActionsDropdown.js +5 -0
  5. package/TableRowActionsDropdown.js.map +1 -0
  6. package/components/dropdown/ButtonDropdown.d.ts +4 -0
  7. package/components/dropdown/ButtonDropdown.js +82 -80
  8. package/components/dropdown/ButtonDropdown.js.map +1 -1
  9. package/components/map/components/Map.js +199 -180
  10. package/components/map/components/Map.js.map +1 -1
  11. package/components/map/components/MapContext.d.ts +2 -0
  12. package/components/map/components/MapContext.js +6 -4
  13. package/components/map/components/MapContext.js.map +1 -1
  14. package/components/map/components/features/MapZoom.js +19 -19
  15. package/components/map/components/features/MapZoom.js.map +1 -1
  16. package/components/map/utils/mapTypes.d.ts +6 -0
  17. package/components/map/utils/mapTypes.js.map +1 -1
  18. package/components/map/utils/mapUtils.d.ts +2 -0
  19. package/components/map/utils/mapUtils.js +4 -0
  20. package/components/map/utils/mapUtils.js.map +1 -1
  21. package/components/table/Table.d.ts +3 -1
  22. package/components/table/Table.js +225 -205
  23. package/components/table/Table.js.map +1 -1
  24. package/components/table/Table.types.d.ts +49 -0
  25. package/components/table/TableExpandedRow.d.ts +4 -0
  26. package/components/table/TableExpandedRow.js +69 -66
  27. package/components/table/TableExpandedRow.js.map +1 -1
  28. package/components/table/TableGroupRow.d.ts +3 -1
  29. package/components/table/TableGroupRow.js +15 -14
  30. package/components/table/TableGroupRow.js.map +1 -1
  31. package/components/table/TableHeader.d.ts +1 -9
  32. package/components/table/TableHeader.js +83 -67
  33. package/components/table/TableHeader.js.map +1 -1
  34. package/components/table/TableRow.d.ts +7 -1
  35. package/components/table/TableRow.js +75 -72
  36. package/components/table/TableRow.js.map +1 -1
  37. package/components/table/TableRowActionsDropdown.d.ts +11 -0
  38. package/components/table/TableRowActionsDropdown.js +22 -0
  39. package/components/table/TableRowActionsDropdown.js.map +1 -0
  40. package/components/table/TableStickyRowButton.d.ts +25 -0
  41. package/components/table/TableStickyRowButton.js +32 -0
  42. package/components/table/TableStickyRowButton.js.map +1 -0
  43. package/components/table/TableToolbar.d.ts +24 -3
  44. package/components/table/TableToolbar.js +78 -37
  45. package/components/table/TableToolbar.js.map +1 -1
  46. package/components/table/TableViewToggles.js +5 -5
  47. package/components/table/TableViewToggles.js.map +1 -1
  48. package/components/table/context/TableInteractionContext.d.ts +3 -0
  49. package/components/table/context/TableInteractionContext.js.map +1 -1
  50. package/components/table/context/TableRenderContext.d.ts +1 -0
  51. package/components/table/context/TableRenderContext.js.map +1 -1
  52. package/components/table/layout/useMeasuredColumnMaxWidths.js +52 -54
  53. package/components/table/layout/useMeasuredColumnMaxWidths.js.map +1 -1
  54. package/components/table/layout/useTableLayout.d.ts +4 -1
  55. package/components/table/layout/useTableLayout.js +54 -48
  56. package/components/table/layout/useTableLayout.js.map +1 -1
  57. package/components/table/layout/useTableVirtualization.js +51 -56
  58. package/components/table/layout/useTableVirtualization.js.map +1 -1
  59. package/components/table/model/resolveResponsiveViewType.d.ts +2 -0
  60. package/components/table/model/resolveResponsiveViewType.js +27 -0
  61. package/components/table/model/resolveResponsiveViewType.js.map +1 -0
  62. package/components/table/render/header/TableHeaderSelectionCell.d.ts +1 -0
  63. package/components/table/render/header/TableHeaderSelectionCell.js +13 -12
  64. package/components/table/render/header/TableHeaderSelectionCell.js.map +1 -1
  65. package/components/table/runtime/useResponsiveResolvedViewType.d.ts +23 -0
  66. package/components/table/runtime/useResponsiveResolvedViewType.js +22 -0
  67. package/components/table/runtime/useResponsiveResolvedViewType.js.map +1 -0
  68. package/components/table/selection/useInternalTableSelectionState.d.ts +2 -0
  69. package/components/table/selection/useInternalTableSelectionState.js +27 -17
  70. package/components/table/selection/useInternalTableSelectionState.js.map +1 -1
  71. package/components/table/selection/useTableSelection.d.ts +5 -1
  72. package/components/table/selection/useTableSelection.js +37 -26
  73. package/components/table/selection/useTableSelection.js.map +1 -1
  74. package/components/table/shared/parsePixelSize.d.ts +2 -0
  75. package/components/table/shared/parsePixelSize.js +13 -0
  76. package/components/table/shared/parsePixelSize.js.map +1 -0
  77. package/hooks/useResizeObserver.d.ts +25 -6
  78. package/hooks/useResizeObserver.js +20 -18
  79. package/hooks/useResizeObserver.js.map +1 -1
  80. package/package.json +10 -10
  81. package/version.d.ts +1 -1
  82. package/version.js +2 -2
  83. package/version.js.map +1 -1
@@ -0,0 +1,32 @@
1
+ import { jsx as o } from "react/jsx-runtime";
2
+ import l from "../button/Button.js";
3
+ import s from "../../utils/classNames.js";
4
+ const u = (a) => {
5
+ const { active: t = !1, disabled: i = !1, onClick: r, className: e, ...n } = a;
6
+ return /* @__PURE__ */ o(
7
+ l,
8
+ {
9
+ ...n,
10
+ bsStyle: "muted",
11
+ bsSize: "sm",
12
+ iconOnly: !0,
13
+ active: t,
14
+ disabled: i,
15
+ className: s("table-sticky-row-button", e),
16
+ onClick: r,
17
+ children: /* @__PURE__ */ o(
18
+ "span",
19
+ {
20
+ className: s(
21
+ "rioglyph rioglyph-pushpin transition-all transition-ease-in-out transition-duration-01 transform-origin-center",
22
+ t ? "rotate-315" : "rotate-360"
23
+ )
24
+ }
25
+ )
26
+ }
27
+ );
28
+ };
29
+ export {
30
+ u as default
31
+ };
32
+ //# sourceMappingURL=TableStickyRowButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TableStickyRowButton.js","sources":["../../../src/components/table/TableStickyRowButton.tsx"],"sourcesContent":["import type { MouseEventHandler } from 'react';\n\nimport Button from '../button/Button';\nimport classNames from '../../utils/classNames';\n\nexport type TableStickyRowButtonProps = {\n /**\n * Controls whether the related row is currently sticky.\n *\n * @default false\n */\n active?: boolean;\n\n /**\n * Disables the sticky row button.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Callback triggered when the sticky row button is clicked.\n */\n onClick?: MouseEventHandler<HTMLButtonElement>;\n\n /**\n * Optional additional class names for the button element.\n */\n className?: string;\n};\n\nconst TableStickyRowButton = (props: TableStickyRowButtonProps) => {\n const { active = false, disabled = false, onClick, className, ...remainingProps } = props;\n\n return (\n <Button\n {...remainingProps}\n bsStyle='muted'\n bsSize='sm'\n iconOnly\n active={active}\n disabled={disabled}\n className={classNames('table-sticky-row-button', className)}\n onClick={onClick}\n >\n <span\n className={classNames(\n 'rioglyph rioglyph-pushpin transition-all transition-ease-in-out transition-duration-01 transform-origin-center',\n active ? 'rotate-315' : 'rotate-360'\n )}\n />\n </Button>\n );\n};\n\nexport default TableStickyRowButton;\n"],"names":["TableStickyRowButton","props","active","disabled","onClick","className","remainingProps","jsx","Button","classNames"],"mappings":";;;AA+BA,MAAMA,IAAuB,CAACC,MAAqC;AAC/D,QAAM,EAAE,QAAAC,IAAS,IAAO,UAAAC,IAAW,IAAO,SAAAC,GAAS,WAAAC,GAAW,GAAGC,EAAA,IAAmBL;AAEpF,SACI,gBAAAM;AAAA,IAACC;AAAA,IAAA;AAAA,MACI,GAAGF;AAAA,MACJ,SAAQ;AAAA,MACR,QAAO;AAAA,MACP,UAAQ;AAAA,MACR,QAAAJ;AAAA,MACA,UAAAC;AAAA,MACA,WAAWM,EAAW,2BAA2BJ,CAAS;AAAA,MAC1D,SAAAD;AAAA,MAEA,UAAA,gBAAAG;AAAA,QAAC;AAAA,QAAA;AAAA,UACG,WAAWE;AAAA,YACP;AAAA,YACAP,IAAS,eAAe;AAAA,UAAA;AAAA,QAC5B;AAAA,MAAA;AAAA,IACJ;AAAA,EAAA;AAGZ;"}
@@ -1,12 +1,33 @@
1
1
  import { PropsWithChildren } from 'react';
2
2
  import { default as TableToolbarColumn } from './TableToolbarColumn';
3
+ export { TableToolbarColumn };
4
+ export type { TableToolbarColumnHorizontalAlign, TableToolbarColumnProps, TableToolbarColumnVerticalAlign, } from './TableToolbarColumn';
3
5
  export type TableToolbarProps = {
4
6
  /**
5
7
  * Optional class names for the wrapper element.
6
8
  */
7
9
  className?: string;
10
+ /**
11
+ * Optional class names for the card that wraps collapsed toolbar controls
12
+ * in the compact mobile layout.
13
+ */
14
+ collapseCardClassName?: string;
15
+ /**
16
+ * Optional toolbar width in pixels at which the toolbar switches into its compact
17
+ * mobile/collapsible layout.
18
+ *
19
+ * @default 544
20
+ */
21
+ responsiveCollapseBreakpoint?: number;
22
+ /**
23
+ * Disables the compact mobile/collapsible toolbar layout.
24
+ *
25
+ * Use this as an escape hatch when a consuming service needs to keep the
26
+ * default wrapping toolbar behavior regardless of the available toolbar width.
27
+ *
28
+ * @default false
29
+ */
30
+ disableResponsiveCollapse?: boolean;
8
31
  };
9
- declare const TableToolbar: ({ className, children }: PropsWithChildren<TableToolbarProps>) => import("react/jsx-runtime").JSX.Element;
32
+ declare const TableToolbar: (props: PropsWithChildren<TableToolbarProps>) => import("react/jsx-runtime").JSX.Element;
10
33
  export default TableToolbar;
11
- export { TableToolbarColumn };
12
- export type { TableToolbarColumnHorizontalAlign, TableToolbarColumnProps, TableToolbarColumnVerticalAlign, } from './TableToolbarColumn';
@@ -1,52 +1,93 @@
1
- import { jsx as s, jsxs as T } from "react/jsx-runtime";
2
- import { useRef as f, useState as v, useLayoutEffect as x, Children as y, isValidElement as b, Fragment as z } from "react";
3
- import N from "../../hooks/useResizeObserver.js";
4
- import p from "../../utils/classNames.js";
5
- import w from "./TableToolbarColumn.js";
6
- const A = (o) => b(o) && o.type === w, h = (o) => {
7
- const t = [];
8
- for (const e of y.toArray(o)) {
9
- if (b(e) && e.type === z) {
10
- const r = h(e.props.children);
11
- if (!r)
1
+ import { jsx as o, jsxs as c, Fragment as k } from "react/jsx-runtime";
2
+ import { useRef as C, useState as x, useLayoutEffect as D, useEffect as G, Children as w, isValidElement as N, Fragment as P } from "react";
3
+ import I from "../../hooks/useResizeObserver.js";
4
+ import K from "../../hooks/useMergeRefs.js";
5
+ import m from "../../utils/classNames.js";
6
+ import U from "../button/ToggleButton.js";
7
+ import V from "../collapse/Collapse.js";
8
+ import $ from "../card/Card.js";
9
+ import q from "./TableSearch.js";
10
+ import J from "./TableToolbarColumn.js";
11
+ const Q = 544, X = (r) => N(r) && r.type === J, B = (r) => {
12
+ const e = [];
13
+ for (const l of w.toArray(r)) {
14
+ if (N(l) && l.type === P) {
15
+ const t = B(l.props.children);
16
+ if (!t)
12
17
  return null;
13
- t.push(...r);
18
+ e.push(...t);
14
19
  continue;
15
20
  }
16
- if (!A(e))
21
+ if (!X(l))
17
22
  return null;
18
- t.push(e);
23
+ e.push(l);
19
24
  }
20
- return t;
21
- }, u = (o) => {
22
- if (!o)
25
+ return e;
26
+ }, F = (r, e) => w.toArray(r).some((l) => N(l) ? l.type === e ? !0 : F(l.props.children, e) : !1), v = (r) => {
27
+ if (!r)
23
28
  return !1;
24
- const t = Array.from(o.children);
25
- if (t.length < 2)
29
+ const e = Array.from(r.children);
30
+ if (e.length < 2)
26
31
  return !1;
27
- const e = (t[0]?.offsetTop ?? 0) + (t[0]?.offsetHeight ?? 0);
28
- return t.some((r) => r.offsetTop + r.offsetHeight !== e);
29
- }, j = ({ className: o, children: t }) => {
30
- const e = f(null), r = f(null), c = f(null), [g, d] = v(!1), [m, , { inlineSize: C }] = N(), n = h(t), a = (n ?? []).filter((l) => l.props.horizontalAlign !== "right"), i = (n ?? []).filter((l) => l.props.horizontalAlign === "right");
31
- return x(() => {
32
- const l = e.current;
33
- l?.classList.add("table-toolbar-measuring");
34
- const R = u(m.current) || u(r.current) || u(c.current);
35
- l?.classList.remove("table-toolbar-measuring"), d(R);
36
- }, [t, a.length, i.length, C]), n?.length ? /* @__PURE__ */ s(
32
+ const l = (e[0]?.offsetTop ?? 0) + (e[0]?.offsetHeight ?? 0);
33
+ return e.some((t) => t.offsetTop + t.offsetHeight !== l);
34
+ }, ie = (r) => {
35
+ const {
36
+ className: e,
37
+ collapseCardClassName: l,
38
+ children: t,
39
+ responsiveCollapseBreakpoint: H = Q,
40
+ disableResponsiveCollapse: _ = !1
41
+ } = r, R = C(null), T = C(null), y = C(null), [M, S] = x(!1), [f, A] = x(!1), [W, , { inlineSize: z }] = I(), [p, , { inlineSize: j }] = I(), L = K(R, W), i = !_ && z !== void 0 && z <= H, u = B(t), s = (u ?? []).filter((a) => a.props.horizontalAlign !== "right"), n = (u ?? []).filter((a) => a.props.horizontalAlign === "right"), d = n.findIndex(
42
+ (a) => F(a.props.children, q)
43
+ ), h = d >= 0 ? n[d] : void 0, E = h ? n.filter((a, g) => g !== d) : n, b = i && E.length > 0, O = b && /* @__PURE__ */ o("div", { className: "table-toolbar-mobile-toggle", children: /* @__PURE__ */ o(
44
+ U,
45
+ {
46
+ active: f,
47
+ "aria-label": f ? "Hide toolbar filters" : "Show toolbar filters",
48
+ bsStyle: "default",
49
+ iconName: "rioglyph-option-horizontal",
50
+ iconOnly: !0,
51
+ onClick: A
52
+ }
53
+ ) });
54
+ return D(() => {
55
+ if (i) {
56
+ S(!1);
57
+ return;
58
+ }
59
+ const a = R.current;
60
+ a?.classList.add("table-toolbar-measuring");
61
+ const g = v(p.current) || v(T.current) || v(y.current);
62
+ a?.classList.remove("table-toolbar-measuring"), S(g);
63
+ }, [t, i, s.length, n.length, j]), G(() => {
64
+ (!i || !b) && A(!1);
65
+ }, [b, i]), u?.length ? i ? /* @__PURE__ */ o("div", { className: m("table-toolbar", "table-toolbar-mobile", e), ref: L, children: /* @__PURE__ */ c("div", { className: "table-toolbar-container table-toolbar-container-mobile", ref: p, children: [
66
+ h ? /* @__PURE__ */ c(k, { children: [
67
+ s.length > 0 && /* @__PURE__ */ o("div", { className: "table-toolbar-mobile-primary", children: /* @__PURE__ */ o("div", { className: "table-toolbar-group-left table-toolbar-group-left-mobile", children: s }) }),
68
+ /* @__PURE__ */ c("div", { className: "table-toolbar-mobile-search-row", children: [
69
+ /* @__PURE__ */ o("div", { className: "table-toolbar-mobile-search", children: h }),
70
+ O
71
+ ] })
72
+ ] }) : /* @__PURE__ */ c("div", { className: "table-toolbar-mobile-primary", children: [
73
+ s.length > 0 && /* @__PURE__ */ o("div", { className: "table-toolbar-group-left table-toolbar-group-left-mobile", children: s }),
74
+ O
75
+ ] }),
76
+ b && /* @__PURE__ */ o(V, { open: f, timeout: 220, children: /* @__PURE__ */ o($, { className: m("table-toolbar-mobile-collapse-card", l), children: /* @__PURE__ */ o("div", { className: "table-toolbar-mobile-collapse", children: E }) }) })
77
+ ] }) }) : /* @__PURE__ */ o(
37
78
  "div",
38
79
  {
39
- className: p("table-toolbar", g && "table-toolbar-has-wrap", o),
40
- ref: e,
41
- children: /* @__PURE__ */ T("div", { className: "table-toolbar-container", ref: m, children: [
42
- a.length > 0 && /* @__PURE__ */ s("div", { className: "table-toolbar-group-left", ref: r, children: a }),
43
- i.length > 0 && /* @__PURE__ */ s("div", { className: "table-toolbar-group-right", ref: c, children: i })
80
+ className: m("table-toolbar", M && "table-toolbar-has-wrap", e),
81
+ ref: L,
82
+ children: /* @__PURE__ */ c("div", { className: "table-toolbar-container", ref: p, children: [
83
+ s.length > 0 && /* @__PURE__ */ o("div", { className: "table-toolbar-group-left", ref: T, children: s }),
84
+ n.length > 0 && /* @__PURE__ */ o("div", { className: "table-toolbar-group-right", ref: y, children: n })
44
85
  ] })
45
86
  }
46
- ) : /* @__PURE__ */ s("div", { className: p("table-toolbar", o), children: t });
87
+ ) : /* @__PURE__ */ o("div", { className: m("table-toolbar", e), children: t });
47
88
  };
48
89
  export {
49
- w as TableToolbarColumn,
50
- j as default
90
+ J as TableToolbarColumn,
91
+ ie as default
51
92
  };
52
93
  //# sourceMappingURL=TableToolbar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TableToolbar.js","sources":["../../../src/components/table/TableToolbar.tsx"],"sourcesContent":["import {\n Children,\n Fragment,\n isValidElement,\n useLayoutEffect,\n useRef,\n useState,\n type PropsWithChildren,\n type ReactElement,\n type ReactNode,\n} from 'react';\n\nimport useResizeObserver from '../../hooks/useResizeObserver';\nimport classNames from '../../utils/classNames';\nimport TableToolbarColumn, { type TableToolbarColumnProps } from './TableToolbarColumn';\n\nexport type TableToolbarProps = {\n /**\n * Optional class names for the wrapper element.\n */\n className?: string;\n};\n\ntype TableToolbarColumnElement = ReactElement<PropsWithChildren<TableToolbarColumnProps>, typeof TableToolbarColumn>;\n\nconst isTableToolbarColumnElement = (child: ReactNode): child is TableToolbarColumnElement =>\n isValidElement(child) && child.type === TableToolbarColumn;\n\nconst collectToolbarColumns = (children: ReactNode): TableToolbarColumnElement[] | null => {\n const columns: TableToolbarColumnElement[] = [];\n\n for (const child of Children.toArray(children)) {\n if (isValidElement(child) && child.type === Fragment) {\n const fragmentColumns = collectToolbarColumns(child.props.children);\n\n if (!fragmentColumns) {\n return null;\n }\n\n columns.push(...fragmentColumns);\n continue;\n }\n\n if (!isTableToolbarColumnElement(child)) {\n return null;\n }\n\n columns.push(child);\n }\n\n return columns;\n};\n\nconst hasWrappedFlexItems = (containerElement: HTMLDivElement | null) => {\n if (!containerElement) {\n return false;\n }\n\n const itemElements = Array.from(containerElement.children) as HTMLElement[];\n\n if (itemElements.length < 2) {\n return false;\n }\n\n const firstLineBottom = (itemElements[0]?.offsetTop ?? 0) + (itemElements[0]?.offsetHeight ?? 0);\n\n return itemElements.some(itemElement => itemElement.offsetTop + itemElement.offsetHeight !== firstLineBottom);\n};\n\nconst TableToolbar = ({ className, children }: PropsWithChildren<TableToolbarProps>) => {\n const toolbarRef = useRef<HTMLDivElement | null>(null);\n const leftGroupRef = useRef<HTMLDivElement | null>(null);\n const rightGroupRef = useRef<HTMLDivElement | null>(null);\n\n const [hasWrappedRows, setHasWrappedRows] = useState(false);\n\n const [toolbarContainerRef, , { inlineSize: toolbarInlineSize }] = useResizeObserver<HTMLDivElement>();\n\n const toolbarColumns = collectToolbarColumns(children);\n\n const leftColumns = (toolbarColumns ?? []).filter(column => column.props.horizontalAlign !== 'right');\n const rightColumns = (toolbarColumns ?? []).filter(column => column.props.horizontalAlign === 'right');\n\n useLayoutEffect(() => {\n const toolbarElement = toolbarRef.current;\n\n toolbarElement?.classList.add('table-toolbar-measuring');\n\n const nextHasWrappedRows =\n hasWrappedFlexItems(toolbarContainerRef.current) ||\n hasWrappedFlexItems(leftGroupRef.current) ||\n hasWrappedFlexItems(rightGroupRef.current);\n\n toolbarElement?.classList.remove('table-toolbar-measuring');\n\n setHasWrappedRows(nextHasWrappedRows);\n }, [children, leftColumns.length, rightColumns.length, toolbarInlineSize]);\n\n if (!toolbarColumns?.length) {\n return <div className={classNames('table-toolbar', className)}>{children}</div>;\n }\n\n return (\n <div\n className={classNames('table-toolbar', hasWrappedRows && 'table-toolbar-has-wrap', className)}\n ref={toolbarRef}\n >\n <div className='table-toolbar-container' ref={toolbarContainerRef}>\n {leftColumns.length > 0 && (\n <div className='table-toolbar-group-left' ref={leftGroupRef}>\n {leftColumns}\n </div>\n )}\n {rightColumns.length > 0 && (\n <div className='table-toolbar-group-right' ref={rightGroupRef}>\n {rightColumns}\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default TableToolbar;\nexport { TableToolbarColumn };\nexport type {\n TableToolbarColumnHorizontalAlign,\n TableToolbarColumnProps,\n TableToolbarColumnVerticalAlign,\n} from './TableToolbarColumn';\n"],"names":["isTableToolbarColumnElement","child","isValidElement","TableToolbarColumn","collectToolbarColumns","children","columns","Children","Fragment","fragmentColumns","hasWrappedFlexItems","containerElement","itemElements","firstLineBottom","itemElement","TableToolbar","className","toolbarRef","useRef","leftGroupRef","rightGroupRef","hasWrappedRows","setHasWrappedRows","useState","toolbarContainerRef","toolbarInlineSize","useResizeObserver","toolbarColumns","leftColumns","column","rightColumns","useLayoutEffect","toolbarElement","nextHasWrappedRows","jsx","classNames","jsxs"],"mappings":";;;;;AAyBA,MAAMA,IAA8B,CAACC,MACjCC,EAAeD,CAAK,KAAKA,EAAM,SAASE,GAEtCC,IAAwB,CAACC,MAA4D;AACvF,QAAMC,IAAuC,CAAA;AAE7C,aAAWL,KAASM,EAAS,QAAQF,CAAQ,GAAG;AAC5C,QAAIH,EAAeD,CAAK,KAAKA,EAAM,SAASO,GAAU;AAClD,YAAMC,IAAkBL,EAAsBH,EAAM,MAAM,QAAQ;AAElE,UAAI,CAACQ;AACD,eAAO;AAGX,MAAAH,EAAQ,KAAK,GAAGG,CAAe;AAC/B;AAAA,IACJ;AAEA,QAAI,CAACT,EAA4BC,CAAK;AAClC,aAAO;AAGX,IAAAK,EAAQ,KAAKL,CAAK;AAAA,EACtB;AAEA,SAAOK;AACX,GAEMI,IAAsB,CAACC,MAA4C;AACrE,MAAI,CAACA;AACD,WAAO;AAGX,QAAMC,IAAe,MAAM,KAAKD,EAAiB,QAAQ;AAEzD,MAAIC,EAAa,SAAS;AACtB,WAAO;AAGX,QAAMC,KAAmBD,EAAa,CAAC,GAAG,aAAa,MAAMA,EAAa,CAAC,GAAG,gBAAgB;AAE9F,SAAOA,EAAa,KAAK,CAAAE,MAAeA,EAAY,YAAYA,EAAY,iBAAiBD,CAAe;AAChH,GAEME,IAAe,CAAC,EAAE,WAAAC,GAAW,UAAAX,QAAqD;AACpF,QAAMY,IAAaC,EAA8B,IAAI,GAC/CC,IAAeD,EAA8B,IAAI,GACjDE,IAAgBF,EAA8B,IAAI,GAElD,CAACG,GAAgBC,CAAiB,IAAIC,EAAS,EAAK,GAEpD,CAACC,KAAuB,EAAE,YAAYC,EAAA,CAAmB,IAAIC,EAAA,GAE7DC,IAAiBvB,EAAsBC,CAAQ,GAE/CuB,KAAeD,KAAkB,CAAA,GAAI,OAAO,CAAAE,MAAUA,EAAO,MAAM,oBAAoB,OAAO,GAC9FC,KAAgBH,KAAkB,CAAA,GAAI,OAAO,CAAAE,MAAUA,EAAO,MAAM,oBAAoB,OAAO;AAiBrG,SAfAE,EAAgB,MAAM;AAClB,UAAMC,IAAiBf,EAAW;AAElC,IAAAe,GAAgB,UAAU,IAAI,yBAAyB;AAEvD,UAAMC,IACFvB,EAAoBc,EAAoB,OAAO,KAC/Cd,EAAoBS,EAAa,OAAO,KACxCT,EAAoBU,EAAc,OAAO;AAE7C,IAAAY,GAAgB,UAAU,OAAO,yBAAyB,GAE1DV,EAAkBW,CAAkB;AAAA,EACxC,GAAG,CAAC5B,GAAUuB,EAAY,QAAQE,EAAa,QAAQL,CAAiB,CAAC,GAEpEE,GAAgB,SAKjB,gBAAAO;AAAA,IAAC;AAAA,IAAA;AAAA,MACG,WAAWC,EAAW,iBAAiBd,KAAkB,0BAA0BL,CAAS;AAAA,MAC5F,KAAKC;AAAA,MAEL,UAAA,gBAAAmB,EAAC,OAAA,EAAI,WAAU,2BAA0B,KAAKZ,GACzC,UAAA;AAAA,QAAAI,EAAY,SAAS,KAClB,gBAAAM,EAAC,OAAA,EAAI,WAAU,4BAA2B,KAAKf,GAC1C,UAAAS,EAAA,CACL;AAAA,QAEHE,EAAa,SAAS,KACnB,gBAAAI,EAAC,SAAI,WAAU,6BAA4B,KAAKd,GAC3C,UAAAU,EAAA,CACL;AAAA,MAAA,EAAA,CAER;AAAA,IAAA;AAAA,EAAA,sBAnBI,OAAA,EAAI,WAAWK,EAAW,iBAAiBnB,CAAS,GAAI,UAAAX,GAAS;AAsBjF;"}
1
+ {"version":3,"file":"TableToolbar.js","sources":["../../../src/components/table/TableToolbar.tsx"],"sourcesContent":["import {\n Children,\n Fragment,\n useEffect,\n isValidElement,\n useLayoutEffect,\n useRef,\n useState,\n type PropsWithChildren,\n type ReactElement,\n type ReactNode,\n} from 'react';\n\nimport useResizeObserver from '../../useResizeObserver';\nimport useMergeRefs from '../../hooks/useMergeRefs';\nimport classNames from '../../utils/classNames';\nimport ToggleButton from '../button/ToggleButton';\nimport Collapse from '../collapse/Collapse';\nimport Card from '../card/Card';\nimport TableSearch from './TableSearch';\nimport TableToolbarColumn, { type TableToolbarColumnProps } from './TableToolbarColumn';\n\nexport { TableToolbarColumn };\nexport type {\n TableToolbarColumnHorizontalAlign,\n TableToolbarColumnProps,\n TableToolbarColumnVerticalAlign,\n} from './TableToolbarColumn';\n\n// Switch the toolbar into the compact mobile layout,\n// based on the available toolbar width instead of the overall viewport width.\nconst DEFAULT_TABLE_TOOLBAR_COLLAPSE_BREAKPOINT = 544;\n\nexport type TableToolbarProps = {\n /**\n * Optional class names for the wrapper element.\n */\n className?: string;\n\n /**\n * Optional class names for the card that wraps collapsed toolbar controls\n * in the compact mobile layout.\n */\n collapseCardClassName?: string;\n\n /**\n * Optional toolbar width in pixels at which the toolbar switches into its compact\n * mobile/collapsible layout.\n *\n * @default 544\n */\n responsiveCollapseBreakpoint?: number;\n\n /**\n * Disables the compact mobile/collapsible toolbar layout.\n *\n * Use this as an escape hatch when a consuming service needs to keep the\n * default wrapping toolbar behavior regardless of the available toolbar width.\n *\n * @default false\n */\n disableResponsiveCollapse?: boolean;\n};\n\ntype TableToolbarColumnElement = ReactElement<PropsWithChildren<TableToolbarColumnProps>, typeof TableToolbarColumn>;\n\nconst isTableToolbarColumnElement = (child: ReactNode): child is TableToolbarColumnElement =>\n isValidElement(child) && child.type === TableToolbarColumn;\n\nconst collectToolbarColumns = (children: ReactNode): TableToolbarColumnElement[] | null => {\n const columns: TableToolbarColumnElement[] = [];\n\n for (const child of Children.toArray(children)) {\n if (isValidElement(child) && child.type === Fragment) {\n const fragmentColumns = collectToolbarColumns(child.props.children);\n\n if (!fragmentColumns) {\n return null;\n }\n\n columns.push(...fragmentColumns);\n continue;\n }\n\n if (!isTableToolbarColumnElement(child)) {\n return null;\n }\n\n columns.push(child);\n }\n\n return columns;\n};\n\nconst hasDescendantType = (node: ReactNode, componentType: unknown): boolean =>\n Children.toArray(node).some(child => {\n if (!isValidElement(child)) {\n return false;\n }\n\n if (child.type === componentType) {\n return true;\n }\n\n return hasDescendantType(child.props.children, componentType);\n });\n\nconst hasWrappedFlexItems = (containerElement: HTMLDivElement | null) => {\n if (!containerElement) {\n return false;\n }\n\n const itemElements = Array.from(containerElement.children) as HTMLElement[];\n\n if (itemElements.length < 2) {\n return false;\n }\n\n const firstLineBottom = (itemElements[0]?.offsetTop ?? 0) + (itemElements[0]?.offsetHeight ?? 0);\n\n return itemElements.some(itemElement => itemElement.offsetTop + itemElement.offsetHeight !== firstLineBottom);\n};\n\nconst TableToolbar = (props: PropsWithChildren<TableToolbarProps>) => {\n const {\n className,\n collapseCardClassName,\n children,\n responsiveCollapseBreakpoint = DEFAULT_TABLE_TOOLBAR_COLLAPSE_BREAKPOINT,\n disableResponsiveCollapse = false,\n } = props;\n\n const toolbarRef = useRef<HTMLDivElement | null>(null);\n const leftGroupRef = useRef<HTMLDivElement | null>(null);\n const rightGroupRef = useRef<HTMLDivElement | null>(null);\n\n const [hasWrappedRows, setHasWrappedRows] = useState(false);\n const [isMobileCollapseOpen, setIsMobileCollapseOpen] = useState(false);\n\n const [toolbarSizeRef, , { inlineSize: toolbarInlineSize }] = useResizeObserver<HTMLDivElement>();\n const [toolbarContainerRef, , { inlineSize: toolbarContainerInlineSize }] = useResizeObserver<HTMLDivElement>();\n const mergedToolbarRefs = useMergeRefs(toolbarRef, toolbarSizeRef);\n\n const isSmallScreen =\n !disableResponsiveCollapse &&\n toolbarInlineSize !== undefined &&\n toolbarInlineSize <= responsiveCollapseBreakpoint;\n\n const toolbarColumns = collectToolbarColumns(children);\n\n const leftColumns = (toolbarColumns ?? []).filter(column => column.props.horizontalAlign !== 'right');\n const rightColumns = (toolbarColumns ?? []).filter(column => column.props.horizontalAlign === 'right');\n\n const searchRightColumnIndex = rightColumns.findIndex(column =>\n hasDescendantType(column.props.children, TableSearch)\n );\n\n const searchRightColumn = searchRightColumnIndex >= 0 ? rightColumns[searchRightColumnIndex] : undefined;\n\n const mobileCollapsedRightColumns = searchRightColumn\n ? rightColumns.filter((_, index) => index !== searchRightColumnIndex)\n : rightColumns;\n\n const hasMobileCollapseToggle = isSmallScreen && mobileCollapsedRightColumns.length > 0;\n\n const mobileCollapseToggle = hasMobileCollapseToggle && (\n <div className='table-toolbar-mobile-toggle'>\n <ToggleButton\n active={isMobileCollapseOpen}\n aria-label={isMobileCollapseOpen ? 'Hide toolbar filters' : 'Show toolbar filters'}\n bsStyle='default'\n iconName={'rioglyph-option-horizontal'}\n iconOnly\n onClick={setIsMobileCollapseOpen}\n />\n </div>\n );\n\n useLayoutEffect(() => {\n if (isSmallScreen) {\n setHasWrappedRows(false);\n return;\n }\n\n const toolbarElement = toolbarRef.current;\n\n toolbarElement?.classList.add('table-toolbar-measuring');\n\n const nextHasWrappedRows =\n hasWrappedFlexItems(toolbarContainerRef.current) ||\n hasWrappedFlexItems(leftGroupRef.current) ||\n hasWrappedFlexItems(rightGroupRef.current);\n\n toolbarElement?.classList.remove('table-toolbar-measuring');\n\n setHasWrappedRows(nextHasWrappedRows);\n }, [children, isSmallScreen, leftColumns.length, rightColumns.length, toolbarContainerInlineSize]);\n\n useEffect(() => {\n if (!isSmallScreen || !hasMobileCollapseToggle) {\n setIsMobileCollapseOpen(false);\n }\n }, [hasMobileCollapseToggle, isSmallScreen]);\n\n if (!toolbarColumns?.length) {\n return <div className={classNames('table-toolbar', className)}>{children}</div>;\n }\n\n if (isSmallScreen) {\n return (\n <div className={classNames('table-toolbar', 'table-toolbar-mobile', className)} ref={mergedToolbarRefs}>\n <div className='table-toolbar-container table-toolbar-container-mobile' ref={toolbarContainerRef}>\n {searchRightColumn ? (\n <>\n {leftColumns.length > 0 && (\n <div className='table-toolbar-mobile-primary'>\n <div className='table-toolbar-group-left table-toolbar-group-left-mobile'>\n {leftColumns}\n </div>\n </div>\n )}\n <div className='table-toolbar-mobile-search-row'>\n <div className='table-toolbar-mobile-search'>{searchRightColumn}</div>\n {mobileCollapseToggle}\n </div>\n </>\n ) : (\n <div className='table-toolbar-mobile-primary'>\n {leftColumns.length > 0 && (\n <div className='table-toolbar-group-left table-toolbar-group-left-mobile'>\n {leftColumns}\n </div>\n )}\n {mobileCollapseToggle}\n </div>\n )}\n\n {hasMobileCollapseToggle && (\n <Collapse open={isMobileCollapseOpen} timeout={220}>\n <Card className={classNames('table-toolbar-mobile-collapse-card', collapseCardClassName)}>\n <div className='table-toolbar-mobile-collapse'>{mobileCollapsedRightColumns}</div>\n </Card>\n </Collapse>\n )}\n </div>\n </div>\n );\n }\n\n return (\n <div\n className={classNames('table-toolbar', hasWrappedRows && 'table-toolbar-has-wrap', className)}\n ref={mergedToolbarRefs}\n >\n <div className='table-toolbar-container' ref={toolbarContainerRef}>\n {leftColumns.length > 0 && (\n <div className='table-toolbar-group-left' ref={leftGroupRef}>\n {leftColumns}\n </div>\n )}\n {rightColumns.length > 0 && (\n <div className='table-toolbar-group-right' ref={rightGroupRef}>\n {rightColumns}\n </div>\n )}\n </div>\n </div>\n );\n};\n\nexport default TableToolbar;\n"],"names":["DEFAULT_TABLE_TOOLBAR_COLLAPSE_BREAKPOINT","isTableToolbarColumnElement","child","isValidElement","TableToolbarColumn","collectToolbarColumns","children","columns","Children","Fragment","fragmentColumns","hasDescendantType","node","componentType","hasWrappedFlexItems","containerElement","itemElements","firstLineBottom","itemElement","TableToolbar","props","className","collapseCardClassName","responsiveCollapseBreakpoint","disableResponsiveCollapse","toolbarRef","useRef","leftGroupRef","rightGroupRef","hasWrappedRows","setHasWrappedRows","useState","isMobileCollapseOpen","setIsMobileCollapseOpen","toolbarSizeRef","toolbarInlineSize","useResizeObserver","toolbarContainerRef","toolbarContainerInlineSize","mergedToolbarRefs","useMergeRefs","isSmallScreen","toolbarColumns","leftColumns","column","rightColumns","searchRightColumnIndex","TableSearch","searchRightColumn","mobileCollapsedRightColumns","_","index","hasMobileCollapseToggle","mobileCollapseToggle","jsx","ToggleButton","useLayoutEffect","toolbarElement","nextHasWrappedRows","useEffect","classNames","jsxs","Collapse","Card"],"mappings":"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"}
@@ -34,15 +34,15 @@ const o = {
34
34
  label: d ?? m ?? "",
35
35
  icon: /* @__PURE__ */ i("span", { className: `rioglyph ${o.TABLE}` })
36
36
  },
37
- {
38
- id: "SINGLE_CARD",
39
- label: C ?? w ?? "",
40
- icon: /* @__PURE__ */ i("span", { className: `rioglyph ${o.SINGLE_CARD}` })
41
- },
42
37
  {
43
38
  id: "MULTI_CARDS",
44
39
  label: g ?? L ?? "",
45
40
  icon: /* @__PURE__ */ i("span", { className: `rioglyph ${o.MULTI_CARDS}` })
41
+ },
42
+ {
43
+ id: "SINGLE_CARD",
44
+ label: C ?? w ?? "",
45
+ icon: /* @__PURE__ */ i("span", { className: `rioglyph ${o.SINGLE_CARD}` })
46
46
  }
47
47
  ], A = n.filter((e) => !T.includes(e.id)), _ = n.some((e) => e.label), h = S("TableViewToggles", a && a);
48
48
  return /* @__PURE__ */ i("div", { ...I, className: h, children: /* @__PURE__ */ i("div", { className: "form-group margin-bottom-0", children: /* @__PURE__ */ i(
@@ -1 +1 @@
1
- {"version":3,"file":"TableViewToggles.js","sources":["../../../src/components/table/TableViewToggles.tsx"],"sourcesContent":["import { type ReactNode, useEffect, useState } from 'react';\nimport { noop } from 'es-toolkit/compat';\n\nimport classNames from '../../utils/classNames';\nimport Select, { type SelectOption } from '../selects/Select';\n\nconst typeIcons: Record<TableViewTogglesViewType, string> = {\n TABLE: 'rioglyph-table-view',\n SINGLE_CARD: 'rioglyph-th-list',\n MULTI_CARDS: 'rioglyph-split-view',\n};\n\ntype TableViewToggleOption = SelectOption & {\n id: TableViewTogglesViewType;\n};\n\nexport type TableViewTogglesViewType = 'SINGLE_CARD' | 'MULTI_CARDS' | 'TABLE';\n\nexport type TableViewTogglesProps = {\n /**\n * The current viewType for controlling the TablesViewToggles component.\n *\n * Possible values are:\n *\n * - `'SINGLE_CARD'`\n * - `'MULTI_CARDS'`\n * - `'TABLE'`\n * - `TableViewToggles.VIEW_TYPE_TABLE`\n * - `TableViewToggles.VIEW_TYPE_SINGLE_CARD`\n * - `TableViewToggles.VIEW_TYPE_MULTI_CARDS`\n */\n viewType?: TableViewTogglesViewType;\n\n /**\n * Defines the initial viewType (when viewType is not controlled from the outside).\n *\n * Possible values are:\n *\n * - `'SINGLE_CARD'`\n * - `'MULTI_CARDS'`\n * - `'TABLE'`\n * - `TableViewToggles.VIEW_TYPE_TABLE`\n * - `TableViewToggles.VIEW_TYPE_SINGLE_CARD`\n * - `TableViewToggles.VIEW_TYPE_MULTI_CARDS`\n *\n * @default TableViewToggles.VIEW_TYPE_TABLE\n */\n initialViewType?: TableViewTogglesViewType;\n\n /**\n * Defines the view types which shall not be supported and are omitted.\n *\n * @default []\n */\n disabledViewTypes?: TableViewTogglesViewType[];\n\n /**\n * Callback function for when the user wants to change the viewType.\n *\n * Receives the new type as an argument.\n *\n * @param viewType The new viewType selected by the user.\n */\n onViewTypeChange: (viewType: TableViewTogglesViewType) => void;\n\n /**\n * Optional tooltip content for table view button.\n *\n * @deprecated Use `tableViewLabel` instead.\n */\n tableViewTooltipContent?: string | ReactNode;\n\n /**\n * Optional label content for the table view select item.\n */\n tableViewLabel?: string | ReactNode;\n\n /**\n * Optional tooltip content for single card view button.\n *\n * @deprecated Use `singleCardViewLabel` instead.\n */\n singleCardViewTooltipContent?: string | ReactNode;\n\n /**\n * Optional label content for the single card view select item.\n */\n singleCardViewLabel?: string | ReactNode;\n\n /**\n * Optional tooltip content for multi card view button.\n *\n * @deprecated Use `multiCardsViewLabel` instead.\n */\n multiCardsViewTooltipContent?: string | ReactNode;\n\n /**\n * Optional label content for the multi cards view select item.\n */\n multiCardsViewLabel?: string | ReactNode;\n\n /**\n * Disables all buttons.\n *\n * This means the buttons cannot be clicked. Used when disabling toolbar buttons during loading state or when the\n * corresponding table is empty.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Optional class names for the wrapper element.\n */\n className?: string;\n};\n\nconst TableViewToggles = (props: TableViewTogglesProps) => {\n const {\n viewType,\n initialViewType = 'TABLE',\n disabledViewTypes = [],\n onViewTypeChange = noop,\n tableViewTooltipContent,\n tableViewLabel,\n singleCardViewTooltipContent,\n singleCardViewLabel,\n multiCardsViewTooltipContent,\n multiCardsViewLabel,\n disabled = false,\n className,\n ...remainingProps\n } = props;\n\n const [internalViewType, setInternalViewType] = useState(initialViewType);\n\n // update internal state when external state changes - controlled component case\n useEffect(() => {\n if (viewType) {\n setInternalViewType(viewType);\n }\n }, [viewType]);\n\n const setViewType = (vt: TableViewTogglesViewType) => {\n setInternalViewType(vt);\n onViewTypeChange(vt);\n };\n\n const allOptions: TableViewToggleOption[] = [\n {\n id: 'TABLE',\n label: tableViewLabel ?? tableViewTooltipContent ?? '',\n icon: <span className={`rioglyph ${typeIcons.TABLE}`} />,\n },\n {\n id: 'SINGLE_CARD',\n label: singleCardViewLabel ?? singleCardViewTooltipContent ?? '',\n icon: <span className={`rioglyph ${typeIcons.SINGLE_CARD}`} />,\n },\n {\n id: 'MULTI_CARDS',\n label: multiCardsViewLabel ?? multiCardsViewTooltipContent ?? '',\n icon: <span className={`rioglyph ${typeIcons.MULTI_CARDS}`} />,\n },\n ];\n\n const options = allOptions.filter(option => !disabledViewTypes.includes(option.id));\n const hasOptionLabels = allOptions.some(option => option.label);\n\n const wrapperClassNames = classNames('TableViewToggles', className && className);\n\n return (\n <div {...remainingProps} className={wrapperClassNames}>\n <div className='form-group margin-bottom-0'>\n <Select\n options={options}\n value={[internalViewType]}\n onChange={item => item && setViewType(item.id as TableViewTogglesViewType)}\n disabled={disabled}\n showSelectedItemIcon\n pullRight\n dropdownClassName={!hasOptionLabels ? 'width-auto' : undefined}\n />\n </div>\n </div>\n );\n};\n\n// Don't export values as string but as a distinct union type\nTableViewToggles.VIEW_TYPE_TABLE = 'TABLE' as TableViewTogglesViewType;\nTableViewToggles.VIEW_TYPE_SINGLE_CARD = 'SINGLE_CARD' as TableViewTogglesViewType;\nTableViewToggles.VIEW_TYPE_MULTI_CARDS = 'MULTI_CARDS' as TableViewTogglesViewType;\n\nexport default TableViewToggles;\n"],"names":["typeIcons","TableViewToggles","props","viewType","initialViewType","disabledViewTypes","onViewTypeChange","noop","tableViewTooltipContent","tableViewLabel","singleCardViewTooltipContent","singleCardViewLabel","multiCardsViewTooltipContent","multiCardsViewLabel","disabled","className","remainingProps","internalViewType","setInternalViewType","useState","useEffect","setViewType","vt","allOptions","jsx","options","option","hasOptionLabels","wrapperClassNames","classNames","Select","item"],"mappings":";;;;;AAMA,MAAMA,IAAsD;AAAA,EACxD,OAAO;AAAA,EACP,aAAa;AAAA,EACb,aAAa;AACjB,GA2GMC,IAAmB,CAACC,MAAiC;AACvD,QAAM;AAAA,IACF,UAAAC;AAAA,IACA,iBAAAC,IAAkB;AAAA,IAClB,mBAAAC,IAAoB,CAAA;AAAA,IACpB,kBAAAC,IAAmBC;AAAA,IACnB,yBAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,8BAAAC;AAAA,IACA,qBAAAC;AAAA,IACA,8BAAAC;AAAA,IACA,qBAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,WAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,IACHd,GAEE,CAACe,GAAkBC,CAAmB,IAAIC,EAASf,CAAe;AAGxE,EAAAgB,EAAU,MAAM;AACZ,IAAIjB,KACAe,EAAoBf,CAAQ;AAAA,EAEpC,GAAG,CAACA,CAAQ,CAAC;AAEb,QAAMkB,IAAc,CAACC,MAAiC;AAClD,IAAAJ,EAAoBI,CAAE,GACtBhB,EAAiBgB,CAAE;AAAA,EACvB,GAEMC,IAAsC;AAAA,IACxC;AAAA,MACI,IAAI;AAAA,MACJ,OAAOd,KAAkBD,KAA2B;AAAA,MACpD,MAAM,gBAAAgB,EAAC,QAAA,EAAK,WAAW,YAAYxB,EAAU,KAAK,GAAA,CAAI;AAAA,IAAA;AAAA,IAE1D;AAAA,MACI,IAAI;AAAA,MACJ,OAAOW,KAAuBD,KAAgC;AAAA,MAC9D,MAAM,gBAAAc,EAAC,QAAA,EAAK,WAAW,YAAYxB,EAAU,WAAW,GAAA,CAAI;AAAA,IAAA;AAAA,IAEhE;AAAA,MACI,IAAI;AAAA,MACJ,OAAOa,KAAuBD,KAAgC;AAAA,MAC9D,MAAM,gBAAAY,EAAC,QAAA,EAAK,WAAW,YAAYxB,EAAU,WAAW,GAAA,CAAI;AAAA,IAAA;AAAA,EAChE,GAGEyB,IAAUF,EAAW,OAAO,CAAAG,MAAU,CAACrB,EAAkB,SAASqB,EAAO,EAAE,CAAC,GAC5EC,IAAkBJ,EAAW,KAAK,CAAAG,MAAUA,EAAO,KAAK,GAExDE,IAAoBC,EAAW,oBAAoBd,KAAaA,CAAS;AAE/E,SACI,gBAAAS,EAAC,SAAK,GAAGR,GAAgB,WAAWY,GAChC,UAAA,gBAAAJ,EAAC,OAAA,EAAI,WAAU,8BACX,UAAA,gBAAAA;AAAA,IAACM;AAAA,IAAA;AAAA,MACG,SAAAL;AAAA,MACA,OAAO,CAACR,CAAgB;AAAA,MACxB,UAAU,CAAAc,MAAQA,KAAQV,EAAYU,EAAK,EAA8B;AAAA,MACzE,UAAAjB;AAAA,MACA,sBAAoB;AAAA,MACpB,WAAS;AAAA,MACT,mBAAoBa,IAAiC,SAAf;AAAA,IAAe;AAAA,EAAA,GAE7D,EAAA,CACJ;AAER;AAGA1B,EAAiB,kBAAkB;AACnCA,EAAiB,wBAAwB;AACzCA,EAAiB,wBAAwB;"}
1
+ {"version":3,"file":"TableViewToggles.js","sources":["../../../src/components/table/TableViewToggles.tsx"],"sourcesContent":["import { type ReactNode, useEffect, useState } from 'react';\nimport { noop } from 'es-toolkit/compat';\n\nimport classNames from '../../utils/classNames';\nimport Select, { type SelectOption } from '../selects/Select';\n\nconst typeIcons: Record<TableViewTogglesViewType, string> = {\n TABLE: 'rioglyph-table-view',\n SINGLE_CARD: 'rioglyph-th-list',\n MULTI_CARDS: 'rioglyph-split-view',\n};\n\ntype TableViewToggleOption = SelectOption & {\n id: TableViewTogglesViewType;\n};\n\nexport type TableViewTogglesViewType = 'SINGLE_CARD' | 'MULTI_CARDS' | 'TABLE';\n\nexport type TableViewTogglesProps = {\n /**\n * The current viewType for controlling the TablesViewToggles component.\n *\n * Possible values are:\n *\n * - `'SINGLE_CARD'`\n * - `'MULTI_CARDS'`\n * - `'TABLE'`\n * - `TableViewToggles.VIEW_TYPE_TABLE`\n * - `TableViewToggles.VIEW_TYPE_SINGLE_CARD`\n * - `TableViewToggles.VIEW_TYPE_MULTI_CARDS`\n */\n viewType?: TableViewTogglesViewType;\n\n /**\n * Defines the initial viewType (when viewType is not controlled from the outside).\n *\n * Possible values are:\n *\n * - `'SINGLE_CARD'`\n * - `'MULTI_CARDS'`\n * - `'TABLE'`\n * - `TableViewToggles.VIEW_TYPE_TABLE`\n * - `TableViewToggles.VIEW_TYPE_SINGLE_CARD`\n * - `TableViewToggles.VIEW_TYPE_MULTI_CARDS`\n *\n * @default TableViewToggles.VIEW_TYPE_TABLE\n */\n initialViewType?: TableViewTogglesViewType;\n\n /**\n * Defines the view types which shall not be supported and are omitted.\n *\n * @default []\n */\n disabledViewTypes?: TableViewTogglesViewType[];\n\n /**\n * Callback function for when the user wants to change the viewType.\n *\n * Receives the new type as an argument.\n *\n * @param viewType The new viewType selected by the user.\n */\n onViewTypeChange: (viewType: TableViewTogglesViewType) => void;\n\n /**\n * Optional tooltip content for table view button.\n *\n * @deprecated Use `tableViewLabel` instead.\n */\n tableViewTooltipContent?: string | ReactNode;\n\n /**\n * Optional label content for the table view select item.\n */\n tableViewLabel?: string | ReactNode;\n\n /**\n * Optional tooltip content for single card view button.\n *\n * @deprecated Use `singleCardViewLabel` instead.\n */\n singleCardViewTooltipContent?: string | ReactNode;\n\n /**\n * Optional label content for the single card view select item.\n */\n singleCardViewLabel?: string | ReactNode;\n\n /**\n * Optional tooltip content for multi card view button.\n *\n * @deprecated Use `multiCardsViewLabel` instead.\n */\n multiCardsViewTooltipContent?: string | ReactNode;\n\n /**\n * Optional label content for the multi cards view select item.\n */\n multiCardsViewLabel?: string | ReactNode;\n\n /**\n * Disables all buttons.\n *\n * This means the buttons cannot be clicked. Used when disabling toolbar buttons during loading state or when the\n * corresponding table is empty.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Optional class names for the wrapper element.\n */\n className?: string;\n};\n\nconst TableViewToggles = (props: TableViewTogglesProps) => {\n const {\n viewType,\n initialViewType = 'TABLE',\n disabledViewTypes = [],\n onViewTypeChange = noop,\n tableViewTooltipContent,\n tableViewLabel,\n singleCardViewTooltipContent,\n singleCardViewLabel,\n multiCardsViewTooltipContent,\n multiCardsViewLabel,\n disabled = false,\n className,\n ...remainingProps\n } = props;\n\n const [internalViewType, setInternalViewType] = useState(initialViewType);\n\n // update internal state when external state changes - controlled component case\n useEffect(() => {\n if (viewType) {\n setInternalViewType(viewType);\n }\n }, [viewType]);\n\n const setViewType = (vt: TableViewTogglesViewType) => {\n setInternalViewType(vt);\n onViewTypeChange(vt);\n };\n\n const allOptions: TableViewToggleOption[] = [\n {\n id: 'TABLE',\n label: tableViewLabel ?? tableViewTooltipContent ?? '',\n icon: <span className={`rioglyph ${typeIcons.TABLE}`} />,\n },\n {\n id: 'MULTI_CARDS',\n label: multiCardsViewLabel ?? multiCardsViewTooltipContent ?? '',\n icon: <span className={`rioglyph ${typeIcons.MULTI_CARDS}`} />,\n },\n {\n id: 'SINGLE_CARD',\n label: singleCardViewLabel ?? singleCardViewTooltipContent ?? '',\n icon: <span className={`rioglyph ${typeIcons.SINGLE_CARD}`} />,\n },\n ];\n\n const options = allOptions.filter(option => !disabledViewTypes.includes(option.id));\n const hasOptionLabels = allOptions.some(option => option.label);\n\n const wrapperClassNames = classNames('TableViewToggles', className && className);\n\n return (\n <div {...remainingProps} className={wrapperClassNames}>\n <div className='form-group margin-bottom-0'>\n <Select\n options={options}\n value={[internalViewType]}\n onChange={item => item && setViewType(item.id as TableViewTogglesViewType)}\n disabled={disabled}\n showSelectedItemIcon\n pullRight\n dropdownClassName={!hasOptionLabels ? 'width-auto' : undefined}\n />\n </div>\n </div>\n );\n};\n\n// Don't export values as string but as a distinct union type\nTableViewToggles.VIEW_TYPE_TABLE = 'TABLE' as TableViewTogglesViewType;\nTableViewToggles.VIEW_TYPE_SINGLE_CARD = 'SINGLE_CARD' as TableViewTogglesViewType;\nTableViewToggles.VIEW_TYPE_MULTI_CARDS = 'MULTI_CARDS' as TableViewTogglesViewType;\n\nexport default TableViewToggles;\n"],"names":["typeIcons","TableViewToggles","props","viewType","initialViewType","disabledViewTypes","onViewTypeChange","noop","tableViewTooltipContent","tableViewLabel","singleCardViewTooltipContent","singleCardViewLabel","multiCardsViewTooltipContent","multiCardsViewLabel","disabled","className","remainingProps","internalViewType","setInternalViewType","useState","useEffect","setViewType","vt","allOptions","jsx","options","option","hasOptionLabels","wrapperClassNames","classNames","Select","item"],"mappings":";;;;;AAMA,MAAMA,IAAsD;AAAA,EACxD,OAAO;AAAA,EACP,aAAa;AAAA,EACb,aAAa;AACjB,GA2GMC,IAAmB,CAACC,MAAiC;AACvD,QAAM;AAAA,IACF,UAAAC;AAAA,IACA,iBAAAC,IAAkB;AAAA,IAClB,mBAAAC,IAAoB,CAAA;AAAA,IACpB,kBAAAC,IAAmBC;AAAA,IACnB,yBAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,8BAAAC;AAAA,IACA,qBAAAC;AAAA,IACA,8BAAAC;AAAA,IACA,qBAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,WAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,IACHd,GAEE,CAACe,GAAkBC,CAAmB,IAAIC,EAASf,CAAe;AAGxE,EAAAgB,EAAU,MAAM;AACZ,IAAIjB,KACAe,EAAoBf,CAAQ;AAAA,EAEpC,GAAG,CAACA,CAAQ,CAAC;AAEb,QAAMkB,IAAc,CAACC,MAAiC;AAClD,IAAAJ,EAAoBI,CAAE,GACtBhB,EAAiBgB,CAAE;AAAA,EACvB,GAEMC,IAAsC;AAAA,IACxC;AAAA,MACI,IAAI;AAAA,MACJ,OAAOd,KAAkBD,KAA2B;AAAA,MACpD,MAAM,gBAAAgB,EAAC,QAAA,EAAK,WAAW,YAAYxB,EAAU,KAAK,GAAA,CAAI;AAAA,IAAA;AAAA,IAE1D;AAAA,MACI,IAAI;AAAA,MACJ,OAAOa,KAAuBD,KAAgC;AAAA,MAC9D,MAAM,gBAAAY,EAAC,QAAA,EAAK,WAAW,YAAYxB,EAAU,WAAW,GAAA,CAAI;AAAA,IAAA;AAAA,IAEhE;AAAA,MACI,IAAI;AAAA,MACJ,OAAOW,KAAuBD,KAAgC;AAAA,MAC9D,MAAM,gBAAAc,EAAC,QAAA,EAAK,WAAW,YAAYxB,EAAU,WAAW,GAAA,CAAI;AAAA,IAAA;AAAA,EAChE,GAGEyB,IAAUF,EAAW,OAAO,CAAAG,MAAU,CAACrB,EAAkB,SAASqB,EAAO,EAAE,CAAC,GAC5EC,IAAkBJ,EAAW,KAAK,CAAAG,MAAUA,EAAO,KAAK,GAExDE,IAAoBC,EAAW,oBAAoBd,KAAaA,CAAS;AAE/E,SACI,gBAAAS,EAAC,SAAK,GAAGR,GAAgB,WAAWY,GAChC,UAAA,gBAAAJ,EAAC,OAAA,EAAI,WAAU,8BACX,UAAA,gBAAAA;AAAA,IAACM;AAAA,IAAA;AAAA,MACG,SAAAL;AAAA,MACA,OAAO,CAACR,CAAgB;AAAA,MACxB,UAAU,CAAAc,MAAQA,KAAQV,EAAYU,EAAK,EAA8B;AAAA,MACzE,UAAAjB;AAAA,MACA,sBAAoB;AAAA,MACpB,WAAS;AAAA,MACT,mBAAoBa,IAAiC,SAAf;AAAA,IAAe;AAAA,EAAA,GAE7D,EAAA,CACJ;AAER;AAGA1B,EAAiB,kBAAkB;AACnCA,EAAiB,wBAAwB;AACzCA,EAAiB,wBAAwB;"}
@@ -10,9 +10,12 @@ import { TableRowData, TableRowId, TableSortDirection } from '../Table.types';
10
10
  export type TableInteractionContextValue<RowType extends TableRowData> = {
11
11
  showSelectionColumn?: boolean;
12
12
  selectedRowIdSet: Set<TableRowId>;
13
+ selectableRowIdSet: Set<TableRowId>;
13
14
  selectionHeaderContent?: ReactNode;
14
15
  isAllRowsSelected?: boolean;
15
16
  isSomeRowsSelected?: boolean;
17
+ hasSelectableRows?: boolean;
18
+ hideSelectionCheckboxesForExcludedRows?: boolean;
16
19
  onToggleAllSelection?: () => void;
17
20
  onToggleRowSelection?: (rowId: TableRowId) => void;
18
21
  activeRowId?: TableRowId;
@@ -1 +1 @@
1
- {"version":3,"file":"TableInteractionContext.js","sources":["../../../../src/components/table/context/TableInteractionContext.tsx"],"sourcesContent":["import { createContext, useContext, type MouseEvent as ReactMouseEvent, type ReactNode } from 'react';\n\nimport type { TableRowData, TableRowId, TableSortDirection } from '../Table.types';\n\n/**\n * User-facing table interaction state and callbacks consumed by header/body cells.\n *\n * These values are conceptually different from the normalized render model:\n * they describe selection, sorting, and row activation/click behavior rather than\n * the structural table draft.\n */\nexport type TableInteractionContextValue<RowType extends TableRowData> = {\n showSelectionColumn?: boolean;\n selectedRowIdSet: Set<TableRowId>;\n selectionHeaderContent?: ReactNode;\n isAllRowsSelected?: boolean;\n isSomeRowsSelected?: boolean;\n onToggleAllSelection?: () => void;\n onToggleRowSelection?: (rowId: TableRowId) => void;\n activeRowId?: TableRowId;\n onActiveRowChange?: (rowId: TableRowId | undefined, row: RowType, rowIndex: number) => void;\n onRowClick?: (row: RowType, rowIndex: number) => void;\n isClickable: boolean;\n onSortChange?: (\n columnKey: string,\n direction: TableSortDirection,\n event: ReactMouseEvent<HTMLButtonElement>\n ) => void;\n};\n\nexport const TableInteractionContext = createContext<TableInteractionContextValue<TableRowData> | null>(null);\n\nexport const useOptionalTableInteractionContext = <RowType extends TableRowData>() =>\n useContext(TableInteractionContext) as TableInteractionContextValue<RowType> | null;\n\nexport const useTableInteractionContext = <RowType extends TableRowData>() => {\n const context = useOptionalTableInteractionContext<RowType>();\n\n if (!context) {\n throw new Error('Table interaction context is missing.');\n }\n\n return context;\n};\n"],"names":["TableInteractionContext","createContext","useOptionalTableInteractionContext","useContext"],"mappings":";AA8BO,MAAMA,IAA0BC,EAAiE,IAAI,GAE/FC,IAAqC,MAC9CC,EAAWH,CAAuB;"}
1
+ {"version":3,"file":"TableInteractionContext.js","sources":["../../../../src/components/table/context/TableInteractionContext.tsx"],"sourcesContent":["import { createContext, useContext, type MouseEvent as ReactMouseEvent, type ReactNode } from 'react';\n\nimport type { TableRowData, TableRowId, TableSortDirection } from '../Table.types';\n\n/**\n * User-facing table interaction state and callbacks consumed by header/body cells.\n *\n * These values are conceptually different from the normalized render model:\n * they describe selection, sorting, and row activation/click behavior rather than\n * the structural table draft.\n */\nexport type TableInteractionContextValue<RowType extends TableRowData> = {\n showSelectionColumn?: boolean;\n selectedRowIdSet: Set<TableRowId>;\n selectableRowIdSet: Set<TableRowId>;\n selectionHeaderContent?: ReactNode;\n isAllRowsSelected?: boolean;\n isSomeRowsSelected?: boolean;\n hasSelectableRows?: boolean;\n hideSelectionCheckboxesForExcludedRows?: boolean;\n onToggleAllSelection?: () => void;\n onToggleRowSelection?: (rowId: TableRowId) => void;\n activeRowId?: TableRowId;\n onActiveRowChange?: (rowId: TableRowId | undefined, row: RowType, rowIndex: number) => void;\n onRowClick?: (row: RowType, rowIndex: number) => void;\n isClickable: boolean;\n onSortChange?: (\n columnKey: string,\n direction: TableSortDirection,\n event: ReactMouseEvent<HTMLButtonElement>\n ) => void;\n};\n\nexport const TableInteractionContext = createContext<TableInteractionContextValue<TableRowData> | null>(null);\n\nexport const useOptionalTableInteractionContext = <RowType extends TableRowData>() =>\n useContext(TableInteractionContext) as TableInteractionContextValue<RowType> | null;\n\nexport const useTableInteractionContext = <RowType extends TableRowData>() => {\n const context = useOptionalTableInteractionContext<RowType>();\n\n if (!context) {\n throw new Error('Table interaction context is missing.');\n }\n\n return context;\n};\n"],"names":["TableInteractionContext","createContext","useOptionalTableInteractionContext","useContext"],"mappings":";AAiCO,MAAMA,IAA0BC,EAAiE,IAAI,GAE/FC,IAAqC,MAC9CC,EAAWH,CAAuB;"}
@@ -45,6 +45,7 @@ export type TableRenderDraft<RowType extends TableRowData> = {
45
45
  rowIndex: number;
46
46
  kind: 'data' | 'expanded' | 'expanded-full-width' | 'group' | 'group-footer' | 'spacer';
47
47
  disabled?: boolean;
48
+ selectable?: boolean;
48
49
  render: () => ReactNode;
49
50
  }[];
50
51
  bodyMaxHeight?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"TableRenderContext.js","sources":["../../../../src/components/table/context/TableRenderContext.tsx"],"sourcesContent":["import { createContext, useContext, type ReactNode } from 'react';\n\nimport type {\n TableColumnDefinition,\n TableHorizontalAlign,\n TableRowData,\n TableRowId,\n TableVerticalAlign,\n} from '../Table.types';\nimport type { TableViewHeader } from '../model/tableView.types';\n\nexport type RenderHeaderColumn<RowType extends TableRowData> = {\n id: string;\n columnKey?: string;\n label: ReactNode;\n icon?: string;\n filter?: ReactNode;\n hideLabel?: boolean;\n width?: number | string;\n mobileLabel?: string;\n horizontalAlign?: TableHorizontalAlign;\n verticalAlign?: TableVerticalAlign;\n headerClassName?: string;\n hideOnMobile?: boolean;\n sortable?: boolean;\n draggable?: boolean;\n resizeable?: boolean;\n minResizeWidth?: number;\n maxResizeWidth?: number;\n row: number;\n colSpan: number;\n rowSpan: number;\n source?: RowType;\n};\n\n/**\n * Mutable draft of the current render pass.\n *\n * The table keeps React composability, but still needs a normalized table model\n * for features such as header placement, footer detection, virtualization, and\n * stable body-row rendering.\n *\n * The table therefore works in two internal stages:\n * 1. Header/body/footer sub-components register the structure they produce into this draft.\n * 2. `Table` promotes that draft into stable draft state and renders from that.\n *\n * The draft is intentionally recreated on every render pass and must not be treated\n * as persistent state.\n */\nexport type TableRenderDraft<RowType extends TableRowData> = {\n headerColumns: RenderHeaderColumn<RowType>[];\n bodyRows: {\n rowId: TableRowId;\n rowIndex: number;\n kind: 'data' | 'expanded' | 'expanded-full-width' | 'group' | 'group-footer' | 'spacer';\n disabled?: boolean;\n render: () => ReactNode;\n }[];\n bodyMaxHeight?: string;\n hasFooter?: boolean;\n hasFooterCells?: boolean;\n hasExpandableRows?: boolean;\n};\n\nexport type RenderBodyRow<RowType extends TableRowData> = Omit<TableRenderDraft<RowType>['bodyRows'][number], 'render'>;\n\n/**\n * Structural render context.\n *\n * This context only carries the normalized render model built from the current\n * render pass. Public render configuration such as `rowClassName` or card/table\n * view mode lives in `TableRenderConfigContext`.\n */\nexport type TableRenderContextValue<RowType extends TableRowData> = {\n header?: TableViewHeader<RowType>;\n columns: RenderHeaderColumn<RowType>[];\n columnDefinitionsByKey: Map<string, TableColumnDefinition<RowType>>;\n columnIndexByKey: Map<string, number>;\n bodyRows: RenderBodyRow<RowType>[];\n renderBodyRow?: (row: RenderBodyRow<RowType>) => ReactNode;\n renderDraft: TableRenderDraft<RowType>;\n hasFooterCells?: boolean;\n hasExpandableRows?: boolean;\n /**\n * Switches body rows into the registration pass.\n *\n * While this flag is true, row components register their normalized metadata in\n * `renderDraft.bodyRows` and return `null` instead of rendering DOM directly.\n * `TableBody` then performs the second pass by rendering the collected rows\n * through `renderBodyRow(...)`.\n */\n isRegisteringBodyRows?: boolean;\n};\n\nexport const TableRenderContext = createContext<TableRenderContextValue<TableRowData> | null>(null);\n\nexport const useOptionalTableRenderContext = <RowType extends TableRowData>() =>\n useContext(TableRenderContext) as TableRenderContextValue<RowType> | null;\n\nexport const useTableRenderContext = <RowType extends TableRowData>() => {\n const context = useOptionalTableRenderContext<RowType>();\n\n if (!context) {\n throw new Error('Table render context is missing.');\n }\n\n return context;\n};\n"],"names":["TableRenderContext","createContext","useOptionalTableRenderContext","useContext"],"mappings":";AA8FO,MAAMA,IAAqBC,EAA4D,IAAI,GAErFC,IAAgC,MACzCC,EAAWH,CAAkB;"}
1
+ {"version":3,"file":"TableRenderContext.js","sources":["../../../../src/components/table/context/TableRenderContext.tsx"],"sourcesContent":["import { createContext, useContext, type ReactNode } from 'react';\n\nimport type {\n TableColumnDefinition,\n TableHorizontalAlign,\n TableRowData,\n TableRowId,\n TableVerticalAlign,\n} from '../Table.types';\nimport type { TableViewHeader } from '../model/tableView.types';\n\nexport type RenderHeaderColumn<RowType extends TableRowData> = {\n id: string;\n columnKey?: string;\n label: ReactNode;\n icon?: string;\n filter?: ReactNode;\n hideLabel?: boolean;\n width?: number | string;\n mobileLabel?: string;\n horizontalAlign?: TableHorizontalAlign;\n verticalAlign?: TableVerticalAlign;\n headerClassName?: string;\n hideOnMobile?: boolean;\n sortable?: boolean;\n draggable?: boolean;\n resizeable?: boolean;\n minResizeWidth?: number;\n maxResizeWidth?: number;\n row: number;\n colSpan: number;\n rowSpan: number;\n source?: RowType;\n};\n\n/**\n * Mutable draft of the current render pass.\n *\n * The table keeps React composability, but still needs a normalized table model\n * for features such as header placement, footer detection, virtualization, and\n * stable body-row rendering.\n *\n * The table therefore works in two internal stages:\n * 1. Header/body/footer sub-components register the structure they produce into this draft.\n * 2. `Table` promotes that draft into stable draft state and renders from that.\n *\n * The draft is intentionally recreated on every render pass and must not be treated\n * as persistent state.\n */\nexport type TableRenderDraft<RowType extends TableRowData> = {\n headerColumns: RenderHeaderColumn<RowType>[];\n bodyRows: {\n rowId: TableRowId;\n rowIndex: number;\n kind: 'data' | 'expanded' | 'expanded-full-width' | 'group' | 'group-footer' | 'spacer';\n disabled?: boolean;\n selectable?: boolean;\n render: () => ReactNode;\n }[];\n bodyMaxHeight?: string;\n hasFooter?: boolean;\n hasFooterCells?: boolean;\n hasExpandableRows?: boolean;\n};\n\nexport type RenderBodyRow<RowType extends TableRowData> = Omit<TableRenderDraft<RowType>['bodyRows'][number], 'render'>;\n\n/**\n * Structural render context.\n *\n * This context only carries the normalized render model built from the current\n * render pass. Public render configuration such as `rowClassName` or card/table\n * view mode lives in `TableRenderConfigContext`.\n */\nexport type TableRenderContextValue<RowType extends TableRowData> = {\n header?: TableViewHeader<RowType>;\n columns: RenderHeaderColumn<RowType>[];\n columnDefinitionsByKey: Map<string, TableColumnDefinition<RowType>>;\n columnIndexByKey: Map<string, number>;\n bodyRows: RenderBodyRow<RowType>[];\n renderBodyRow?: (row: RenderBodyRow<RowType>) => ReactNode;\n renderDraft: TableRenderDraft<RowType>;\n hasFooterCells?: boolean;\n hasExpandableRows?: boolean;\n /**\n * Switches body rows into the registration pass.\n *\n * While this flag is true, row components register their normalized metadata in\n * `renderDraft.bodyRows` and return `null` instead of rendering DOM directly.\n * `TableBody` then performs the second pass by rendering the collected rows\n * through `renderBodyRow(...)`.\n */\n isRegisteringBodyRows?: boolean;\n};\n\nexport const TableRenderContext = createContext<TableRenderContextValue<TableRowData> | null>(null);\n\nexport const useOptionalTableRenderContext = <RowType extends TableRowData>() =>\n useContext(TableRenderContext) as TableRenderContextValue<RowType> | null;\n\nexport const useTableRenderContext = <RowType extends TableRowData>() => {\n const context = useOptionalTableRenderContext<RowType>();\n\n if (!context) {\n throw new Error('Table render context is missing.');\n }\n\n return context;\n};\n"],"names":["TableRenderContext","createContext","useOptionalTableRenderContext","useContext"],"mappings":";AA+FO,MAAMA,IAAqBC,EAA4D,IAAI,GAErFC,IAAgC,MACzCC,EAAWH,CAAkB;"}
@@ -1,85 +1,83 @@
1
- import { useState as S, useRef as p, useMemo as w, useLayoutEffect as R } from "react";
2
- const A = 1, E = (t) => {
1
+ import { useState as A, useRef as z, useMemo as F, useLayoutEffect as N } from "react";
2
+ import a from "../../../hooks/useResizeObserver.js";
3
+ const j = 1, x = (t) => {
3
4
  const e = t?.trim().match(/^(-?\d+(?:\.\d+)?)px$/);
4
5
  return e ? Number(e[1]) : void 0;
5
- }, x = (t) => {
6
+ }, C = (t) => {
6
7
  const e = t.getBoundingClientRect().width;
7
8
  return e > 0 ? Math.ceil(e) : t.scrollWidth;
8
- }, O = (t) => {
9
+ }, P = (t) => {
9
10
  if (!t)
10
11
  return 0;
11
12
  const e = window.getComputedStyle(t), n = Number.parseFloat(e.columnGap || e.gap || "0");
12
13
  return Number.isFinite(n) ? Math.ceil(n) : 0;
13
- }, q = (t) => {
14
+ }, T = (t) => {
14
15
  const e = t.querySelector(".table-head-label");
15
16
  if (e) {
16
- const s = t.querySelector(".sort-arrows");
17
- return x(e) + (s ? x(s) : 0) + (s ? O(t.querySelector(".table-head-button")) : 0);
17
+ const o = t.querySelector(".sort-arrows");
18
+ return C(e) + (o ? C(o) : 0) + (o ? P(t.querySelector(".table-head-button")) : 0);
18
19
  }
19
20
  return (t.querySelector(".table-cell-content, .table-head-button-label") ?? t).scrollWidth;
20
- }, z = (t, e) => Object.fromEntries(
21
- Object.entries(e).map(([n, s]) => {
22
- const i = t[n], u = E(i), r = E(s);
21
+ }, _ = (t, e) => Object.fromEntries(
22
+ Object.entries(e).map(([n, o]) => {
23
+ const u = t[n], i = x(u), r = x(o);
23
24
  return [
24
25
  n,
25
- u !== void 0 && r !== void 0 && Math.abs(u - r) <= A ? i : s
26
+ i !== void 0 && r !== void 0 && Math.abs(i - r) <= j ? u : o
26
27
  ];
27
28
  })
28
- ), P = (t) => {
29
- const { columns: e, enabled: n, tableWrapperRef: s } = t, [i, u] = S({}), r = p(""), a = p({}), y = w(
30
- () => e.map((o) => `${o.key}:${o.width === void 0 ? "auto" : String(o.width)}`).join("|"),
29
+ ), D = (t) => {
30
+ const { columns: e, enabled: n, tableWrapperRef: o } = t, [u, i] = A({}), r = z(""), c = z({}), g = F(
31
+ () => e.map((l) => `${l.key}:${l.width === void 0 ? "auto" : String(l.width)}`).join("|"),
31
32
  [e]
32
- );
33
- return R(() => {
34
- const o = s.current;
35
- if (!n || !o) {
36
- r.current && (r.current = "", a.current = {}, u({}));
33
+ ), s = o.current, v = s?.querySelector(".table-head") ?? null, w = s?.querySelector(".table-body") ?? null, R = s?.querySelector(".table-footer") ?? null, q = s?.querySelector(".table-scroll-content") ?? null, [, , b] = a(s), [, , S] = a(v), [, , M] = a(w), [, , f] = a(R), [, , p] = a(q);
34
+ return N(() => {
35
+ if (!n || !s) {
36
+ r.current && (r.current = "", c.current = {}, i({}));
37
37
  return;
38
38
  }
39
39
  if (e.length === 0) {
40
- r.current && (r.current = "", a.current = {}, u({}));
40
+ r.current && (r.current = "", c.current = {}, i({}));
41
41
  return;
42
42
  }
43
- const h = e.filter((c) => c.width === void 0);
44
- if (h.length === 0) {
45
- r.current && (r.current = "", a.current = {}, u({}));
43
+ const l = e.filter((d) => d.width === void 0);
44
+ if (l.length === 0) {
45
+ r.current && (r.current = "", c.current = {}, i({}));
46
46
  return;
47
47
  }
48
- const m = () => {
49
- const c = Array.from(o.querySelectorAll("[data-column]")), C = Object.fromEntries(
50
- h.flatMap((M) => {
51
- const W = c.filter((d) => d.dataset.column === M.key).reduce(
52
- (d, g) => Math.max(d, q(g)),
48
+ (() => {
49
+ const d = Array.from(s.querySelectorAll("[data-column]")), k = Object.fromEntries(
50
+ l.flatMap((E) => {
51
+ const y = d.filter((h) => h.dataset.column === E.key).reduce(
52
+ (h, O) => Math.max(h, T(O)),
53
53
  0
54
54
  );
55
- return W > 0 ? [[M.key, `${Math.ceil(W)}px`]] : [];
55
+ return y > 0 ? [[E.key, `${Math.ceil(y)}px`]] : [];
56
56
  })
57
- ), l = z(
58
- a.current,
59
- C
60
- ), f = JSON.stringify(l);
61
- f !== r.current && (r.current = f, a.current = l, u(l));
62
- };
63
- m();
64
- const v = [
65
- o,
66
- ...Array.from(
67
- o.querySelectorAll(
68
- ".table-head, .table-body, .table-footer, .table-scroll-content"
69
- )
70
- )
71
- ], b = new ResizeObserver(() => {
72
- m();
73
- });
74
- return v.forEach((c) => {
75
- b.observe(c);
76
- }), () => {
77
- b.disconnect();
78
- };
79
- }, [y, n, s]), i;
57
+ ), m = _(
58
+ c.current,
59
+ k
60
+ ), W = JSON.stringify(m);
61
+ W !== r.current && (r.current = W, c.current = m, i(m));
62
+ })();
63
+ }, [
64
+ g,
65
+ n,
66
+ s,
67
+ b.blockSize,
68
+ b.inlineSize,
69
+ S.blockSize,
70
+ S.inlineSize,
71
+ M.blockSize,
72
+ M.inlineSize,
73
+ f.blockSize,
74
+ f.inlineSize,
75
+ p.blockSize,
76
+ p.inlineSize
77
+ ]), u;
80
78
  };
81
79
  export {
82
- z as stabilizeMeasuredColumnMaxWidths,
83
- P as useMeasuredColumnMaxWidths
80
+ _ as stabilizeMeasuredColumnMaxWidths,
81
+ D as useMeasuredColumnMaxWidths
84
82
  };
85
83
  //# sourceMappingURL=useMeasuredColumnMaxWidths.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useMeasuredColumnMaxWidths.js","sources":["../../../../src/components/table/layout/useMeasuredColumnMaxWidths.ts"],"sourcesContent":["import { useLayoutEffect, useMemo, useRef, useState, type RefObject } from 'react';\n\nimport type { TableColumnDefinition, TableRowData } from '../Table.types';\n\nconst MEASURED_WIDTH_JITTER_TOLERANCE_PX = 1;\n\nconst parsePixelWidth = (width?: string) => {\n const match = width?.trim().match(/^(-?\\d+(?:\\.\\d+)?)px$/);\n\n return match ? Number(match[1]) : undefined;\n};\n\nconst measureRenderedWidth = (element: HTMLElement) => {\n const renderedWidth = element.getBoundingClientRect().width;\n\n return renderedWidth > 0 ? Math.ceil(renderedWidth) : element.scrollWidth;\n};\n\nconst resolveFlexGapWidth = (element: HTMLElement | null) => {\n if (!element) {\n return 0;\n }\n\n const styles = window.getComputedStyle(element);\n const gap = Number.parseFloat(styles.columnGap || styles.gap || '0');\n\n return Number.isFinite(gap) ? Math.ceil(gap) : 0;\n};\n\nconst measureColumnContentWidth = (element: HTMLElement) => {\n const headerLabelElement = element.querySelector<HTMLElement>('.table-head-label');\n\n if (headerLabelElement) {\n const sortArrowsElement = element.querySelector<HTMLElement>('.sort-arrows');\n\n return (\n measureRenderedWidth(headerLabelElement) +\n (sortArrowsElement ? measureRenderedWidth(sortArrowsElement) : 0) +\n (sortArrowsElement ? resolveFlexGapWidth(element.querySelector<HTMLElement>('.table-head-button')) : 0)\n );\n }\n\n const contentElement =\n element.querySelector<HTMLElement>('.table-cell-content, .table-head-button-label') ?? element;\n\n return contentElement.scrollWidth;\n};\n\nexport const stabilizeMeasuredColumnMaxWidths = (\n previousMeasuredColumnMaxWidths: Record<string, string>,\n nextMeasuredColumnMaxWidths: Record<string, string>\n) =>\n Object.fromEntries(\n Object.entries(nextMeasuredColumnMaxWidths).map(([columnKey, nextMeasuredWidth]) => {\n const previousMeasuredWidth = previousMeasuredColumnMaxWidths[columnKey];\n const previousMeasuredWidthPx = parsePixelWidth(previousMeasuredWidth);\n const nextMeasuredWidthPx = parsePixelWidth(nextMeasuredWidth);\n\n return [\n columnKey,\n previousMeasuredWidthPx !== undefined &&\n nextMeasuredWidthPx !== undefined &&\n Math.abs(previousMeasuredWidthPx - nextMeasuredWidthPx) <= MEASURED_WIDTH_JITTER_TOLERANCE_PX\n ? previousMeasuredWidth\n : nextMeasuredWidth,\n ];\n })\n );\n\ntype UseMeasuredColumnMaxWidthsProps<RowType extends TableRowData> = {\n columns: TableColumnDefinition<RowType>[];\n enabled: boolean;\n tableWrapperRef: RefObject<HTMLDivElement | null>;\n};\n\nexport const useMeasuredColumnMaxWidths = <RowType extends TableRowData>(\n props: UseMeasuredColumnMaxWidthsProps<RowType>\n) => {\n const { columns, enabled, tableWrapperRef } = props;\n const [measuredColumnMaxWidths, setMeasuredColumnMaxWidths] = useState<Record<string, string>>({});\n const previousMeasuredWidthsRef = useRef('');\n const previousMeasuredColumnMaxWidthsRef = useRef<Record<string, string>>({});\n const columnsSignature = useMemo(\n () =>\n columns\n .map(column => `${column.key}:${column.width === undefined ? 'auto' : String(column.width)}`)\n .join('|'),\n [columns]\n );\n\n useLayoutEffect(() => {\n const wrapperElement = tableWrapperRef.current;\n\n if (!enabled || !wrapperElement) {\n if (previousMeasuredWidthsRef.current) {\n previousMeasuredWidthsRef.current = '';\n previousMeasuredColumnMaxWidthsRef.current = {};\n setMeasuredColumnMaxWidths({});\n }\n\n return;\n }\n\n if (columns.length === 0) {\n if (previousMeasuredWidthsRef.current) {\n previousMeasuredWidthsRef.current = '';\n previousMeasuredColumnMaxWidthsRef.current = {};\n setMeasuredColumnMaxWidths({});\n }\n\n return;\n }\n\n const columnsWithoutWidth = columns.filter(column => column.width === undefined);\n\n if (columnsWithoutWidth.length === 0) {\n if (previousMeasuredWidthsRef.current) {\n previousMeasuredWidthsRef.current = '';\n previousMeasuredColumnMaxWidthsRef.current = {};\n setMeasuredColumnMaxWidths({});\n }\n\n return;\n }\n\n const measureColumnMaxWidths = () => {\n const columnElements = Array.from(wrapperElement.querySelectorAll<HTMLElement>('[data-column]'));\n const nextMeasuredColumnMaxWidths = Object.fromEntries(\n columnsWithoutWidth.flatMap(column => {\n const matchingElements = columnElements.filter(element => element.dataset.column === column.key);\n const measuredWidth = matchingElements.reduce(\n (largestWidth, element) => Math.max(largestWidth, measureColumnContentWidth(element)),\n 0\n );\n\n return measuredWidth > 0 ? [[column.key, `${Math.ceil(measuredWidth)}px`]] : [];\n })\n );\n const stabilizedMeasuredColumnMaxWidths = stabilizeMeasuredColumnMaxWidths(\n previousMeasuredColumnMaxWidthsRef.current,\n nextMeasuredColumnMaxWidths\n );\n const serializedMeasuredWidths = JSON.stringify(stabilizedMeasuredColumnMaxWidths);\n\n if (serializedMeasuredWidths !== previousMeasuredWidthsRef.current) {\n previousMeasuredWidthsRef.current = serializedMeasuredWidths;\n previousMeasuredColumnMaxWidthsRef.current = stabilizedMeasuredColumnMaxWidths;\n setMeasuredColumnMaxWidths(stabilizedMeasuredColumnMaxWidths);\n }\n };\n\n measureColumnMaxWidths();\n\n const observedElements = [\n wrapperElement,\n ...Array.from(\n wrapperElement.querySelectorAll<HTMLElement>(\n '.table-head, .table-body, .table-footer, .table-scroll-content'\n )\n ),\n ];\n const resizeObserver = new ResizeObserver(() => {\n measureColumnMaxWidths();\n });\n\n observedElements.forEach(element => {\n resizeObserver.observe(element);\n });\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [columnsSignature, enabled, tableWrapperRef]);\n\n return measuredColumnMaxWidths;\n};\n"],"names":["MEASURED_WIDTH_JITTER_TOLERANCE_PX","parsePixelWidth","width","match","measureRenderedWidth","element","renderedWidth","resolveFlexGapWidth","styles","gap","measureColumnContentWidth","headerLabelElement","sortArrowsElement","stabilizeMeasuredColumnMaxWidths","previousMeasuredColumnMaxWidths","nextMeasuredColumnMaxWidths","columnKey","nextMeasuredWidth","previousMeasuredWidth","previousMeasuredWidthPx","nextMeasuredWidthPx","useMeasuredColumnMaxWidths","props","columns","enabled","tableWrapperRef","measuredColumnMaxWidths","setMeasuredColumnMaxWidths","useState","previousMeasuredWidthsRef","useRef","previousMeasuredColumnMaxWidthsRef","columnsSignature","useMemo","column","useLayoutEffect","wrapperElement","columnsWithoutWidth","measureColumnMaxWidths","columnElements","measuredWidth","largestWidth","stabilizedMeasuredColumnMaxWidths","serializedMeasuredWidths","observedElements","resizeObserver"],"mappings":"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"}
1
+ {"version":3,"file":"useMeasuredColumnMaxWidths.js","sources":["../../../../src/components/table/layout/useMeasuredColumnMaxWidths.ts"],"sourcesContent":["import { useLayoutEffect, useMemo, useRef, useState, type RefObject } from 'react';\n\nimport useResizeObserver from '../../../useResizeObserver';\nimport type { TableColumnDefinition, TableRowData } from '../Table.types';\n\nconst MEASURED_WIDTH_JITTER_TOLERANCE_PX = 1;\n\nconst parsePixelWidth = (width?: string) => {\n const match = width?.trim().match(/^(-?\\d+(?:\\.\\d+)?)px$/);\n\n return match ? Number(match[1]) : undefined;\n};\n\nconst measureRenderedWidth = (element: HTMLElement) => {\n const renderedWidth = element.getBoundingClientRect().width;\n\n return renderedWidth > 0 ? Math.ceil(renderedWidth) : element.scrollWidth;\n};\n\nconst resolveFlexGapWidth = (element: HTMLElement | null) => {\n if (!element) {\n return 0;\n }\n\n const styles = window.getComputedStyle(element);\n const gap = Number.parseFloat(styles.columnGap || styles.gap || '0');\n\n return Number.isFinite(gap) ? Math.ceil(gap) : 0;\n};\n\nconst measureColumnContentWidth = (element: HTMLElement) => {\n const headerLabelElement = element.querySelector<HTMLElement>('.table-head-label');\n\n if (headerLabelElement) {\n const sortArrowsElement = element.querySelector<HTMLElement>('.sort-arrows');\n\n return (\n measureRenderedWidth(headerLabelElement) +\n (sortArrowsElement ? measureRenderedWidth(sortArrowsElement) : 0) +\n (sortArrowsElement ? resolveFlexGapWidth(element.querySelector<HTMLElement>('.table-head-button')) : 0)\n );\n }\n\n const contentElement =\n element.querySelector<HTMLElement>('.table-cell-content, .table-head-button-label') ?? element;\n\n return contentElement.scrollWidth;\n};\n\nexport const stabilizeMeasuredColumnMaxWidths = (\n previousMeasuredColumnMaxWidths: Record<string, string>,\n nextMeasuredColumnMaxWidths: Record<string, string>\n) =>\n Object.fromEntries(\n Object.entries(nextMeasuredColumnMaxWidths).map(([columnKey, nextMeasuredWidth]) => {\n const previousMeasuredWidth = previousMeasuredColumnMaxWidths[columnKey];\n const previousMeasuredWidthPx = parsePixelWidth(previousMeasuredWidth);\n const nextMeasuredWidthPx = parsePixelWidth(nextMeasuredWidth);\n\n return [\n columnKey,\n previousMeasuredWidthPx !== undefined &&\n nextMeasuredWidthPx !== undefined &&\n Math.abs(previousMeasuredWidthPx - nextMeasuredWidthPx) <= MEASURED_WIDTH_JITTER_TOLERANCE_PX\n ? previousMeasuredWidth\n : nextMeasuredWidth,\n ];\n })\n );\n\ntype UseMeasuredColumnMaxWidthsProps<RowType extends TableRowData> = {\n columns: TableColumnDefinition<RowType>[];\n enabled: boolean;\n tableWrapperRef: RefObject<HTMLDivElement | null>;\n};\n\nexport const useMeasuredColumnMaxWidths = <RowType extends TableRowData>(\n props: UseMeasuredColumnMaxWidthsProps<RowType>\n) => {\n const { columns, enabled, tableWrapperRef } = props;\n const [measuredColumnMaxWidths, setMeasuredColumnMaxWidths] = useState<Record<string, string>>({});\n const previousMeasuredWidthsRef = useRef('');\n const previousMeasuredColumnMaxWidthsRef = useRef<Record<string, string>>({});\n const columnsSignature = useMemo(\n () =>\n columns\n .map(column => `${column.key}:${column.width === undefined ? 'auto' : String(column.width)}`)\n .join('|'),\n [columns]\n );\n const wrapperElement = tableWrapperRef.current;\n const tableHeadElement = wrapperElement?.querySelector<HTMLDivElement>('.table-head') ?? null;\n const tableBodyElement = wrapperElement?.querySelector<HTMLDivElement>('.table-body') ?? null;\n const tableFooterElement = wrapperElement?.querySelector<HTMLDivElement>('.table-footer') ?? null;\n const tableScrollContentElement = wrapperElement?.querySelector<HTMLDivElement>('.table-scroll-content') ?? null;\n const [, , wrapperSize] = useResizeObserver(wrapperElement);\n const [, , tableHeadSize] = useResizeObserver(tableHeadElement);\n const [, , tableBodySize] = useResizeObserver(tableBodyElement);\n const [, , tableFooterSize] = useResizeObserver(tableFooterElement);\n const [, , tableScrollContentSize] = useResizeObserver(tableScrollContentElement);\n\n useLayoutEffect(() => {\n if (!enabled || !wrapperElement) {\n if (previousMeasuredWidthsRef.current) {\n previousMeasuredWidthsRef.current = '';\n previousMeasuredColumnMaxWidthsRef.current = {};\n setMeasuredColumnMaxWidths({});\n }\n\n return;\n }\n\n if (columns.length === 0) {\n if (previousMeasuredWidthsRef.current) {\n previousMeasuredWidthsRef.current = '';\n previousMeasuredColumnMaxWidthsRef.current = {};\n setMeasuredColumnMaxWidths({});\n }\n\n return;\n }\n\n const columnsWithoutWidth = columns.filter(column => column.width === undefined);\n\n if (columnsWithoutWidth.length === 0) {\n if (previousMeasuredWidthsRef.current) {\n previousMeasuredWidthsRef.current = '';\n previousMeasuredColumnMaxWidthsRef.current = {};\n setMeasuredColumnMaxWidths({});\n }\n\n return;\n }\n\n const measureColumnMaxWidths = () => {\n const columnElements = Array.from(wrapperElement.querySelectorAll<HTMLElement>('[data-column]'));\n const nextMeasuredColumnMaxWidths = Object.fromEntries(\n columnsWithoutWidth.flatMap(column => {\n const matchingElements = columnElements.filter(element => element.dataset.column === column.key);\n const measuredWidth = matchingElements.reduce(\n (largestWidth, element) => Math.max(largestWidth, measureColumnContentWidth(element)),\n 0\n );\n\n return measuredWidth > 0 ? [[column.key, `${Math.ceil(measuredWidth)}px`]] : [];\n })\n );\n const stabilizedMeasuredColumnMaxWidths = stabilizeMeasuredColumnMaxWidths(\n previousMeasuredColumnMaxWidthsRef.current,\n nextMeasuredColumnMaxWidths\n );\n const serializedMeasuredWidths = JSON.stringify(stabilizedMeasuredColumnMaxWidths);\n\n if (serializedMeasuredWidths !== previousMeasuredWidthsRef.current) {\n previousMeasuredWidthsRef.current = serializedMeasuredWidths;\n previousMeasuredColumnMaxWidthsRef.current = stabilizedMeasuredColumnMaxWidths;\n setMeasuredColumnMaxWidths(stabilizedMeasuredColumnMaxWidths);\n }\n };\n\n measureColumnMaxWidths();\n }, [\n columnsSignature,\n enabled,\n wrapperElement,\n wrapperSize.blockSize,\n wrapperSize.inlineSize,\n tableHeadSize.blockSize,\n tableHeadSize.inlineSize,\n tableBodySize.blockSize,\n tableBodySize.inlineSize,\n tableFooterSize.blockSize,\n tableFooterSize.inlineSize,\n tableScrollContentSize.blockSize,\n tableScrollContentSize.inlineSize,\n ]);\n\n return measuredColumnMaxWidths;\n};\n"],"names":["MEASURED_WIDTH_JITTER_TOLERANCE_PX","parsePixelWidth","width","match","measureRenderedWidth","element","renderedWidth","resolveFlexGapWidth","styles","gap","measureColumnContentWidth","headerLabelElement","sortArrowsElement","stabilizeMeasuredColumnMaxWidths","previousMeasuredColumnMaxWidths","nextMeasuredColumnMaxWidths","columnKey","nextMeasuredWidth","previousMeasuredWidth","previousMeasuredWidthPx","nextMeasuredWidthPx","useMeasuredColumnMaxWidths","props","columns","enabled","tableWrapperRef","measuredColumnMaxWidths","setMeasuredColumnMaxWidths","useState","previousMeasuredWidthsRef","useRef","previousMeasuredColumnMaxWidthsRef","columnsSignature","useMemo","column","wrapperElement","tableHeadElement","tableBodyElement","tableFooterElement","tableScrollContentElement","wrapperSize","useResizeObserver","tableHeadSize","tableBodySize","tableFooterSize","tableScrollContentSize","useLayoutEffect","columnsWithoutWidth","columnElements","measuredWidth","largestWidth","stabilizedMeasuredColumnMaxWidths","serializedMeasuredWidths"],"mappings":"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"}