@agilant/toga-blox 1.0.206 → 1.0.208

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,3 +1,3 @@
1
1
  import { TableCellProps } from "./types";
2
- declare const TableCell: ({ cell, isLastCell, expanded, onToggle, maxCharacters, cellMaxWidthWhenExpanded, cellColor, additionalCellClassNames, toggleComponent: ToggleComponent, cellExpandable, linkTextClassNames, cellTextClassNames, onOverflow, cellKey, }: TableCellProps) => import("react/jsx-runtime").JSX.Element;
2
+ declare const TableCell: ({ cell, isLastCell, expanded, onToggle, maxCharacters, cellMaxWidthWhenExpanded, cellColor, additionalCellClassNames, toggleComponent: ToggleComponent, cellExpandable, linkTextClassNames, cellTextClassNames, onCellOverflow, }: TableCellProps) => import("react/jsx-runtime").JSX.Element;
3
3
  export default TableCell;
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // src/components/TableCell/TableCell.tsx
3
- import { useEffect } from "react";
3
+ import { useEffect, useRef } from "react";
4
4
  const DEFAULT_MAX_CHARS = 30;
5
5
  // Default only implements the **collapsed** “Show more” UI.
6
6
  // We’ll never use its expanded branch, since expanded is handled below.
@@ -8,7 +8,8 @@ const DefaultCollapsedToggle = ({ onToggle, truncated, className = "", linkTextC
8
8
  e.stopPropagation();
9
9
  onToggle();
10
10
  }, children: _jsxs("span", { children: [truncated, "\u2026", _jsx("span", { className: `hidden group-hover:inline text-purple-500 ml-1 underline ${linkTextClassNames}`, children: "Show more" })] }) }));
11
- const TableCell = ({ cell, isLastCell, expanded, onToggle, maxCharacters = DEFAULT_MAX_CHARS, cellMaxWidthWhenExpanded = 50, cellColor = "bg-blue-500", additionalCellClassNames = "", toggleComponent: ToggleComponent = DefaultCollapsedToggle, cellExpandable = false, linkTextClassNames = "text-purple-500 ml-1 underline", cellTextClassNames = "", onOverflow = () => { }, cellKey, }) => {
11
+ const TableCell = ({ cell, isLastCell, expanded, onToggle, maxCharacters = DEFAULT_MAX_CHARS, cellMaxWidthWhenExpanded = 50, cellColor = "bg-blue-500", additionalCellClassNames = "", toggleComponent: ToggleComponent = DefaultCollapsedToggle, cellExpandable = false, linkTextClassNames = "text-purple-500 ml-1 underline", cellTextClassNames = "", onCellOverflow = () => { }, }) => {
12
+ const prev = useRef();
12
13
  // --- truncation logic ---
13
14
  const isString = typeof cell.value === "string";
14
15
  const fullText = isString ? cell.value : "";
@@ -30,10 +31,14 @@ const TableCell = ({ cell, isLastCell, expanded, onToggle, maxCharacters = DEFAU
30
31
  }
31
32
  : {},
32
33
  });
33
- const { key: domKey, ...safeCellProps } = rawCellProps;
34
+ const { key: cellKey, ...safeCellProps } = rawCellProps;
35
+ console.warn(fullText.length, "LENGTH");
34
36
  useEffect(() => {
35
- onOverflow(isLong);
36
- }, [isLong, onOverflow]);
37
+ if (prev.current !== needsToggle) {
38
+ onCellOverflow(needsToggle);
39
+ prev.current = needsToggle;
40
+ }
41
+ }, [needsToggle, onCellOverflow]);
37
42
  return (_jsx("td", { ...safeCellProps, className: isStickyColumn ? undefined : isLastCell ? "" : baseTd, children: _jsx("div", { className: wrapper, style: { maxWidth: `${cellMaxWidthWhenExpanded}ch` }, children: needsToggle ? (!expanded ? (_jsx(ToggleComponent, { expanded: expanded, onToggle: onToggle, truncated: truncated, fullText: fullText, className: additionalCellClassNames, linkTextClassNames: linkTextClassNames })) : (_jsxs("div", { className: "flex flex-col", style: {
38
43
  maxWidth: `${cellMaxWidthWhenExpanded}ch`,
39
44
  }, children: [_jsx("span", { className: `text-left pr-5 ${cellTextClassNames}`, children: fullText }), _jsx("span", { onClick: (e) => {
@@ -35,6 +35,5 @@ export interface TableCellProps {
35
35
  /** classes for both “more” & “less” links */
36
36
  linkTextClassNames?: string;
37
37
  cellTextClassNames: string;
38
- onOverflow?: (overflowing: boolean) => void;
39
- cellKey: string;
38
+ onCellOverflow?: (isOverflowing: boolean) => void;
40
39
  }
@@ -29,7 +29,7 @@ export interface TableRowProps<T extends DataWithUUID> {
29
29
  cellMaxWidthWhenExpanded: number;
30
30
  additionalCellClassNames: string;
31
31
  toggleComponent?: React.ComponentType<ToggleProps>;
32
- onCellOverflow?: (cellKey: string, isOverflowing: boolean) => void;
32
+ onRowOverflow?: (rowUuid: string, hasOverflow: boolean) => void;
33
33
  }
34
- declare const TableRow: <T extends DataWithUUID>({ row, prepareRow, activeIndex, activeRowColor, rowHoverClasses, rowClassNames, hasInfiniteScroll, rowUuid, onRowClick, expandedCells, toggleCell, hasDropDown, onFetchRowData, loadingIndicator, errorIndicator, expandedContent, expandedRowUuid, cellExpandable, onToggleRow, maxCharacters, cellColor, cellMaxWidthWhenExpanded, additionalCellClassNames, toggleComponent, linkTextClassNames, cellTextClassNames, onCellOverflow, }: TableRowProps<T>) => import("react/jsx-runtime").JSX.Element;
34
+ declare const TableRow: <T extends DataWithUUID>({ row, prepareRow, activeIndex, activeRowColor, rowHoverClasses, rowClassNames, hasInfiniteScroll, rowUuid, onRowClick, expandedCells, toggleCell, hasDropDown, onFetchRowData, loadingIndicator, errorIndicator, expandedContent, expandedRowUuid, cellExpandable, onToggleRow, maxCharacters, cellColor, cellMaxWidthWhenExpanded, additionalCellClassNames, toggleComponent, linkTextClassNames, cellTextClassNames, onRowOverflow, }: TableRowProps<T>) => import("react/jsx-runtime").JSX.Element;
35
35
  export default TableRow;
@@ -1,11 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // src/components/TableRow/TableRow.tsx
3
- import { Fragment, useState } from "react";
3
+ import { Fragment, useState, useCallback } from "react";
4
4
  import { motion, AnimatePresence } from "framer-motion";
5
5
  import TableCell from "../TableCell";
6
- const TableRow = ({ row, prepareRow, activeIndex, activeRowColor = "bg-pink-100", rowHoverClasses = "hover:bg-navy-100 hover:cursor-pointer", rowClassNames = "", hasInfiniteScroll, rowUuid, onRowClick, expandedCells, toggleCell, hasDropDown = false, onFetchRowData, loadingIndicator, errorIndicator, expandedContent, expandedRowUuid = null, cellExpandable = false, onToggleRow, maxCharacters = 30, cellColor = "bg-blue-50", cellMaxWidthWhenExpanded = 50, additionalCellClassNames = "", toggleComponent = undefined, linkTextClassNames = "", cellTextClassNames = "", onCellOverflow, }) => {
6
+ const TableRow = ({ row, prepareRow, activeIndex, activeRowColor = "bg-pink-100", rowHoverClasses = "hover:bg-navy-100 hover:cursor-pointer", rowClassNames = "", hasInfiniteScroll, rowUuid, onRowClick, expandedCells, toggleCell, hasDropDown = false, onFetchRowData, loadingIndicator, errorIndicator, expandedContent, expandedRowUuid = null, cellExpandable = false, onToggleRow, maxCharacters = 30, cellColor = "bg-blue-50", cellMaxWidthWhenExpanded = 50, additionalCellClassNames = "", toggleComponent = undefined, linkTextClassNames = "", cellTextClassNames = "", onRowOverflow = () => { }, }) => {
7
7
  prepareRow(row);
8
8
  const rowClasses = `border-primary${activeIndex === row.index ? ` activeRow ${activeRowColor}` : ""}`;
9
+ const [overflowMap, setOverflowMap] = useState({});
9
10
  /* keep fetch/loading local */
10
11
  const [isLoading, setIsLoading] = useState(false);
11
12
  const [error, setError] = useState(null);
@@ -31,6 +32,15 @@ const TableRow = ({ row, prepareRow, activeIndex, activeRowColor = "bg-pink-100"
31
32
  }
32
33
  }
33
34
  };
35
+ const handleOverflow = useCallback((cellKey, isOverflowing) => {
36
+ setOverflowMap((m) => {
37
+ const next = { ...m, [cellKey]: isOverflowing };
38
+ const anyOverflow = Object.values(next).some(Boolean);
39
+ // notify parent of overall row overflow
40
+ onRowOverflow?.(rowUuid, anyOverflow);
41
+ return next;
42
+ });
43
+ }, [onRowOverflow, rowUuid]);
34
44
  // Fix: Key is discarded from the spread obj, react still gets key just not from spread i.e. key={rowUuid}
35
45
  // Pull props ahead of time and separate out 'key'
36
46
  // If row.getRowProps exists, call function, else use empty
@@ -41,10 +51,7 @@ const TableRow = ({ row, prepareRow, activeIndex, activeRowColor = "bg-pink-100"
41
51
  : {};
42
52
  return (_jsxs(Fragment, { children: [_jsx("tr", { "data-testid": "table-row", className: `border-b border-b-navy-200 ${rowHoverClasses} ${rowClasses} ${rowClassNames}`, onClick: handleRowClick, ...safeRowProps, children: row.cells.map((cell, idx) => {
43
53
  const cellKey = `${rowUuid ?? "no-uuid"}-${cell.column.id}`;
44
- const handleOverflow = (isOverflowing) => {
45
- onCellOverflow?.(cellKey, isOverflowing);
46
- };
47
- return (_jsx(TableCell, { cell: cell, isLastCell: idx === row.cells.length - 1, hasInfiniteScroll: hasInfiniteScroll, cellExpandable: cellExpandable, expanded: expandedCells[cellKey] ?? false, onToggle: () => toggleCell(cellKey), linkTextClassNames: linkTextClassNames, maxCharacters: maxCharacters, cellColor: cellColor, cellMaxWidthWhenExpanded: cellMaxWidthWhenExpanded, additionalCellClassNames: additionalCellClassNames, toggleComponent: toggleComponent, cellTextClassNames: cellTextClassNames, onOverflow: handleOverflow, cellKey: cellKey }, cellKey));
54
+ return (_jsx(TableCell, { cell: cell, isLastCell: idx === row.cells.length - 1, hasInfiniteScroll: hasInfiniteScroll, cellExpandable: cellExpandable, expanded: expandedCells[cellKey] ?? false, onToggle: () => toggleCell(cellKey), linkTextClassNames: linkTextClassNames, maxCharacters: maxCharacters, cellColor: cellColor, cellMaxWidthWhenExpanded: cellMaxWidthWhenExpanded, additionalCellClassNames: additionalCellClassNames, toggleComponent: toggleComponent, cellTextClassNames: cellTextClassNames, onCellOverflow: (isOverflowing) => handleOverflow(cellKey, isOverflowing) }, cellKey));
48
55
  }) }, rowUuid), hasDropDown && (_jsx(AnimatePresence, { children: isExpanded && (_jsx("tr", { "data-testid": "expanded-row", children: _jsx("td", { colSpan: row.cells.length, className: "p-0", children: _jsx(motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.3 }, className: "overflow-hidden w-full", children: isLoading ? (loadingIndicator ?? (_jsx("span", { children: "Loading..." }))) : error ? (errorIndicator ? (errorIndicator(error)) : (_jsxs("span", { className: "text-red-700", children: ["Error: ", error.message] }))) : (expandedContent ?? (_jsxs("span", { children: ["drop down \u2013 ", rowUuid] }))) }, "expanded-dropdown-content") }) })) }))] }));
49
56
  };
50
57
  export default TableRow;
@@ -11,7 +11,7 @@ const sampleData = {
11
11
  uuid: "12345",
12
12
  name: "John Doe",
13
13
  age: 30,
14
- address: "123 Main St, Springfield, IL 62701, USA – apartment 4B",
14
+ address: "123 Main St, Springfield, IL 62701, USA – apartment 4B 123 Main St, Springfield, IL 62701, USA – apartment 4B 123 Main St, Springfield, IL 62701, USA – apartment 4B 123 Main St, Springfield, IL 62701, USA – apartment 4B",
15
15
  email: "john.doe@example.com",
16
16
  phone: "+1 555-123-4567",
17
17
  status: "Active",
@@ -97,13 +97,17 @@ export default meta;
97
97
  const Template = (args) => {
98
98
  // ── cell-level state (unchanged) ──
99
99
  const [expandedCells, setExpandedCells] = React.useState({});
100
+ const [rowHasOverflow, setRowHasOverflow] = React.useState(false);
100
101
  const toggleCell = React.useCallback((key) => setExpandedCells((s) => ({ ...s, [key]: !s[key] })), []);
101
102
  // ── **new** single-row expansion state ──
102
103
  const [expandedRowUuid, setExpandedRowUuid] = React.useState(null);
103
104
  const onToggleRow = React.useCallback((uuid) => setExpandedRowUuid((prev) => (prev === uuid ? null : uuid)), []);
104
- return (_jsx("table", { className: "min-w-[700px]", children: _jsx("tbody", { children: _jsx(TableRow, { additionalCellClassNames: "", cellColor: "", cellMaxWidthWhenExpanded: 0, row: undefined, prepareRow: function (row) {
105
- throw new Error("Function not implemented.");
106
- }, ...args, expandedCells: expandedCells, toggleCell: toggleCell, hasInfiniteScroll: args.hasInfiniteScroll ?? true, onRowClick: args.onRowClick ?? (() => alert("from row")), expandedRowUuid: expandedRowUuid, onToggleRow: onToggleRow, maxCharacters: 30 }) }) }));
105
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { style: { marginBottom: 12 }, children: ["\uD83D\uDEA8 Row overflow?", " ", _jsx("strong", { children: rowHasOverflow ? "YES" : "no" })] }), _jsx("table", { className: "min-w-[700px]", children: _jsx("tbody", { children: _jsx(TableRow, { additionalCellClassNames: "", cellColor: "", cellMaxWidthWhenExpanded: 0, row: undefined, prepareRow: function (row) {
106
+ throw new Error("Function not implemented.");
107
+ }, ...args, expandedCells: expandedCells, toggleCell: toggleCell, hasInfiniteScroll: args.hasInfiniteScroll ?? true, onRowClick: args.onRowClick ?? (() => alert("from row")), expandedRowUuid: expandedRowUuid, onToggleRow: onToggleRow, maxCharacters: 30, onRowOverflow: (_uuid, anyOverflow) => {
108
+ console.log("onRowOverflow:", anyOverflow);
109
+ setRowHasOverflow(anyOverflow);
110
+ } }) }) })] }));
107
111
  };
108
112
  /* ------------------------------------------------------------------ */
109
113
  /* STORIES */
@@ -117,6 +121,7 @@ Default.args = {
117
121
  globalTrimActive: false,
118
122
  hasDropDown: false,
119
123
  rowUuid: sampleData.uuid,
124
+ cellExpandable: true,
120
125
  };
121
126
  export const ExpandableRow = Template.bind({});
122
127
  ExpandableRow.args = {
@@ -129,7 +134,7 @@ export const MultipleRows = () => {
129
134
  const toggleCell = React.useCallback((key) => setExpandedCells((s) => ({ ...s, [key]: !s[key] })), []);
130
135
  const [expandedRowUuid, setExpandedRowUuid] = React.useState(null);
131
136
  const onToggleRow = React.useCallback((uuid) => setExpandedRowUuid((prev) => (prev === uuid ? null : uuid)), []);
132
- return (_jsx("table", { className: "min-w-[700px]", children: _jsxs("tbody", { children: [_jsx(TableRow, { row: mockRow, prepareRow: prepareRow, hasInfiniteScroll: true, onRowClick: () => alert("from row"), hasDropDown: true, rowUuid: "1", expandedContent: sampleData.expandedContent, expandedCells: expandedCells, toggleCell: toggleCell, expandedRowUuid: expandedRowUuid, onToggleRow: onToggleRow, maxCharacters: 30, cellColor: "", cellMaxWidthWhenExpanded: 0, additionalCellClassNames: "" }), _jsx(TableRow, { row: mockRow2, prepareRow: prepareRow, hasInfiniteScroll: true, onRowClick: () => alert("from row"), hasDropDown: false, rowUuid: "2", expandedContent: sampleData.expandedContent, expandedCells: expandedCells, toggleCell: toggleCell, expandedRowUuid: expandedRowUuid, onToggleRow: onToggleRow, cellExpandable: true, maxCharacters: 30, cellColor: "", cellMaxWidthWhenExpanded: 0, additionalCellClassNames: "" })] }) }));
137
+ return (_jsx("table", { className: "min-w-[700px]", children: _jsxs("tbody", { children: [_jsx(TableRow, { row: mockRow, prepareRow: prepareRow, hasInfiniteScroll: true, onRowClick: () => alert("from row"), hasDropDown: true, rowUuid: "1", expandedContent: sampleData.expandedContent, expandedCells: expandedCells, toggleCell: toggleCell, expandedRowUuid: expandedRowUuid, onToggleRow: onToggleRow, maxCharacters: 30, cellColor: "", cellMaxWidthWhenExpanded: 0, additionalCellClassNames: "", cellExpandable: true }), _jsx(TableRow, { row: mockRow2, prepareRow: prepareRow, hasInfiniteScroll: true, onRowClick: () => alert("from row"), hasDropDown: false, rowUuid: "2", expandedContent: sampleData.expandedContent, expandedCells: expandedCells, toggleCell: toggleCell, expandedRowUuid: expandedRowUuid, onToggleRow: onToggleRow, cellExpandable: true, maxCharacters: 30, cellColor: "", cellMaxWidthWhenExpanded: 0, additionalCellClassNames: "" })] }) }));
133
138
  };
134
139
  export const WithCustomToggle = Template.bind({});
135
140
  WithCustomToggle.args = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agilant/toga-blox",
3
3
  "private": false,
4
- "version": "1.0.206",
4
+ "version": "1.0.208",
5
5
  "description": "",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",