@multiplatform.one/table-primitives 7.46.0 → 7.47.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/src/index.tsx CHANGED
@@ -6,21 +6,27 @@
6
6
  */
7
7
 
8
8
  import {
9
+ edgeColorAt,
9
10
  hairline,
10
11
  MIN_PRESS_TARGET,
12
+ PageGutter,
11
13
  Surface,
12
14
  transitionProps,
15
+ usePhoneTableBleed,
13
16
  useResolvedKnobs,
14
17
  sizeTokenStop,
18
+ SizableText,
19
+ type PhoneTableBleed,
15
20
  } from "@multiplatform.one/theme";
16
21
  import { TableCellContext } from "./tableCellContext";
17
22
  import { wrapBareTextChildren } from "./textRidesText";
18
23
  import { Children, Fragment, createContext, isValidElement, useContext } from "react";
19
- import type { FontSizeTokens, SizeTokens } from "tamagui";
24
+ import type { FontSizeTokens, SizeTokens, SpaceTokens } from "tamagui";
20
25
  import {
21
- SizableText,
26
+ SizableText as TamaguiSizableText,
22
27
  Theme,
23
28
  ThemeableStack,
29
+ YStack,
24
30
  createStyledContext,
25
31
  isWeb,
26
32
  styled,
@@ -263,6 +269,122 @@ export function tablePressFill(restFill: unknown): `$color${number}` {
263
269
  return `$color${Math.max(step + 1, 4)}`;
264
270
  }
265
271
 
272
+ // LC-146 PHONE-TABLE-BLEED: below `$sm` a table on the page line runs edge to
273
+ // edge, and the gutter it dropped becomes the inset of each row's first and
274
+ // last cell, so text stays on the page line while rows reach the screen edge.
275
+ const TableEdgeInsetContext = createContext<string | null>(null);
276
+
277
+ type CellEdge = "first" | "last" | "only";
278
+ const CellEdgeContext = createContext<CellEdge | undefined>(undefined);
279
+
280
+ /** The gutter the cells of the enclosing table take at its edges, or null. */
281
+ export function useTableEdgeInset(): string | null {
282
+ return useContext(TableEdgeInsetContext);
283
+ }
284
+
285
+ /**
286
+ * Hands every row a full-bleed table's edge inset. Hosts that bleed their own
287
+ * outer frame (a scroll viewport around the Table) wrap custom rows in it;
288
+ * the Table primitive provides it itself.
289
+ */
290
+ export function TableEdgeInset({
291
+ inset,
292
+ children,
293
+ }: {
294
+ inset: string | null;
295
+ children: React.ReactNode;
296
+ }) {
297
+ return (
298
+ <TableEdgeInsetContext.Provider value={inset}>
299
+ <PageGutter inset={null}>{children}</PageGutter>
300
+ </TableEdgeInsetContext.Provider>
301
+ );
302
+ }
303
+
304
+ function isRtlDocument(): boolean {
305
+ return isWeb && typeof document !== "undefined" && document.documentElement?.dir === "rtl";
306
+ }
307
+
308
+ /**
309
+ * The horizontal padding of an edge cell: the gutter on the outer side, the
310
+ * cell's own padding on the inner side. Native takes logical edges (Yoga lets
311
+ * start/end win over left/right); web writes the physical sides so they
312
+ * replace the cell's own `paddingHorizontal` instead of racing it in CSS.
313
+ */
314
+ function cellEdgePadding(
315
+ edge: CellEdge,
316
+ inset: string,
317
+ own: { paddingHorizontal?: unknown; paddingLeft?: unknown; paddingRight?: unknown },
318
+ ): Record<string, unknown> {
319
+ const start = edge === "first" || edge === "only";
320
+ const end = edge === "last" || edge === "only";
321
+ if (!isWeb) {
322
+ return {
323
+ ...(start ? { paddingStart: inset } : {}),
324
+ ...(end ? { paddingEnd: inset } : {}),
325
+ };
326
+ }
327
+ const rtl = isRtlDocument();
328
+ const left = rtl ? end : start;
329
+ const right = rtl ? start : end;
330
+ return {
331
+ paddingLeft: left ? inset : (own.paddingLeft ?? own.paddingHorizontal),
332
+ paddingRight: right ? inset : (own.paddingRight ?? own.paddingHorizontal),
333
+ };
334
+ }
335
+
336
+ /** Marks a row's first and last element children for their edge inset. */
337
+ function markEdgeCells(children: React.ReactNode): React.ReactNode {
338
+ const cells = flattenChildren(children).filter(isValidElement);
339
+ return cells.map((cell, index) => {
340
+ const edge: CellEdge | undefined =
341
+ cells.length === 1
342
+ ? "only"
343
+ : index === 0
344
+ ? "first"
345
+ : index === cells.length - 1
346
+ ? "last"
347
+ : undefined;
348
+ return (
349
+ <CellEdgeContext.Provider key={cell.key ?? index} value={edge}>
350
+ {cell}
351
+ </CellEdgeContext.Provider>
352
+ );
353
+ });
354
+ }
355
+
356
+ /**
357
+ * Marks the first and last cells of a row that is not a Table.Row (a
358
+ * virtualized host's div rows) for the enclosing table's edge inset.
359
+ */
360
+ export function TableEdgeCells({ children }: { children: React.ReactNode }) {
361
+ const inset = useContext(TableEdgeInsetContext);
362
+ return <>{inset ? markEdgeCells(children) : children}</>;
363
+ }
364
+
365
+ /**
366
+ * LC-146 recipe for one row of a full-bleed card or document list: no card
367
+ * chrome at the screen edge, a hairline between rows, and the gutter as the
368
+ * row's horizontal inset.
369
+ */
370
+ export function phoneBleedRowProps(inset: string) {
371
+ return {
372
+ borderRadius: 0,
373
+ borderWidth: 0,
374
+ ...hairline.bottom,
375
+ borderColor: "$borderColor",
376
+ elevation: 0,
377
+ shadowColor: "transparent",
378
+ paddingLeft: inset,
379
+ paddingRight: inset,
380
+ } as const;
381
+ }
382
+
383
+ /** LC-146 recipe for a full-bleed list frame: out to the screen edges, rows abut. */
384
+ export function phoneBleedListProps(bleed: Pick<PhoneTableBleed, "frame"> | null) {
385
+ return { ...(bleed ? bleed.frame : {}), gap: 0 } as const;
386
+ }
387
+
266
388
  const BodyRowIndexContext = createContext<number | undefined>(undefined);
267
389
 
268
390
  function indexBodyRows(children: React.ReactNode, counter: { next: number }): React.ReactNode {
@@ -275,6 +397,8 @@ function indexBodyRows(children: React.ReactNode, counter: { next: number }): Re
275
397
  </Fragment>
276
398
  );
277
399
  }
400
+ // A hidden row (DataTable's filler and clip fade) is chrome, not a record.
401
+ if ((child.props as { "aria-hidden"?: unknown })["aria-hidden"] === true) return child;
278
402
  return (
279
403
  <BodyRowIndexContext.Provider value={counter.next++}>{child}</BodyRowIndexContext.Provider>
280
404
  );
@@ -521,9 +645,13 @@ function extractCardModel(children: React.ReactNode): {
521
645
  /** Card list rendering for the Table primitive (layout="cards" / narrow auto). */
522
646
  function TableCardsList({
523
647
  children,
648
+ edgeInset,
649
+ selfBleed,
524
650
  ...props
525
651
  }: {
526
652
  children?: React.ReactNode;
653
+ edgeInset?: string | null;
654
+ selfBleed?: PhoneTableBleed | null;
527
655
  [key: string]: any;
528
656
  }) {
529
657
  const { knobProps } = useResolvedKnobs();
@@ -551,15 +679,21 @@ function TableCardsList({
551
679
  unknown
552
680
  >)}
553
681
  {...viewProps}
682
+ {...(edgeInset ? phoneBleedListProps(selfBleed ?? null) : {})}
683
+ {...(edgeInset ? ({ "data-phone-bleed": "true" } as Record<string, unknown>) : {})}
554
684
  >
555
- {caption != null &&
556
- (typeof caption === "string" || typeof caption === "number" ? (
557
- <SizableText fontSize={knobProps.sizeToken as FontSizeTokens} color="$color10">
558
- {caption}
559
- </SizableText>
560
- ) : (
561
- caption
562
- ))}
685
+ {caption != null && (
686
+ // LC-146: the caption stays on the page line while the cards bleed.
687
+ <YStack {...(edgeInset ? { paddingHorizontal: edgeInset as SpaceTokens } : {})}>
688
+ {typeof caption === "string" || typeof caption === "number" ? (
689
+ <SizableText fontSize={knobProps.sizeToken as FontSizeTokens} color="$color10">
690
+ {caption}
691
+ </SizableText>
692
+ ) : (
693
+ caption
694
+ )}
695
+ </YStack>
696
+ )}
563
697
  {rows.map((row, rowIndex) => {
564
698
  const stripe = tableZebraStripe(knobProps.tableZebra, rowIndex);
565
699
  const card = (
@@ -568,13 +702,17 @@ function TableCardsList({
568
702
  testID="table-card"
569
703
  {...knobProps.surface}
570
704
  {...knobProps.cardSurface}
571
- elevation={knobProps.elevation}
572
705
  {...motion}
573
- borderColor="$color6"
574
706
  {...(stripe === "odd"
575
707
  ? { backgroundColor: tableZebraFill(knobProps.cardSurface.backgroundColor) }
576
708
  : {})}
577
709
  {...(row.intent ? { backgroundColor: "$color3" as const } : {})}
710
+ {...(edgeInset
711
+ ? phoneBleedRowProps(edgeInset)
712
+ : {
713
+ elevation: knobProps.elevation,
714
+ borderColor: edgeColorAt("$color6", knobProps.borderWidthStop),
715
+ })}
578
716
  {...({ "data-table-zebra": stripe } as Record<string, unknown>)}
579
717
  >
580
718
  {row.cells.map((cell, index) => {
@@ -627,6 +765,13 @@ export interface ThemedTableProps extends Omit<React.ComponentProps<typeof Table
627
765
  size?: SizeTokens;
628
766
  /** Size key every cell's Surface forwards to its content. Default `size`, else `$3`. */
629
767
  cellSize?: SizeTokens;
768
+ /**
769
+ * LC-146: the gutter each row's first and last cell take as their inset
770
+ * when the table runs edge to edge below `$sm`. Omitted, a Table on the page
771
+ * line bleeds itself; a host that bleeds its own outer frame (a scroll
772
+ * viewport) passes the inset; null keeps the table inside the gutter.
773
+ */
774
+ edgeInset?: string | null;
630
775
  }
631
776
 
632
777
  /** The size key every cell's Surface forwards to its content (default `$3`). */
@@ -645,44 +790,81 @@ function ThemedTableComp({ size, cellSize, ...props }: ThemedTableProps) {
645
790
 
646
791
  function ThemedTableFrame({
647
792
  layout = "table",
793
+ edgeInset,
648
794
  ...props
649
795
  }: Omit<ThemedTableProps, "size" | "cellSize">) {
650
796
  const { knobProps } = useResolvedKnobs();
651
797
  const { sm } = useMedia();
798
+ const bleed = usePhoneTableBleed();
799
+ // LC-146: auto-bleed only when no host has decided for the table.
800
+ const selfBleed = edgeInset === undefined ? bleed : null;
801
+ const inset = edgeInset === undefined ? (bleed?.inset ?? null) : edgeInset;
652
802
  // LC-86: resolveKnobs already floors outlined+none to the hairline (0.5).
653
803
  const resolvedBorderWidth = knobProps.surface.borderWidth;
654
804
 
655
805
  const showCards = layout === "cards" || (layout === "auto" && sm === false);
656
806
  if (showCards) {
657
- return <TableCardsList {...props} />;
807
+ return (
808
+ <PageGutter inset={null}>
809
+ <TableCardsList {...props} edgeInset={inset} selfBleed={selfBleed} />
810
+ </PageGutter>
811
+ );
658
812
  }
659
813
 
660
814
  const motion = transitionProps(knobProps.motion.control);
815
+ const table = (
816
+ <TableComp
817
+ // Table frames are R-OUTER + SF-CARD-tier surface (theme-propagation-spec
818
+ // `@multiplatform.one/table-primitives`): outer corners follow the capped
819
+ // outer radius map; like the card list, the fill never takes the
820
+ // control flip.
821
+ {...knobProps.surface}
822
+ {...knobProps.borderRadiusNested}
823
+ borderWidth={resolvedBorderWidth}
824
+ elevation={knobProps.elevation}
825
+ {...motion}
826
+ // Size knob sets default row height through the table context; consumer
827
+ // cellHeight (table- or cell-level) still overrides via {...props}.
828
+ cellHeight={knobProps.sizeToken as SizeTokens}
829
+ {...({ "data-animation": knobProps.motion.control.transition ? "on" : "none" } as Record<
830
+ string,
831
+ unknown
832
+ >)}
833
+ {...props}
834
+ // A full-bleed table has no side frame: the screen edge is its edge.
835
+ {...(inset
836
+ ? {
837
+ borderLeftWidth: 0,
838
+ borderRightWidth: 0,
839
+ borderRadius: 0,
840
+ ...({ "data-phone-bleed": "true" } as Record<string, unknown>),
841
+ }
842
+ : {})}
843
+ // borderSpacing 0 neutralizes the real <table> UA default (2px gaps
844
+ // between cells) so the migrated element keeps the div-table look.
845
+ style={[{ tableLayout: "fixed" as const, borderSpacing: 0 }, props.style]}
846
+ >
847
+ <TableEdgeInset inset={inset}>{props.children}</TableEdgeInset>
848
+ </TableComp>
849
+ );
661
850
  return (
662
851
  // A table nested in a body cell must not stripe its rows by the outer index.
663
852
  <BodyRowIndexContext.Provider value={undefined}>
664
- <TableComp
665
- // Table frames are R-OUTER + SF-CARD-tier surface (theme-propagation-spec
666
- // `@multiplatform.one/table-primitives`): outer corners follow the capped
667
- // outer radius map; like the card list, the fill never takes the
668
- // control flip.
669
- {...knobProps.surface}
670
- {...knobProps.borderRadiusNested}
671
- borderWidth={resolvedBorderWidth}
672
- elevation={knobProps.elevation}
673
- {...motion}
674
- // Size knob sets default row height through the table context; consumer
675
- // cellHeight (table- or cell-level) still overrides via {...props}.
676
- cellHeight={knobProps.sizeToken as SizeTokens}
677
- {...({ "data-animation": knobProps.motion.control.transition ? "on" : "none" } as Record<
678
- string,
679
- unknown
680
- >)}
681
- {...props}
682
- // borderSpacing 0 neutralizes the real <table> UA default (2px gaps
683
- // between cells) so the migrated element keeps the div-table look.
684
- style={[{ tableLayout: "fixed" as const, borderSpacing: 0 }, props.style]}
685
- />
853
+ {selfBleed ? (
854
+ // The table keeps width 100%, which ignores a negative end margin, so
855
+ // a plain stack takes the bleed and the table fills it.
856
+ <YStack
857
+ {...selfBleed.frame}
858
+ alignSelf="stretch"
859
+ {...((props.displayMode ?? (isWeb ? "table" : "flex")) === "flex"
860
+ ? { flexGrow: 1, flexShrink: 1, flexBasis: "auto" as const, minHeight: 0 }
861
+ : {})}
862
+ >
863
+ {table}
864
+ </YStack>
865
+ ) : (
866
+ table
867
+ )}
686
868
  </BodyRowIndexContext.Provider>
687
869
  );
688
870
  }
@@ -700,6 +882,11 @@ function ThemedTableHead(props: React.ComponentProps<typeof TableHead>) {
700
882
  function ThemedRow({ accent, error, warning, success, ...props }: ThemedRowProps) {
701
883
  const { knobProps } = useResolvedKnobs();
702
884
  const context = TableContext.useStyledContext();
885
+ const edgeInset = useContext(TableEdgeInsetContext);
886
+ // A presentation row only hosts nested rows (the virtualized body), which
887
+ // mark their own edge cells through TableEdgeCells.
888
+ const children =
889
+ edgeInset && props.role !== "presentation" ? markEdgeCells(props.children) : props.children;
703
890
  const motion = transitionProps(knobProps.motion.control);
704
891
  const intent = resolveIntent({ accent, error, warning, success } as ThemedRowProps);
705
892
  const bodyIndex = useContext(BodyRowIndexContext);
@@ -742,7 +929,9 @@ function ThemedRow({ accent, error, warning, success, ...props }: ThemedRowProps
742
929
  {...(stripe === "odd" && !intent && props.backgroundColor == null
743
930
  ? { backgroundColor: tableZebraFill(knobProps.surface.backgroundColor) }
744
931
  : {})}
745
- />
932
+ >
933
+ {children}
934
+ </Row>
746
935
  );
747
936
 
748
937
  if (intent) {
@@ -787,7 +976,7 @@ function TableCellSurfaceBody({
787
976
  // fontWeight like any body text (MPO-446); the weight is the last prop so
788
977
  // no size or family variant paints the font ramp's weight over it.
789
978
  return wrapBareTextChildren(children, (label, key) => (
790
- <SizableText
979
+ <TamaguiSizableText
791
980
  key={key}
792
981
  {...(isHeader ? {} : body)}
793
982
  fontSize={knobProps.sizeToken as FontSizeTokens}
@@ -805,22 +994,42 @@ function TableCellSurfaceBody({
805
994
  fontWeight={isHeader ? "600" : (bodyWeight as "400")}
806
995
  >
807
996
  {label}
808
- </SizableText>
997
+ </TamaguiSizableText>
809
998
  ));
810
999
  }
811
1000
 
1001
+ function useCellEdgePadding(
1002
+ own: Record<string, unknown>,
1003
+ base: { paddingHorizontal: string },
1004
+ ): Record<string, unknown> | null {
1005
+ const inset = useContext(TableEdgeInsetContext);
1006
+ const edge = useContext(CellEdgeContext);
1007
+ if (!inset || !edge) return null;
1008
+ return {
1009
+ ...cellEdgePadding(edge, inset, {
1010
+ paddingHorizontal: own.paddingHorizontal ?? base.paddingHorizontal,
1011
+ paddingLeft: own.paddingLeft,
1012
+ paddingRight: own.paddingRight,
1013
+ }),
1014
+ "data-cell-edge": edge,
1015
+ };
1016
+ }
1017
+
812
1018
  function ThemedCell({ children, style, ...props }: React.ComponentProps<typeof Cell>) {
813
1019
  const { knobProps } = useResolvedKnobs();
814
1020
  const motion = transitionProps(knobProps.motion.control);
1021
+ const base = getTableCellPadding(sizeTokenStop(knobProps.sizeToken));
1022
+ const edgePadding = useCellEdgePadding(props as Record<string, unknown>, base);
815
1023
  return (
816
1024
  <Cell
817
- {...getTableCellPadding(sizeTokenStop(knobProps.sizeToken))}
1025
+ {...base}
818
1026
  {...motion}
819
1027
  {...({ "data-animation": knobProps.motion.control.transition ? "on" : "none" } as Record<
820
1028
  string,
821
1029
  unknown
822
1030
  >)}
823
1031
  {...props}
1032
+ {...edgePadding}
824
1033
  // Compose (not replace) the inline style so a consumer style (e.g.
825
1034
  // sticky pinned cells) keeps the verticalAlign baseline.
826
1035
  style={[{ verticalAlign: "middle" }, style as any]}
@@ -833,15 +1042,18 @@ function ThemedCell({ children, style, ...props }: React.ComponentProps<typeof C
833
1042
  function ThemedHeaderCell({ children, style, ...props }: React.ComponentProps<typeof HeaderCell>) {
834
1043
  const { knobProps } = useResolvedKnobs();
835
1044
  const motion = transitionProps(knobProps.motion.control);
1045
+ const base = getTableCellPadding(sizeTokenStop(knobProps.sizeToken));
1046
+ const edgePadding = useCellEdgePadding(props as Record<string, unknown>, base);
836
1047
  return (
837
1048
  <HeaderCell
838
- {...getTableCellPadding(sizeTokenStop(knobProps.sizeToken))}
1049
+ {...base}
839
1050
  {...motion}
840
1051
  {...({ "data-animation": knobProps.motion.control.transition ? "on" : "none" } as Record<
841
1052
  string,
842
1053
  unknown
843
1054
  >)}
844
1055
  {...props}
1056
+ {...edgePadding}
845
1057
  // Compose (not replace) the inline style so consumer styles (sticky
846
1058
  // pinned headers) keep the real-<th> UA neutralizers (bold/centered).
847
1059
  style={[{ verticalAlign: "middle", fontWeight: "normal", textAlign: "start" }, style as any]}
package/types/index.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  * Layer 1 only: depends on theme + Tamagui (no forms, no data-table).
5
5
  * Consumed by @multiplatform.one/table, @multiplatform.one/forms, etc.
6
6
  */
7
+ import { type PhoneTableBleed } from "@multiplatform.one/theme";
7
8
  import type { SizeTokens } from "tamagui";
8
9
  export { TableCellContext, useIsInTableCell, useTableCellContext } from "./tableCellContext";
9
10
  export type { TableCellContextValue } from "./tableCellContext";
@@ -27,8 +28,8 @@ type AlignCells = {
27
28
  declare const Row: import("tamagui").TamaguiComponent<import("@tamagui/web").TamaDefer, import("tamagui").TamaguiElement, import("@tamagui/core").RNTamaguiViewNonStyleProps, import("@tamagui/web").StackStyleBase, {
28
29
  elevation?: number | SizeTokens | undefined;
29
30
  transparent?: boolean | undefined;
30
- fullscreen?: boolean | undefined;
31
31
  circular?: boolean | undefined;
32
+ fullscreen?: boolean | undefined;
32
33
  elevate?: boolean | undefined;
33
34
  bordered?: boolean | undefined;
34
35
  chromeless?: boolean | "all" | undefined;
@@ -38,8 +39,8 @@ declare const Row: import("tamagui").TamaguiComponent<import("@tamagui/web").Tam
38
39
  declare const Cell: import("tamagui").TamaguiComponent<import("@tamagui/web").TamaDefer, import("tamagui").TamaguiElement, import("@tamagui/core").RNTamaguiViewNonStyleProps, import("@tamagui/web").StackStyleBase, {
39
40
  elevation?: number | SizeTokens | undefined;
40
41
  transparent?: boolean | undefined;
41
- fullscreen?: boolean | undefined;
42
42
  circular?: boolean | undefined;
43
+ fullscreen?: boolean | undefined;
43
44
  elevate?: boolean | undefined;
44
45
  bordered?: boolean | undefined;
45
46
  chromeless?: boolean | "all" | undefined;
@@ -52,8 +53,8 @@ declare const Cell: import("tamagui").TamaguiComponent<import("@tamagui/web").Ta
52
53
  declare const HeaderCell: import("tamagui").TamaguiComponent<import("@tamagui/web").TamaDefer, import("tamagui").TamaguiElement, import("@tamagui/core").RNTamaguiViewNonStyleProps, import("@tamagui/web").StackStyleBase, {
53
54
  elevation?: number | SizeTokens | undefined;
54
55
  transparent?: boolean | undefined;
55
- fullscreen?: boolean | undefined;
56
56
  circular?: boolean | undefined;
57
+ fullscreen?: boolean | undefined;
57
58
  elevate?: boolean | undefined;
58
59
  bordered?: boolean | undefined;
59
60
  chromeless?: boolean | "all" | undefined;
@@ -67,11 +68,50 @@ export type TableZebraStripe = "off" | "even" | "odd";
67
68
  export declare function tableZebraStripe(tableZebra: unknown, index: number): TableZebraStripe;
68
69
  export declare function tableZebraFill(hostFill: unknown): `$color${number}`;
69
70
  export declare function tablePressFill(restFill: unknown): `$color${number}`;
71
+ /** The gutter the cells of the enclosing table take at its edges, or null. */
72
+ export declare function useTableEdgeInset(): string | null;
73
+ /**
74
+ * Hands every row a full-bleed table's edge inset. Hosts that bleed their own
75
+ * outer frame (a scroll viewport around the Table) wrap custom rows in it;
76
+ * the Table primitive provides it itself.
77
+ */
78
+ export declare function TableEdgeInset({ inset, children, }: {
79
+ inset: string | null;
80
+ children: React.ReactNode;
81
+ }): import("react/jsx-runtime").JSX.Element;
82
+ /**
83
+ * Marks the first and last cells of a row that is not a Table.Row (a
84
+ * virtualized host's div rows) for the enclosing table's edge inset.
85
+ */
86
+ export declare function TableEdgeCells({ children }: {
87
+ children: React.ReactNode;
88
+ }): import("react/jsx-runtime").JSX.Element;
89
+ /**
90
+ * LC-146 recipe for one row of a full-bleed card or document list: no card
91
+ * chrome at the screen edge, a hairline between rows, and the gutter as the
92
+ * row's horizontal inset.
93
+ */
94
+ export declare function phoneBleedRowProps(inset: string): {
95
+ readonly borderColor: "$borderColor";
96
+ readonly elevation: 0;
97
+ readonly shadowColor: "transparent";
98
+ readonly paddingLeft: string;
99
+ readonly paddingRight: string;
100
+ readonly borderBottomWidth: number;
101
+ readonly className: "mp-hairline-b";
102
+ readonly borderRadius: 0;
103
+ readonly borderWidth: 0;
104
+ };
105
+ /** LC-146 recipe for a full-bleed list frame: out to the screen edges, rows abut. */
106
+ export declare function phoneBleedListProps(bleed: Pick<PhoneTableBleed, "frame"> | null): {
107
+ readonly gap: 0;
108
+ readonly marginHorizontal?: string | undefined;
109
+ };
70
110
  declare const TableBody: import("tamagui").TamaguiComponent<import("@tamagui/web").TamaDefer, import("tamagui").TamaguiElement, import("@tamagui/core").RNTamaguiViewNonStyleProps, import("@tamagui/web").StackStyleBase, {
71
111
  elevation?: number | SizeTokens | undefined;
72
112
  transparent?: boolean | undefined;
73
- fullscreen?: boolean | undefined;
74
113
  circular?: boolean | undefined;
114
+ fullscreen?: boolean | undefined;
75
115
  elevate?: boolean | undefined;
76
116
  bordered?: boolean | undefined;
77
117
  chromeless?: boolean | "all" | undefined;
@@ -80,8 +120,8 @@ declare const TableBody: import("tamagui").TamaguiComponent<import("@tamagui/web
80
120
  declare const TableHead: import("tamagui").TamaguiComponent<import("@tamagui/web").TamaDefer, import("tamagui").TamaguiElement, import("@tamagui/core").RNTamaguiViewNonStyleProps, import("@tamagui/web").StackStyleBase, {
81
121
  elevation?: number | SizeTokens | undefined;
82
122
  transparent?: boolean | undefined;
83
- fullscreen?: boolean | undefined;
84
123
  circular?: boolean | undefined;
124
+ fullscreen?: boolean | undefined;
85
125
  elevate?: boolean | undefined;
86
126
  bordered?: boolean | undefined;
87
127
  chromeless?: boolean | "all" | undefined;
@@ -90,8 +130,8 @@ declare const TableHead: import("tamagui").TamaguiComponent<import("@tamagui/web
90
130
  declare const TableFoot: import("tamagui").TamaguiComponent<import("@tamagui/web").TamaDefer, import("tamagui").TamaguiElement, import("@tamagui/core").RNTamaguiViewNonStyleProps, import("@tamagui/web").StackStyleBase, {
91
131
  elevation?: number | SizeTokens | undefined;
92
132
  transparent?: boolean | undefined;
93
- fullscreen?: boolean | undefined;
94
133
  circular?: boolean | undefined;
134
+ fullscreen?: boolean | undefined;
95
135
  elevate?: boolean | undefined;
96
136
  bordered?: boolean | undefined;
97
137
  chromeless?: boolean | "all" | undefined;
@@ -109,8 +149,8 @@ declare const TableCaption: import("tamagui").TamaguiComponent<import("@tamagui/
109
149
  declare const TableComp: import("tamagui").TamaguiComponent<import("@tamagui/web").TamaDefer, import("tamagui").TamaguiElement, import("@tamagui/core").RNTamaguiViewNonStyleProps, import("@tamagui/web").StackStyleBase, {
110
150
  elevation?: number | SizeTokens | undefined;
111
151
  transparent?: boolean | undefined;
112
- fullscreen?: boolean | undefined;
113
152
  circular?: boolean | undefined;
153
+ fullscreen?: boolean | undefined;
114
154
  elevate?: boolean | undefined;
115
155
  bordered?: boolean | undefined;
116
156
  chromeless?: boolean | "all" | undefined;
@@ -153,6 +193,13 @@ export interface ThemedTableProps extends Omit<React.ComponentProps<typeof Table
153
193
  size?: SizeTokens;
154
194
  /** Size key every cell's Surface forwards to its content. Default `size`, else `$3`. */
155
195
  cellSize?: SizeTokens;
196
+ /**
197
+ * LC-146: the gutter each row's first and last cell take as their inset
198
+ * when the table runs edge to edge below `$sm`. Omitted, a Table on the page
199
+ * line bleeds itself; a host that bleeds its own outer frame (a scroll
200
+ * viewport) passes the inset; null keeps the table inside the gutter.
201
+ */
202
+ edgeInset?: string | null;
156
203
  }
157
204
  declare function ThemedTableComp({ size, cellSize, ...props }: ThemedTableProps): import("react/jsx-runtime").JSX.Element;
158
205
  declare function ThemedTableBody({ children, ...props }: React.ComponentProps<typeof TableBody>): import("react/jsx-runtime").JSX.Element;
@@ -169,8 +216,8 @@ export declare const Table: typeof ThemedTableComp & {
169
216
  Foot: import("tamagui").TamaguiComponent<import("@tamagui/web").TamaDefer, import("tamagui").TamaguiElement, import("@tamagui/core").RNTamaguiViewNonStyleProps, import("@tamagui/web").StackStyleBase, {
170
217
  elevation?: number | SizeTokens | undefined;
171
218
  transparent?: boolean | undefined;
172
- fullscreen?: boolean | undefined;
173
219
  circular?: boolean | undefined;
220
+ fullscreen?: boolean | undefined;
174
221
  elevate?: boolean | undefined;
175
222
  bordered?: boolean | undefined;
176
223
  chromeless?: boolean | "all" | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,OAAO,KAAK,EAAkB,UAAU,EAAE,MAAM,SAAS,CAAC;AAY1D,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC7F,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAExE,KAAK,UAAU,GAAG;IAChB,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;IAC9B,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;CAC/B,CAAC;AA2CF;;;;;;;;;;GAUG;AAEH,uBAAuB;AACvB,QAAA,MAAM,GAAG;;;;;;;;;;6CAsBP,CAAC;AAEH,QAAA,MAAM,IAAI;;;;;;;;;;;;;6CAyDR,CAAC;AAEH,QAAA,MAAM,UAAU;;;;;;;;;;;;;6CA4Dd,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;AAEtD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAGrF;AASD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAEnE;AAID,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAKnE;AAoBD,QAAA,MAAM,SAAS;;;;;;;;;6CAyBb,CAAC;AAEH,QAAA,MAAM,SAAS;;;;;;;;;6CAmBb,CAAC;AAEH,QAAA,MAAM,SAAS;;;;;;;;;6CAiBb,CAAC;AAEH,QAAA,MAAM,YAAY;;;;;;;;6CAUhB,CAAC;AAEH,QAAA,MAAM,SAAS;;;;;;;;;;;;;6CAsCb,CAAC;AAKH,MAAM,WAAW,cAAe,SAAQ,KAAK,CAAC,cAAc,CAAC,OAAO,GAAG,CAAC;IACtE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAUD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG;IACjD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB,CAOA;AAED;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AA+KrD,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5F,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;OAGG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,wFAAwF;IACxF,QAAQ,CAAC,EAAE,UAAU,CAAC;CACvB;AAMD,iBAAS,eAAe,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,2CAQtE;AA8CD,iBAAS,eAAe,CAAC,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,SAAS,CAAC,2CAEtF;AAED,iBAAS,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,SAAS,CAAC,2CAIrE;AAED,iBAAS,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,2CAwD/E;AAwDD,iBAAS,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,IAAI,CAAC,2CAmBnF;AAED,iBAAS,gBAAgB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,UAAU,CAAC,2CAmB/F;AAED,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;CAQhB,CAAC;AAGH,MAAM,MAAM,UAAU,GAAG,gBAAgB,CAAC;AAC1C,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC;AAC3C,MAAM,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,IAAI,CAAC,CAAC;AAC/D,MAAM,MAAM,oBAAoB,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,UAAU,CAAC,CAAC;AAC3E,MAAM,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,SAAS,CAAC,CAAC;AACpE,MAAM,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,SAAS,CAAC,CAAC;AACpE,MAAM,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,SAAS,CAAC,CAAC;AACpE,MAAM,MAAM,iBAAiB,GAAG,KAAK,CAAC,cAAc,CAAC,OAAO,YAAY,CAAC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}