@trail-ui/react
Version:
349 lines (342 loc) • 13.1 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/editable-table/grouped-row-header/grouped-row-header.tsx
var grouped_row_header_exports = {};
__export(grouped_row_header_exports, {
default: () => GroupedRowHeader
});
module.exports = __toCommonJS(grouped_row_header_exports);
var import_react4 = require("react");
// src/editable-table/focus-handler/focus-handler-provider.tsx
var import_react2 = require("react");
// src/editable-table/table-context/table-context-provider.tsx
var import_react = require("react");
var import_jsx_runtime = require("react/jsx-runtime");
var EditableTableContext = (0, import_react.createContext)({
handleSaveData: () => {
},
idSelector: () => {
},
table: {},
tableName: "",
groupData: [],
allowBulkGroupSelection: false,
doesRowHeaderExist: false
});
function useTableContext(cell) {
const { handleSaveData, ...rest } = (0, import_react.useContext)(EditableTableContext);
function updateData(value) {
var _a, _b;
if (cell) {
const accessorKey = cell.column.columnDef.accessorKey;
const groupId = (_a = cell.row.original) == null ? void 0 : _a.editableTableGroupId;
handleSaveData({
accessorKey,
columnId: cell.column.id,
rowId: rest.idSelector(cell.row.original),
value,
...groupId ? { groupId } : {}
});
(_b = rest.table.options.meta) == null ? void 0 : _b.updateData(cell.row.id, accessorKey, value);
}
}
return {
...cell ? { updateData } : {},
...rest
};
}
// src/editable-table/focus-handler/focus-handler-provider.tsx
var import_jsx_runtime2 = require("react/jsx-runtime");
var FocusDataContext = (0, import_react2.createContext)({
columnIndex: 0,
rowId: null,
cellType: "headerCell" /* headerCell */,
groupId: null,
rowIndex: 0
});
var FocusDispatchContext = (0, import_react2.createContext)(() => {
});
function useFocusHandler({
cellType,
columnIndex,
groupId,
rowId,
rowIndex
}) {
var _a;
const focusedCell = (0, import_react2.useContext)(FocusDataContext);
const setFocusedCell = (0, import_react2.useContext)(FocusDispatchContext);
const { allowBulkGroupSelection, tableRef, table, serverPagination } = useTableContext();
const filteredRows = (_a = table == null ? void 0 : table.getRowModel().rows) != null ? _a : [];
const localRowIndex = filteredRows.findIndex((row) => row.id === rowId);
const isCurrentCellFocused = (0, import_react2.useMemo)(() => {
var _a2;
const isFocused = ((_a2 = tableRef.current) == null ? void 0 : _a2.contains(document.activeElement)) && focusedCell.cellType === cellType;
switch (cellType) {
case "headerCell" /* headerCell */:
case "footerCell" /* footerCell */:
return isFocused && focusedCell.columnIndex === columnIndex;
case "groupHeaderCell" /* groupHeaderCell */: {
let isGroup = focusedCell.groupId === groupId;
if (allowBulkGroupSelection) {
isGroup && (isGroup = columnIndex === 0 ? focusedCell.columnIndex === 0 : focusedCell.columnIndex > 0);
}
return isFocused && isGroup;
}
case "dataCell" /* dataCell */:
return isFocused && focusedCell.rowIndex === localRowIndex && focusedCell.columnIndex === columnIndex;
default:
return false;
}
}, [focusedCell, columnIndex, cellType, groupId, localRowIndex, allowBulkGroupSelection]);
const focusCurrentCell = (0, import_react2.useCallback)(() => {
setFocusedCell == null ? void 0 : setFocusedCell({ columnIndex, rowId, cellType, groupId, rowIndex });
}, [columnIndex, rowId, cellType, groupId, rowIndex]);
const resetFocus = (0, import_react2.useCallback)(() => {
setFocusedCell == null ? void 0 : setFocusedCell({
cellType: "headerCell" /* headerCell */,
rowId: null,
groupId: null,
rowIndex: -1,
columnIndex: 0
});
}, []);
return {
isCurrentCellFocused,
focusCurrentCell,
resetFocus
};
}
// src/editable-table/components-for-stories/checkbox.tsx
var import_react3 = require("react");
var import_jsx_runtime3 = require("react/jsx-runtime");
var CellCheckbox = (0, import_react3.forwardRef)(
({ isIndeterminate, isSelected, ...props }, ref) => {
const checkboxRef = (0, import_react3.useRef)(null);
(0, import_react3.useEffect)(() => {
if (typeof ref === "function") {
ref(checkboxRef.current);
} else if (ref) {
ref.current = checkboxRef.current;
}
}, [ref]);
(0, import_react3.useEffect)(() => {
if (checkboxRef.current) {
checkboxRef.current.indeterminate = isIndeterminate != null ? isIndeterminate : false;
}
}, [isIndeterminate]);
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "custom-checkbox text-center", children: [
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { ...props, ref: checkboxRef, type: "checkbox" }),
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "box bg-neutral-50", children: [
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
"svg",
{
className: `checkmark ${isSelected ? "visible" : "hidden"}`,
"aria-hidden": "true",
role: "presentation",
viewBox: "0 0 17 18",
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { points: "1 9 7 14 15 4" })
}
),
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
"svg",
{
className: `indeterminate-mark ${isIndeterminate ? "visible" : "hidden"}`,
"aria-hidden": "true",
role: "presentation",
stroke: "currentColor",
strokeWidth: "3",
viewBox: "0 0 24 24",
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "3", x2: "21", y1: "12", y2: "12" })
}
)
] })
] });
}
);
CellCheckbox.displayName = "CellCheckbox";
var checkbox_default = CellCheckbox;
// src/editable-table/grouped-row-header/grouped-row-header.tsx
var import_jsx_runtime4 = require("react/jsx-runtime");
function GroupedRowHeader(props) {
const { groupData, table, allowBulkGroupSelection } = useTableContext();
const currentGroupData = groupData.find((d) => d.groupId === props.groupId);
const columns = table.getHeaderGroups()[0].headers.length;
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("tr", { children: [
allowBulkGroupSelection && currentGroupData && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
GroupHeaderRowCheckbox,
{
groupData: currentGroupData,
columnIndex: allowBulkGroupSelection ? 1 : 0
}
),
currentGroupData && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
GroupRowHeaderCell,
{
groupData: currentGroupData,
columnIndex: allowBulkGroupSelection ? 1 : 0,
colSpan: allowBulkGroupSelection ? columns - 1 : columns
}
)
] });
}
function GroupHeaderRowCheckbox(props) {
var _a;
const [isChecked, setIsChecked] = (0, import_react4.useState)(false);
const cellRef = (0, import_react4.useRef)(null);
const selectAllId = (0, import_react4.useId)();
const { table } = useTableContext();
const { focusCurrentCell, isCurrentCellFocused } = useFocusHandler({
cellType: "groupHeaderCell" /* groupHeaderCell */,
columnIndex: 0,
groupId: (_a = props.groupData) == null ? void 0 : _a.groupId,
rowId: null,
rowIndex: -1
});
const currentPageRowIds = (0, import_react4.useMemo)(
() => new Set(
table.getRowModel().rows.filter(
(r) => r.original.editableTableGroupId === props.groupData.groupId
).map((r) => r.id)
),
[table.getState().pagination.pageSize, table.getState().pagination.pageIndex]
);
function toggleRowsSelection() {
let newValue = false;
if (!isChecked || isChecked === "mixed") {
newValue = true;
}
currentPageRowIds.forEach((id) => {
table.getRowModel().rowsById[id].toggleSelected(newValue);
});
}
(0, import_react4.useEffect)(() => {
var _a2;
if (isCurrentCellFocused) {
(_a2 = cellRef.current) == null ? void 0 : _a2.focus();
}
}, [isCurrentCellFocused]);
(0, import_react4.useEffect)(() => {
const ids = props.groupData.ids.filter((id) => currentPageRowIds.has(id));
const selectedRowIds = Object.keys(table.getState().rowSelection);
if (hasAll(ids, selectedRowIds)) {
setIsChecked(true);
} else if (hasSome(ids, selectedRowIds)) {
setIsChecked("mixed");
} else {
setIsChecked(false);
}
}, [
table.getState().rowSelection,
table.getState().pagination.pageSize,
table.getState().pagination.pageIndex
]);
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("td", { className: "border-b border-r border-t border-neutral-200 bg-neutral-50 px-2 py-2 text-left text-sm font-normal text-neutral-900 last:border-r-0", children: [
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { id: selectAllId, className: "hidden", children: "Select all instances under" }),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
"div",
{
"aria-labelledby": `${selectAllId} ${props.groupData.groupId}`,
role: "checkbox",
"aria-checked": isChecked,
ref: cellRef,
className: "td-content flex h-6 w-6 items-center justify-center outline-purple-600",
onClick: (e) => {
var _a2;
if (e.target.tagName.toLowerCase() === "input") {
focusCurrentCell();
return;
}
const checkbox = (_a2 = cellRef.current) == null ? void 0 : _a2.querySelector('input[type="checkbox"]');
checkbox == null ? void 0 : checkbox.click();
focusCurrentCell();
},
onKeyDown: (e) => {
var _a2;
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
const checkbox = (_a2 = cellRef.current) == null ? void 0 : _a2.querySelector('input[type="checkbox"]');
if (checkbox) {
checkbox.click();
}
}
},
tabIndex: isCurrentCellFocused ? 0 : -1,
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
checkbox_default,
{
"aria-hidden": true,
tabIndex: -1,
type: "checkbox",
"aria-label": "Select all status",
checked: !!isChecked,
isIndeterminate: isChecked === "mixed",
isSelected: isChecked,
onChange: toggleRowsSelection
}
)
}
)
] });
}
function GroupRowHeaderCell(props) {
var _a;
const cellRef = (0, import_react4.useRef)(null);
const { focusCurrentCell, isCurrentCellFocused } = useFocusHandler({
cellType: "groupHeaderCell" /* groupHeaderCell */,
columnIndex: props.columnIndex,
groupId: (_a = props.groupData) == null ? void 0 : _a.groupId,
rowId: null,
rowIndex: -1
});
(0, import_react4.useEffect)(() => {
var _a2;
if (isCurrentCellFocused) {
(_a2 = cellRef.current) == null ? void 0 : _a2.focus();
}
}, [isCurrentCellFocused]);
return (
// biome-ignore lint/a11y/useKeyWithClickEvents: <explanation>
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
"th",
{
id: props.groupData.groupId,
ref: cellRef,
className: `border-b border-r border-t border-neutral-200 px-2 py-2 text-left text-sm font-normal text-neutral-900 last:border-r-0 focus:outline-purple-700 focus:[outline-style:solid]`,
onClick: focusCurrentCell,
tabIndex: isCurrentCellFocused ? 0 : -1,
colSpan: props.colSpan,
scope: "colgroup",
children: [
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "overflow-hidden text-sm font-semibold", children: props.groupData.groupName }),
" ",
props.groupData.description && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "overflow-hidden text-sm text-neutral-600", children: props.groupData.description })
]
}
)
);
}
function hasSome(array1, array2) {
const set2 = new Set(array2);
return array1.some((item) => set2.has(item));
}
function hasAll(array1, array2) {
const set2 = new Set(array2);
return array1.every((item) => set2.has(item));
}