@sincpro/web-ui 0.1.0 → 0.2.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.
Files changed (119) hide show
  1. package/README.md +37 -10
  2. package/dist/components/activity/Activity.d.ts +69 -0
  3. package/dist/components/activity/Activity.js +279 -0
  4. package/dist/components/{chatter → activity}/Messages.d.ts +2 -2
  5. package/dist/components/{chatter → activity}/Messages.js +9 -6
  6. package/dist/components/{chatter → activity}/index.d.ts +1 -1
  7. package/dist/components/activity/index.js +4 -0
  8. package/dist/components/assist/AssistMark.d.ts +3 -3
  9. package/dist/components/assist/AssistMark.js +1 -1
  10. package/dist/components/assist/assist.d.ts +1 -1
  11. package/dist/components/assist/assist.js +1 -1
  12. package/dist/components/form/Sheet.d.ts +4 -0
  13. package/dist/components/form/Sheet.js +11 -4
  14. package/dist/components/index.d.ts +1 -1
  15. package/dist/components/index.js +1 -1
  16. package/dist/components/lines/LineItems.d.ts +42 -5
  17. package/dist/components/lines/LineItems.js +106 -18
  18. package/dist/components/listing/Listing.js +1 -1
  19. package/dist/components/listing/ListingBar.d.ts +41 -2
  20. package/dist/components/listing/ListingBar.js +43 -4
  21. package/dist/components/listing/Row.d.ts +5 -1
  22. package/dist/components/listing/Row.js +3 -2
  23. package/dist/components/record/RecordHeader.d.ts +21 -17
  24. package/dist/components/record/RecordHeader.js +46 -14
  25. package/dist/components/record/RecordNotices.d.ts +37 -0
  26. package/dist/components/record/RecordNotices.js +75 -0
  27. package/dist/components/record/ThumbBar.js +1 -1
  28. package/dist/foundations/copy.d.ts +96 -12
  29. package/dist/foundations/copy.es.js +63 -10
  30. package/dist/foundations/copy.js +55 -7
  31. package/dist/primitives/choice/ComboBox.d.ts +3 -0
  32. package/dist/primitives/choice/ComboBox.js +2 -2
  33. package/dist/primitives/choice/SearchField.d.ts +10 -1
  34. package/dist/primitives/choice/SearchField.js +21 -2
  35. package/dist/primitives/date/Calendar.js +30 -6
  36. package/dist/primitives/date/DatePicker.d.ts +11 -3
  37. package/dist/primitives/date/DatePicker.js +12 -8
  38. package/dist/primitives/date/DateTime.d.ts +35 -0
  39. package/dist/primitives/date/DateTime.js +100 -0
  40. package/dist/primitives/date/index.d.ts +1 -0
  41. package/dist/primitives/date/index.js +4 -2
  42. package/dist/primitives/dialog/Drill.d.ts +90 -0
  43. package/dist/primitives/dialog/Drill.js +172 -0
  44. package/dist/primitives/dialog/index.d.ts +1 -0
  45. package/dist/primitives/dialog/index.js +2 -0
  46. package/dist/primitives/field/DropZone.js +1 -1
  47. package/dist/primitives/field/Field.d.ts +14 -2
  48. package/dist/primitives/field/Field.js +25 -14
  49. package/dist/primitives/field/copy.d.ts +16 -0
  50. package/dist/primitives/field/copy.js +69 -0
  51. package/dist/primitives/field/index.d.ts +2 -0
  52. package/dist/primitives/field/index.js +4 -0
  53. package/dist/primitives/field/note.d.ts +55 -0
  54. package/dist/primitives/field/note.js +117 -0
  55. package/dist/primitives/index.d.ts +1 -0
  56. package/dist/primitives/index.js +1 -0
  57. package/dist/primitives/menu/Menu.d.ts +28 -0
  58. package/dist/primitives/menu/Menu.js +47 -17
  59. package/dist/primitives/notice/Callout.js +1 -1
  60. package/dist/primitives/notice/Flag.d.ts +13 -0
  61. package/dist/primitives/notice/Flag.js +31 -0
  62. package/dist/primitives/notice/index.d.ts +1 -0
  63. package/dist/primitives/notice/index.js +1 -0
  64. package/dist/primitives/overlay/Preview.d.ts +19 -0
  65. package/dist/primitives/overlay/Preview.js +60 -0
  66. package/dist/primitives/overlay/index.d.ts +1 -0
  67. package/dist/primitives/overlay/index.js +3 -1
  68. package/dist/primitives/picker/Picker.d.ts +41 -0
  69. package/dist/primitives/picker/Picker.js +62 -8
  70. package/dist/primitives/table/CellCopy.d.ts +20 -0
  71. package/dist/primitives/table/CellCopy.js +23 -0
  72. package/dist/primitives/table/DataTable.d.ts +55 -1
  73. package/dist/primitives/table/DataTable.js +126 -40
  74. package/dist/primitives/table/EditableTable.d.ts +97 -2
  75. package/dist/primitives/table/EditableTable.js +223 -29
  76. package/dist/primitives/table/SheetTable.d.ts +4 -1
  77. package/dist/primitives/table/SheetTable.js +38 -5
  78. package/dist/primitives/table/index.d.ts +2 -2
  79. package/dist/primitives/table/index.js +1 -1
  80. package/dist/primitives/tabs/Tabs.d.ts +2 -2
  81. package/dist/primitives/tabs/Tabs.js +1 -1
  82. package/dist/primitives/tag/TagsField.d.ts +3 -0
  83. package/dist/primitives/tag/TagsField.js +6 -2
  84. package/dist/primitives/tree/Tree.d.ts +56 -0
  85. package/dist/primitives/tree/Tree.js +74 -0
  86. package/dist/primitives/tree/index.d.ts +1 -0
  87. package/dist/primitives/tree/index.js +3 -0
  88. package/dist/primitives/value/Copyable.d.ts +11 -0
  89. package/dist/primitives/value/Copyable.js +27 -6
  90. package/dist/primitives/value/Fecha.js +10 -1
  91. package/dist/primitives/value/ProgressBar.d.ts +31 -0
  92. package/dist/primitives/value/ProgressBar.js +53 -0
  93. package/dist/primitives/value/Relation.d.ts +6 -1
  94. package/dist/primitives/value/Relation.js +27 -10
  95. package/dist/primitives/value/Totals.d.ts +102 -7
  96. package/dist/primitives/value/Totals.js +52 -2
  97. package/dist/primitives/value/Value.d.ts +0 -37
  98. package/dist/primitives/value/Value.js +0 -39
  99. package/dist/primitives/value/index.d.ts +4 -3
  100. package/dist/primitives/value/index.js +4 -3
  101. package/dist/tokens.css +44 -7
  102. package/dist/views/list/List.d.ts +8 -2
  103. package/dist/views/list/List.js +6 -2
  104. package/dist/views/list/ListView.d.ts +1 -1
  105. package/dist/views/list/ListView.js +34 -8
  106. package/dist/views/list/derive.d.ts +12 -1
  107. package/dist/views/list/derive.js +29 -3
  108. package/dist/views/list/presentations.d.ts +2 -2
  109. package/dist/views/list/presentations.js +5 -3
  110. package/dist/views/list/types.d.ts +13 -1
  111. package/dist/views/record/Record.d.ts +27 -8
  112. package/dist/views/record/Record.js +97 -27
  113. package/dist/views/record/index.d.ts +1 -1
  114. package/package.json +5 -1
  115. package/dist/components/chatter/Chatter.d.ts +0 -161
  116. package/dist/components/chatter/Chatter.js +0 -232
  117. package/dist/components/chatter/index.js +0 -4
  118. /package/dist/components/{chatter → activity}/Timeline.d.ts +0 -0
  119. /package/dist/components/{chatter → activity}/Timeline.js +0 -0
@@ -47,45 +47,6 @@ export function Numeric({ value, unit, format = "integer", }) {
47
47
  : formatCount(value);
48
48
  return (_jsxs("span", { className: "block text-right text-body tabular-nums whitespace-nowrap text-ink", children: [_jsx("span", { className: "tabular-nums", children: text }), unit === undefined ? null : _jsx("span", { className: "ml-1 text-muted", children: unit })] }));
49
49
  }
50
- /**
51
- * A real bar, never a spinner.
52
- *
53
- * Context: a spinner says «wait» and doesn't say how much; a bar says both
54
- * things.
55
- *
56
- * ── Why the fill is FLAT and the gradient is asked for ──────────────
57
- *
58
- * The bar always lived with `bar-brand`, the blue→gold gradient. At 3 px and at
59
- * 62 % that doesn't read as a brand: it reads as a blue bar with a broken tip.
60
- * A gradient needs length to be a gradient, and a bar inside a list row doesn't
61
- * have it.
62
- *
63
- * Now the fill is a flat tone —and the tone SAYS something: `good` finished,
64
- * `warn` is running slow, `bad` failed— and the gradient is asked for with
65
- * `tone="brand"`, which is the long bar of a live import: there it does have room
66
- * to be read.
67
- *
68
- * And it got fatter, from 3 px to 6 px. At 3 px it isn't a bar, it's a line: it
69
- * can't be told apart from a separator and the fill isn't visible unless it goes
70
- * past 20 %.
71
- */
72
- export function ProgressBar({ value, label, width = "w-24", tone = "brand",
73
- /** The percentage next to it. It is turned off when the bar lives inside
74
- * something that already says the figure —a cell with its column— and it
75
- * would only mean reading it twice. */
76
- showValue = true, }) {
77
- const clamped = Math.max(0, Math.min(100, Math.round(value)));
78
- const fill = tone === "brand" ? "bar-brand" : FILL[tone];
79
- return (_jsxs("span", { className: "flex items-center gap-2", children: [_jsx("span", { className: `h-(--size-track) overflow-hidden rounded-pill bg-ink/10 ${width}`, role: "progressbar", "aria-valuenow": clamped, "aria-valuemin": 0, "aria-valuemax": 100, "aria-label": label, children: _jsx("span", { className: `block h-full rounded-pill transition-[width] duration-(--duration-panel) ease-out ${fill}`, style: { width: `${clamped}%` } }) }), showValue ? (_jsxs("span", { className: "text-meta tabular-nums text-muted", children: [clamped, "%"] })) : null] }));
80
- }
81
- const FILL = {
82
- neutral: "bg-muted",
83
- info: "bg-info",
84
- good: "bg-good",
85
- warn: "bg-warn",
86
- bad: "bg-bad",
87
- accent: "bg-accent",
88
- };
89
50
  /**
90
51
  * The content of a data cell, with what the system decides and the view does not.
91
52
  *
@@ -1,8 +1,9 @@
1
- export { Copyable, type CopyableProps } from "./Copyable.js";
1
+ export { Copyable, type CopyableProps, CopyButton, } from "./Copyable.js";
2
2
  export { DateValue, formatDateTime, formatRelative, } from "./Fecha.js";
3
3
  export { Meter, type MeterLevel, meterLevel, type MeterProps, type MeterThresholds, } from "./Meter.js";
4
4
  export { Metric, type MetricProps, Metrics } from "./Metric.js";
5
5
  export { Avatar, type AvatarSize, ContactCard, type ContactCardProps, type PersonContact, UserChip, type UserChipProps, UserStack, } from "./Person.js";
6
+ export { ProgressBar, type ProgressBarProps, } from "./ProgressBar.js";
6
7
  export { RelationCard, type RelationCardProps, type RelationSummary, RelationValue, type RelationValueProps, } from "./Relation.js";
7
- export { Totals, type TotalsRow } from "./Totals.js";
8
- export { Cell, formatCount, formatDistance, formatNumber, KeyValue, Numeric, ProgressBar, } from "./Value.js";
8
+ export { Totals, type TotalsCredit, type TotalsDeduction, type TotalsFact, type TotalsProps, type TotalsRow, } from "./Totals.js";
9
+ export { Cell, formatCount, formatDistance, formatNumber, KeyValue, Numeric, } from "./Value.js";
@@ -1,9 +1,10 @@
1
1
  /* Show a number or a datum so that it reads as such and not as text. */
2
- export { Copyable } from "./Copyable.js";
2
+ export { Copyable, CopyButton, } from "./Copyable.js";
3
3
  export { DateValue, formatDateTime, formatRelative, } from "./Fecha.js";
4
4
  export { Meter, meterLevel, } from "./Meter.js";
5
5
  export { Metric, Metrics } from "./Metric.js";
6
6
  export { Avatar, ContactCard, UserChip, UserStack, } from "./Person.js";
7
+ export { ProgressBar, } from "./ProgressBar.js";
7
8
  export { RelationCard, RelationValue, } from "./Relation.js";
8
- export { Totals } from "./Totals.js";
9
- export { Cell, formatCount, formatDistance, formatNumber, KeyValue, Numeric, ProgressBar, } from "./Value.js";
9
+ export { Totals, } from "./Totals.js";
10
+ export { Cell, formatCount, formatDistance, formatNumber, KeyValue, Numeric, } from "./Value.js";
package/dist/tokens.css CHANGED
@@ -501,13 +501,25 @@
501
501
  —which has to stay clickable— reduced to a useless strip. */
502
502
  --container-peek: 30rem;
503
503
 
504
- /* The width of the chatter, beside a record. Narrower than the peek because it
505
- is not a record: it is a column of one-line entries —«se evaluó el
506
- resultado», «el proyecto pasó a generado»— and 22rem holds one of those
507
- without wrapping while leaving the record the width it needs. A system
508
- decision for the same reason the peek is: two records whose history column
509
- is a different width read as two different screens. */
510
- --container-chatter: 22rem;
504
+ /* THE ACTIVITY COLUMN — at the RIGHT of a record's sheet, joined to it (`Activity`,
505
+ `RecordHeader` THE PAGE). It holds what is true now (the record's
506
+ notices and its fields' and rows' notes, compact) over what happened (the timeline:
507
+ messages, notes and events by time) — both always in sight.
508
+
509
+ `--container-activity` is the column: 22rem holds a notice with its action and a
510
+ message bubble of readable measure.
511
+
512
+ `--container-beside` is how wide the record's PAGE has to be for the column to stand
513
+ beside the sheet: the column and a sheet that keeps 54rem — two groups of fields side by
514
+ side still fit their labels. Narrower (a laptop with a sidebar, a phone, a `Drill`), the
515
+ panel goes BELOW the sheet as a card. Written as a number and not a `calc()` because a container query cannot
516
+ read a variable.
517
+
518
+ `--container-record` is the pair at its widest — the sheet's reading width and the
519
+ column — so on a big screen they are placed together, centred. At 1680 px: 72 + 22. */
520
+ --container-activity: 22rem;
521
+ --container-beside: 76rem;
522
+ --container-record: calc(var(--container-sheet) + var(--container-activity));
511
523
 
512
524
  /* Below this a surface is held in one hand: a phone, or a panel just as narrow. 40rem is
513
525
  the width the list already stops offering a table at (`ListView`), and it is the same
@@ -523,6 +535,12 @@
523
535
  covering the bottom of the screen, which is exactly where the sheet's actions are. */
524
536
  --size-sheet: 90dvh;
525
537
 
538
+ /* How tall a floating list grows before it scrolls inside: about eight two-line rows,
539
+ the height a capped `Picker` already has, so a list that loads page after page from the
540
+ backend opens at the same size as one that shows the first eight. Taller, and a list of
541
+ two thousand customers fills the window and covers the form it is choosing for. */
542
+ --size-dropdown: 20rem;
543
+
526
544
  /* The width of a module's sidebar. 15rem holds an icon, a screen name of two
527
545
  words —«Notas de crédito», «Órdenes de compra»— a count and one step of
528
546
  nesting without truncating, and still leaves a 1280-wide window more than
@@ -583,6 +601,25 @@
583
601
  --duration-panel: 240ms;
584
602
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
585
603
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
604
+
605
+ /* The one loop of the system: the bar of a task under way that cannot say how far
606
+ it is (`ProgressBar` without a value). It is not a move between two states — it
607
+ has no end until the task ends — so the 250ms ceiling above does not apply; at
608
+ 1.6s a bar that stays a minute on screen moves slowly enough not to flicker in
609
+ the corner of the eye. The bar uses it behind `motion-safe:`: with reduced
610
+ motion it stands still. */
611
+ --animate-progress-sweep: progress-sweep 1.6s var(--ease-in-out) infinite;
612
+ }
613
+
614
+ /* The segment is two fifths of its track: from just off the left edge (-100 % of
615
+ itself) to just off the right one (250 % of itself = the track's width). */
616
+ @keyframes progress-sweep {
617
+ from {
618
+ translate: -100%;
619
+ }
620
+ to {
621
+ translate: 250%;
622
+ }
586
623
  }
587
624
 
588
625
  /* ==================================================================== *
@@ -1,7 +1,7 @@
1
1
  import type { ListIdentity } from "../../components/listing/ListingBar.js";
2
2
  import type { SortField } from "../../components/listing/SortMenu.js";
3
3
  import type { Surface } from "../../foundations/types.js";
4
- import type { DataColumn } from "../../primitives/table/DataTable.js";
4
+ import type { DataColumn, DataTableCreate } from "../../primitives/table/DataTable.js";
5
5
  import type { RowAction } from "../../primitives/table/RowActions.js";
6
6
  import type { SortState } from "../../primitives/table/Table.js";
7
7
  import { type ListCrumb, type ListEmpty, type ListGroup, type ListPivot, type ListPresent, type ListReport, type ListSheet, type RowOf } from "./types.js";
@@ -41,6 +41,9 @@ type TableProps<T extends object> = {
41
41
  /** Lo que se le hace a UNA fila sin entrar. Se dibujan escondidas y aparecen
42
42
  * sobre la fila que se está apuntando. */
43
43
  rowActions?: (item: T) => readonly RowAction[];
44
+ /** Escribir un registro nuevo como una fila más de la tabla (la lista editable de
45
+ * Odoo). Ver la cabecera de `DataTable`. */
46
+ create?: DataTableCreate<T>;
44
47
  };
45
48
  /** El tablero. Sin `card`, la tarjeta sale de lo que ya dice `List.Rows`: el
46
49
  * nombre, el `meta` y las fichas. Escribirla igual es declarar que ESTA lista
@@ -55,6 +58,9 @@ type SheetProps<T> = Partial<ListSheet<T>>;
55
58
  export type ListProps<T extends object> = {
56
59
  items: readonly T[];
57
60
  keyOf: (item: T) => string;
61
+ /** The list is a FIELD of a record — a one2many / many2many — and not a screen: a
62
+ * one-line bar that does not stick. See «A list INSIDE a record» above. */
63
+ embedded?: boolean;
58
64
  /** En qué superficie se apoya la BARRA. `canvas` (el default) es una barra
59
65
  * de control clara; `chrome` la convierte en una banda oscura, una opción
60
66
  * explícita: la barra de la aplicación es la única banda oscura de la
@@ -93,7 +99,7 @@ export type ListProps<T extends object> = {
93
99
  empty?: ListEmpty;
94
100
  children?: ReactNode;
95
101
  };
96
- export declare function List<T extends object>({ items, keyOf, surface, group, selection, sort, onSortChange, sortable, present, onPresentChange, onOpen, onPeek, isPeeked, state, filtered, empty, children, }: ListProps<T>): import("react").JSX.Element;
102
+ export declare function List<T extends object>({ items, keyOf, embedded, surface, group, selection, sort, onSortChange, sortable, present, onPresentChange, onOpen, onPeek, isPeeked, state, filtered, empty, children, }: ListProps<T>): import("react").JSX.Element;
97
103
  export declare namespace List {
98
104
  var Bar: ((props: BarProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"bar">;
99
105
  var Crumbs: ((props: CrumbsProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"crumbs">;
@@ -22,6 +22,9 @@ const Views = slot("views", (_props) => null);
22
22
  * arriba de las filas, porque son del conjunto y no del marco. */
23
23
  const Metrics = slot("metrics", (_props) => null);
24
24
  const Rows = slot("rows", (_props) => null);
25
+ /* Through `unknown`: `create` both receives and hands back a `T` (`onChange`, `draft`),
26
+ so `TableProps` is invariant in `T` and `TableProps<never>` no longer narrows to it. The
27
+ slot only carries the props; `List` reads them back typed against the list's `T`. */
25
28
  const TableSlot = slot("table", (_props) => null);
26
29
  const Board = slot("board", (_props) => null);
27
30
  const SheetSlot = slot("sheet", (_props) => null);
@@ -39,7 +42,7 @@ const PRESENT_OF = {
39
42
  pivot: "pivot",
40
43
  };
41
44
  const FACES = ["rows", "table", "board", "sheet", "report", "pivot"];
42
- export function List({ items, keyOf, surface, group, selection, sort, onSortChange, sortable, present, onPresentChange, onOpen, onPeek, isPeeked, state, filtered, empty, children, }) {
45
+ export function List({ items, keyOf, embedded, surface, group, selection, sort, onSortChange, sortable, present, onPresentChange, onOpen, onPeek, isPeeked, state, filtered, empty, children, }) {
43
46
  const top = flatten(children);
44
47
  const bar = flatten(propsOf(pick(top, "bar"))?.children);
45
48
  const crumbs = propsOf(pick(bar, "crumbs"))?.crumbs;
@@ -65,12 +68,13 @@ export function List({ items, keyOf, surface, group, selection, sort, onSortChan
65
68
  /* La escotilla: lo que el arquetipo no previó se dibuja igual, debajo. Que
66
69
  aparezca algo acá es la señal de que al arquetipo le falta una pieza. */
67
70
  const rest = loose(top, ["bar", "metrics", ...FACES]);
68
- return (_jsx(ListView, { items: items, keyOf: keyOf, row: rows?.row ?? (() => ({ name: "" })), ...(rows?.header === undefined ? {} : { rowHeader: rows.header }), ...(identity === undefined ? {} : { identity }), ...(crumbs === undefined ? {} : { crumbs }), ...(surface === undefined ? {} : { surface }), ...(search === undefined ? {} : { search }), ...(actions === undefined ? {} : { actions }), ...(pagination === undefined ? {} : { pagination }), ...(views === undefined ? {} : { views }), ...(metrics === undefined ? {} : { metrics }), ...(table === undefined
71
+ return (_jsx(ListView, { items: items, keyOf: keyOf, row: rows?.row ?? (() => ({ name: "" })), ...(rows?.header === undefined ? {} : { rowHeader: rows.header }), ...(identity === undefined ? {} : { identity }), ...(crumbs === undefined ? {} : { crumbs }), ...(embedded === undefined ? {} : { embedded }), ...(surface === undefined ? {} : { surface }), ...(search === undefined ? {} : { search }), ...(actions === undefined ? {} : { actions }), ...(pagination === undefined ? {} : { pagination }), ...(views === undefined ? {} : { views }), ...(metrics === undefined ? {} : { metrics }), ...(table === undefined
69
72
  ? {}
70
73
  : {
71
74
  columns: table.columns,
72
75
  ...(table.totals === undefined ? {} : { totals: table.totals }),
73
76
  ...(table.rowActions === undefined ? {} : { rowActions: table.rowActions }),
77
+ ...(table.create === undefined ? {} : { create: table.create }),
74
78
  ...(table.visibleColumnIds === undefined
75
79
  ? {}
76
80
  : { visibleColumnIds: table.visibleColumnIds }),
@@ -1,5 +1,5 @@
1
1
  import type { ListViewProps } from "./types.js";
2
- export declare function ListView<T extends object>({ items, keyOf, identity, crumbs, surface, metrics, search, pagination, views, actions, row, rowHeader, columns, visibleColumnIds, onVisibleColumnIdsChange, card, sheet, report, pivot, present: requested, presents, onPresentChange, sort, onSortChange, sortable, totals, rowActions, group, selection, onOpen, onPeek, state, filtered, empty, children, }: ListViewProps<T>): import("react").JSX.Element;
2
+ export declare function ListView<T extends object>({ items, keyOf, identity, crumbs, embedded, surface: requestedSurface, metrics, search, pagination, views, actions, row, rowHeader, columns, visibleColumnIds, onVisibleColumnIdsChange, card, sheet, report, pivot, present: requested, presents, onPresentChange, sort, onSortChange, sortable, totals, rowActions, create, group, selection, onOpen, onPeek, state, filtered, empty, children, }: ListViewProps<T>): import("react").JSX.Element;
3
3
  /** What a list offers when it fails and can be retried. */
4
4
  export declare function RetryAction({ onRetry }: {
5
5
  onRetry: () => void;
@@ -18,7 +18,7 @@ import { Empty, Failed, Skeleton } from "../../primitives/notice/Notice.js";
18
18
  import { PivotTable } from "../../primitives/table/PivotTable.js";
19
19
  import { ReportTable } from "../../primitives/table/ReportTable.js";
20
20
  import { groupedColumnIds } from "./columns.js";
21
- import { groupLevelsOf, reportRowsOf, sheetFromColumns, sheetRowsOf, } from "./derive.js";
21
+ import { groupLevelsOf, reportColumnsOf, reportRowsOf, sheetFromColumns, sheetRowsOf, } from "./derive.js";
22
22
  import { SheetPresentation, TablePresentation, } from "./presentations.js";
23
23
  import { useNarrowList } from "./useNarrowList.js";
24
24
  import { Grid3x3, LayoutGrid, List, Sheet, Sigma, Table2 } from "lucide-react";
@@ -58,8 +58,11 @@ const PRESENT_ICONS = [
58
58
  /* La cuadrícula: dos ejes, y lo que importa está adentro. */
59
59
  { id: "pivot", icon: Grid3x3 },
60
60
  ];
61
- export function ListView({ items, keyOf, identity, crumbs, surface, metrics, search, pagination, views, actions, row, rowHeader, columns, visibleColumnIds, onVisibleColumnIdsChange, card, sheet, report, pivot, present: requested = "rows", presents, onPresentChange, sort, onSortChange, sortable, totals = false, rowActions, group, selection, onOpen, onPeek, state, filtered = false, empty, children, }) {
61
+ export function ListView({ items, keyOf, identity, crumbs, embedded = false, surface: requestedSurface, metrics, search, pagination, views, actions, row, rowHeader, columns, visibleColumnIds, onVisibleColumnIdsChange, card, sheet, report, pivot, present: requested = "rows", presents, onPresentChange, sort, onSortChange, sortable, totals = false, rowActions, create, group, selection, onOpen, onPeek, state, filtered = false, empty, children, }) {
62
62
  const { frame, offered, present } = useNarrowList(presents, requested);
63
+ /* Embedded, the list sits on the record's paper: there is no dark band to inherit, and a
64
+ navy switcher inside a white sheet would be a second chrome on the screen. */
65
+ const surface = embedded ? undefined : requestedSurface;
63
66
  const density = useDensity();
64
67
  const copy = useUiCopy();
65
68
  const loading = state?.loading === true;
@@ -128,7 +131,15 @@ export function ListView({ items, keyOf, identity, crumbs, surface, metrics, sea
128
131
  present === "pivot" ? null : (_jsx(SortMenu, { fields: sortable, sort: sort ?? null, onSortChange: (next) => onSortChange?.(next), ...(surface === undefined ? {} : { surface }) }));
129
132
  const rightViews = views ?? switcher;
130
133
  const viewsSlot = columnsMenu === null && sortMenu === null && rightViews === undefined ? undefined : (_jsxs(_Fragment, { children: [sortMenu, columnsMenu, rightViews] }));
131
- const bar = (_jsx(ListingBar, { surface: surface, ...(crumbs === undefined || crumbs.length === 0 || density === "compact"
134
+ /* Embedded, the line is drawn only if it has something to OFFER: a count alone repeats
135
+ what the rows (and the footer) already say. */
136
+ const barHasControls = !embedded ||
137
+ search !== undefined ||
138
+ viewsSlot !== undefined ||
139
+ actions !== undefined ||
140
+ pagination !== undefined ||
141
+ (selection?.count ?? 0) > 0;
142
+ const bar = !barHasControls ? undefined : (_jsx(ListingBar, { surface: surface, ...(embedded ? { inline: true, count: items.length } : {}), ...(embedded || crumbs === undefined || crumbs.length === 0 || density === "compact"
132
143
  ? {}
133
144
  : {
134
145
  crumbs: (_jsx(Breadcrumb, { crumbs: crumbs, ...(surface === undefined ? {} : { surface }) })),
@@ -183,7 +194,10 @@ export function ListView({ items, keyOf, identity, crumbs, surface, metrics, sea
183
194
  error === null &&
184
195
  (present === "pivot" && pivotShown !== undefined
185
196
  ? pivotIsEmpty(pivotShown)
186
- : items.length === 0);
197
+ : items.length === 0) &&
198
+ /* The first record of an empty list is written in the table, not under a sentence
199
+ saying there is nothing. */
200
+ !(present === "table" && create?.draft != null);
187
201
  /* La única línea que hace agrupable a una vista: el árbol que le pasaron, o el
188
202
  que se arma con las filas en la mano. */
189
203
  const piles = useMemo(() => pilesOf(ordered, group), [group, ordered]);
@@ -225,7 +239,7 @@ export function ListView({ items, keyOf, identity, crumbs, surface, metrics, sea
225
239
  };
226
240
  const body = present === "table" && shownColumns !== undefined ? (
227
241
  /* The table receives EVERYTHING that belongs to the set: see `TablePresentation`. */
228
- _jsx(TablePresentation, { items: items, columns: shownColumns, keyOf: keyOf, levels: groupLevels, ...(sort === undefined ? {} : { sort }), ...(onSortChange === undefined ? {} : { onSortChange }), ...(group === undefined ? {} : { group }), ...(selection === undefined ? {} : { selection }), totals: totals, ...(rowActions === undefined ? {} : { rowActions }), ...(onPeek === undefined ? {} : { onPeek }), ...(onOpen === undefined ? {} : { onOpen }) })) : present === "sheet" && sheetSpec !== undefined ? (
242
+ _jsx(TablePresentation, { items: items, columns: shownColumns, keyOf: keyOf, levels: groupLevels, ...(sort === undefined ? {} : { sort }), ...(onSortChange === undefined ? {} : { onSortChange }), ...(group === undefined ? {} : { group }), ...(selection === undefined ? {} : { selection }), totals: totals, ...(rowActions === undefined ? {} : { rowActions }), ...(create === undefined ? {} : { create }), ...(onPeek === undefined ? {} : { onPeek }), ...(onOpen === undefined ? {} : { onOpen }) })) : present === "sheet" && sheetSpec !== undefined ? (
229
243
  /* La planilla recibe el conjunto por ÍNDICE y no una matriz ya armada: ver `SheetPresentation`. */
230
244
  _jsx(SheetPresentation, { spec: sheetSpec, entries: sheetRows, ordered: ordered, ...(group === undefined ? {} : { group }) })) : present === "report" && report !== undefined ? (
231
245
  /* El informe declarado por el dominio no se ORDENA desde la barra: el
@@ -233,7 +247,15 @@ export function ListView({ items, keyOf, identity, crumbs, surface, metrics, sea
233
247
  Activos» en el medio. Pero sí se AGRUPA cuando las líneas no vienen
234
248
  declaradas: ahí el informe es este conjunto contado por los niveles que
235
249
  estén puestos. */
236
- _jsx(ReportTable, { columns: report.columns, rows: report.rows ?? reportRows, ...(report.defaultOpen === undefined ? {} : { defaultOpen: report.defaultOpen }), ...(report.height === undefined ? {} : { height: report.height }) })) : present === "pivot" && pivotShown !== undefined ? (
250
+ _jsx(ReportTable
251
+ /* Built from the piles, the numbers are the list's columns' — and so is how they
252
+ are written. Declared by the domain, the columns are the domain's. */
253
+ , {
254
+ /* Built from the piles, the numbers are the list's columns' — and so is how they
255
+ are written. Declared by the domain, the columns are the domain's. */
256
+ columns: report.rows === undefined
257
+ ? reportColumnsOf(report.columns, columns)
258
+ : report.columns, rows: report.rows ?? reportRows, ...(report.defaultOpen === undefined ? {} : { defaultOpen: report.defaultOpen }), ...(report.height === undefined ? {} : { height: report.height }) })) : present === "pivot" && pivotShown !== undefined ? (
237
259
  /* El pivote recibe la grilla y nada más: no hay selección que pasarle
238
260
  —una casilla por montón elegiría cosas que no son registros—, no hay
239
261
  orden —cada eje viene en el orden de sus claves— y no hay menú de
@@ -253,8 +275,12 @@ export function ListView({ items, keyOf, identity, crumbs, surface, metrics, sea
253
275
  wrapped it in a `div` to get both. */
254
276
  _jsxs("div", { ref: frame, className: "@container flex min-w-0 flex-1 flex-col bg-surface", children: [_jsxs(Listing, { bar: bar,
255
277
  /* La barra se queda arriba: con 187 filas, scrollear para ver la última
256
- dejaba sin buscador, sin paginador y sin el conmutador. */
257
- sticky: true, ...(surface === undefined ? {} : { surface }), ...(metrics === undefined
278
+ dejaba sin buscador, sin paginador y sin el conmutador.
279
+ Embedded it does NOT: the record has its own sticky parts (its rail, its tabs),
280
+ and a second band stuck under them — or carried up into the frame's header slot,
281
+ which is what a sticky list bar does under a sidebar — would cover the record
282
+ for a collection of a dozen rows. */
283
+ sticky: !embedded, ...(surface === undefined ? {} : { surface }), ...(metrics === undefined
258
284
  ? {}
259
285
  : {
260
286
  metrics: _jsx("div", { className: "px-3.5", children: metrics }),
@@ -1,6 +1,6 @@
1
1
  import { type Pile } from "../../foundations/grouping.js";
2
2
  import { type DataColumn } from "../../primitives/table/DataTable.js";
3
- import type { ReportRow } from "../../primitives/table/ReportTable.js";
3
+ import type { ReportColumn, ReportRow } from "../../primitives/table/ReportTable.js";
4
4
  import type { SheetColumn } from "../../primitives/table/SheetTable.js";
5
5
  import type { ListGroup, ListSheet, RowOf } from "./types.js";
6
6
  /**
@@ -74,3 +74,14 @@ export declare function sheetRowsOf<T extends object>(piles: readonly Pile<T>[]
74
74
  * no digan totales distintos del mismo conjunto.
75
75
  */
76
76
  export declare function reportRowsOf<T extends object>(piles: readonly Pile<T>[] | null, columns: readonly DataColumn<T>[] | undefined, row: (item: T) => RowOf): readonly ReportRow[];
77
+ /**
78
+ * The columns of a report built from the piles, written like the list's own columns.
79
+ *
80
+ * `reportRowsOf` puts in position `i` the aggregate of the `i`-th column that declared one,
81
+ * so `report.columns[i]` is THAT column's: a report column without its own `format` takes
82
+ * the one the list column declared — otherwise the report wrote «Bs. 78.752,90» in the
83
+ * table's footer and «78.752,90» in its own total line. A format declared on the report
84
+ * column wins: it is the more specific declaration. A `count` column keeps the report's own
85
+ * number format — a count of rows is not an amount.
86
+ */
87
+ export declare function reportColumnsOf<T extends object>(reportColumns: readonly ReportColumn[], columns: readonly DataColumn<T>[] | undefined): readonly ReportColumn[];
@@ -1,5 +1,5 @@
1
1
  import { levelKey, pathKey, pileItems, pileLabel, } from "../../foundations/grouping.js";
2
- import { aggregateOf } from "../../primitives/table/DataTable.js";
2
+ import { aggregateFormat, aggregateOf, aggregateText, } from "../../primitives/table/DataTable.js";
3
3
  /**
4
4
  * Context: what a list DERIVES from its set, as pure functions — the table's group levels,
5
5
  * the sheet drawn from the declared columns, the sheet's flattened band/row sequence and
@@ -114,10 +114,14 @@ export function sheetRowsOf(piles, isOpen, columns) {
114
114
  las `columns` de la lista —las mismas que suma el pie de la
115
115
  tabla— para que la planilla y la tabla no digan números distintos
116
116
  del mismo montón. La planilla declara SUS columnas aparte, así que
117
- se busca por id. */
117
+ se busca por id. Y se ESCRIBE como el pie: con el `format` de la
118
+ columna, para que el montón no diga «78752,9» debajo de «Bs.». */
118
119
  total: (column) => {
119
120
  const declared = columns?.find((one) => one.id === column.id);
120
- return declared === undefined ? null : aggregateOf(declared, inside);
121
+ const value = declared === undefined ? null : aggregateOf(declared, inside);
122
+ return declared === undefined || value === null
123
+ ? null
124
+ : aggregateText(declared, value);
121
125
  },
122
126
  },
123
127
  });
@@ -179,3 +183,25 @@ export function reportRowsOf(piles, columns, row) {
179
183
  };
180
184
  return piles.map(line);
181
185
  }
186
+ /**
187
+ * The columns of a report built from the piles, written like the list's own columns.
188
+ *
189
+ * `reportRowsOf` puts in position `i` the aggregate of the `i`-th column that declared one,
190
+ * so `report.columns[i]` is THAT column's: a report column without its own `format` takes
191
+ * the one the list column declared — otherwise the report wrote «Bs. 78.752,90» in the
192
+ * table's footer and «78.752,90» in its own total line. A format declared on the report
193
+ * column wins: it is the more specific declaration. A `count` column keeps the report's own
194
+ * number format — a count of rows is not an amount.
195
+ */
196
+ export function reportColumnsOf(reportColumns, columns) {
197
+ if (columns === undefined)
198
+ return reportColumns;
199
+ const numeric = columns.filter((column) => column.aggregate !== undefined);
200
+ return reportColumns.map((column, index) => {
201
+ const declared = numeric[index];
202
+ const format = declared === undefined ? undefined : aggregateFormat(declared);
203
+ return column.format !== undefined || format === undefined
204
+ ? column
205
+ : { ...column, format };
206
+ });
207
+ }
@@ -15,11 +15,11 @@ type TableProps<T extends object> = {
15
15
  levels: NonNullable<Parameters<typeof DataTable<T>>[0]["levels"]>;
16
16
  group?: ListGroup<T>;
17
17
  totals: boolean;
18
- } & Pick<ListViewProps<T>, "sort" | "onSortChange" | "selection" | "rowActions" | "onPeek" | "onOpen">;
18
+ } & Pick<ListViewProps<T>, "sort" | "onSortChange" | "selection" | "rowActions" | "create" | "onPeek" | "onOpen">;
19
19
  /** The table receives EVERYTHING that belongs to the set —sorting, selection, grouping,
20
20
  * which columns are on screen— and not a trimmed down version: that was exactly the trap
21
21
  * this archetype exists to avoid, that switching presentation loses capabilities. */
22
- export declare function TablePresentation<T extends object>({ items, columns, keyOf, levels, group, totals, sort, onSortChange, selection, rowActions, onPeek, onOpen, }: TableProps<T>): import("react").JSX.Element;
22
+ export declare function TablePresentation<T extends object>({ items, columns, keyOf, levels, group, totals, sort, onSortChange, selection, rowActions, create, onPeek, onOpen, }: TableProps<T>): import("react").JSX.Element;
23
23
  type SheetProps<T extends object> = {
24
24
  spec: ListSheet<T>;
25
25
  /** The flattened bands and rows when the set is grouped; `null` when it is not. */
@@ -6,7 +6,7 @@ import { SheetTable } from "../../primitives/table/SheetTable.js";
6
6
  /** The table receives EVERYTHING that belongs to the set —sorting, selection, grouping,
7
7
  * which columns are on screen— and not a trimmed down version: that was exactly the trap
8
8
  * this archetype exists to avoid, that switching presentation loses capabilities. */
9
- export function TablePresentation({ items, columns, keyOf, levels, group, totals, sort, onSortChange, selection, rowActions, onPeek, onOpen, }) {
9
+ export function TablePresentation({ items, columns, keyOf, levels, group, totals, sort, onSortChange, selection, rowActions, create, onPeek, onOpen, }) {
10
10
  return (_jsx(DataTable, { data: items, columns: columns, getRowId: keyOf, ...(sort === undefined ? {} : { sort }), ...(onSortChange === undefined ? {} : { onSortChange }), ...(levels.length === 0 ? {} : { levels: levels }), ...(group?.collapsed === undefined ? {} : { collapsed: group.collapsed }), ...(group?.onToggle === undefined ? {} : { onGroupToggle: group.onToggle }), ...(selection === undefined
11
11
  ? {}
12
12
  : {
@@ -22,7 +22,7 @@ export function TablePresentation({ items, columns, keyOf, levels, group, totals
22
22
  selection.toggle(id);
23
23
  }
24
24
  },
25
- }), ...(totals ? { totals: true } : {}), ...(rowActions === undefined ? {} : { rowActions }), ...((onPeek ?? onOpen) === undefined ? {} : { onRowClick: onPeek ?? onOpen }) }));
25
+ }), ...(totals ? { totals: true } : {}), ...(rowActions === undefined ? {} : { rowActions }), ...(create === undefined ? {} : { create }), ...((onPeek ?? onOpen) === undefined ? {} : { onRowClick: onPeek ?? onOpen }) }));
26
26
  }
27
27
  /** The sheet receives the set by INDEX and not a ready-made matrix: `SheetTable` is
28
28
  * virtualized precisely so as not to materialize a million rows, and handing it copies
@@ -99,5 +99,7 @@ export function SheetPresentation({ spec, entries, ordered, group, }) {
99
99
  ? false
100
100
  : (spec.editable?.(item, column, columnIndex) ?? false);
101
101
  },
102
- }) }));
102
+ }), ...(spec.onAddRow === undefined || entries !== null
103
+ ? {}
104
+ : { onAddRow: spec.onAddRow }) }));
103
105
  }
@@ -4,7 +4,7 @@ import type { SortField } from "../../components/listing/SortMenu.js";
4
4
  import type { Grouping, GroupLevel } from "../../foundations/grouping.js";
5
5
  import type { Pivot, PivotKey, PivotSpec } from "../../foundations/pivot.js";
6
6
  import type { Surface, Tone } from "../../foundations/types.js";
7
- import type { DataColumn } from "../../primitives/table/DataTable.js";
7
+ import type { DataColumn, DataTableCreate } from "../../primitives/table/DataTable.js";
8
8
  import type { ReportColumn, ReportRow } from "../../primitives/table/ReportTable.js";
9
9
  import type { RowAction } from "../../primitives/table/RowActions.js";
10
10
  import type { SheetColumn } from "../../primitives/table/SheetTable.js";
@@ -87,6 +87,9 @@ export type ListSheet<T> = {
87
87
  * convertirlo al tipo de la columna es del dominio, no de acá. */
88
88
  onCommit?: (item: T, column: SheetColumn, columnIndex: number, next: string) => void;
89
89
  editable?: (item: T, column: SheetColumn, columnIndex: number) => boolean;
90
+ /** Present = the sheet adds rows: «add a row» under it, and `Enter` on the last row.
91
+ * The consumer appends the item; the sheet lands on it. Not while grouped. */
92
+ onAddRow?: () => void;
90
93
  };
91
94
  /**
92
95
  * El INFORME de una lista: los períodos y la jerarquía que termina en totales.
@@ -160,6 +163,11 @@ export type ListViewProps<T extends object> = {
160
163
  /** The metrics that also NARROW: «2 por confirmar», «41 por entregar». They go
161
164
  * below the bar and above the rows — they belong to the set, not to the frame. */
162
165
  metrics?: ReactNode;
166
+ /** The list is a FIELD of a record (a one2many / many2many) and not a screen: the bar
167
+ * is one line — search, count, sort, columns, switcher, actions —, it does not stick
168
+ * and it does not move into the frame's header. Identity and crumbs are not drawn: the
169
+ * record around it already says them. See `ListingBar`'s header. */
170
+ embedded?: boolean;
163
171
  /** Which surface the BAR sits on. `canvas` (the default) is a light control bar;
164
172
  * `chrome` turns it into a dark band — an explicit choice, since the application bar
165
173
  * is the screen's one dark band (same as the rail of a record). */
@@ -212,6 +220,10 @@ export type ListViewProps<T extends object> = {
212
220
  /** What gets done to ONE row without entering it, in the table presentation.
213
221
  * They are drawn hidden and appear on the row being pointed at. */
214
222
  rowActions?: (item: T) => readonly RowAction[];
223
+ /** Write a new record as a row of the table presentation — Odoo's editable list. The
224
+ * columns that declare `input` get a control in that row. See `DataTable`'s header.
225
+ * While a record is being written the table shows even if the set is empty. */
226
+ create?: DataTableCreate<T>;
215
227
  /** The board presentation. */
216
228
  card?: (item: T) => ReactNode;
217
229
  /**
@@ -1,12 +1,14 @@
1
+ import { type ActivityProps } from "../../components/activity/Activity.js";
1
2
  import { type SheetField, type SheetLayout } from "../../components/form/Sheet.js";
2
3
  import type { Crumb } from "../../components/record/Breadcrumb.js";
3
4
  import type { DirtyState } from "../../components/record/DirtyActions.js";
5
+ import { type RecordNoticeSpec } from "../../components/record/RecordNotices.js";
4
6
  import { RecordSkeleton } from "../../components/record/RecordSkeleton.js";
5
7
  import { type Stage } from "../../components/record/StatusBar.js";
6
8
  import type { Surface, Tone } from "../../foundations/types.js";
7
9
  import { type TabNotice } from "../../primitives/tabs/Tabs.js";
8
10
  import type { LucideIcon } from "lucide-react";
9
- import type { ReactNode } from "react";
11
+ import { type ReactNode } from "react";
10
12
  export type RecordIdentity = {
11
13
  icon?: LucideIcon;
12
14
  title: ReactNode;
@@ -42,6 +44,9 @@ export type RecordPager = {
42
44
  onNext?: () => void;
43
45
  };
44
46
  export type { SheetField };
47
+ /** A notice of the record: the props of `Record.Notice` (a `Callout` without its × label,
48
+ * which the record writes from the copy table). */
49
+ export type RecordNotice = RecordNoticeSpec;
45
50
  type RailProps = {
46
51
  children?: ReactNode;
47
52
  /** The rail's surface. `canvas` (the default) is a light control bar; `chrome` is the dark
@@ -95,9 +100,27 @@ type PageProps = {
95
100
  notice?: TabNotice;
96
101
  children?: ReactNode;
97
102
  };
103
+ /** The record's ACTIVITY panel, as DATA: its conversation, its history, its composer.
104
+ * The record draws the `Activity` itself and gives it what only the record has — its
105
+ * notices (the ones that are not blocking), and the indicator in the rail that opens the
106
+ * panel on them.
107
+ *
108
+ * Context: it was `<Record.Chatter><Chatter open onToggle …/></Record.Chatter>`, a node
109
+ * the record could only place. Written as data — like `Record.Status` — the record owns
110
+ * the panel's open state (`defaultOpen`, or `open` + `onOpenChange` to control it), so
111
+ * «⚠ 2 avisos» in the rail can open it and move the focus to its notices. */
112
+ export type RecordActivityProps = Omit<ActivityProps, "open" | "onToggle" | "alerts" | "alertsId"> & {
113
+ /** Starts OPEN unless this says otherwise: on a big screen you see what the record has. */
114
+ defaultOpen?: boolean;
115
+ /** Controls the panel: then `onOpenChange` must follow it. Remembering it between
116
+ * records is the app's — the system only reports. */
117
+ open?: boolean;
118
+ onOpenChange?: (open: boolean) => void;
119
+ };
98
120
  export type RecordProps = {
99
121
  identity: RecordIdentity;
100
- /** Lo que falló al operar sobre el registro. Va arriba del papel, adentro. */
122
+ /** Lo que falló al operar sobre el registro. Va con los avisos que bloquean, primero:
123
+ * entre el riel y el papel, siempre a la vista (ver `Record.Notice`). */
101
124
  error?: string | null;
102
125
  /** Hay cambios sin guardar. Su presencia REEMPLAZA los botones de acción por
103
126
  * guardar y descartar — ver la nota en `RecordHeader`. */
@@ -114,13 +137,9 @@ export declare namespace Record {
114
137
  var Actions: ((props: ActionsProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"actions">;
115
138
  var Status: ((props: StatusProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"status">;
116
139
  var Paper: ((props: PaperProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"paper">;
117
- var Chatter: ((props: {
118
- children?: ReactNode;
119
- /** `page` lo pone SIEMPRE debajo y a todo el ancho, como una hoja propia. Sin
120
- * esto va al costado cuando hay ancho, que es la forma angosta. */
121
- layout?: "aside" | "page";
122
- }) => ReactNode) & import("../../foundations/slots.js").Slotted<"chatter">;
140
+ var Activity: ((props: RecordActivityProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"activity">;
123
141
  var Facts: ((props: FactsProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"facts">;
124
142
  var Pages: ((props: PagesProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"pages">;
125
143
  var Page: ((props: PageProps) => ReactNode) & import("../../foundations/slots.js").Slotted<"page">;
144
+ var Notice: ((props: RecordNoticeSpec) => ReactNode) & import("../../foundations/slots.js").Slotted<"notice">;
126
145
  }