@crisp-ui-kit/crisp 0.33.5 → 0.35.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 (46) hide show
  1. package/dist/cjs/components/datatable/datatable.js +65 -5
  2. package/dist/cjs/components/datatable/datatable.recipe.js +2 -0
  3. package/dist/cjs/components/filldoc/filldoc.js +102 -0
  4. package/dist/cjs/components/filldoc/filldoc.recipe.js +211 -0
  5. package/dist/cjs/components/filldoc/index.js +10 -0
  6. package/dist/cjs/components/filldoc/serialize.js +39 -0
  7. package/dist/cjs/components/fillsheet/fillsheet.js +719 -0
  8. package/dist/cjs/components/fillsheet/fillsheet.recipe.js +325 -0
  9. package/dist/cjs/components/fillsheet/index.js +12 -0
  10. package/dist/cjs/components/fillsheet/serialize.js +82 -0
  11. package/dist/cjs/index.js +2 -0
  12. package/dist/cjs/product/recordpage/recordpage.js +1 -1
  13. package/dist/datatable.css +13 -5
  14. package/dist/datatable.layered.css +13 -5
  15. package/dist/esm/components/datatable/datatable.js +65 -5
  16. package/dist/esm/components/datatable/datatable.recipe.js +2 -0
  17. package/dist/esm/components/filldoc/filldoc.js +66 -0
  18. package/dist/esm/components/filldoc/filldoc.recipe.js +208 -0
  19. package/dist/esm/components/filldoc/index.js +3 -0
  20. package/dist/esm/components/filldoc/serialize.js +35 -0
  21. package/dist/esm/components/fillsheet/fillsheet.js +683 -0
  22. package/dist/esm/components/fillsheet/fillsheet.recipe.js +322 -0
  23. package/dist/esm/components/fillsheet/index.js +3 -0
  24. package/dist/esm/components/fillsheet/serialize.js +76 -0
  25. package/dist/esm/index.js +2 -0
  26. package/dist/esm/product/recordpage/recordpage.js +1 -1
  27. package/dist/filldoc.css +31 -0
  28. package/dist/filldoc.d.ts +7 -0
  29. package/dist/filldoc.layered.css +33 -0
  30. package/dist/fillsheet.css +29 -0
  31. package/dist/fillsheet.d.ts +7 -0
  32. package/dist/fillsheet.layered.css +31 -0
  33. package/dist/styles.css +75 -89
  34. package/dist/styles.layered.css +75 -89
  35. package/dist/tokens.css +0 -84
  36. package/dist/types/components/datatable/datatable.d.ts +7 -1
  37. package/dist/types/components/filldoc/filldoc.d.ts +79 -0
  38. package/dist/types/components/filldoc/filldoc.recipe.d.ts +201 -0
  39. package/dist/types/components/filldoc/index.d.ts +3 -0
  40. package/dist/types/components/filldoc/serialize.d.ts +5 -0
  41. package/dist/types/components/fillsheet/fillsheet.d.ts +165 -0
  42. package/dist/types/components/fillsheet/fillsheet.recipe.d.ts +202 -0
  43. package/dist/types/components/fillsheet/index.d.ts +3 -0
  44. package/dist/types/components/fillsheet/serialize.d.ts +45 -0
  45. package/dist/types/index.d.ts +2 -0
  46. package/package.json +11 -1
package/dist/styles.css CHANGED
@@ -122,90 +122,6 @@
122
122
  --crisp-font-sans: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
123
123
  }
124
124
 
125
- /* -----------------------------------------------------------------
126
- * Deprecated unprefixed aliases (issue #276) — SCHEDULED FOR REMOVAL in
127
- * the next major version. Prefer the --crisp-* custom property
128
- * above; these only forward to it so an existing override keeps working.
129
- * ----------------------------------------------------------------- */
130
- :root {
131
- --bg-brand-solid: var(--crisp-bg-brand-solid);
132
- --bg-brand-solid-pressed: var(--crisp-bg-brand-solid-pressed);
133
- --fg-on-brand: var(--crisp-fg-on-brand);
134
- --fg-on-tone: var(--crisp-fg-on-tone);
135
- --bg-surface: var(--crisp-bg-surface);
136
- --bg-raised: var(--crisp-bg-raised);
137
- --border-default: var(--crisp-border-default);
138
- --border-subtle: var(--crisp-border-subtle);
139
- --ring-neutral: var(--crisp-ring-neutral);
140
- --bg-tile-active: var(--crisp-bg-tile-active);
141
- --shadow-tile-active: var(--crisp-shadow-tile-active);
142
- --bg-overlay-frost: var(--crisp-bg-overlay-frost);
143
- --shadow-overlay1: var(--crisp-shadow-overlay1);
144
- --shadow-overlay2: var(--crisp-shadow-overlay2);
145
- --shadow-overlay3: var(--crisp-shadow-overlay3);
146
- --bg-popover: var(--crisp-bg-popover);
147
- --ring-popover: var(--crisp-ring-popover);
148
- --shadow-popover1: var(--crisp-shadow-popover1);
149
- --shadow-popover2: var(--crisp-shadow-popover2);
150
- --shadow-popover3: var(--crisp-shadow-popover3);
151
- --fg-primary: var(--crisp-fg-primary);
152
- --fg-muted: var(--crisp-fg-muted);
153
- --bg-danger: var(--crisp-bg-danger);
154
- --bg-danger-solid: var(--crisp-bg-danger-solid);
155
- --stroke-field-focus: var(--crisp-stroke-field-focus);
156
- --fg-disabled: var(--crisp-fg-disabled);
157
- --bg-neutral-weak: var(--crisp-bg-neutral-weak);
158
- --bg-neutral-inverted: var(--crisp-bg-neutral-inverted);
159
- --fg-on-neutral-inverted: var(--crisp-fg-on-neutral-inverted);
160
- --fg-neutral-subtle: var(--crisp-fg-neutral-subtle);
161
- --fg-neutral-muted: var(--crisp-fg-neutral-muted);
162
- --stroke-focus-ring: var(--crisp-stroke-focus-ring);
163
- --bg-success: var(--crisp-bg-success);
164
- --bg-warning: var(--crisp-bg-warning);
165
- --bg-orange: var(--crisp-bg-orange);
166
- --bg-cyan: var(--crisp-bg-cyan);
167
- --bg-purple: var(--crisp-bg-purple);
168
- --bg-sidebar: var(--crisp-bg-sidebar);
169
- --bg-subtle: var(--crisp-bg-subtle);
170
- --space-1: var(--crisp-space-1);
171
- --space-2: var(--crisp-space-2);
172
- --space-3: var(--crisp-space-3);
173
- --space-4: var(--crisp-space-4);
174
- --space-5: var(--crisp-space-5);
175
- --space-6: var(--crisp-space-6);
176
- --space-8: var(--crisp-space-8);
177
- --space-px: var(--crisp-space-px);
178
- --space-0-5: var(--crisp-space-0-5);
179
- --space-1-5: var(--crisp-space-1-5);
180
- --space-2-5: var(--crisp-space-2-5);
181
- --radius-chip: var(--crisp-radius-chip);
182
- --radius-sm: var(--crisp-radius-sm);
183
- --radius-md: var(--crisp-radius-md);
184
- --radius-lg: var(--crisp-radius-lg);
185
- --radius-xl: var(--crisp-radius-xl);
186
- --radius-2xl: var(--crisp-radius-2xl);
187
- --radius-full: var(--crisp-radius-full);
188
- --size-icon: var(--crisp-size-icon);
189
- --size-chip: var(--crisp-size-chip);
190
- --size-row: var(--crisp-size-row);
191
- --size-menuRow: var(--crisp-size-menuRow);
192
- --size-tableRow: var(--crisp-size-tableRow);
193
- --size-tableHeader: var(--crisp-size-tableHeader);
194
- --size-header: var(--crisp-size-header);
195
- --size-calendarCell: var(--crisp-size-calendarCell);
196
- --size-calendarPill: var(--crisp-size-calendarPill);
197
- --text-xs: var(--crisp-text-xs);
198
- --text-sm: var(--crisp-text-sm);
199
- --text-md: var(--crisp-text-md);
200
- --text-lg: var(--crisp-text-lg);
201
- --text-xl: var(--crisp-text-xl);
202
- --weight-regular: var(--crisp-weight-regular);
203
- --weight-medium: var(--crisp-weight-medium);
204
- --weight-semibold: var(--crisp-weight-semibold);
205
- --weight-bold: var(--crisp-weight-bold);
206
- --font-sans: var(--crisp-font-sans);
207
- }
208
-
209
125
  .crisp-accordion {
210
126
  display: flex; flex-direction: column; font-family: var(--crisp-font-sans);
211
127
  & .crisp-accordion-item { border-bottom: 1px solid var(--crisp-border-subtle); }
@@ -595,6 +511,8 @@
595
511
  & tbody tr[data-selected] td[data-sticky] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 10%, var(--crisp-bg-surface)); }
596
512
  & tbody tr:hover td[data-sticky] { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, var(--crisp-bg-surface)); }
597
513
  & .crisp-table-scroll[data-scrolled-x] [data-sticky-edge] { clip-path: inset(0 -38px 0 0); box-shadow: 6px 0 16px 4px rgba(0,0,0,0.12); }
514
+ /* mirror of the rule above, for stickyLast's trailing column (#327) */
515
+ & .crisp-table-scroll[data-scrolled-x-end] [data-sticky-edge-end] { clip-path: inset(0 0 0 -38px); box-shadow: -6px 0 16px 4px rgba(0,0,0,0.12); }
598
516
  /* add-row + summary footer */
599
517
  & .crisp-datatable-addcell { padding: 0; border-top: none; }
600
518
  & .crisp-datatable-addrow { display: flex; align-items: center; gap: var(--crisp-space-2); width: 100%; height: var(--crisp-size-tableRow); padding: 0 var(--crisp-space-2); border: none; border-top: 1px solid var(--crisp-border-subtle); background: var(--crisp-bg-surface); color: var(--crisp-fg-muted); font-family: inherit; font-size: var(--crisp-text-lg); cursor: pointer; transition: background-color .12s; }
@@ -618,7 +536,12 @@
618
536
  & .crisp-datatable-entity { display: flex; align-items: center; gap: var(--crisp-space-1-5); min-width: 0; color: var(--crisp-fg-primary); font-weight: var(--crisp-weight-medium); }
619
537
  & .crisp-datatable-entity-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
620
538
  & .crisp-datatable-avatar { width: var(--crisp-size-icon); height: var(--crisp-size-icon); border-radius: var(--crisp-radius-sm); flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; font-size: 10px; line-height: 1; font-weight: var(--crisp-weight-semibold); text-transform: uppercase; color: var(--crisp-fg-on-brand); background: var(--crisp-bg-brand-solid); }
621
- & .crisp-datatable-avatar[data-tone="success"] { background: var(--crisp-bg-success); } & .crisp-datatable-avatar[data-tone="warning"] { background: var(--crisp-bg-warning); } & .crisp-datatable-avatar[data-tone="danger"] { background: var(--crisp-bg-danger); } & .crisp-datatable-avatar[data-tone="purple"] { background: var(--crisp-bg-purple); } & .crisp-datatable-avatar[data-tone="cyan"] { background: var(--crisp-bg-cyan); } & .crisp-datatable-avatar[data-tone="orange"] { background: var(--crisp-bg-orange); }
539
+ & .crisp-datatable-avatar[data-tone="success"] { background: var(--crisp-bg-success); }
540
+ & .crisp-datatable-avatar[data-tone="warning"] { background: var(--crisp-bg-warning); }
541
+ & .crisp-datatable-avatar[data-tone="danger"] { background: var(--crisp-bg-danger); }
542
+ & .crisp-datatable-avatar[data-tone="purple"] { background: var(--crisp-bg-purple); }
543
+ & .crisp-datatable-avatar[data-tone="cyan"] { background: var(--crisp-bg-cyan); }
544
+ & .crisp-datatable-avatar[data-tone="orange"] { background: var(--crisp-bg-orange); }
622
545
  & .crisp-datatable-avatar img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
623
546
  & .crisp-datatable-tags { display: flex; align-items: center; gap: var(--crisp-space-1); overflow: hidden; }
624
547
  & .crisp-datatable-tag { display: inline-flex; align-items: center; height: var(--crisp-size-chip); padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-chip); font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); white-space: nowrap; background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: color-mix(in srgb, var(--crisp-fg-primary) 82%, transparent); }
@@ -631,10 +554,11 @@
631
554
  & .crisp-datatable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); }
632
555
  & .crisp-datatable-num { font-variant-numeric: tabular-nums; }
633
556
  & .crisp-datatable-muted { color: var(--crisp-fg-muted); }
634
- /* row drag-to-reorder -- a Settings > Objects > Attributes screen measures
635
- a leading 20px grip column, a 16px grip icon, and the row's own hairline doubling as the drop indicator (it tints toward the brand colour as the active drop target). The affordance + geometry are measured; the drag MECHANISM is crisp's existing house idiom -- HTML5
636
- draggable + dataTransfer, the same one column reorder already uses
637
- (RecordsTable's reorderColumn) -- not a proprietary pointer-events implementation. */
557
+ /* row drag-to-reorder -- a Settings > Objects > Attributes screen measures a leading 20px grip column, a 16px grip icon, and the row's own
558
+ hairline doubling as the drop indicator (it tints toward the brand
559
+ colour as the active drop target). The affordance + geometry are
560
+ measured; the drag MECHANISM is crisp's existing house idiom -- HTML5 draggable + dataTransfer, the same one column reorder already uses (RecordsTable's reorderColumn) -- not a proprietary
561
+ pointer-events implementation. */
638
562
  & .crisp-datatable-col-grip { width: 20px; padding: 0; text-align: center; }
639
563
  & .crisp-datatable-grip { display: inline-flex; align-items: center; justify-content: center; width: 100%; height: 100%; margin: 0; border: none; border-radius: 0; background: none; font-family: inherit; color: var(--crisp-fg-muted); cursor: grab; }
640
564
  & .crisp-datatable-grip:active { cursor: grabbing; }
@@ -920,6 +844,68 @@
920
844
  }
921
845
  }
922
846
 
847
+ .crisp-filldoc {
848
+ display: flex; flex-direction: column; gap: var(--crisp-space-4); box-sizing: border-box; width: 210mm; min-height: 297mm; padding: 20mm; margin: 0 auto; background: var(--crisp-bg-surface); font-family: var(--crisp-font-sans); font-size: var(--crisp-text-lg); line-height: 22px; color: var(--crisp-fg-primary); border-radius: 0; box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
849
+ &:focus, &:focus-visible { outline: none; }
850
+ & .crisp-filldoc-block { position: relative; }
851
+ & .crisp-filldoc-heading { margin: 0; font-size: var(--crisp-text-xl); font-weight: var(--crisp-weight-semibold); line-height: 26px; color: var(--crisp-fg-primary); white-space: pre-wrap; overflow-wrap: break-word; }
852
+ & .crisp-filldoc-text { margin: 0; font-size: var(--crisp-text-lg); line-height: 22px; color: var(--crisp-fg-primary); white-space: pre-wrap; overflow-wrap: break-word; }
853
+ & .crisp-filldoc-writer { display: block; width: 100%; margin: 0; padding: 0; border: none; outline: none; background: transparent; font-family: inherit; font-size: inherit; font-weight: inherit; line-height: inherit; color: inherit; resize: none; overflow: hidden; user-select: text; -webkit-user-select: text; }
854
+ & .crisp-filldoc-insert { position: absolute; inset-inline-start: 0; inset-inline-end: 0; inset-block-end: calc(var(--crisp-space-4) / -2); height: var(--crisp-space-4); display: flex; align-items: center; gap: var(--crisp-space-2); opacity: 0; transition: opacity .1s; cursor: pointer; }
855
+ & .crisp-filldoc-block:hover .crisp-filldoc-insert, & .crisp-filldoc-insert:focus-within { opacity: 1; }
856
+ & .crisp-filldoc-insert-rule { flex: 1; height: 1px; background: var(--crisp-border-default); }
857
+ & .crisp-filldoc-insert button { display: inline-flex; align-items: center; height: 20px; padding: 0 var(--crisp-space-1-5); border: none; border-radius: var(--crisp-radius-sm); background: var(--crisp-bg-raised); font-family: inherit; font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); cursor: pointer; }
858
+ & .crisp-filldoc-insert button:hover { background: var(--crisp-bg-neutral-weak); color: var(--crisp-fg-primary); }
859
+ & .crisp-filldoc-tools { position: absolute; inset-inline-end: 100%; inset-block-start: 0; padding-inline-end: var(--crisp-space-2); display: flex; gap: var(--crisp-space-1); opacity: 0; transition: opacity .1s; }
860
+ & .crisp-filldoc-block:hover .crisp-filldoc-tools, & .crisp-filldoc-tools:focus-within { opacity: 1; }
861
+ & .crisp-filldoc-tools button { width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: transparent; font-family: inherit; font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); cursor: pointer; }
862
+ & .crisp-filldoc-tools button:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
863
+ }
864
+ .crisp-filldoc--page_a4 {
865
+
866
+ }
867
+ .crisp-filldoc--page_auto {
868
+ width: 100%; min-height: 0; max-width: 210mm;
869
+ }
870
+
871
+ @media (prefers-reduced-motion: reduce) {
872
+ .crisp-filldoc, .crisp-filldoc * {
873
+ animation-duration: 0.01ms !important;
874
+ animation-iteration-count: 1 !important;
875
+ transition-duration: 0.01ms !important;
876
+ }
877
+ }
878
+
879
+ .crisp-fillsheet {
880
+ display: grid; grid-template-columns: var(--crisp-fillsheet-cols); grid-template-rows: var(--crisp-fillsheet-rows); position: relative; overflow: auto; max-width: 100%; box-sizing: border-box; font-family: var(--crisp-font-sans); font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); background: var(--crisp-bg-surface); border-radius: 0; border: 1px solid var(--crisp-border-default); user-select: none; -webkit-user-select: none;
881
+ &:focus, &:focus-visible { outline: none; }
882
+ & .crisp-fillsheet-cell { position: relative; display: flex; align-items: flex-start; min-width: 0; padding-inline: var(--crisp-space-3); padding-block: var(--crisp-space-3); border-inline-end: 1px solid var(--crisp-border-default); border-block-end: 1px solid var(--crisp-border-default); background: var(--crisp-bg-surface); white-space: pre-wrap; overflow-wrap: break-word; line-height: 20px; cursor: cell; }
883
+ & .crisp-fillsheet-cell[aria-readonly] { background: var(--crisp-bg-raised); color: var(--crisp-fg-muted); }
884
+ & .crisp-fillsheet-cell:last-child { border-inline-end: none; }
885
+ & > div:last-child .crisp-fillsheet-cell { border-block-end: none; }
886
+ & .crisp-fillsheet-cell[data-align="end"] { justify-content: flex-end; font-variant-numeric: tabular-nums; }
887
+ &[data-multi] .crisp-fillsheet-cell[data-range] { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
888
+ &[data-keynav] .crisp-fillsheet-cell[data-selected] { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); box-shadow: inset 0 -2px 0 var(--crisp-fg-primary); }
889
+ & .crisp-fillsheet-cell[data-editing] { background: var(--crisp-bg-surface); }
890
+ & .crisp-fillsheet-colresize { position: absolute; inset-block-start: 0; inset-block-end: 0; inset-inline-end: 0; z-index: 3; width: 5px; cursor: col-resize; touch-action: none; }
891
+ & .crisp-fillsheet-rowresize { position: absolute; inset-inline-start: 0; inset-inline-end: 0; inset-block-end: 0; z-index: 3; height: 5px; cursor: row-resize; touch-action: none; }
892
+ & .crisp-fillsheet-colresize:hover { background: linear-gradient(to right, transparent 0, transparent calc(50% - 1px), var(--crisp-fg-primary) calc(50% - 1px), var(--crisp-fg-primary) calc(50% + 1px), transparent calc(50% + 1px)); }
893
+ & .crisp-fillsheet-rowresize:hover { background: linear-gradient(to bottom, transparent 0, transparent calc(50% - 1px), var(--crisp-fg-primary) calc(50% - 1px), var(--crisp-fg-primary) calc(50% + 1px), transparent calc(50% + 1px)); }
894
+ & .crisp-fillsheet-editor { display: block; flex-grow: 1; width: 100%; min-width: 0; margin: 0; padding: 0; border: none; outline: none; background: transparent; font-family: inherit; font-size: inherit; line-height: 20px; color: inherit; resize: none; user-select: text; -webkit-user-select: text; overflow: hidden; }
895
+ & .crisp-fillsheet-select .crisp-select-trigger { width: 100%; height: 100%; padding: 0; border: none; background: transparent; box-shadow: none; font: inherit; color: inherit; }
896
+ & .crisp-fillsheet-select .crisp-select-trigger:hover, & .crisp-fillsheet-select .crisp-select-trigger[data-open] { background: transparent; box-shadow: none; }
897
+ & .crisp-fillsheet-select .crisp-select-chevron { display: none; }
898
+ }
899
+ .crisp-fillsheet--surface_panel {
900
+
901
+ }
902
+ .crisp-fillsheet--surface_paper {
903
+ box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
904
+ }
905
+ .crisp-fillsheet--surface_bare {
906
+ border: none;
907
+ }
908
+
923
909
  .crisp-formfield {
924
910
  display: flex; flex-direction: column; gap: var(--crisp-space-1-5); box-sizing: border-box; font-family: var(--crisp-font-sans);
925
911
  & .crisp-formfield-label { display: inline-flex; align-items: center; gap: var(--crisp-space-1); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
@@ -122,90 +122,6 @@
122
122
  --crisp-font-sans: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
123
123
  }
124
124
 
125
- /* -----------------------------------------------------------------
126
- * Deprecated unprefixed aliases (issue #276) — SCHEDULED FOR REMOVAL in
127
- * the next major version. Prefer the --crisp-* custom property
128
- * above; these only forward to it so an existing override keeps working.
129
- * ----------------------------------------------------------------- */
130
- :root {
131
- --bg-brand-solid: var(--crisp-bg-brand-solid);
132
- --bg-brand-solid-pressed: var(--crisp-bg-brand-solid-pressed);
133
- --fg-on-brand: var(--crisp-fg-on-brand);
134
- --fg-on-tone: var(--crisp-fg-on-tone);
135
- --bg-surface: var(--crisp-bg-surface);
136
- --bg-raised: var(--crisp-bg-raised);
137
- --border-default: var(--crisp-border-default);
138
- --border-subtle: var(--crisp-border-subtle);
139
- --ring-neutral: var(--crisp-ring-neutral);
140
- --bg-tile-active: var(--crisp-bg-tile-active);
141
- --shadow-tile-active: var(--crisp-shadow-tile-active);
142
- --bg-overlay-frost: var(--crisp-bg-overlay-frost);
143
- --shadow-overlay1: var(--crisp-shadow-overlay1);
144
- --shadow-overlay2: var(--crisp-shadow-overlay2);
145
- --shadow-overlay3: var(--crisp-shadow-overlay3);
146
- --bg-popover: var(--crisp-bg-popover);
147
- --ring-popover: var(--crisp-ring-popover);
148
- --shadow-popover1: var(--crisp-shadow-popover1);
149
- --shadow-popover2: var(--crisp-shadow-popover2);
150
- --shadow-popover3: var(--crisp-shadow-popover3);
151
- --fg-primary: var(--crisp-fg-primary);
152
- --fg-muted: var(--crisp-fg-muted);
153
- --bg-danger: var(--crisp-bg-danger);
154
- --bg-danger-solid: var(--crisp-bg-danger-solid);
155
- --stroke-field-focus: var(--crisp-stroke-field-focus);
156
- --fg-disabled: var(--crisp-fg-disabled);
157
- --bg-neutral-weak: var(--crisp-bg-neutral-weak);
158
- --bg-neutral-inverted: var(--crisp-bg-neutral-inverted);
159
- --fg-on-neutral-inverted: var(--crisp-fg-on-neutral-inverted);
160
- --fg-neutral-subtle: var(--crisp-fg-neutral-subtle);
161
- --fg-neutral-muted: var(--crisp-fg-neutral-muted);
162
- --stroke-focus-ring: var(--crisp-stroke-focus-ring);
163
- --bg-success: var(--crisp-bg-success);
164
- --bg-warning: var(--crisp-bg-warning);
165
- --bg-orange: var(--crisp-bg-orange);
166
- --bg-cyan: var(--crisp-bg-cyan);
167
- --bg-purple: var(--crisp-bg-purple);
168
- --bg-sidebar: var(--crisp-bg-sidebar);
169
- --bg-subtle: var(--crisp-bg-subtle);
170
- --space-1: var(--crisp-space-1);
171
- --space-2: var(--crisp-space-2);
172
- --space-3: var(--crisp-space-3);
173
- --space-4: var(--crisp-space-4);
174
- --space-5: var(--crisp-space-5);
175
- --space-6: var(--crisp-space-6);
176
- --space-8: var(--crisp-space-8);
177
- --space-px: var(--crisp-space-px);
178
- --space-0-5: var(--crisp-space-0-5);
179
- --space-1-5: var(--crisp-space-1-5);
180
- --space-2-5: var(--crisp-space-2-5);
181
- --radius-chip: var(--crisp-radius-chip);
182
- --radius-sm: var(--crisp-radius-sm);
183
- --radius-md: var(--crisp-radius-md);
184
- --radius-lg: var(--crisp-radius-lg);
185
- --radius-xl: var(--crisp-radius-xl);
186
- --radius-2xl: var(--crisp-radius-2xl);
187
- --radius-full: var(--crisp-radius-full);
188
- --size-icon: var(--crisp-size-icon);
189
- --size-chip: var(--crisp-size-chip);
190
- --size-row: var(--crisp-size-row);
191
- --size-menuRow: var(--crisp-size-menuRow);
192
- --size-tableRow: var(--crisp-size-tableRow);
193
- --size-tableHeader: var(--crisp-size-tableHeader);
194
- --size-header: var(--crisp-size-header);
195
- --size-calendarCell: var(--crisp-size-calendarCell);
196
- --size-calendarPill: var(--crisp-size-calendarPill);
197
- --text-xs: var(--crisp-text-xs);
198
- --text-sm: var(--crisp-text-sm);
199
- --text-md: var(--crisp-text-md);
200
- --text-lg: var(--crisp-text-lg);
201
- --text-xl: var(--crisp-text-xl);
202
- --weight-regular: var(--crisp-weight-regular);
203
- --weight-medium: var(--crisp-weight-medium);
204
- --weight-semibold: var(--crisp-weight-semibold);
205
- --weight-bold: var(--crisp-weight-bold);
206
- --font-sans: var(--crisp-font-sans);
207
- }
208
-
209
125
  @layer crisp-components {
210
126
  .crisp-accordion {
211
127
  display: flex; flex-direction: column; font-family: var(--crisp-font-sans);
@@ -596,6 +512,8 @@
596
512
  & tbody tr[data-selected] td[data-sticky] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 10%, var(--crisp-bg-surface)); }
597
513
  & tbody tr:hover td[data-sticky] { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, var(--crisp-bg-surface)); }
598
514
  & .crisp-table-scroll[data-scrolled-x] [data-sticky-edge] { clip-path: inset(0 -38px 0 0); box-shadow: 6px 0 16px 4px rgba(0,0,0,0.12); }
515
+ /* mirror of the rule above, for stickyLast's trailing column (#327) */
516
+ & .crisp-table-scroll[data-scrolled-x-end] [data-sticky-edge-end] { clip-path: inset(0 0 0 -38px); box-shadow: -6px 0 16px 4px rgba(0,0,0,0.12); }
599
517
  /* add-row + summary footer */
600
518
  & .crisp-datatable-addcell { padding: 0; border-top: none; }
601
519
  & .crisp-datatable-addrow { display: flex; align-items: center; gap: var(--crisp-space-2); width: 100%; height: var(--crisp-size-tableRow); padding: 0 var(--crisp-space-2); border: none; border-top: 1px solid var(--crisp-border-subtle); background: var(--crisp-bg-surface); color: var(--crisp-fg-muted); font-family: inherit; font-size: var(--crisp-text-lg); cursor: pointer; transition: background-color .12s; }
@@ -619,7 +537,12 @@
619
537
  & .crisp-datatable-entity { display: flex; align-items: center; gap: var(--crisp-space-1-5); min-width: 0; color: var(--crisp-fg-primary); font-weight: var(--crisp-weight-medium); }
620
538
  & .crisp-datatable-entity-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
621
539
  & .crisp-datatable-avatar { width: var(--crisp-size-icon); height: var(--crisp-size-icon); border-radius: var(--crisp-radius-sm); flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; font-size: 10px; line-height: 1; font-weight: var(--crisp-weight-semibold); text-transform: uppercase; color: var(--crisp-fg-on-brand); background: var(--crisp-bg-brand-solid); }
622
- & .crisp-datatable-avatar[data-tone="success"] { background: var(--crisp-bg-success); } & .crisp-datatable-avatar[data-tone="warning"] { background: var(--crisp-bg-warning); } & .crisp-datatable-avatar[data-tone="danger"] { background: var(--crisp-bg-danger); } & .crisp-datatable-avatar[data-tone="purple"] { background: var(--crisp-bg-purple); } & .crisp-datatable-avatar[data-tone="cyan"] { background: var(--crisp-bg-cyan); } & .crisp-datatable-avatar[data-tone="orange"] { background: var(--crisp-bg-orange); }
540
+ & .crisp-datatable-avatar[data-tone="success"] { background: var(--crisp-bg-success); }
541
+ & .crisp-datatable-avatar[data-tone="warning"] { background: var(--crisp-bg-warning); }
542
+ & .crisp-datatable-avatar[data-tone="danger"] { background: var(--crisp-bg-danger); }
543
+ & .crisp-datatable-avatar[data-tone="purple"] { background: var(--crisp-bg-purple); }
544
+ & .crisp-datatable-avatar[data-tone="cyan"] { background: var(--crisp-bg-cyan); }
545
+ & .crisp-datatable-avatar[data-tone="orange"] { background: var(--crisp-bg-orange); }
623
546
  & .crisp-datatable-avatar img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
624
547
  & .crisp-datatable-tags { display: flex; align-items: center; gap: var(--crisp-space-1); overflow: hidden; }
625
548
  & .crisp-datatable-tag { display: inline-flex; align-items: center; height: var(--crisp-size-chip); padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-chip); font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); white-space: nowrap; background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: color-mix(in srgb, var(--crisp-fg-primary) 82%, transparent); }
@@ -632,10 +555,11 @@
632
555
  & .crisp-datatable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); }
633
556
  & .crisp-datatable-num { font-variant-numeric: tabular-nums; }
634
557
  & .crisp-datatable-muted { color: var(--crisp-fg-muted); }
635
- /* row drag-to-reorder -- a Settings > Objects > Attributes screen measures
636
- a leading 20px grip column, a 16px grip icon, and the row's own hairline doubling as the drop indicator (it tints toward the brand colour as the active drop target). The affordance + geometry are measured; the drag MECHANISM is crisp's existing house idiom -- HTML5
637
- draggable + dataTransfer, the same one column reorder already uses
638
- (RecordsTable's reorderColumn) -- not a proprietary pointer-events implementation. */
558
+ /* row drag-to-reorder -- a Settings > Objects > Attributes screen measures a leading 20px grip column, a 16px grip icon, and the row's own
559
+ hairline doubling as the drop indicator (it tints toward the brand
560
+ colour as the active drop target). The affordance + geometry are
561
+ measured; the drag MECHANISM is crisp's existing house idiom -- HTML5 draggable + dataTransfer, the same one column reorder already uses (RecordsTable's reorderColumn) -- not a proprietary
562
+ pointer-events implementation. */
639
563
  & .crisp-datatable-col-grip { width: 20px; padding: 0; text-align: center; }
640
564
  & .crisp-datatable-grip { display: inline-flex; align-items: center; justify-content: center; width: 100%; height: 100%; margin: 0; border: none; border-radius: 0; background: none; font-family: inherit; color: var(--crisp-fg-muted); cursor: grab; }
641
565
  & .crisp-datatable-grip:active { cursor: grabbing; }
@@ -921,6 +845,68 @@
921
845
  }
922
846
  }
923
847
 
848
+ .crisp-filldoc {
849
+ display: flex; flex-direction: column; gap: var(--crisp-space-4); box-sizing: border-box; width: 210mm; min-height: 297mm; padding: 20mm; margin: 0 auto; background: var(--crisp-bg-surface); font-family: var(--crisp-font-sans); font-size: var(--crisp-text-lg); line-height: 22px; color: var(--crisp-fg-primary); border-radius: 0; box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
850
+ &:focus, &:focus-visible { outline: none; }
851
+ & .crisp-filldoc-block { position: relative; }
852
+ & .crisp-filldoc-heading { margin: 0; font-size: var(--crisp-text-xl); font-weight: var(--crisp-weight-semibold); line-height: 26px; color: var(--crisp-fg-primary); white-space: pre-wrap; overflow-wrap: break-word; }
853
+ & .crisp-filldoc-text { margin: 0; font-size: var(--crisp-text-lg); line-height: 22px; color: var(--crisp-fg-primary); white-space: pre-wrap; overflow-wrap: break-word; }
854
+ & .crisp-filldoc-writer { display: block; width: 100%; margin: 0; padding: 0; border: none; outline: none; background: transparent; font-family: inherit; font-size: inherit; font-weight: inherit; line-height: inherit; color: inherit; resize: none; overflow: hidden; user-select: text; -webkit-user-select: text; }
855
+ & .crisp-filldoc-insert { position: absolute; inset-inline-start: 0; inset-inline-end: 0; inset-block-end: calc(var(--crisp-space-4) / -2); height: var(--crisp-space-4); display: flex; align-items: center; gap: var(--crisp-space-2); opacity: 0; transition: opacity .1s; cursor: pointer; }
856
+ & .crisp-filldoc-block:hover .crisp-filldoc-insert, & .crisp-filldoc-insert:focus-within { opacity: 1; }
857
+ & .crisp-filldoc-insert-rule { flex: 1; height: 1px; background: var(--crisp-border-default); }
858
+ & .crisp-filldoc-insert button { display: inline-flex; align-items: center; height: 20px; padding: 0 var(--crisp-space-1-5); border: none; border-radius: var(--crisp-radius-sm); background: var(--crisp-bg-raised); font-family: inherit; font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); cursor: pointer; }
859
+ & .crisp-filldoc-insert button:hover { background: var(--crisp-bg-neutral-weak); color: var(--crisp-fg-primary); }
860
+ & .crisp-filldoc-tools { position: absolute; inset-inline-end: 100%; inset-block-start: 0; padding-inline-end: var(--crisp-space-2); display: flex; gap: var(--crisp-space-1); opacity: 0; transition: opacity .1s; }
861
+ & .crisp-filldoc-block:hover .crisp-filldoc-tools, & .crisp-filldoc-tools:focus-within { opacity: 1; }
862
+ & .crisp-filldoc-tools button { width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: transparent; font-family: inherit; font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); cursor: pointer; }
863
+ & .crisp-filldoc-tools button:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
864
+ }
865
+ .crisp-filldoc--page_a4 {
866
+
867
+ }
868
+ .crisp-filldoc--page_auto {
869
+ width: 100%; min-height: 0; max-width: 210mm;
870
+ }
871
+
872
+ @media (prefers-reduced-motion: reduce) {
873
+ .crisp-filldoc, .crisp-filldoc * {
874
+ animation-duration: 0.01ms !important;
875
+ animation-iteration-count: 1 !important;
876
+ transition-duration: 0.01ms !important;
877
+ }
878
+ }
879
+
880
+ .crisp-fillsheet {
881
+ display: grid; grid-template-columns: var(--crisp-fillsheet-cols); grid-template-rows: var(--crisp-fillsheet-rows); position: relative; overflow: auto; max-width: 100%; box-sizing: border-box; font-family: var(--crisp-font-sans); font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); background: var(--crisp-bg-surface); border-radius: 0; border: 1px solid var(--crisp-border-default); user-select: none; -webkit-user-select: none;
882
+ &:focus, &:focus-visible { outline: none; }
883
+ & .crisp-fillsheet-cell { position: relative; display: flex; align-items: flex-start; min-width: 0; padding-inline: var(--crisp-space-3); padding-block: var(--crisp-space-3); border-inline-end: 1px solid var(--crisp-border-default); border-block-end: 1px solid var(--crisp-border-default); background: var(--crisp-bg-surface); white-space: pre-wrap; overflow-wrap: break-word; line-height: 20px; cursor: cell; }
884
+ & .crisp-fillsheet-cell[aria-readonly] { background: var(--crisp-bg-raised); color: var(--crisp-fg-muted); }
885
+ & .crisp-fillsheet-cell:last-child { border-inline-end: none; }
886
+ & > div:last-child .crisp-fillsheet-cell { border-block-end: none; }
887
+ & .crisp-fillsheet-cell[data-align="end"] { justify-content: flex-end; font-variant-numeric: tabular-nums; }
888
+ &[data-multi] .crisp-fillsheet-cell[data-range] { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
889
+ &[data-keynav] .crisp-fillsheet-cell[data-selected] { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); box-shadow: inset 0 -2px 0 var(--crisp-fg-primary); }
890
+ & .crisp-fillsheet-cell[data-editing] { background: var(--crisp-bg-surface); }
891
+ & .crisp-fillsheet-colresize { position: absolute; inset-block-start: 0; inset-block-end: 0; inset-inline-end: 0; z-index: 3; width: 5px; cursor: col-resize; touch-action: none; }
892
+ & .crisp-fillsheet-rowresize { position: absolute; inset-inline-start: 0; inset-inline-end: 0; inset-block-end: 0; z-index: 3; height: 5px; cursor: row-resize; touch-action: none; }
893
+ & .crisp-fillsheet-colresize:hover { background: linear-gradient(to right, transparent 0, transparent calc(50% - 1px), var(--crisp-fg-primary) calc(50% - 1px), var(--crisp-fg-primary) calc(50% + 1px), transparent calc(50% + 1px)); }
894
+ & .crisp-fillsheet-rowresize:hover { background: linear-gradient(to bottom, transparent 0, transparent calc(50% - 1px), var(--crisp-fg-primary) calc(50% - 1px), var(--crisp-fg-primary) calc(50% + 1px), transparent calc(50% + 1px)); }
895
+ & .crisp-fillsheet-editor { display: block; flex-grow: 1; width: 100%; min-width: 0; margin: 0; padding: 0; border: none; outline: none; background: transparent; font-family: inherit; font-size: inherit; line-height: 20px; color: inherit; resize: none; user-select: text; -webkit-user-select: text; overflow: hidden; }
896
+ & .crisp-fillsheet-select .crisp-select-trigger { width: 100%; height: 100%; padding: 0; border: none; background: transparent; box-shadow: none; font: inherit; color: inherit; }
897
+ & .crisp-fillsheet-select .crisp-select-trigger:hover, & .crisp-fillsheet-select .crisp-select-trigger[data-open] { background: transparent; box-shadow: none; }
898
+ & .crisp-fillsheet-select .crisp-select-chevron { display: none; }
899
+ }
900
+ .crisp-fillsheet--surface_panel {
901
+
902
+ }
903
+ .crisp-fillsheet--surface_paper {
904
+ box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3);
905
+ }
906
+ .crisp-fillsheet--surface_bare {
907
+ border: none;
908
+ }
909
+
924
910
  .crisp-formfield {
925
911
  display: flex; flex-direction: column; gap: var(--crisp-space-1-5); box-sizing: border-box; font-family: var(--crisp-font-sans);
926
912
  & .crisp-formfield-label { display: inline-flex; align-items: center; gap: var(--crisp-space-1); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
package/dist/tokens.css CHANGED
@@ -121,87 +121,3 @@
121
121
  --crisp-weight-bold: 700;
122
122
  --crisp-font-sans: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
123
123
  }
124
-
125
- /* -----------------------------------------------------------------
126
- * Deprecated unprefixed aliases (issue #276) — SCHEDULED FOR REMOVAL in
127
- * the next major version. Prefer the --crisp-* custom property
128
- * above; these only forward to it so an existing override keeps working.
129
- * ----------------------------------------------------------------- */
130
- :root {
131
- --bg-brand-solid: var(--crisp-bg-brand-solid);
132
- --bg-brand-solid-pressed: var(--crisp-bg-brand-solid-pressed);
133
- --fg-on-brand: var(--crisp-fg-on-brand);
134
- --fg-on-tone: var(--crisp-fg-on-tone);
135
- --bg-surface: var(--crisp-bg-surface);
136
- --bg-raised: var(--crisp-bg-raised);
137
- --border-default: var(--crisp-border-default);
138
- --border-subtle: var(--crisp-border-subtle);
139
- --ring-neutral: var(--crisp-ring-neutral);
140
- --bg-tile-active: var(--crisp-bg-tile-active);
141
- --shadow-tile-active: var(--crisp-shadow-tile-active);
142
- --bg-overlay-frost: var(--crisp-bg-overlay-frost);
143
- --shadow-overlay1: var(--crisp-shadow-overlay1);
144
- --shadow-overlay2: var(--crisp-shadow-overlay2);
145
- --shadow-overlay3: var(--crisp-shadow-overlay3);
146
- --bg-popover: var(--crisp-bg-popover);
147
- --ring-popover: var(--crisp-ring-popover);
148
- --shadow-popover1: var(--crisp-shadow-popover1);
149
- --shadow-popover2: var(--crisp-shadow-popover2);
150
- --shadow-popover3: var(--crisp-shadow-popover3);
151
- --fg-primary: var(--crisp-fg-primary);
152
- --fg-muted: var(--crisp-fg-muted);
153
- --bg-danger: var(--crisp-bg-danger);
154
- --bg-danger-solid: var(--crisp-bg-danger-solid);
155
- --stroke-field-focus: var(--crisp-stroke-field-focus);
156
- --fg-disabled: var(--crisp-fg-disabled);
157
- --bg-neutral-weak: var(--crisp-bg-neutral-weak);
158
- --bg-neutral-inverted: var(--crisp-bg-neutral-inverted);
159
- --fg-on-neutral-inverted: var(--crisp-fg-on-neutral-inverted);
160
- --fg-neutral-subtle: var(--crisp-fg-neutral-subtle);
161
- --fg-neutral-muted: var(--crisp-fg-neutral-muted);
162
- --stroke-focus-ring: var(--crisp-stroke-focus-ring);
163
- --bg-success: var(--crisp-bg-success);
164
- --bg-warning: var(--crisp-bg-warning);
165
- --bg-orange: var(--crisp-bg-orange);
166
- --bg-cyan: var(--crisp-bg-cyan);
167
- --bg-purple: var(--crisp-bg-purple);
168
- --bg-sidebar: var(--crisp-bg-sidebar);
169
- --bg-subtle: var(--crisp-bg-subtle);
170
- --space-1: var(--crisp-space-1);
171
- --space-2: var(--crisp-space-2);
172
- --space-3: var(--crisp-space-3);
173
- --space-4: var(--crisp-space-4);
174
- --space-5: var(--crisp-space-5);
175
- --space-6: var(--crisp-space-6);
176
- --space-8: var(--crisp-space-8);
177
- --space-px: var(--crisp-space-px);
178
- --space-0-5: var(--crisp-space-0-5);
179
- --space-1-5: var(--crisp-space-1-5);
180
- --space-2-5: var(--crisp-space-2-5);
181
- --radius-chip: var(--crisp-radius-chip);
182
- --radius-sm: var(--crisp-radius-sm);
183
- --radius-md: var(--crisp-radius-md);
184
- --radius-lg: var(--crisp-radius-lg);
185
- --radius-xl: var(--crisp-radius-xl);
186
- --radius-2xl: var(--crisp-radius-2xl);
187
- --radius-full: var(--crisp-radius-full);
188
- --size-icon: var(--crisp-size-icon);
189
- --size-chip: var(--crisp-size-chip);
190
- --size-row: var(--crisp-size-row);
191
- --size-menuRow: var(--crisp-size-menuRow);
192
- --size-tableRow: var(--crisp-size-tableRow);
193
- --size-tableHeader: var(--crisp-size-tableHeader);
194
- --size-header: var(--crisp-size-header);
195
- --size-calendarCell: var(--crisp-size-calendarCell);
196
- --size-calendarPill: var(--crisp-size-calendarPill);
197
- --text-xs: var(--crisp-text-xs);
198
- --text-sm: var(--crisp-text-sm);
199
- --text-md: var(--crisp-text-md);
200
- --text-lg: var(--crisp-text-lg);
201
- --text-xl: var(--crisp-text-xl);
202
- --weight-regular: var(--crisp-weight-regular);
203
- --weight-medium: var(--crisp-weight-medium);
204
- --weight-semibold: var(--crisp-weight-semibold);
205
- --weight-bold: var(--crisp-weight-bold);
206
- --font-sans: var(--crisp-font-sans);
207
- }
@@ -129,6 +129,12 @@ export type DataTableProps<T extends {
129
129
  onEdit?: (id: string, key: string, value: string) => void;
130
130
  /** Sticky the first column(s) with a horizontal scroll shadow (default true). */
131
131
  stickyFirst?: boolean;
132
+ /** Sticky the LAST column with a horizontal scroll shadow, mirroring
133
+ * `stickyFirst` (default false — additive, so an existing table's trailing
134
+ * column doesn't start pinning without being asked). Follows reading
135
+ * direction like `stickyFirst` does: it pins to the trailing edge, which is
136
+ * the left edge under `dir="rtl"` (#288). */
137
+ stickyLast?: boolean;
132
138
  /** BCP 47 locale for the built-in `date`/`number`/`currency` renderers
133
139
  * (default "en-US"). Formats the date and groups the number the way that
134
140
  * locale's readers expect — e.g. "mn-MN" renders a date as "2026.09.12"
@@ -163,7 +169,7 @@ export type DataTableProps<T extends {
163
169
  };
164
170
  export declare function DataTable<T extends {
165
171
  id: string;
166
- }>({ columns: columnsProp, data, selectable, selectedIds, onSelectionChange, selectAllLabel, selectRowLabel, selectionAnnouncement, columnMenu, onColumnsChange, groupBy, onRowsReorder, error, sort: sortProp, defaultSort, onSortChange, filterable, searchPlaceholder, searchLabel, onEdit, stickyFirst, locale: localeProp, avatarTone, surface, interactive, onRowClick, onAddRow, addRowLabel, empty, showCount, countLabel, toolbar, className, reorderRowLabel, ...rest }: DataTableProps<T>): React.JSX.Element;
172
+ }>({ columns: columnsProp, data, selectable, selectedIds, onSelectionChange, selectAllLabel, selectRowLabel, selectionAnnouncement, columnMenu, onColumnsChange, groupBy, onRowsReorder, error, sort: sortProp, defaultSort, onSortChange, filterable, searchPlaceholder, searchLabel, onEdit, stickyFirst, stickyLast, locale: localeProp, avatarTone, surface, interactive, onRowClick, onAddRow, addRowLabel, empty, showCount, countLabel, toolbar, className, reorderRowLabel, ...rest }: DataTableProps<T>): React.JSX.Element;
167
173
  export declare namespace DataTable {
168
174
  var displayName: string;
169
175
  }
@@ -0,0 +1,79 @@
1
+ import * as React from "react";
2
+ import { type FillSheetColumn } from "../fillsheet";
3
+ /** A heading, a paragraph, or a sheet. */
4
+ export type FillDocBlock = {
5
+ id: string;
6
+ type: "heading";
7
+ text: string;
8
+ } | {
9
+ id: string;
10
+ type: "text";
11
+ text: string;
12
+ } | {
13
+ id: string;
14
+ type: "table";
15
+ columns: FillSheetColumn[];
16
+ value: string[][];
17
+ /** The sheet's accessible name; see FillSheet's `label`. */
18
+ label?: string;
19
+ };
20
+ export type FillDocProps = {
21
+ /** The document, in order. */
22
+ blocks: FillDocBlock[];
23
+ /** Every edit comes back through here — typing, inserting, removing. */
24
+ onBlocksChange?: (next: FillDocBlock[]) => void;
25
+ /**
26
+ * `edit` is the person who MAKES the document: they can type anywhere and
27
+ * add or remove blocks. `fill` is the person who fills it in — the prose is
28
+ * fixed and only the sheets take input.
29
+ */
30
+ mode?: "edit" | "fill";
31
+ /** `a4` is a real page; `auto` grows to its content. */
32
+ page?: "a4" | "auto";
33
+ /** The document's accessible name. No English default — see FillSheet. */
34
+ label?: string;
35
+ /** Copy for the insert controls. English defaults, overridable. */
36
+ addTextLabel?: string;
37
+ addHeadingLabel?: string;
38
+ addTableLabel?: string;
39
+ removeLabel?: string;
40
+ className?: string;
41
+ style?: React.CSSProperties;
42
+ } & Omit<React.HTMLAttributes<HTMLDivElement>, "onChange" | "children">;
43
+ /**
44
+ * A page you can write on, of which a sheet is one block.
45
+ *
46
+ * FillSheet is the table; this is the document it sits in. The two share a
47
+ * look on purpose -- a real page, real margins, square corners, and nothing
48
+ * drawn that is not content -- and the same split between the person who
49
+ * MAKES a form and the person who fills it in: in `edit` you write the prose
50
+ * and add or remove blocks, in `fill` the prose is fixed and only the sheets
51
+ * take input.
52
+ *
53
+ * Every block's controls are hidden until the pointer is in that block. A
54
+ * page covered in handles and grips stops looking like a page, which is the
55
+ * whole thing this is for.
56
+ */
57
+ export declare const FillDoc: React.ForwardRefExoticComponent<{
58
+ /** The document, in order. */
59
+ blocks: FillDocBlock[];
60
+ /** Every edit comes back through here — typing, inserting, removing. */
61
+ onBlocksChange?: (next: FillDocBlock[]) => void;
62
+ /**
63
+ * `edit` is the person who MAKES the document: they can type anywhere and
64
+ * add or remove blocks. `fill` is the person who fills it in — the prose is
65
+ * fixed and only the sheets take input.
66
+ */
67
+ mode?: "edit" | "fill";
68
+ /** `a4` is a real page; `auto` grows to its content. */
69
+ page?: "a4" | "auto";
70
+ /** The document's accessible name. No English default — see FillSheet. */
71
+ label?: string;
72
+ /** Copy for the insert controls. English defaults, overridable. */
73
+ addTextLabel?: string;
74
+ addHeadingLabel?: string;
75
+ addTableLabel?: string;
76
+ removeLabel?: string;
77
+ className?: string;
78
+ style?: React.CSSProperties;
79
+ } & Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "onChange"> & React.RefAttributes<HTMLDivElement>>;