@multiplatform.one/table 7.29.0 → 7.29.1

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.
@@ -7,6 +7,10 @@
7
7
  * copy of the row seeded on open. "Done" and an outside click commit the
8
8
  * draft once; "Cancel" and Escape discard it. A read-only row opens for
9
9
  * viewing with a single "Close".
10
+ *
11
+ * The pencil is the dialog's `Dialog.Trigger`: tamagui's modal close returns
12
+ * focus to the trigger ref and nowhere else, so without it every close
13
+ * dropped focus on <body> (MPO-471).
10
14
  */
11
15
 
12
16
  import { DialogContent, DialogOverlay, ScrollView } from "@multiplatform.one/components";
@@ -99,75 +103,72 @@ export function RowDetailEditor<TData extends DataTableData>({
99
103
  const current = draft ?? row;
100
104
 
101
105
  return (
102
- <>
103
- <Button
104
- chromeless
105
- compact={compact}
106
- onPress={() => handleOpenChange(true)}
107
- hitSlop={knobProps.nestedControl.hitSlop}
108
- aria-label={triggerLabel}
109
- aria-haspopup="dialog"
110
- aria-expanded={draft !== null}
111
- >
112
- <PencilSimpleIcon size={16} />
113
- </Button>
114
- <Dialog open={draft !== null} onOpenChange={handleOpenChange} modal>
115
- <Dialog.Portal>
116
- <DialogOverlay opacity={0.5} />
117
- <DialogContent
118
- maxWidth={720}
119
- maxHeight="80vh"
120
- width="90vw"
121
- onEscapeKeyDown={() => {
122
- discardRef.current = true;
123
- }}
124
- >
125
- <Dialog.Title {...knobProps.heading}>
126
- {withInterp(t("Row {{row}}", { row: rowNumber }), { row: rowNumber })}
127
- </Dialog.Title>
128
- <ScrollView flexShrink={1} minHeight={0}>
129
- <TableCellContext.Provider value={{ inTableCell: false }}>
130
- <YStack {...knobProps.gapLg}>
131
- {columns.map((col) => {
132
- const columnId = columnKey(col);
133
- if (isCellHidden?.(current, columnId, rowIndex)) return null;
134
- const label = typeof col.header === "string" ? col.header : columnId;
135
- return (
136
- <YStack key={columnId} {...knobProps.gap}>
137
- <Text {...knobProps.label}>{label}</Text>
138
- <DataTableCell
139
- value={current[columnId as keyof TData]}
140
- onChange={(value) => setDraftValue(columnId, value)}
141
- field={(col.field || "input") as DataTableField}
142
- fieldProps={col.fieldProps as DataTableFieldProps | undefined}
143
- readOnly={readOnly}
144
- compact={false}
145
- columnId={columnId}
146
- columnLabel={label}
147
- rowIndex={rowIndex}
148
- rowData={current}
149
- />
150
- </YStack>
151
- );
152
- })}
153
- </YStack>
154
- </TableCellContext.Provider>
155
- </ScrollView>
156
- <XStack {...knobProps.gap} justifyContent="flex-end">
157
- {readOnly ? (
158
- <Button onPress={handleCancel}>{t("Close")}</Button>
159
- ) : (
160
- <>
161
- <Button onPress={handleCancel}>{t("Cancel")}</Button>
162
- <Button theme="accent" onPress={() => handleOpenChange(false)}>
163
- {t("Done")}
164
- </Button>
165
- </>
166
- )}
167
- </XStack>
168
- </DialogContent>
169
- </Dialog.Portal>
170
- </Dialog>
171
- </>
106
+ <Dialog open={draft !== null} onOpenChange={handleOpenChange} modal>
107
+ <Dialog.Trigger asChild>
108
+ <Button
109
+ chromeless
110
+ compact={compact}
111
+ hitSlop={knobProps.nestedControl.hitSlop}
112
+ aria-label={triggerLabel}
113
+ >
114
+ <PencilSimpleIcon size={16} />
115
+ </Button>
116
+ </Dialog.Trigger>
117
+ <Dialog.Portal>
118
+ <DialogOverlay opacity={0.5} />
119
+ <DialogContent
120
+ maxWidth={720}
121
+ maxHeight="80vh"
122
+ width="90vw"
123
+ onEscapeKeyDown={() => {
124
+ discardRef.current = true;
125
+ }}
126
+ >
127
+ <Dialog.Title {...knobProps.heading}>
128
+ {withInterp(t("Row {{row}}", { row: rowNumber }), { row: rowNumber })}
129
+ </Dialog.Title>
130
+ <ScrollView flexShrink={1} minHeight={0}>
131
+ <TableCellContext.Provider value={{ inTableCell: false }}>
132
+ <YStack {...knobProps.gapLg}>
133
+ {columns.map((col) => {
134
+ const columnId = columnKey(col);
135
+ if (isCellHidden?.(current, columnId, rowIndex)) return null;
136
+ const label = typeof col.header === "string" ? col.header : columnId;
137
+ return (
138
+ <YStack key={columnId} {...knobProps.gap}>
139
+ <Text {...knobProps.label}>{label}</Text>
140
+ <DataTableCell
141
+ value={current[columnId as keyof TData]}
142
+ onChange={(value) => setDraftValue(columnId, value)}
143
+ field={(col.field || "input") as DataTableField}
144
+ fieldProps={col.fieldProps as DataTableFieldProps | undefined}
145
+ readOnly={readOnly}
146
+ compact={false}
147
+ columnId={columnId}
148
+ columnLabel={label}
149
+ rowIndex={rowIndex}
150
+ rowData={current}
151
+ />
152
+ </YStack>
153
+ );
154
+ })}
155
+ </YStack>
156
+ </TableCellContext.Provider>
157
+ </ScrollView>
158
+ <XStack {...knobProps.gap} justifyContent="flex-end">
159
+ {readOnly ? (
160
+ <Button onPress={handleCancel}>{t("Close")}</Button>
161
+ ) : (
162
+ <>
163
+ <Button onPress={handleCancel}>{t("Cancel")}</Button>
164
+ <Button theme="accent" onPress={() => handleOpenChange(false)}>
165
+ {t("Done")}
166
+ </Button>
167
+ </>
168
+ )}
169
+ </XStack>
170
+ </DialogContent>
171
+ </Dialog.Portal>
172
+ </Dialog>
172
173
  );
173
174
  }
@@ -363,6 +363,34 @@ function TableInputInner<TData extends DataTableData>({
363
363
  },
364
364
  [rows, commit, onCellChange],
365
365
  );
366
+ const rowDetailCommitRef = useRef(handleRowDetailCommit);
367
+ rowDetailCommitRef.current = handleRowDetailCommit;
368
+
369
+ // flexRender mounts each `cell` as a component, so a fresh renderer on every
370
+ // row commit remounted the pencil under its closing dialog, and the dialog
371
+ // then had no connected trigger to return focus to (MPO-471).
372
+ const detailColumn = useMemo<ColumnDef<TData, unknown> | null>(
373
+ () =>
374
+ rowDetail
375
+ ? {
376
+ id: "_detail",
377
+ header: "",
378
+ size: chromePx + 16,
379
+ cell: ({ row }) => (
380
+ <Detail
381
+ row={row.original}
382
+ rowIndex={row.index}
383
+ columns={detailColumns}
384
+ readOnly={readOnly}
385
+ compact={compact}
386
+ isCellHidden={isCellHidden}
387
+ onCommit={(next, changed) => rowDetailCommitRef.current(row.index, next, changed)}
388
+ />
389
+ ),
390
+ }
391
+ : null,
392
+ [rowDetail, chromePx, detailColumns, readOnly, compact, isCellHidden],
393
+ );
366
394
 
367
395
  useEffect(() => {
368
396
  const id = pendingFocusRef.current;
@@ -490,24 +518,7 @@ function TableInputInner<TData extends DataTableData>({
490
518
  } as ColumnDef<TData, unknown>);
491
519
  });
492
520
 
493
- if (rowDetail) {
494
- cols.push({
495
- id: "_detail",
496
- header: "",
497
- size: chromePx + 16,
498
- cell: ({ row }) => (
499
- <Detail
500
- row={row.original}
501
- rowIndex={row.index}
502
- columns={detailColumns}
503
- readOnly={readOnly}
504
- compact={compact}
505
- isCellHidden={isCellHidden}
506
- onCommit={(next, changed) => handleRowDetailCommit(row.index, next, changed)}
507
- />
508
- ),
509
- });
510
- }
521
+ if (detailColumn) cols.push(detailColumn);
511
522
 
512
523
  if (showDeleteRow && !readOnly) {
513
524
  cols.push({
@@ -550,10 +561,8 @@ function TableInputInner<TData extends DataTableData>({
550
561
  knobProps.label.fontSize,
551
562
  knobProps.nestedControl.hitSlop,
552
563
  reorderEnabled,
553
- rowDetail,
554
- detailColumns,
564
+ detailColumn,
555
565
  isCellHidden,
556
- handleRowDetailCommit,
557
566
  ]);
558
567
 
559
568
  const table = useReactTable({
@@ -7,6 +7,10 @@
7
7
  * copy of the row seeded on open. "Done" and an outside click commit the
8
8
  * draft once; "Cancel" and Escape discard it. A read-only row opens for
9
9
  * viewing with a single "Close".
10
+ *
11
+ * The pencil is the dialog's `Dialog.Trigger`: tamagui's modal close returns
12
+ * focus to the trigger ref and nowhere else, so without it every close
13
+ * dropped focus on <body> (MPO-471).
10
14
  */
11
15
  import type { DataTableColumn, DataTableData } from "../../types";
12
16
  import { type ChildCellHidden } from "./shared";
@@ -1 +1 @@
1
- {"version":3,"file":"RowDetailEditor.d.ts","sourceRoot":"","sources":["../../../src/components/TableInput/RowDetailEditor.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EAGd,MAAM,aAAa,CAAC;AAIrB,OAAO,EAA6B,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3E,MAAM,WAAW,oBAAoB,CAAC,KAAK,SAAS,aAAa;IAC/D,GAAG,EAAE,KAAK,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;IAClC,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;IACtC,2EAA2E;IAC3E,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACnD;AAED,wBAAgB,eAAe,CAAC,KAAK,SAAS,aAAa,EAAE,EAC3D,GAAG,EACH,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,QAAQ,GACT,EAAE,oBAAoB,CAAC,KAAK,CAAC,2CA4H7B"}
1
+ {"version":3,"file":"RowDetailEditor.d.ts","sourceRoot":"","sources":["../../../src/components/TableInput/RowDetailEditor.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AASH,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EAGd,MAAM,aAAa,CAAC;AAIrB,OAAO,EAA6B,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3E,MAAM,WAAW,oBAAoB,CAAC,KAAK,SAAS,aAAa;IAC/D,GAAG,EAAE,KAAK,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;IAClC,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;IACtC,2EAA2E;IAC3E,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACnD;AAED,wBAAgB,eAAe,CAAC,KAAK,SAAS,aAAa,EAAE,EAC3D,GAAG,EACH,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,QAAQ,GACT,EAAE,oBAAoB,CAAC,KAAK,CAAC,2CAyH7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TableInput/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAQH,OAAO,EAML,KAAK,UAAU,EAChB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,mBAAmB,EACnB,cAAc,EACf,MAAM,aAAa,CAAC;AAIrB,OAAO,EAML,KAAK,eAAe,EACrB,MAAM,UAAU,CAAC;AAIlB,MAAM,WAAW,eAAe,CAAC,KAAK,SAAS,aAAa,GAAG,aAAa;IAC1E,mFAAmF;IACnF,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC;IACf,4DAA4D;IAC5D,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;IAClC,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IACnC,sEAAsE;IACtE,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IACvC,iFAAiF;IACjF,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5E,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,mDAAmD;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kCAAkC;IAClC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qCAAqC;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yCAAyC;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,UAAU,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC5B,0BAA0B;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;IACzC,kEAAkE;IAClE,YAAY,CAAC,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;CACvC;AAED,wBAAgB,UAAU,CAAC,KAAK,SAAS,aAAa,GAAG,aAAa,EAAE,EACtE,IAAS,EACT,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,IAAI,EACJ,IAAI,EAAE,QAAQ,EACd,UAAU,EACV,QAAQ,EACR,QAAgB,EAChB,QAAgB,EAChB,cAAqB,EACrB,UAAiB,EACjB,aAAoB,EACpB,OAAO,EACP,OAAO,EACP,UAAU,EACV,YAAY,EACZ,YAAY,EAAE,SAAS,EACvB,OAAc,EACd,aAAqB,EACrB,SAAiB,EACjB,aAAa,EACb,YAAY,GACb,EAAE,eAAe,CAAC,KAAK,CAAC,2CA0ExB;AA2fD,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,cAAc,EAAE,mBAAmB,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/TableInput/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAQH,OAAO,EAML,KAAK,UAAU,EAChB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,mBAAmB,EACnB,cAAc,EACf,MAAM,aAAa,CAAC;AAIrB,OAAO,EAML,KAAK,eAAe,EACrB,MAAM,UAAU,CAAC;AAIlB,MAAM,WAAW,eAAe,CAAC,KAAK,SAAS,aAAa,GAAG,aAAa;IAC1E,mFAAmF;IACnF,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC;IACf,4DAA4D;IAC5D,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;IAClC,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IACnC,sEAAsE;IACtE,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;IACvC,iFAAiF;IACjF,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5E,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,mDAAmD;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kCAAkC;IAClC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qCAAqC;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yCAAyC;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,UAAU,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC5B,0BAA0B;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;IACzC,kEAAkE;IAClE,YAAY,CAAC,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;CACvC;AAED,wBAAgB,UAAU,CAAC,KAAK,SAAS,aAAa,GAAG,aAAa,EAAE,EACtE,IAAS,EACT,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,IAAI,EACJ,IAAI,EAAE,QAAQ,EACd,UAAU,EACV,QAAQ,EACR,QAAgB,EAChB,QAAgB,EAChB,cAAqB,EACrB,UAAiB,EACjB,aAAoB,EACpB,OAAO,EACP,OAAO,EACP,UAAU,EACV,YAAY,EACZ,YAAY,EAAE,SAAS,EACvB,OAAc,EACd,aAAqB,EACrB,SAAiB,EACjB,aAAa,EACb,YAAY,GACb,EAAE,eAAe,CAAC,KAAK,CAAC,2CA0ExB;AAogBD,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,cAAc,EAAE,mBAAmB,EAAE,CAAC"}