@dbcdk/react-components 0.0.35 → 0.0.36

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.
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { TextWrap } from 'lucide-react';
3
+ import { isValidElement } from 'react';
3
4
  import { useMemo, useState } from 'react';
4
5
  import styles from './CodeBlock.module.css';
5
6
  import { Button } from '../button/Button';
@@ -15,12 +16,22 @@ const looksLikeStackFrame = (line) => {
15
16
  t.startsWith('↳') || // some tools
16
17
  /^at\s+\w/.test(t));
17
18
  };
19
+ function getTextContent(node) {
20
+ if (node == null || typeof node === 'boolean')
21
+ return '';
22
+ if (typeof node === 'string' || typeof node === 'number')
23
+ return String(node);
24
+ if (Array.isArray(node))
25
+ return node.map(getTextContent).join('');
26
+ if (isValidElement(node))
27
+ return getTextContent(node.props.children);
28
+ return '';
29
+ }
18
30
  export function CodeBlock({ code, children, copyButton, copyText, size = 'md', smart = true, wrap = true, }) {
19
- var _a;
20
31
  const text = typeof code === 'string' ? code : undefined;
21
- const copy = (_a = copyText !== null && copyText !== void 0 ? copyText : text) !== null && _a !== void 0 ? _a : '';
22
32
  const hasChildren = children !== undefined && children !== null;
23
33
  const [isWrapped, setIsWrapped] = useState(wrap);
34
+ const copy = useMemo(() => { var _a; return (_a = copyText !== null && copyText !== void 0 ? copyText : text) !== null && _a !== void 0 ? _a : getTextContent(children); }, [copyText, text, children]);
24
35
  const lines = useMemo(() => (smart && !hasChildren && typeof text === 'string' ? text.split('\n') : null), [smart, hasChildren, text]);
25
36
  return (_jsxs("div", { className: [
26
37
  styles.wrapper,
@@ -7,6 +7,7 @@ export interface ColumnItem<T> {
7
7
  header: string | (() => ReactNode);
8
8
  accessor?: keyof T;
9
9
  width?: number | string;
10
+ fitContent?: boolean;
10
11
  sortable?: boolean;
11
12
  sortFunction?: (a: T, b: T) => -1 | 0 | 1;
12
13
  render?: (item: T) => ReactNode;
@@ -22,6 +22,7 @@ export function TanstackTable(props) {
22
22
  const [columnSizing, setColumnSizing] = React.useState({});
23
23
  const containerRef = React.useRef(null);
24
24
  const [availableWidth, setAvailableWidth] = React.useState(undefined);
25
+ const [measuredFitContentWidths, setMeasuredFitContentWidths] = React.useState({});
25
26
  const table = useReactTable({
26
27
  data,
27
28
  columns: columns,
@@ -68,6 +69,31 @@ export function TanstackTable(props) {
68
69
  observer.observe(el);
69
70
  return () => observer.disconnect();
70
71
  }, []);
72
+ React.useLayoutEffect(() => {
73
+ const root = containerRef.current;
74
+ if (!root)
75
+ return;
76
+ const next = {};
77
+ const nodes = root.querySelectorAll('[data-fit-content-column="true"][data-column-id]');
78
+ nodes.forEach(node => {
79
+ var _a;
80
+ const id = node.dataset.columnId;
81
+ if (!id)
82
+ return;
83
+ const width = Math.ceil(node.scrollWidth);
84
+ if (width <= 0)
85
+ return;
86
+ next[id] = Math.max((_a = next[id]) !== null && _a !== void 0 ? _a : 0, width);
87
+ });
88
+ setMeasuredFitContentWidths(prev => {
89
+ const prevKeys = Object.keys(prev);
90
+ const nextKeys = Object.keys(next);
91
+ if (prevKeys.length === nextKeys.length && nextKeys.every(key => prev[key] === next[key])) {
92
+ return prev;
93
+ }
94
+ return next;
95
+ });
96
+ }, [data, columns, columnVisibility, props.loading, uiSorting]);
71
97
  const distributedLayout = React.useMemo(() => {
72
98
  if (availableWidth == null)
73
99
  return null;
@@ -77,8 +103,17 @@ export function TanstackTable(props) {
77
103
  defaultMinPx: 80,
78
104
  columnSizing,
79
105
  availableWidth,
106
+ measuredFitContentWidths,
80
107
  });
81
- }, [table, selectedRows, onRowSelect, dataKey, columnSizing, availableWidth]);
108
+ }, [
109
+ table,
110
+ selectedRows,
111
+ onRowSelect,
112
+ dataKey,
113
+ columnSizing,
114
+ availableWidth,
115
+ measuredFitContentWidths,
116
+ ]);
82
117
  const resolvedLayout = React.useMemo(() => {
83
118
  const next = {};
84
119
  table.getVisibleLeafColumns().forEach((column) => {
@@ -15,7 +15,7 @@ export function TableHeaderCell({ column, index, sortById, sortDirection, onSort
15
15
  const nextDirection = getNextSortDirection(column.sortable, active, sortDirection !== null && sortDirection !== void 0 ? sortDirection : null);
16
16
  onSortChange(column, nextDirection);
17
17
  };
18
- return (_jsxs("th", { className: cx(styles.headerCell, dividerClass), scope: "col", "aria-sort": ariaSort, "data-align": align, "data-divider": column.divider, "data-column-index": index, children: [_jsx("div", { className: alignClasses.inner, children: _jsx("div", { className: alignClasses.main, children: column.sortable ? (_jsxs("button", { type: "button", className: alignClasses.button, onClick: handleToggleSort, onKeyDown: e => {
18
+ return (_jsxs("th", { className: cx(styles.headerCell, dividerClass), scope: "col", "aria-sort": ariaSort, "data-align": align, "data-divider": column.divider, "data-column-index": index, "data-column-id": column.id, "data-fit-content-column": column.fitContent || undefined, children: [_jsx("div", { className: alignClasses.inner, children: _jsx("div", { className: alignClasses.main, children: column.sortable ? (_jsxs("button", { type: "button", className: alignClasses.button, onClick: handleToggleSort, onKeyDown: e => {
19
19
  if (!shouldToggleOnKey(e.key))
20
20
  return;
21
21
  e.preventDefault();
@@ -46,8 +46,10 @@ export function TableRow({ row, rowId, columns, selectedRows, hasSelection, sele
46
46
  onRowSelect === null || onRowSelect === void 0 ? void 0 : onRowSelect(rowId, checked);
47
47
  } })) }) }) })) : null, columns.map(column => {
48
48
  var _a;
49
- const allowWrap = shouldAllowWrap(column.allowWrap, isSelected, viewMode);
49
+ const allowWrap = column.fitContent
50
+ ? false
51
+ : shouldAllowWrap(column.allowWrap, isSelected, viewMode);
50
52
  const cellValue = getCellDisplayValue(row, column);
51
- return (_jsx("td", { className: cx(styles.cell, allowWrap ? styles.allowWrap : styles.nowrap, column.divider === 'left' && styles.dividerLeft, column.divider === 'right' && styles.dividerRight), "data-align": (_a = column.align) !== null && _a !== void 0 ? _a : 'left', "data-divider": column.divider, children: _jsx("div", { className: styles.cellContent, children: allowWrap ? cellValue : _jsx("div", { className: styles.cellValueEllipsis, children: cellValue }) }) }, column.id));
53
+ return (_jsx("td", { className: cx(styles.cell, allowWrap ? styles.allowWrap : styles.nowrap, column.divider === 'left' && styles.dividerLeft, column.divider === 'right' && styles.dividerRight), "data-align": (_a = column.align) !== null && _a !== void 0 ? _a : 'left', "data-divider": column.divider, "data-column-id": column.id, "data-fit-content-column": column.fitContent || undefined, children: _jsx("div", { className: styles.cellContent, children: allowWrap ? cellValue : _jsx("div", { className: styles.cellValueEllipsis, children: cellValue }) }) }, column.id));
52
54
  })] }));
53
55
  }
@@ -17,6 +17,7 @@ export declare function buildDistributedColumnWidths(args: {
17
17
  defaultMinPx: number;
18
18
  columnSizing: ColumnSizingState;
19
19
  availableWidth: number;
20
+ measuredFitContentWidths?: Record<string, number>;
20
21
  }): {
21
22
  selectionWidth?: number;
22
23
  widths: Record<string, number>;
@@ -20,7 +20,7 @@ export function buildColumnVisibilityFromVisibleIds(defs, visibleColumnIds) {
20
20
  }
21
21
  export function mapDefsToColumnItems(defs, columnVisibility, resolvedLayout = {}) {
22
22
  return defs.map((def, index) => {
23
- var _a, _b, _c, _d, _e, _f, _g;
23
+ var _a, _b, _c, _d, _e, _f, _g, _h;
24
24
  const id = getColumnId(def, index);
25
25
  const accessorKey = def.accessorKey;
26
26
  const accessorFn = def.accessorFn;
@@ -55,10 +55,11 @@ export function mapDefsToColumnItems(defs, columnVisibility, resolvedLayout = {}
55
55
  render,
56
56
  hidden: !isVisible,
57
57
  width: (_e = resolvedLayout[id]) === null || _e === void 0 ? void 0 : _e.width,
58
+ fitContent: (_f = meta.fitContent) !== null && _f !== void 0 ? _f : false,
58
59
  align: meta.align,
59
60
  verticalAlign: meta.verticalAlign,
60
- emptyPlaceholder: (_f = meta.emptyPlaceholder) !== null && _f !== void 0 ? _f : '-',
61
- allowWrap: (_g = meta.allowWrap) !== null && _g !== void 0 ? _g : false,
61
+ emptyPlaceholder: (_g = meta.emptyPlaceholder) !== null && _g !== void 0 ? _g : '-',
62
+ allowWrap: (_h = meta.allowWrap) !== null && _h !== void 0 ? _h : false,
62
63
  severity: meta.severity,
63
64
  divider: meta.divider,
64
65
  };
@@ -106,11 +107,11 @@ function toIntegerTrackWidths(tracks, targetWidth) {
106
107
  return Object.fromEntries(floored.map(track => [track.id, track.width]));
107
108
  }
108
109
  export function buildDistributedColumnWidths(args) {
109
- const { table, hasSelection, defaultMinPx, columnSizing, availableWidth } = args;
110
+ const { table, hasSelection, defaultMinPx, columnSizing, availableWidth, measuredFitContentWidths = {}, } = args;
110
111
  const leaf = table.getVisibleLeafColumns();
111
112
  const selectionWidth = hasSelection ? SELECTION_COLUMN_PX : 0;
112
113
  const tracks = leaf.map((c) => {
113
- var _a, _b, _c, _d, _e;
114
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
114
115
  const def = c.columnDef;
115
116
  const meta = ((_b = ((_a = def.meta) !== null && _a !== void 0 ? _a : {})) !== null && _b !== void 0 ? _b : {});
116
117
  const min = Math.max(1, Number((_c = def.minSize) !== null && _c !== void 0 ? _c : defaultMinPx));
@@ -126,7 +127,19 @@ export function buildDistributedColumnWidths(args) {
126
127
  fixed: true,
127
128
  };
128
129
  }
129
- const rawWeight = Number((_e = (_d = meta.weight) !== null && _d !== void 0 ? _d : def.size) !== null && _e !== void 0 ? _e : DEFAULT_COLUMN_PX);
130
+ if (meta.fitContent) {
131
+ const preferredRaw = Number((_g = (_f = (_e = (_d = measuredFitContentWidths[c.id]) !== null && _d !== void 0 ? _d : def.size) !== null && _e !== void 0 ? _e : def.maxSize) !== null && _f !== void 0 ? _f : def.minSize) !== null && _g !== void 0 ? _g : defaultMinPx);
132
+ const preferred = Number.isFinite(preferredRaw) && preferredRaw > 0 ? preferredRaw : defaultMinPx;
133
+ const fitWidth = Math.round(clamp(preferred, min, max));
134
+ return {
135
+ id: c.id,
136
+ width: fitWidth,
137
+ weight: 0,
138
+ max: fitWidth,
139
+ fixed: true,
140
+ };
141
+ }
142
+ const rawWeight = Number((_j = (_h = meta.weight) !== null && _h !== void 0 ? _h : def.size) !== null && _j !== void 0 ? _j : DEFAULT_COLUMN_PX);
130
143
  const weight = Number.isFinite(rawWeight) && rawWeight > 0 ? rawWeight : DEFAULT_COLUMN_PX;
131
144
  return {
132
145
  id: c.id,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dbcdk/react-components",
3
- "version": "0.0.35",
3
+ "version": "0.0.36",
4
4
  "description": "Reusable React components for DBC projects",
5
5
  "license": "ISC",
6
6
  "author": "",