@multiplatform.one/table 7.11.0 → 7.16.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.
- package/README.md +1 -1
- package/dist/cjs/components/ChildTable/index.cjs +8 -2
- package/dist/cjs/components/ChildTable/index.native.js +8 -2
- package/dist/cjs/components/ChildTable/index.native.js.map +1 -1
- package/dist/cjs/components/ColumnHeaderFilter/index.cjs +77 -111
- package/dist/cjs/components/ColumnHeaderFilter/index.native.js +89 -129
- package/dist/cjs/components/ColumnHeaderFilter/index.native.js.map +1 -1
- package/dist/cjs/components/DataTable/DataTableRoot.cjs +17 -1
- package/dist/cjs/components/DataTable/DataTableRoot.native.js +25 -2
- package/dist/cjs/components/DataTable/DataTableRoot.native.js.map +1 -1
- package/dist/cjs/components/DataTableBulkActions/index.cjs +1 -1
- package/dist/cjs/components/DataTableBulkActions/index.native.js +1 -1
- package/dist/cjs/components/DataTableBulkActions/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableCell/CellModalEditor.cjs +72 -70
- package/dist/cjs/components/DataTableCell/index.cjs +2 -2
- package/dist/cjs/components/DataTableCell/index.native.js +2 -11
- package/dist/cjs/components/DataTableCell/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableDateFilter/index.cjs +135 -158
- package/dist/cjs/components/DataTableDateFilter/index.native.js +153 -183
- package/dist/cjs/components/DataTableDateFilter/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableExport/index.cjs +122 -139
- package/dist/cjs/components/DataTableExport/index.native.js +135 -157
- package/dist/cjs/components/DataTableExport/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableGrouping/index.cjs +192 -212
- package/dist/cjs/components/DataTableGrouping/index.native.js +209 -230
- package/dist/cjs/components/DataTableGrouping/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableSearch/index.cjs +103 -115
- package/dist/cjs/components/DataTableSearch/index.native.js +111 -123
- package/dist/cjs/components/DataTableSearch/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableToolbar/index.cjs +44 -61
- package/dist/cjs/components/DataTableToolbar/index.native.js +46 -65
- package/dist/cjs/components/DataTableToolbar/index.native.js.map +1 -1
- package/dist/cjs/components/DataTableViewOptions/index.cjs +38 -54
- package/dist/cjs/components/DataTableViewOptions/index.native.js +40 -56
- package/dist/cjs/components/DataTableViewOptions/index.native.js.map +1 -1
- package/dist/cjs/components/FilterOperatorValueEditor/index.cjs +3 -11
- package/dist/cjs/components/FilterOperatorValueEditor/index.native.js +3 -11
- package/dist/cjs/components/FilterOperatorValueEditor/index.native.js.map +1 -1
- package/dist/cjs/components/SimpleTable/index.cjs +2 -6
- package/dist/cjs/components/SimpleTable/index.native.js +2 -6
- package/dist/cjs/components/SimpleTable/index.native.js.map +1 -1
- package/dist/cjs/components/TableInput/RowDetailEditor.cjs +190 -0
- package/dist/cjs/components/TableInput/RowDetailEditor.native.js +172 -0
- package/dist/cjs/components/TableInput/RowDetailEditor.native.js.map +1 -0
- package/dist/cjs/components/TableInput/index.cjs +42 -5
- package/dist/cjs/components/TableInput/index.native.js +64 -1
- package/dist/cjs/components/TableInput/index.native.js.map +1 -1
- package/dist/cjs/components/TableInput/shared.cjs +8 -0
- package/dist/cjs/components/TableInput/shared.native.js +10 -0
- package/dist/cjs/components/TableInput/shared.native.js.map +1 -1
- package/dist/cjs/hooks/useDataTable.cjs +11 -1
- package/dist/cjs/hooks/useDataTable.native.js +12 -2
- package/dist/cjs/hooks/useDataTable.native.js.map +1 -1
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/utils/rowPress.cjs +4 -1
- package/dist/cjs/utils/rowPress.native.js +4 -1
- package/dist/cjs/utils/rowPress.native.js.map +1 -1
- package/dist/esm/components/ChildTable/index.mjs +8 -2
- package/dist/esm/components/ChildTable/index.mjs.map +1 -1
- package/dist/esm/components/ChildTable/index.native.js +8 -2
- package/dist/esm/components/ChildTable/index.native.js.map +1 -1
- package/dist/esm/components/ColumnHeaderFilter/index.mjs +80 -114
- package/dist/esm/components/ColumnHeaderFilter/index.mjs.map +1 -1
- package/dist/esm/components/ColumnHeaderFilter/index.native.js +92 -132
- package/dist/esm/components/ColumnHeaderFilter/index.native.js.map +1 -1
- package/dist/esm/components/DataTable/DataTableRoot.mjs +17 -1
- package/dist/esm/components/DataTable/DataTableRoot.mjs.map +1 -1
- package/dist/esm/components/DataTable/DataTableRoot.native.js +25 -2
- package/dist/esm/components/DataTable/DataTableRoot.native.js.map +1 -1
- package/dist/esm/components/DataTableBulkActions/index.mjs +1 -1
- package/dist/esm/components/DataTableBulkActions/index.mjs.map +1 -1
- package/dist/esm/components/DataTableBulkActions/index.native.js +1 -1
- package/dist/esm/components/DataTableBulkActions/index.native.js.map +1 -1
- package/dist/esm/components/DataTableCell/CellModalEditor.mjs +76 -74
- package/dist/esm/components/DataTableCell/CellModalEditor.mjs.map +1 -1
- package/dist/esm/components/DataTableCell/index.mjs +3 -3
- package/dist/esm/components/DataTableCell/index.mjs.map +1 -1
- package/dist/esm/components/DataTableCell/index.native.js +3 -12
- package/dist/esm/components/DataTableCell/index.native.js.map +1 -1
- package/dist/esm/components/DataTableDateFilter/index.mjs +137 -160
- package/dist/esm/components/DataTableDateFilter/index.mjs.map +1 -1
- package/dist/esm/components/DataTableDateFilter/index.native.js +155 -185
- package/dist/esm/components/DataTableDateFilter/index.native.js.map +1 -1
- package/dist/esm/components/DataTableExport/index.mjs +124 -141
- package/dist/esm/components/DataTableExport/index.mjs.map +1 -1
- package/dist/esm/components/DataTableExport/index.native.js +137 -159
- package/dist/esm/components/DataTableExport/index.native.js.map +1 -1
- package/dist/esm/components/DataTableGrouping/index.mjs +194 -214
- package/dist/esm/components/DataTableGrouping/index.mjs.map +1 -1
- package/dist/esm/components/DataTableGrouping/index.native.js +211 -232
- package/dist/esm/components/DataTableGrouping/index.native.js.map +1 -1
- package/dist/esm/components/DataTableSearch/index.mjs +105 -117
- package/dist/esm/components/DataTableSearch/index.mjs.map +1 -1
- package/dist/esm/components/DataTableSearch/index.native.js +113 -125
- package/dist/esm/components/DataTableSearch/index.native.js.map +1 -1
- package/dist/esm/components/DataTableToolbar/index.mjs +46 -63
- package/dist/esm/components/DataTableToolbar/index.mjs.map +1 -1
- package/dist/esm/components/DataTableToolbar/index.native.js +48 -67
- package/dist/esm/components/DataTableToolbar/index.native.js.map +1 -1
- package/dist/esm/components/DataTableViewOptions/index.mjs +40 -56
- package/dist/esm/components/DataTableViewOptions/index.mjs.map +1 -1
- package/dist/esm/components/DataTableViewOptions/index.native.js +42 -58
- package/dist/esm/components/DataTableViewOptions/index.native.js.map +1 -1
- package/dist/esm/components/FilterOperatorValueEditor/index.mjs +3 -11
- package/dist/esm/components/FilterOperatorValueEditor/index.mjs.map +1 -1
- package/dist/esm/components/FilterOperatorValueEditor/index.native.js +3 -11
- package/dist/esm/components/FilterOperatorValueEditor/index.native.js.map +1 -1
- package/dist/esm/components/SimpleTable/index.mjs +3 -7
- package/dist/esm/components/SimpleTable/index.mjs.map +1 -1
- package/dist/esm/components/SimpleTable/index.native.js +3 -7
- package/dist/esm/components/SimpleTable/index.native.js.map +1 -1
- package/dist/esm/components/TableInput/RowDetailEditor.mjs +165 -0
- package/dist/esm/components/TableInput/RowDetailEditor.mjs.map +1 -0
- package/dist/esm/components/TableInput/RowDetailEditor.native.js +144 -0
- package/dist/esm/components/TableInput/RowDetailEditor.native.js.map +1 -0
- package/dist/esm/components/TableInput/index.mjs +42 -5
- package/dist/esm/components/TableInput/index.mjs.map +1 -1
- package/dist/esm/components/TableInput/index.native.js +64 -1
- package/dist/esm/components/TableInput/index.native.js.map +1 -1
- package/dist/esm/components/TableInput/shared.mjs +7 -1
- package/dist/esm/components/TableInput/shared.mjs.map +1 -1
- package/dist/esm/components/TableInput/shared.native.js +9 -1
- package/dist/esm/components/TableInput/shared.native.js.map +1 -1
- package/dist/esm/hooks/useDataTable.mjs +11 -1
- package/dist/esm/hooks/useDataTable.mjs.map +1 -1
- package/dist/esm/hooks/useDataTable.native.js +12 -2
- package/dist/esm/hooks/useDataTable.native.js.map +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/utils/rowPress.mjs +4 -1
- package/dist/esm/utils/rowPress.mjs.map +1 -1
- package/dist/esm/utils/rowPress.native.js +4 -1
- package/dist/esm/utils/rowPress.native.js.map +1 -1
- package/dist/jsx/components/ChildTable/index.mjs +8 -2
- package/dist/jsx/components/ChildTable/index.mjs.map +1 -1
- package/dist/jsx/components/ChildTable/index.native.js +8 -2
- package/dist/jsx/components/ChildTable/index.native.js.map +1 -1
- package/dist/jsx/components/ColumnHeaderFilter/index.mjs +80 -114
- package/dist/jsx/components/ColumnHeaderFilter/index.mjs.map +1 -1
- package/dist/jsx/components/ColumnHeaderFilter/index.native.js +89 -129
- package/dist/jsx/components/ColumnHeaderFilter/index.native.js.map +1 -1
- package/dist/jsx/components/DataTable/DataTableRoot.mjs +17 -1
- package/dist/jsx/components/DataTable/DataTableRoot.mjs.map +1 -1
- package/dist/jsx/components/DataTable/DataTableRoot.native.js +25 -2
- package/dist/jsx/components/DataTable/DataTableRoot.native.js.map +1 -1
- package/dist/jsx/components/DataTableBulkActions/index.mjs +1 -1
- package/dist/jsx/components/DataTableBulkActions/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableBulkActions/index.native.js +1 -1
- package/dist/jsx/components/DataTableBulkActions/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableCell/CellModalEditor.mjs +76 -74
- package/dist/jsx/components/DataTableCell/CellModalEditor.mjs.map +1 -1
- package/dist/jsx/components/DataTableCell/index.mjs +3 -3
- package/dist/jsx/components/DataTableCell/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableCell/index.native.js +2 -11
- package/dist/jsx/components/DataTableCell/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableDateFilter/index.mjs +137 -160
- package/dist/jsx/components/DataTableDateFilter/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableDateFilter/index.native.js +153 -183
- package/dist/jsx/components/DataTableDateFilter/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableExport/index.mjs +124 -141
- package/dist/jsx/components/DataTableExport/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableExport/index.native.js +135 -157
- package/dist/jsx/components/DataTableExport/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableGrouping/index.mjs +194 -214
- package/dist/jsx/components/DataTableGrouping/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableGrouping/index.native.js +209 -230
- package/dist/jsx/components/DataTableGrouping/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableSearch/index.mjs +105 -117
- package/dist/jsx/components/DataTableSearch/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableSearch/index.native.js +111 -123
- package/dist/jsx/components/DataTableSearch/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableToolbar/index.mjs +46 -63
- package/dist/jsx/components/DataTableToolbar/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableToolbar/index.native.js +46 -65
- package/dist/jsx/components/DataTableToolbar/index.native.js.map +1 -1
- package/dist/jsx/components/DataTableViewOptions/index.mjs +40 -56
- package/dist/jsx/components/DataTableViewOptions/index.mjs.map +1 -1
- package/dist/jsx/components/DataTableViewOptions/index.native.js +40 -56
- package/dist/jsx/components/DataTableViewOptions/index.native.js.map +1 -1
- package/dist/jsx/components/FilterOperatorValueEditor/index.mjs +3 -11
- package/dist/jsx/components/FilterOperatorValueEditor/index.mjs.map +1 -1
- package/dist/jsx/components/FilterOperatorValueEditor/index.native.js +3 -11
- package/dist/jsx/components/FilterOperatorValueEditor/index.native.js.map +1 -1
- package/dist/jsx/components/SimpleTable/index.mjs +3 -7
- package/dist/jsx/components/SimpleTable/index.mjs.map +1 -1
- package/dist/jsx/components/SimpleTable/index.native.js +2 -6
- package/dist/jsx/components/SimpleTable/index.native.js.map +1 -1
- package/dist/jsx/components/TableInput/RowDetailEditor.mjs +165 -0
- package/dist/jsx/components/TableInput/RowDetailEditor.mjs.map +1 -0
- package/dist/jsx/components/TableInput/RowDetailEditor.native.js +172 -0
- package/dist/jsx/components/TableInput/RowDetailEditor.native.js.map +1 -0
- package/dist/jsx/components/TableInput/index.mjs +42 -5
- package/dist/jsx/components/TableInput/index.mjs.map +1 -1
- package/dist/jsx/components/TableInput/index.native.js +64 -1
- package/dist/jsx/components/TableInput/index.native.js.map +1 -1
- package/dist/jsx/components/TableInput/shared.mjs +7 -1
- package/dist/jsx/components/TableInput/shared.mjs.map +1 -1
- package/dist/jsx/components/TableInput/shared.native.js +10 -0
- package/dist/jsx/components/TableInput/shared.native.js.map +1 -1
- package/dist/jsx/hooks/useDataTable.mjs +11 -1
- package/dist/jsx/hooks/useDataTable.mjs.map +1 -1
- package/dist/jsx/hooks/useDataTable.native.js +12 -2
- package/dist/jsx/hooks/useDataTable.native.js.map +1 -1
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/utils/rowPress.mjs +4 -1
- package/dist/jsx/utils/rowPress.mjs.map +1 -1
- package/dist/jsx/utils/rowPress.native.js +4 -1
- package/dist/jsx/utils/rowPress.native.js.map +1 -1
- package/package.json +14 -14
- package/src/components/ChildTable/childTable.cellHidden.spec.tsx +57 -0
- package/src/components/ChildTable/childTable.rowDetail.spec.tsx +120 -0
- package/src/components/ChildTable/index.tsx +16 -0
- package/src/components/ColumnHeaderFilter/index.tsx +89 -116
- package/src/components/DataTable/DataTable.stories.tsx +71 -6
- package/src/components/DataTable/DataTableRoot.tsx +27 -4
- package/src/components/DataTable/dataTableMobileCards.spec.tsx +1 -4
- package/src/components/DataTable/headerContainment.spec.tsx +91 -0
- package/src/components/DataTable/rowPress.spec.tsx +2 -6
- package/src/components/DataTableBulkActions/DataTableBulkActions.stories.tsx +5 -4
- package/src/components/DataTableBulkActions/index.tsx +1 -1
- package/src/components/DataTableCell/CellModalEditor.tsx +95 -75
- package/src/components/DataTableCell/cellDraftPolicy.spec.tsx +12 -2
- package/src/components/DataTableCell/cellModalEditor.spec.tsx +75 -49
- package/src/components/DataTableCell/dataTableCell.spec.tsx +31 -14
- package/src/components/DataTableCell/index.tsx +3 -2
- package/src/components/DataTableDateFilter/DataTableDateFilter.spec.tsx +6 -3
- package/src/components/DataTableDateFilter/index.tsx +151 -180
- package/src/components/DataTableExport/index.tsx +135 -142
- package/src/components/DataTableGrouping/index.tsx +193 -195
- package/src/components/DataTableSearch/index.tsx +111 -109
- package/src/components/DataTableToolbar/index.tsx +39 -46
- package/src/components/DataTableViewOptions/DataTableViewOptions.stories.tsx +52 -0
- package/src/components/DataTableViewOptions/index.tsx +32 -40
- package/src/components/FilterOperatorValueEditor/FilterOperatorValueEditor.spec.tsx +64 -2
- package/src/components/FilterOperatorValueEditor/index.tsx +0 -8
- package/src/components/SimpleTable/index.tsx +3 -2
- package/src/components/SimpleTable/simpleTable.spec.tsx +15 -0
- package/src/components/Table/accessibility.spec.tsx +7 -19
- package/src/components/TableInput/RowDetailEditor.native.tsx +134 -0
- package/src/components/TableInput/RowDetailEditor.tsx +173 -0
- package/src/components/TableInput/index.native.tsx +49 -1
- package/src/components/TableInput/index.tsx +65 -10
- package/src/components/TableInput/shared.ts +29 -0
- package/src/components/tableDropdowns.spec.tsx +172 -0
- package/src/hooks/useDataTable.spec.ts +39 -0
- package/src/hooks/useDataTable.ts +15 -1
- package/src/index.ts +1 -0
- package/src/utils/rowPress.ts +3 -0
- package/types/components/ChildTable/index.d.ts +10 -0
- package/types/components/ChildTable/index.d.ts.map +1 -1
- package/types/components/ColumnHeaderFilter/index.d.ts +1 -1
- package/types/components/ColumnHeaderFilter/index.d.ts.map +1 -1
- package/types/components/DataTable/DataTableRoot.d.ts.map +1 -1
- package/types/components/DataTableCell/CellModalEditor.d.ts +10 -7
- package/types/components/DataTableCell/CellModalEditor.d.ts.map +1 -1
- package/types/components/DataTableCell/index.d.ts.map +1 -1
- package/types/components/DataTableDateFilter/index.d.ts.map +1 -1
- package/types/components/DataTableGrouping/index.d.ts.map +1 -1
- package/types/components/DataTableSearch/index.d.ts.map +1 -1
- package/types/components/FilterOperatorValueEditor/index.d.ts.map +1 -1
- package/types/components/SimpleTable/index.d.ts.map +1 -1
- package/types/components/TableInput/RowDetailEditor.d.ts +24 -0
- package/types/components/TableInput/RowDetailEditor.d.ts.map +1 -0
- package/types/components/TableInput/RowDetailEditor.native.d.ts +11 -0
- package/types/components/TableInput/RowDetailEditor.native.d.ts.map +1 -0
- package/types/components/TableInput/index.d.ts +11 -2
- package/types/components/TableInput/index.d.ts.map +1 -1
- package/types/components/TableInput/index.native.d.ts +8 -1
- package/types/components/TableInput/index.native.d.ts.map +1 -1
- package/types/components/TableInput/shared.d.ts +11 -0
- package/types/components/TableInput/shared.d.ts.map +1 -1
- package/types/hooks/useDataTable.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/utils/rowPress.d.ts.map +1 -1
|
@@ -605,6 +605,36 @@ export const WithColumnPinning: Story = {
|
|
|
605
605
|
},
|
|
606
606
|
};
|
|
607
607
|
|
|
608
|
+
function RtlDocument({ children }: { children: React.ReactNode }) {
|
|
609
|
+
React.useEffect(() => {
|
|
610
|
+
const previous = document.documentElement.getAttribute("dir");
|
|
611
|
+
document.documentElement.setAttribute("dir", "rtl");
|
|
612
|
+
return () => {
|
|
613
|
+
if (previous === null) document.documentElement.removeAttribute("dir");
|
|
614
|
+
else document.documentElement.setAttribute("dir", previous);
|
|
615
|
+
};
|
|
616
|
+
}, []);
|
|
617
|
+
return <>{children}</>;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
export const WithColumnPinningRTL: Story = {
|
|
621
|
+
name: "With Column Pinning RTL",
|
|
622
|
+
args: WithColumnPinning.args,
|
|
623
|
+
render: (args) => (
|
|
624
|
+
<RtlDocument>
|
|
625
|
+
<DataTable {...args} />
|
|
626
|
+
</RtlDocument>
|
|
627
|
+
),
|
|
628
|
+
parameters: {
|
|
629
|
+
docs: {
|
|
630
|
+
description: {
|
|
631
|
+
story:
|
|
632
|
+
"WithColumnPinning under a right-to-left document. Pinned columns stick to the inline start and end, which are the right and left edges here, and each sticky inset is the summed width of the pinned cells before it (MPO-236).",
|
|
633
|
+
},
|
|
634
|
+
},
|
|
635
|
+
},
|
|
636
|
+
};
|
|
637
|
+
|
|
608
638
|
export const WithKeyboardNavigation: Story = {
|
|
609
639
|
args: {
|
|
610
640
|
data: sampleData,
|
|
@@ -2951,15 +2981,11 @@ export const CompoundComposition: Story = {
|
|
|
2951
2981
|
*/
|
|
2952
2982
|
const RowPressStory = () => {
|
|
2953
2983
|
const data = useMemo(() => generateUsers(8), []);
|
|
2954
|
-
// Explicit ids on every column: DataTable seeds columnOrder from
|
|
2955
|
-
// `col.id || ""`, so mixing id-less accessor columns with id'd display
|
|
2956
|
-
// columns would reorder the id'd ones first.
|
|
2957
2984
|
const rowPressColumns = useMemo<DataTableColumn<User>[]>(
|
|
2958
2985
|
() => [
|
|
2959
|
-
{
|
|
2960
|
-
{
|
|
2986
|
+
{ accessorKey: "firstName", header: "First Name" },
|
|
2987
|
+
{ accessorKey: "department", header: "Department" },
|
|
2961
2988
|
{
|
|
2962
|
-
id: "salary",
|
|
2963
2989
|
accessorKey: "salary",
|
|
2964
2990
|
header: "Salary",
|
|
2965
2991
|
align: "right",
|
|
@@ -3321,3 +3347,42 @@ export const ColumnWidthContract: Story = {
|
|
|
3321
3347
|
);
|
|
3322
3348
|
},
|
|
3323
3349
|
};
|
|
3350
|
+
|
|
3351
|
+
const narrowHeaderRows = [
|
|
3352
|
+
{ id: "1", account: "acme-website", quantity: 142, status: "Live", owner: "Rivera" },
|
|
3353
|
+
{ id: "2", account: "tamagui-docs", quantity: 89, status: "Draft", owner: "Okafor" },
|
|
3354
|
+
{ id: "3", account: "mobile-app", quantity: 34, status: "Live", owner: "Lindqvist" },
|
|
3355
|
+
];
|
|
3356
|
+
|
|
3357
|
+
const narrowHeaderColumns: DataTableColumn<(typeof narrowHeaderRows)[number]>[] = [
|
|
3358
|
+
{ id: "account", accessorKey: "account", header: "Customer account (input)", width: 104 },
|
|
3359
|
+
{
|
|
3360
|
+
id: "quantity",
|
|
3361
|
+
accessorKey: "quantity",
|
|
3362
|
+
header: "Quantity (stepper)",
|
|
3363
|
+
align: "right",
|
|
3364
|
+
width: 104,
|
|
3365
|
+
},
|
|
3366
|
+
{ id: "status", accessorKey: "status", header: "Status (select)", width: 104 },
|
|
3367
|
+
{ id: "owner", accessorKey: "owner", header: "Responsibilities", width: 104 },
|
|
3368
|
+
];
|
|
3369
|
+
|
|
3370
|
+
/**
|
|
3371
|
+
* MPO-336 / LC-10: every column is narrower than its header label plus the
|
|
3372
|
+
* sort and filter glyphs. Each label wraps inside its own header cell, a
|
|
3373
|
+
* single long word breaks rather than overflowing, and the glyphs stay in
|
|
3374
|
+
* their column. Quantity is right-aligned (numbers, DG-TBL-01), the case
|
|
3375
|
+
* that used to spill left over the previous column.
|
|
3376
|
+
*/
|
|
3377
|
+
export const NarrowHeaders: Story = {
|
|
3378
|
+
args: {
|
|
3379
|
+
data: narrowHeaderRows,
|
|
3380
|
+
columns: narrowHeaderColumns as DataTableColumn<Record<string, any>>[],
|
|
3381
|
+
layout: "table",
|
|
3382
|
+
columnLayout: "scroll",
|
|
3383
|
+
enableSorting: true,
|
|
3384
|
+
enableFiltering: true,
|
|
3385
|
+
enablePagination: false,
|
|
3386
|
+
readOnly: true,
|
|
3387
|
+
},
|
|
3388
|
+
};
|
|
@@ -1658,21 +1658,39 @@ export function DataTableRoot<TData extends Record<string, any> = Record<string,
|
|
|
1658
1658
|
}
|
|
1659
1659
|
: {})}
|
|
1660
1660
|
>
|
|
1661
|
+
{/* LC-10 (MPO-336): only the label yields
|
|
1662
|
+
to a narrow column; the glyphs keep their
|
|
1663
|
+
size or they paint into the next one. The
|
|
1664
|
+
filter cluster wraps under the label first,
|
|
1665
|
+
so the label keeps the column's width. */}
|
|
1661
1666
|
<View
|
|
1662
1667
|
flexDirection="row"
|
|
1668
|
+
flexWrap="wrap"
|
|
1663
1669
|
gap="$2"
|
|
1664
1670
|
alignItems="center"
|
|
1665
1671
|
justifyContent={isRightAligned ? "flex-end" : "space-between"}
|
|
1666
1672
|
flex={1}
|
|
1673
|
+
minWidth={0}
|
|
1667
1674
|
>
|
|
1668
1675
|
<View
|
|
1669
1676
|
flexDirection="row"
|
|
1670
1677
|
gap="$2"
|
|
1671
1678
|
alignItems="center"
|
|
1672
|
-
|
|
1679
|
+
flexGrow={isRightAligned ? 0 : 1}
|
|
1680
|
+
flexShrink={1}
|
|
1681
|
+
flexBasis="auto"
|
|
1682
|
+
minWidth={0}
|
|
1673
1683
|
justifyContent={isRightAligned ? "flex-end" : undefined}
|
|
1674
1684
|
>
|
|
1675
|
-
<Text
|
|
1685
|
+
<Text
|
|
1686
|
+
fontSize={knobProps.sizeToken}
|
|
1687
|
+
userSelect="none"
|
|
1688
|
+
flexShrink={1}
|
|
1689
|
+
minWidth={0}
|
|
1690
|
+
textAlign={isRightAligned ? "right" : undefined}
|
|
1691
|
+
data-header-label=""
|
|
1692
|
+
{...(isWeb ? { style: { overflowWrap: "anywhere" } } : {})}
|
|
1693
|
+
>
|
|
1676
1694
|
{header.isPlaceholder
|
|
1677
1695
|
? null
|
|
1678
1696
|
: flexRender(
|
|
@@ -1690,7 +1708,7 @@ export function DataTableRoot<TData extends Record<string, any> = Record<string,
|
|
|
1690
1708
|
: t("Click to sort (Shift+click for multi-sort)")
|
|
1691
1709
|
}
|
|
1692
1710
|
>
|
|
1693
|
-
<View aria-hidden={true} role="presentation">
|
|
1711
|
+
<View aria-hidden={true} role="presentation" flexShrink={0}>
|
|
1694
1712
|
{sortDirection === "asc" && (
|
|
1695
1713
|
<CaretDownIcon
|
|
1696
1714
|
size={chrome.iconPx}
|
|
@@ -1714,7 +1732,12 @@ export function DataTableRoot<TData extends Record<string, any> = Record<string,
|
|
|
1714
1732
|
</Tooltip>
|
|
1715
1733
|
)}
|
|
1716
1734
|
</View>
|
|
1717
|
-
<View
|
|
1735
|
+
<View
|
|
1736
|
+
flexDirection="row"
|
|
1737
|
+
gap="$1"
|
|
1738
|
+
alignItems="center"
|
|
1739
|
+
flexShrink={0}
|
|
1740
|
+
>
|
|
1718
1741
|
{enableFiltering && header.column.getCanFilter() && (
|
|
1719
1742
|
<ColumnHeaderFilter
|
|
1720
1743
|
columnId={header.column.id}
|
|
@@ -102,12 +102,9 @@ describe("DataTableMobileCards", () => {
|
|
|
102
102
|
});
|
|
103
103
|
|
|
104
104
|
it("a control keeps a row of its own and prints no label", () => {
|
|
105
|
-
// Explicit id on BOTH columns: DataTable seeds columnOrder from
|
|
106
|
-
// `col.id || ""`, so an id-less accessor column beside an id'd one would
|
|
107
|
-
// put `_actions` first and make the control the card title instead.
|
|
108
105
|
const { container } = renderCards({
|
|
109
106
|
columns: [
|
|
110
|
-
{
|
|
107
|
+
{ accessorKey: "firstName", header: "First Name" },
|
|
111
108
|
{ id: "_actions", accessorKey: "lastName", header: "Actions", meta: { role: "actions" } },
|
|
112
109
|
],
|
|
113
110
|
});
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MPO-336 / LC-10 FRAME-CONTAINMENT at the header grain.
|
|
3
|
+
*
|
|
4
|
+
* A header label wider than its column painted over the next column: the
|
|
5
|
+
* label run would not shrink below its max-content width, so a start-aligned
|
|
6
|
+
* label pushed its sort and filter glyphs into the neighbour and an
|
|
7
|
+
* end-aligned (number) label spilled left over the previous column. The
|
|
8
|
+
* label is now the part that yields: it shrinks to the column and wraps,
|
|
9
|
+
* breaking a long word if it must, while the glyphs keep their size.
|
|
10
|
+
*
|
|
11
|
+
* happy-dom does no layout, so this pins the flex contract that produces the
|
|
12
|
+
* containment. The painted geometry is measured in Storybook by the LC-10
|
|
13
|
+
* probe (`table-datatable--narrow-headers`, scripts/storybook-rubric).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
17
|
+
import { describe, expect, it } from "vitest";
|
|
18
|
+
import type { DataTableColumn } from "../../types";
|
|
19
|
+
import { DataTable } from "./index";
|
|
20
|
+
|
|
21
|
+
type Row = { id: string; account: string; quantity: number };
|
|
22
|
+
|
|
23
|
+
const rows: Row[] = [
|
|
24
|
+
{ id: "1", account: "acme-website", quantity: 142 },
|
|
25
|
+
{ id: "2", account: "tamagui-docs", quantity: 89 },
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
const columns: DataTableColumn<Row>[] = [
|
|
29
|
+
{ id: "account", accessorKey: "account", header: "Customer account (input)", width: 96 },
|
|
30
|
+
{
|
|
31
|
+
id: "quantity",
|
|
32
|
+
accessorKey: "quantity",
|
|
33
|
+
header: "Quantity (stepper)",
|
|
34
|
+
align: "right",
|
|
35
|
+
width: 96,
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
function style(el: Element, prop: "flexShrink" | "minWidth" | "overflowWrap"): string {
|
|
40
|
+
const inline = (el as HTMLElement).style[prop];
|
|
41
|
+
return inline || getComputedStyle(el)[prop];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function renderNarrow() {
|
|
45
|
+
return renderWithProviders(
|
|
46
|
+
<DataTable<Row>
|
|
47
|
+
data={rows}
|
|
48
|
+
columns={columns}
|
|
49
|
+
layout="table"
|
|
50
|
+
columnLayout="scroll"
|
|
51
|
+
enableSorting
|
|
52
|
+
enableFiltering
|
|
53
|
+
enablePagination={false}
|
|
54
|
+
readOnly
|
|
55
|
+
/>,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
describe("DataTable header labels stay inside their column (MPO-336)", () => {
|
|
60
|
+
it.each(["account", "quantity"])("the %s label shrinks and wraps", (id) => {
|
|
61
|
+
const { container } = renderNarrow();
|
|
62
|
+
const header = container.querySelector(`#${id}-header`) as HTMLElement;
|
|
63
|
+
expect(header).toBeTruthy();
|
|
64
|
+
const label = header.querySelector("[data-header-label]");
|
|
65
|
+
expect(label, "header label run is marked").not.toBeNull();
|
|
66
|
+
expect(style(label!, "flexShrink")).toBe("1");
|
|
67
|
+
expect(style(label!, "minWidth")).toMatch(/^0(px)?$/);
|
|
68
|
+
expect(style(label!, "overflowWrap")).toBe("anywhere");
|
|
69
|
+
// Every ancestor between the label and the cell yields too, or the
|
|
70
|
+
// label's min-content width comes back through its parent.
|
|
71
|
+
for (let node = label!.parentElement; node && node !== header; node = node.parentElement) {
|
|
72
|
+
if (getComputedStyle(node).display === "contents") continue;
|
|
73
|
+
expect(style(node, "minWidth"), "ancestor min-width").toMatch(/^0(px)?$/);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("the sort and filter glyphs keep their size", () => {
|
|
78
|
+
const { container } = renderNarrow();
|
|
79
|
+
const header = container.querySelector("#account-header") as HTMLElement;
|
|
80
|
+
const label = header.querySelector("[data-header-label]")!;
|
|
81
|
+
const glyphs = [...header.querySelectorAll("svg")];
|
|
82
|
+
expect(glyphs.length).toBeGreaterThanOrEqual(2);
|
|
83
|
+
for (const svg of glyphs) {
|
|
84
|
+
let node: Element | null = svg;
|
|
85
|
+
while (node && node.parentElement && !node.parentElement.contains(label)) {
|
|
86
|
+
node = node.parentElement;
|
|
87
|
+
}
|
|
88
|
+
expect(style(node!, "flexShrink"), "glyph slot").toBe("0");
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
@@ -31,13 +31,9 @@ const sampleData: Person[] = [
|
|
|
31
31
|
{ id: 3, firstName: "Carol", age: 20 },
|
|
32
32
|
];
|
|
33
33
|
|
|
34
|
-
// Explicit ids: DataTable seeds columnOrder from `col.id || ""`, so mixing
|
|
35
|
-
// id-less accessor columns with an id'd display column would reorder the
|
|
36
|
-
// display column first (and identity fallbacks would read it as the "first
|
|
37
|
-
// visible cell").
|
|
38
34
|
const columns: DataTableColumn<Person>[] = [
|
|
39
|
-
{
|
|
40
|
-
{
|
|
35
|
+
{ accessorKey: "firstName", header: "First Name" },
|
|
36
|
+
{ accessorKey: "age", header: "Age" },
|
|
41
37
|
];
|
|
42
38
|
|
|
43
39
|
function pressRows(container: HTMLElement): HTMLElement[] {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { Checkbox } from "@multiplatform.one/forms";
|
|
1
2
|
import { action } from "@multiplatform.one/storybook";
|
|
2
3
|
import React from "react";
|
|
3
|
-
import {
|
|
4
|
+
import { Text, XStack, YStack } from "tamagui";
|
|
4
5
|
import { type BulkAction, DataTableBulkActions, useRowSelection } from "./index";
|
|
5
6
|
|
|
6
7
|
// Define the data type
|
|
@@ -309,7 +310,7 @@ export const WithRowSelectionHook = () => {
|
|
|
309
310
|
>
|
|
310
311
|
<Checkbox
|
|
311
312
|
checked={selection.isSelected(task)}
|
|
312
|
-
|
|
313
|
+
onChange={() => {}} // Handled by onPress
|
|
313
314
|
/>
|
|
314
315
|
<YStack flex={1}>
|
|
315
316
|
<Text fontWeight="500">{task.title}</Text>
|
|
@@ -324,9 +325,9 @@ export const WithRowSelectionHook = () => {
|
|
|
324
325
|
<XStack gap="$3" alignItems="center">
|
|
325
326
|
<Checkbox
|
|
326
327
|
checked={selection.isAllSelected || selection.isIndeterminate}
|
|
327
|
-
|
|
328
|
+
onChange={() => selection.toggleAll()}
|
|
329
|
+
label="Select All"
|
|
328
330
|
/>
|
|
329
|
-
<Text>Select All</Text>
|
|
330
331
|
<Text fontSize="$2" color="$gray11">
|
|
331
332
|
({selection.selectedItems.length} selected)
|
|
332
333
|
</Text>
|
|
@@ -172,7 +172,7 @@ export function DataTableBulkActions<T = any>(props: DataTableBulkActionsProps<T
|
|
|
172
172
|
<Button
|
|
173
173
|
key={action.id}
|
|
174
174
|
size={knobProps.sizeToken}
|
|
175
|
-
|
|
175
|
+
error={action.variant === "destructive"}
|
|
176
176
|
disabled={action.disabled}
|
|
177
177
|
// DG-ST-03: reason renders via the Button explain affordance;
|
|
178
178
|
// executing is derived busy state (spinner), not a bare disable.
|
|
@@ -1,23 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CellModalEditor — wraps tall field types (FileUpload, Signature, RichText,
|
|
3
|
-
* etc.) in a
|
|
4
|
-
* `FieldDisplay` summary; click opens
|
|
3
|
+
* etc.) in a forms FloatingPanel that opens on cell click. The cell shows a
|
|
4
|
+
* compact `FieldDisplay` summary; a click opens the full editor in a panel
|
|
5
|
+
* that attaches to the cell it was opened from (MPO-38 cover contract), the
|
|
6
|
+
* same FloatingPanel the native variant uses (a sheet there and at 640 and
|
|
7
|
+
* below). It never grows the row (LC-06).
|
|
5
8
|
*
|
|
6
|
-
* The
|
|
9
|
+
* The panel is a staging buffer (UX-023 / Axiom 7 AGENCY): the inner editor
|
|
7
10
|
* is wired to a local draft seeded from the committed value on open — nothing
|
|
8
|
-
* reaches the row while the
|
|
11
|
+
* reaches the row while the panel is open. "Done" commits the draft once via
|
|
9
12
|
* `onCommit`; an outside click also commits (LC-21: a cell editor's draft
|
|
10
13
|
* still commits on the outside-click close); "Cancel" and Escape discard the
|
|
11
14
|
* draft and leave the row untouched. Cancel is never disabled (LC-30) and the
|
|
12
|
-
* footer stays within the two-action
|
|
15
|
+
* footer stays within the two-action budget (LC-31).
|
|
13
16
|
*/
|
|
14
17
|
|
|
15
|
-
import {
|
|
16
|
-
|
|
18
|
+
import {
|
|
19
|
+
Button,
|
|
20
|
+
FieldDisplay,
|
|
21
|
+
FloatingPanel,
|
|
22
|
+
type FieldDisplayType,
|
|
23
|
+
} from "@multiplatform.one/forms";
|
|
17
24
|
import { TableCellContext } from "@multiplatform.one/table-primitives";
|
|
18
25
|
import { useResolvedKnobs } from "@multiplatform.one/theme";
|
|
19
|
-
import { useCallback, useRef, useState, type ReactNode } from "react";
|
|
20
|
-
import {
|
|
26
|
+
import { useCallback, useEffect, useRef, useState, type ReactNode } from "react";
|
|
27
|
+
import { Text, View, XStack, YStack, isWeb } from "tamagui";
|
|
21
28
|
import { t } from "../../shared/t";
|
|
22
29
|
|
|
23
30
|
export interface CellModalEditorProps {
|
|
@@ -29,12 +36,12 @@ export interface CellModalEditorProps {
|
|
|
29
36
|
/** Commits the staged draft to the row. Fires at most once per session. */
|
|
30
37
|
onCommit: (value: any) => void;
|
|
31
38
|
/**
|
|
32
|
-
* Full editor mounted inside the
|
|
39
|
+
* Full editor mounted inside the panel, wired to the staged draft: render
|
|
33
40
|
* with `draftValue` and report edits through `onDraftChange` — never
|
|
34
41
|
* straight to the row.
|
|
35
42
|
*/
|
|
36
43
|
children: (draftValue: any, onDraftChange: (value: any) => void) => ReactNode;
|
|
37
|
-
/** Title shown in the
|
|
44
|
+
/** Title shown in the panel header. */
|
|
38
45
|
title?: string;
|
|
39
46
|
/**
|
|
40
47
|
* Accessible name for the chromeless cell trigger (column header).
|
|
@@ -56,7 +63,7 @@ export function CellModalEditor({
|
|
|
56
63
|
}: CellModalEditorProps) {
|
|
57
64
|
const { knobProps } = useResolvedKnobs();
|
|
58
65
|
const [open, setOpen] = useState(false);
|
|
59
|
-
// Draft session: exists only while the
|
|
66
|
+
// Draft session: exists only while the panel is open, seeded from the
|
|
60
67
|
// committed value so the editor starts at the cell's current value
|
|
61
68
|
// (Axiom 11 VALUE IS DATA).
|
|
62
69
|
const [draft, setDraft] = useState<{ value: any } | null>(null);
|
|
@@ -67,7 +74,7 @@ export function CellModalEditor({
|
|
|
67
74
|
const onCommitRef = useRef(onCommit);
|
|
68
75
|
onCommitRef.current = onCommit;
|
|
69
76
|
// Escape / Cancel flag the close as a discard before onOpenChange(false)
|
|
70
|
-
// lands; every other close path (Done,
|
|
77
|
+
// lands; every other close path (Done, outside click) commits.
|
|
71
78
|
const discardRef = useRef(false);
|
|
72
79
|
|
|
73
80
|
const handleOpen = useCallback(() => {
|
|
@@ -97,6 +104,18 @@ export function CellModalEditor({
|
|
|
97
104
|
[handleOpen],
|
|
98
105
|
);
|
|
99
106
|
|
|
107
|
+
// FloatingPanel reports every close as onOpenChange(false). Escape is a
|
|
108
|
+
// dismissal, not a confirm, so it is flagged in the capture phase, before
|
|
109
|
+
// the panel's own Escape listener closes it.
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
if (!open || !isWeb || typeof document === "undefined") return;
|
|
112
|
+
const flagEscape = (event: KeyboardEvent) => {
|
|
113
|
+
if (event.key === "Escape") discardRef.current = true;
|
|
114
|
+
};
|
|
115
|
+
document.addEventListener("keydown", flagEscape, true);
|
|
116
|
+
return () => document.removeEventListener("keydown", flagEscape, true);
|
|
117
|
+
}, [open]);
|
|
118
|
+
|
|
100
119
|
const handleCancel = useCallback(() => {
|
|
101
120
|
discardRef.current = true;
|
|
102
121
|
handleOpenChange(false);
|
|
@@ -108,76 +127,77 @@ export function CellModalEditor({
|
|
|
108
127
|
}, []);
|
|
109
128
|
|
|
110
129
|
const triggerLocked = disabled || readOnly;
|
|
111
|
-
const handleTriggerKeyDown = (event: {
|
|
130
|
+
const handleTriggerKeyDown = (event: {
|
|
131
|
+
key?: string;
|
|
132
|
+
preventDefault?: () => void;
|
|
133
|
+
stopPropagation?: () => void;
|
|
134
|
+
}) => {
|
|
112
135
|
if (triggerLocked) return;
|
|
113
136
|
if (event.key === "Enter" || event.key === " ") {
|
|
114
137
|
event.preventDefault?.();
|
|
138
|
+
event.stopPropagation?.();
|
|
115
139
|
handleOpen();
|
|
116
140
|
}
|
|
117
141
|
};
|
|
118
142
|
|
|
143
|
+
const trigger = (
|
|
144
|
+
<View
|
|
145
|
+
cursor={triggerLocked ? "default" : "pointer"}
|
|
146
|
+
opacity={disabled ? 0.5 : 1}
|
|
147
|
+
flexDirection="row"
|
|
148
|
+
alignItems="center"
|
|
149
|
+
width="100%"
|
|
150
|
+
paddingHorizontal="$1"
|
|
151
|
+
paddingVertical="$1"
|
|
152
|
+
hoverStyle={!triggerLocked ? { backgroundColor: "$backgroundHover" } : undefined}
|
|
153
|
+
// LC-71: parent CellWrapper paints the one ring on the cell boundary.
|
|
154
|
+
outlineWidth={0}
|
|
155
|
+
focusVisibleStyle={{ outlineWidth: 0 }}
|
|
156
|
+
{...(isWeb && !triggerLocked
|
|
157
|
+
? {
|
|
158
|
+
role: "button" as const,
|
|
159
|
+
tabIndex: 0,
|
|
160
|
+
"aria-label": label,
|
|
161
|
+
"aria-haspopup": "dialog" as const,
|
|
162
|
+
"aria-expanded": open,
|
|
163
|
+
onKeyDown: handleTriggerKeyDown,
|
|
164
|
+
}
|
|
165
|
+
: undefined)}
|
|
166
|
+
>
|
|
167
|
+
<FieldDisplay field={field} value={value} fieldProps={fieldProps} />
|
|
168
|
+
</View>
|
|
169
|
+
);
|
|
170
|
+
|
|
119
171
|
return (
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
outlineWidth={0}
|
|
133
|
-
focusVisibleStyle={{ outlineWidth: 0 }}
|
|
134
|
-
{...(isWeb && !triggerLocked
|
|
135
|
-
? {
|
|
136
|
-
role: "button" as const,
|
|
137
|
-
tabIndex: 0,
|
|
138
|
-
"aria-label": label,
|
|
139
|
-
"aria-haspopup": "dialog" as const,
|
|
140
|
-
"aria-expanded": open,
|
|
141
|
-
onKeyDown: handleTriggerKeyDown,
|
|
142
|
-
}
|
|
143
|
-
: undefined)}
|
|
172
|
+
<FloatingPanel
|
|
173
|
+
open={open}
|
|
174
|
+
onOpenChange={handleOpenChange}
|
|
175
|
+
disabled={triggerLocked}
|
|
176
|
+
trigger={trigger}
|
|
177
|
+
>
|
|
178
|
+
<YStack
|
|
179
|
+
{...knobProps.gap}
|
|
180
|
+
width={720}
|
|
181
|
+
maxWidth="90vw"
|
|
182
|
+
data-testid="cell-modal-editor-panel"
|
|
183
|
+
data-dismiss-class="compose"
|
|
144
184
|
>
|
|
145
|
-
<
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
<
|
|
149
|
-
<
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
basis-0 wrapper collapses and its children paint over the
|
|
163
|
-
footer / past the dialog frame (LC-10). The context reset
|
|
164
|
-
restores full field chrome — the modal is not a table cell,
|
|
165
|
-
but React context flows through the Dialog portal. */}
|
|
166
|
-
<YStack flexShrink={1} minHeight={0}>
|
|
167
|
-
<TableCellContext.Provider value={{ inTableCell: false }}>
|
|
168
|
-
{children(draft ? draft.value : value, handleDraftChange)}
|
|
169
|
-
</TableCellContext.Provider>
|
|
170
|
-
</YStack>
|
|
171
|
-
<XStack {...knobProps.gap} justifyContent="flex-end">
|
|
172
|
-
{/* LC-30 CANCEL-ALWAYS-LIVE: the discard exit never disables. */}
|
|
173
|
-
<Button onPress={handleCancel}>{t("Cancel")}</Button>
|
|
174
|
-
<Button theme="accent" onPress={() => handleOpenChange(false)}>
|
|
175
|
-
{t("Done")}
|
|
176
|
-
</Button>
|
|
177
|
-
</XStack>
|
|
178
|
-
</DialogContent>
|
|
179
|
-
</Dialog.Portal>
|
|
180
|
-
</Dialog>
|
|
181
|
-
</>
|
|
185
|
+
<Text {...knobProps.heading}>{title ?? t("Edit")}</Text>
|
|
186
|
+
{/* The panel is not a table cell: restore full field chrome. React
|
|
187
|
+
context flows in because the panel renders inline (no portal). */}
|
|
188
|
+
<YStack flexShrink={1} minHeight={0}>
|
|
189
|
+
<TableCellContext.Provider value={{ inTableCell: false }}>
|
|
190
|
+
{children(draft ? draft.value : value, handleDraftChange)}
|
|
191
|
+
</TableCellContext.Provider>
|
|
192
|
+
</YStack>
|
|
193
|
+
<XStack {...knobProps.gap} justifyContent="flex-end">
|
|
194
|
+
{/* LC-30 CANCEL-ALWAYS-LIVE: the discard exit never disables. */}
|
|
195
|
+
<Button onPress={handleCancel}>{t("Cancel")}</Button>
|
|
196
|
+
<Button theme="accent" onPress={() => handleOpenChange(false)}>
|
|
197
|
+
{t("Done")}
|
|
198
|
+
</Button>
|
|
199
|
+
</XStack>
|
|
200
|
+
</YStack>
|
|
201
|
+
</FloatingPanel>
|
|
182
202
|
);
|
|
183
203
|
}
|
|
@@ -153,7 +153,8 @@ function MockRadioGroup({ value, onValueChange, options }: any) {
|
|
|
153
153
|
|
|
154
154
|
/**
|
|
155
155
|
* Functional FloatingPanel fake: trigger toggles open; children render only
|
|
156
|
-
* while open (mirrors the popover/sheet contract
|
|
156
|
+
* while open; Escape inside closes it (mirrors the popover/sheet contract
|
|
157
|
+
* CellOptionsEditor and CellModalEditor rely on).
|
|
157
158
|
*/
|
|
158
159
|
function MockFloatingPanel({ open, onOpenChange, trigger, children, disabled }: any) {
|
|
159
160
|
return (
|
|
@@ -166,7 +167,16 @@ function MockFloatingPanel({ open, onOpenChange, trigger, children, disabled }:
|
|
|
166
167
|
>
|
|
167
168
|
{trigger}
|
|
168
169
|
</div>
|
|
169
|
-
{open ?
|
|
170
|
+
{open ? (
|
|
171
|
+
<div
|
|
172
|
+
data-testid="floating-panel-content"
|
|
173
|
+
onKeyDown={(event) => {
|
|
174
|
+
if (event.key === "Escape") onOpenChange?.(false);
|
|
175
|
+
}}
|
|
176
|
+
>
|
|
177
|
+
{children}
|
|
178
|
+
</div>
|
|
179
|
+
) : null}
|
|
170
180
|
</div>
|
|
171
181
|
);
|
|
172
182
|
}
|