@kanunilabs/datagrid 1.9.1 → 1.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/datagrid.umd.js +8 -8
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +52 -4
- package/dist/index.d.ts +52 -4
- package/dist/index.js +2 -2
- package/dist/styles.css +411 -1
- package/dist/themes/all.css +108 -0
- package/dist/themes/amber.css +3 -0
- package/dist/themes/aubergine.css +3 -0
- package/dist/themes/azure.css +3 -0
- package/dist/themes/burgundy.css +3 -0
- package/dist/themes/charcoal.css +3 -0
- package/dist/themes/contrast-dark.css +3 -0
- package/dist/themes/contrast-light.css +3 -0
- package/dist/themes/coral.css +3 -0
- package/dist/themes/corporate.css +3 -0
- package/dist/themes/deep-sea.css +3 -0
- package/dist/themes/editorial.css +3 -0
- package/dist/themes/ember.css +3 -0
- package/dist/themes/emerald.css +3 -0
- package/dist/themes/forest.css +3 -0
- package/dist/themes/glacier.css +3 -0
- package/dist/themes/graphite.css +3 -0
- package/dist/themes/indigo-night.css +3 -0
- package/dist/themes/indigo.css +3 -0
- package/dist/themes/ivory.css +3 -0
- package/dist/themes/lagoon.css +3 -0
- package/dist/themes/linen.css +3 -0
- package/dist/themes/midnight.css +3 -0
- package/dist/themes/mist.css +3 -0
- package/dist/themes/monochrome.css +3 -0
- package/dist/themes/onyx.css +3 -0
- package/dist/themes/orchid.css +3 -0
- package/dist/themes/porcelain.css +3 -0
- package/dist/themes/rose.css +3 -0
- package/dist/themes/sandstone.css +3 -0
- package/dist/themes/slate-night.css +3 -0
- package/dist/themes/slate.css +3 -0
- package/dist/themes/steel.css +3 -0
- package/dist/themes/stone.css +3 -0
- package/dist/themes/taupe.css +3 -0
- package/dist/themes/teal.css +3 -0
- package/dist/themes/terminal.css +3 -0
- package/package.json +3 -3
package/dist/styles.css
CHANGED
|
@@ -84,6 +84,9 @@
|
|
|
84
84
|
--dg-danger: #dc2626; /* red-600 — borders, solid fills */
|
|
85
85
|
--dg-danger-text: #b91c1c; /* red-700 — text on a light surface */
|
|
86
86
|
--dg-on-danger: #ffffff; /* text ON a solid --dg-danger fill */
|
|
87
|
+
--dg-success: #15803d; /* green-700 — fills ("saved" marks) */
|
|
88
|
+
--dg-success-text: #166534; /* success as text on a light surface */
|
|
89
|
+
--dg-on-success: #ffffff; /* text ON a solid --dg-success fill */
|
|
87
90
|
--dg-warning: #b45309; /* amber-700 */
|
|
88
91
|
--dg-selected-bg: var(--dg-primary-soft);
|
|
89
92
|
/* Search highlight (P2.4). Amber rather than the accent: the accent already
|
|
@@ -171,10 +174,20 @@
|
|
|
171
174
|
color: var(--dg-text);
|
|
172
175
|
}
|
|
173
176
|
|
|
177
|
+
/* Typeface. Inherited from the page unless --dg-font-family names one — set
|
|
178
|
+
it once (on :root, or in a palette class) and the grid, the Enterprise
|
|
179
|
+
chrome around it and every popup portalled to <body> use it. Without the
|
|
180
|
+
variable, a font set only on the grid's container never reached the menus
|
|
181
|
+
and dialogs, which inherit from <body> (2026-10-16, customer request). */
|
|
182
|
+
.kanuni-datagrid-enterprise,
|
|
183
|
+
.kanuni-datagrid-detached {
|
|
184
|
+
font-family: var(--dg-font-family, inherit);
|
|
185
|
+
}
|
|
186
|
+
|
|
174
187
|
/* The grid's own box. */
|
|
175
188
|
.kanuni-datagrid-root {
|
|
176
189
|
box-sizing: border-box;
|
|
177
|
-
font-family: inherit;
|
|
190
|
+
font-family: var(--dg-font-family, inherit);
|
|
178
191
|
-webkit-font-smoothing: antialiased;
|
|
179
192
|
-moz-osx-font-smoothing: grayscale;
|
|
180
193
|
position: relative;
|
|
@@ -229,6 +242,9 @@
|
|
|
229
242
|
/* The dark danger is a LIGHT red, so what sits on it has to be dark. White
|
|
230
243
|
on #f87171 measures 2.4:1 — the delete button's own label. */
|
|
231
244
|
--dg-on-danger: #450a0a;
|
|
245
|
+
--dg-success: #4ade80;
|
|
246
|
+
--dg-success-text: #86efac;
|
|
247
|
+
--dg-on-success: #0d2817;
|
|
232
248
|
--dg-warning: #fbbf24;
|
|
233
249
|
--dg-overlay: rgba(2, 6, 23, 0.7);
|
|
234
250
|
--dg-scrollbar-thumb: #475569;
|
|
@@ -663,6 +679,48 @@
|
|
|
663
679
|
font-size: 11px;
|
|
664
680
|
}
|
|
665
681
|
|
|
682
|
+
/* The search box's own refusal (`toolbar.search.validate`), right after it. */
|
|
683
|
+
.kanuni-datagrid-toolbar-search-error {
|
|
684
|
+
color: var(--dg-danger-text);
|
|
685
|
+
font-size: 11px;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
.kanuni-datagrid-toolbar-search[aria-invalid='true'] {
|
|
689
|
+
border-color: var(--dg-danger);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
/* An app's own button (GridToolbarButton / toolbarButton()), drawn like the
|
|
693
|
+
grid's commands wherever it sits: the toolbar's rule above reaches only its
|
|
694
|
+
DIRECT children, and the status bar has none. */
|
|
695
|
+
.kanuni-datagrid-app-button {
|
|
696
|
+
display: inline-flex;
|
|
697
|
+
align-items: center;
|
|
698
|
+
justify-content: center;
|
|
699
|
+
gap: 5px;
|
|
700
|
+
padding: 3px 10px;
|
|
701
|
+
border: 1px solid var(--dg-border-strong);
|
|
702
|
+
border-radius: var(--dg-radius-control);
|
|
703
|
+
background: var(--dg-surface);
|
|
704
|
+
color: inherit;
|
|
705
|
+
font: inherit;
|
|
706
|
+
font-size: var(--dg-control-font-size);
|
|
707
|
+
cursor: pointer;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
.kanuni-datagrid-app-button.kanuni-datagrid-toolbar-icon-button {
|
|
711
|
+
padding: 0;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
.kanuni-datagrid-app-button:hover:not([aria-disabled='true']) {
|
|
715
|
+
background: var(--dg-surface-hover);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/* Unavailable but still focusable, so its reason can be read. */
|
|
719
|
+
.kanuni-datagrid-app-button[aria-disabled='true'] {
|
|
720
|
+
opacity: 0.6;
|
|
721
|
+
cursor: not-allowed;
|
|
722
|
+
}
|
|
723
|
+
|
|
666
724
|
/*
|
|
667
725
|
* The same message, but floating where a context menu just was — the cell
|
|
668
726
|
* menu's Export entries have nowhere else to report a missing optional peer.
|
|
@@ -1870,6 +1928,17 @@
|
|
|
1870
1928
|
flex: none;
|
|
1871
1929
|
}
|
|
1872
1930
|
|
|
1931
|
+
/* A row of a server's list whose piece has not arrived: the slot is held (the
|
|
1932
|
+
scroll bar describes the whole list), the value is not known yet. */
|
|
1933
|
+
.kanuni-datagrid-filter-item--pending {
|
|
1934
|
+
color: var(--dg-text-muted);
|
|
1935
|
+
cursor: default;
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
.kanuni-datagrid-filter-item--pending:hover {
|
|
1939
|
+
background: transparent;
|
|
1940
|
+
}
|
|
1941
|
+
|
|
1873
1942
|
.kanuni-datagrid-filter-item:hover,
|
|
1874
1943
|
.kanuni-datagrid-filter-item--active {
|
|
1875
1944
|
background: var(--dg-surface-hover);
|
|
@@ -2830,6 +2899,19 @@
|
|
|
2830
2899
|
margin: 0 calc(var(--dg-cell-padding-x) * -1);
|
|
2831
2900
|
}
|
|
2832
2901
|
|
|
2902
|
+
/* ...but the TEXT stays where the cell drew it. Widened to the cell's edges
|
|
2903
|
+
with only 4px of padding, the value jumped left by the cell padding as the
|
|
2904
|
+
editor opened; in row mode, with every cell open, no value lined up with the
|
|
2905
|
+
column above it (2026-10-19, content session). The date editor's own input
|
|
2906
|
+
keeps its 4px, so its wrapper makes up the rest. */
|
|
2907
|
+
.kanuni-datagrid-root .kanuni-datagrid-cell > .kanuni-datagrid-editor:not([type='checkbox']) {
|
|
2908
|
+
padding-inline: var(--dg-cell-padding-x);
|
|
2909
|
+
}
|
|
2910
|
+
|
|
2911
|
+
.kanuni-datagrid-root .kanuni-datagrid-cell > .kanuni-datagrid-date-editor {
|
|
2912
|
+
padding-inline: max(0px, calc(var(--dg-cell-padding-x) - 4px)) 0;
|
|
2913
|
+
}
|
|
2914
|
+
|
|
2833
2915
|
/* In a WRAPPED cell the editor takes the LINE BOX, not the row height.
|
|
2834
2916
|
A wrapping cell is as tall as its own text: one line of it is
|
|
2835
2917
|
`padding-block x2 + --dg-wrap-line-height`, which is shorter than a standard
|
|
@@ -2867,6 +2949,38 @@
|
|
|
2867
2949
|
background: var(--dg-surface);
|
|
2868
2950
|
}
|
|
2869
2951
|
|
|
2952
|
+
/* Row mode opens every cell of the row at once and marks none of them
|
|
2953
|
+
`--editing`, so the focused one kept its ring around the underlined editor —
|
|
2954
|
+
the double rectangle above, on one cell of the row (2026-10-19, content
|
|
2955
|
+
session). Any cell that holds an editor drops the ring. */
|
|
2956
|
+
.kanuni-datagrid-root .kanuni-datagrid-cell--focused:has(> .kanuni-datagrid-editor),
|
|
2957
|
+
.kanuni-datagrid-root .kanuni-datagrid-cell--focused:has(> .kanuni-datagrid-date-editor) {
|
|
2958
|
+
outline: none;
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2961
|
+
/* A number is typed where it is read: right-aligned, as the cell shows it.
|
|
2962
|
+
Left-aligned editors made the value jump across the column the moment the
|
|
2963
|
+
cell opened, and in row mode two number editors side by side read as one
|
|
2964
|
+
field. */
|
|
2965
|
+
.kanuni-datagrid-root .kanuni-datagrid-cell--number > .kanuni-datagrid-editor {
|
|
2966
|
+
text-align: right;
|
|
2967
|
+
}
|
|
2968
|
+
|
|
2969
|
+
/* Chrome keeps ~15px at the end of a number input for its spin buttons, shown
|
|
2970
|
+
or not, so a right-aligned value still stopped short of the column's
|
|
2971
|
+
numbers. In a row-high cell the arrows are too small to use anyway; the
|
|
2972
|
+
keyboard's arrow keys move between cells here. */
|
|
2973
|
+
.kanuni-datagrid-root input.kanuni-datagrid-editor[type='number'] {
|
|
2974
|
+
appearance: textfield;
|
|
2975
|
+
-moz-appearance: textfield;
|
|
2976
|
+
}
|
|
2977
|
+
|
|
2978
|
+
.kanuni-datagrid-root input.kanuni-datagrid-editor[type='number']::-webkit-inner-spin-button,
|
|
2979
|
+
.kanuni-datagrid-root input.kanuni-datagrid-editor[type='number']::-webkit-outer-spin-button {
|
|
2980
|
+
-webkit-appearance: none;
|
|
2981
|
+
margin: 0;
|
|
2982
|
+
}
|
|
2983
|
+
|
|
2870
2984
|
.kanuni-datagrid-root input.kanuni-datagrid-editor[type='checkbox'] {
|
|
2871
2985
|
width: auto;
|
|
2872
2986
|
height: auto;
|
|
@@ -3350,6 +3464,51 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
|
|
|
3350
3464
|
outline-offset: -1px;
|
|
3351
3465
|
}
|
|
3352
3466
|
|
|
3467
|
+
/* The date and lookup editors in a form are the CELL editors (one control per
|
|
3468
|
+
column), whose look is an underline sized to a row. In a form that read as a
|
|
3469
|
+
different kind of field from its boxed neighbours (2026-10-19, content
|
|
3470
|
+
session), so here they take the form's box: on the date editor's wrapper,
|
|
3471
|
+
which holds the calendar button too, and on a lookup's input directly. */
|
|
3472
|
+
.kanuni-datagrid-root .kanuni-datagrid-edit-form-lookup > .kanuni-datagrid-editor,
|
|
3473
|
+
.kanuni-datagrid-edit-form-lookup > .kanuni-datagrid-date-editor {
|
|
3474
|
+
height: auto;
|
|
3475
|
+
padding: 4px 6px;
|
|
3476
|
+
border: 1px solid var(--dg-border-strong);
|
|
3477
|
+
border-radius: var(--dg-radius-control);
|
|
3478
|
+
background: var(--dg-surface);
|
|
3479
|
+
}
|
|
3480
|
+
|
|
3481
|
+
.kanuni-datagrid-root .kanuni-datagrid-edit-form-lookup > .kanuni-datagrid-date-editor > .kanuni-datagrid-editor {
|
|
3482
|
+
height: auto;
|
|
3483
|
+
padding: 0;
|
|
3484
|
+
border: none;
|
|
3485
|
+
}
|
|
3486
|
+
|
|
3487
|
+
.kanuni-datagrid-root .kanuni-datagrid-edit-form-lookup > .kanuni-datagrid-editor:focus,
|
|
3488
|
+
.kanuni-datagrid-edit-form-lookup > .kanuni-datagrid-date-editor:focus-within {
|
|
3489
|
+
outline: 2px solid var(--dg-primary);
|
|
3490
|
+
outline-offset: -1px;
|
|
3491
|
+
}
|
|
3492
|
+
|
|
3493
|
+
/* A field the user cannot change must not look like one they can.
|
|
3494
|
+
`editable: false` columns were drawn as disabled inputs with the same
|
|
3495
|
+
surface, border and text as the open ones: readers clicked them and nothing
|
|
3496
|
+
happened (2026-10-19, content session). Recessed surface, muted text, a
|
|
3497
|
+
lighter border and the not-allowed cursor — the value stays readable. */
|
|
3498
|
+
.kanuni-datagrid-edit-form-input:disabled,
|
|
3499
|
+
.kanuni-datagrid-root .kanuni-datagrid-edit-form-lookup > .kanuni-datagrid-editor:disabled,
|
|
3500
|
+
.kanuni-datagrid-edit-form-lookup > .kanuni-datagrid-date-editor:has(.kanuni-datagrid-editor:disabled) {
|
|
3501
|
+
border-color: var(--dg-border);
|
|
3502
|
+
background: var(--dg-surface-header);
|
|
3503
|
+
color: var(--dg-text-muted);
|
|
3504
|
+
cursor: not-allowed;
|
|
3505
|
+
}
|
|
3506
|
+
|
|
3507
|
+
.kanuni-datagrid-root .kanuni-datagrid-edit-form-lookup .kanuni-datagrid-date-editor .kanuni-datagrid-editor:disabled {
|
|
3508
|
+
color: var(--dg-text-muted);
|
|
3509
|
+
cursor: not-allowed;
|
|
3510
|
+
}
|
|
3511
|
+
|
|
3353
3512
|
.kanuni-datagrid-edit-form-field[data-invalid] .kanuni-datagrid-edit-form-input {
|
|
3354
3513
|
border-color: var(--dg-danger);
|
|
3355
3514
|
}
|
|
@@ -3454,6 +3613,218 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
|
|
|
3454
3613
|
pointer-events: none;
|
|
3455
3614
|
}
|
|
3456
3615
|
|
|
3616
|
+
/* ─────────────────────────────────────────────────────────────
|
|
3617
|
+
Row save status (`rowStatus`, Community, 2026-10-16).
|
|
3618
|
+
─────────────────────────────────────────────────────────────
|
|
3619
|
+
A customer whose grid saves every edit at once asked to see each row's
|
|
3620
|
+
save: unsaved, in flight, saved, refused. Both renderers put
|
|
3621
|
+
`data-row-status` and `kanuni-datagrid-row--status-<status>` on the ROW
|
|
3622
|
+
element — one element per row, pinned cells included — so the marker is
|
|
3623
|
+
drawn once per row and cannot repeat per pinned block.
|
|
3624
|
+
|
|
3625
|
+
The marker is the row's own `::before`: a sticky flex item at the inline
|
|
3626
|
+
start that gives its width back with a negative margin. Sticky, because
|
|
3627
|
+
the row is as wide as all its columns and scrolls sideways — a plain left
|
|
3628
|
+
border or inset shadow on the row would scroll out of view with the first
|
|
3629
|
+
column, and under a pinned-left column it would be painted over. It sits
|
|
3630
|
+
above pinned cells (z-index) and moves no cell content. `inset-inline-start`
|
|
3631
|
+
puts it on the right edge under `dir="rtl"`. The focused row keeps its own
|
|
3632
|
+
inset bar; at the leading edge the status marker covers it, which is the
|
|
3633
|
+
more urgent of the two. */
|
|
3634
|
+
.kanuni-datagrid-root,
|
|
3635
|
+
.kanuni-datagrid-enterprise,
|
|
3636
|
+
.kanuni-datagrid-detached {
|
|
3637
|
+
--dg-row-status-width: 3px;
|
|
3638
|
+
--dg-row-status-changed: var(--dg-warning);
|
|
3639
|
+
--dg-row-status-saving: var(--dg-primary);
|
|
3640
|
+
/* The success fill: every palette and scheme sets it, dark ones included. */
|
|
3641
|
+
--dg-row-status-saved: var(--dg-success);
|
|
3642
|
+
--dg-row-status-error: var(--dg-danger);
|
|
3643
|
+
/* How strongly `tint: true` washes the row. */
|
|
3644
|
+
--dg-row-status-tint: 8%;
|
|
3645
|
+
}
|
|
3646
|
+
|
|
3647
|
+
.kanuni-datagrid-row--status-changed {
|
|
3648
|
+
--dg-row-status-color: var(--dg-row-status-changed);
|
|
3649
|
+
}
|
|
3650
|
+
|
|
3651
|
+
.kanuni-datagrid-row--status-saving {
|
|
3652
|
+
--dg-row-status-color: var(--dg-row-status-saving);
|
|
3653
|
+
}
|
|
3654
|
+
|
|
3655
|
+
.kanuni-datagrid-row--status-saved {
|
|
3656
|
+
--dg-row-status-color: var(--dg-row-status-saved);
|
|
3657
|
+
}
|
|
3658
|
+
|
|
3659
|
+
.kanuni-datagrid-row--status-error {
|
|
3660
|
+
--dg-row-status-color: var(--dg-row-status-error);
|
|
3661
|
+
}
|
|
3662
|
+
|
|
3663
|
+
.kanuni-datagrid-row[data-row-status]::before {
|
|
3664
|
+
content: '';
|
|
3665
|
+
position: sticky;
|
|
3666
|
+
inset-inline-start: 0;
|
|
3667
|
+
/* Above pinned cells (2), below the row being edited (4): at 6 the next
|
|
3668
|
+
row's marker cut through the editor's error bubble, which hangs one row
|
|
3669
|
+
down (pre-release review, 2026-10-16). */
|
|
3670
|
+
z-index: 3;
|
|
3671
|
+
flex: none;
|
|
3672
|
+
align-self: stretch;
|
|
3673
|
+
width: var(--dg-row-status-width);
|
|
3674
|
+
margin-inline-end: calc(-1 * var(--dg-row-status-width));
|
|
3675
|
+
background: var(--dg-row-status-color);
|
|
3676
|
+
pointer-events: none;
|
|
3677
|
+
}
|
|
3678
|
+
|
|
3679
|
+
/* The tint is a translucent IMAGE over whatever colour the row already has —
|
|
3680
|
+
stripe, hover, selection or focus — so those still read through it. Pinned
|
|
3681
|
+
cells inherit the row's background but the hover rule resets theirs, so
|
|
3682
|
+
they are named here too (three classes + an attribute: above the hover and
|
|
3683
|
+
selection rules, which are two classes). */
|
|
3684
|
+
.kanuni-datagrid-row.kanuni-datagrid-row--status-tint[data-row-status],
|
|
3685
|
+
.kanuni-datagrid-row.kanuni-datagrid-row--status-tint[data-row-status] .kanuni-datagrid-cell--pinned {
|
|
3686
|
+
background-image: linear-gradient(
|
|
3687
|
+
color-mix(in srgb, var(--dg-row-status-color) var(--dg-row-status-tint), transparent),
|
|
3688
|
+
color-mix(in srgb, var(--dg-row-status-color) var(--dg-row-status-tint), transparent)
|
|
3689
|
+
);
|
|
3690
|
+
}
|
|
3691
|
+
|
|
3692
|
+
/* High contrast drops background colours; the marker is the whole signal,
|
|
3693
|
+
so it keeps its own. */
|
|
3694
|
+
@media (forced-colors: active) {
|
|
3695
|
+
.kanuni-datagrid-row[data-row-status]::before {
|
|
3696
|
+
forced-color-adjust: none;
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
3699
|
+
|
|
3700
|
+
/* ── Message rows (`rowStatus.messages`, 2026-10-16) ─────────
|
|
3701
|
+
A refused save's reason in a row under it, with Retry and Delete row. The
|
|
3702
|
+
in-grid edit form's shape: sticky to the scroller's inline start and as wide
|
|
3703
|
+
as the VIEWPORT, so it stays in view while the columns scroll. The ground
|
|
3704
|
+
stays the surface — the text is the danger TEXT colour, measured at 4.5:1
|
|
3705
|
+
on it — and the row's own marker colour runs down its leading edge. */
|
|
3706
|
+
.kanuni-datagrid-message-row {
|
|
3707
|
+
background: var(--dg-surface);
|
|
3708
|
+
border-bottom: 1px solid var(--dg-border);
|
|
3709
|
+
}
|
|
3710
|
+
|
|
3711
|
+
.kanuni-datagrid-message-cell {
|
|
3712
|
+
position: sticky;
|
|
3713
|
+
inset-inline-start: 0;
|
|
3714
|
+
box-sizing: border-box;
|
|
3715
|
+
width: var(--dg-viewport-width, 100%);
|
|
3716
|
+
height: 100%;
|
|
3717
|
+
border-inline-start: var(--dg-row-status-width) solid var(--dg-row-status-error);
|
|
3718
|
+
user-select: text;
|
|
3719
|
+
}
|
|
3720
|
+
|
|
3721
|
+
.kanuni-datagrid-row-message {
|
|
3722
|
+
display: flex;
|
|
3723
|
+
align-items: center;
|
|
3724
|
+
gap: 8px;
|
|
3725
|
+
height: 100%;
|
|
3726
|
+
padding: 0 var(--dg-cell-padding-x);
|
|
3727
|
+
color: var(--dg-danger-text);
|
|
3728
|
+
font-size: var(--dg-chrome-font-size);
|
|
3729
|
+
}
|
|
3730
|
+
|
|
3731
|
+
.kanuni-datagrid-row-message-icon {
|
|
3732
|
+
flex: none;
|
|
3733
|
+
}
|
|
3734
|
+
|
|
3735
|
+
.kanuni-datagrid-row-message-text {
|
|
3736
|
+
flex: 1 1 auto;
|
|
3737
|
+
min-width: 0;
|
|
3738
|
+
overflow: hidden;
|
|
3739
|
+
text-overflow: ellipsis;
|
|
3740
|
+
white-space: nowrap;
|
|
3741
|
+
}
|
|
3742
|
+
|
|
3743
|
+
.kanuni-datagrid-root .kanuni-datagrid-row-message-button {
|
|
3744
|
+
flex: none;
|
|
3745
|
+
height: min(var(--dg-control-height), calc(100% - 6px));
|
|
3746
|
+
padding: 0 8px;
|
|
3747
|
+
border: 1px solid var(--dg-border-strong);
|
|
3748
|
+
border-radius: var(--dg-radius-control);
|
|
3749
|
+
background: var(--dg-surface);
|
|
3750
|
+
color: var(--dg-text);
|
|
3751
|
+
font: inherit;
|
|
3752
|
+
cursor: pointer;
|
|
3753
|
+
}
|
|
3754
|
+
|
|
3755
|
+
.kanuni-datagrid-root .kanuni-datagrid-row-message-button:hover {
|
|
3756
|
+
background: var(--dg-surface-hover);
|
|
3757
|
+
}
|
|
3758
|
+
|
|
3759
|
+
.kanuni-datagrid-root .kanuni-datagrid-row-message-button:focus-visible {
|
|
3760
|
+
outline: 2px solid var(--dg-focus-ring);
|
|
3761
|
+
outline-offset: 1px;
|
|
3762
|
+
}
|
|
3763
|
+
|
|
3764
|
+
/* ── Status column (`rowStatus.icons`, 2026-10-16) ───────────
|
|
3765
|
+
A glyph per status so it does not rest on colour alone: a dot while
|
|
3766
|
+
changed, a turning ring while saving, a tick when saved, a triangle when
|
|
3767
|
+
refused. Drawn as a MASK filled with the status colour, so a palette or a
|
|
3768
|
+
scheme recolours it like the marker. The cell exists on every row (an empty
|
|
3769
|
+
one where there is no status) so the columns beside it never step. */
|
|
3770
|
+
.kanuni-datagrid-status-cell {
|
|
3771
|
+
display: flex;
|
|
3772
|
+
align-items: center;
|
|
3773
|
+
justify-content: center;
|
|
3774
|
+
padding: 0;
|
|
3775
|
+
}
|
|
3776
|
+
|
|
3777
|
+
.kanuni-datagrid-status-icon {
|
|
3778
|
+
display: none;
|
|
3779
|
+
width: 12px;
|
|
3780
|
+
height: 12px;
|
|
3781
|
+
background: var(--dg-row-status-color);
|
|
3782
|
+
-webkit-mask: var(--dg-row-status-glyph) center / contain no-repeat;
|
|
3783
|
+
mask: var(--dg-row-status-glyph) center / contain no-repeat;
|
|
3784
|
+
}
|
|
3785
|
+
|
|
3786
|
+
.kanuni-datagrid-row[data-row-status] .kanuni-datagrid-status-icon {
|
|
3787
|
+
display: block;
|
|
3788
|
+
}
|
|
3789
|
+
|
|
3790
|
+
.kanuni-datagrid-row--status-changed {
|
|
3791
|
+
--dg-row-status-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3.5'/%3E%3C/svg%3E");
|
|
3792
|
+
}
|
|
3793
|
+
|
|
3794
|
+
.kanuni-datagrid-row--status-saving {
|
|
3795
|
+
--dg-row-status-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 2a6 6 0 1 1-6 6' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round'/%3E%3C/svg%3E");
|
|
3796
|
+
}
|
|
3797
|
+
|
|
3798
|
+
.kanuni-datagrid-row--status-saved {
|
|
3799
|
+
--dg-row-status-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8.5 6.5 12.5 13.5 3.5' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
3800
|
+
}
|
|
3801
|
+
|
|
3802
|
+
.kanuni-datagrid-row--status-error {
|
|
3803
|
+
--dg-row-status-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 1 15.5 14.5H.5z M7 6v4.5h2V6z M7 11.5v2h2v-2z' fill-rule='evenodd'/%3E%3C/svg%3E");
|
|
3804
|
+
}
|
|
3805
|
+
|
|
3806
|
+
.kanuni-datagrid-row--status-saving .kanuni-datagrid-status-icon {
|
|
3807
|
+
animation: kanuni-datagrid-status-spin 0.9s linear infinite;
|
|
3808
|
+
}
|
|
3809
|
+
|
|
3810
|
+
@keyframes kanuni-datagrid-status-spin {
|
|
3811
|
+
to {
|
|
3812
|
+
transform: rotate(360deg);
|
|
3813
|
+
}
|
|
3814
|
+
}
|
|
3815
|
+
|
|
3816
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3817
|
+
.kanuni-datagrid-row--status-saving .kanuni-datagrid-status-icon {
|
|
3818
|
+
animation: none;
|
|
3819
|
+
}
|
|
3820
|
+
}
|
|
3821
|
+
|
|
3822
|
+
@media (forced-colors: active) {
|
|
3823
|
+
.kanuni-datagrid-status-icon {
|
|
3824
|
+
background: CanvasText;
|
|
3825
|
+
}
|
|
3826
|
+
}
|
|
3827
|
+
|
|
3457
3828
|
/* ─────────────────────────────────────────────────────────────
|
|
3458
3829
|
KANUNILABS DataGrid — packaged themes
|
|
3459
3830
|
─────────────────────────────────────────────────────────────
|
|
@@ -3920,6 +4291,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
|
|
|
3920
4291
|
--dg-danger: #f87171;
|
|
3921
4292
|
--dg-danger-text: #fca5a5;
|
|
3922
4293
|
--dg-on-danger: #450a0a;
|
|
4294
|
+
--dg-success: #4ade80;
|
|
4295
|
+
--dg-success-text: #86efac;
|
|
4296
|
+
--dg-on-success: #0d2817;
|
|
3923
4297
|
--dg-warning: #fbbf24;
|
|
3924
4298
|
--dg-overlay: rgba(12, 10, 9, 0.72);
|
|
3925
4299
|
|
|
@@ -4268,6 +4642,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
|
|
|
4268
4642
|
--dg-danger: #a2515a; /* Aurora nord11, deepened for white text */
|
|
4269
4643
|
--dg-danger-text: #8f4149;
|
|
4270
4644
|
--dg-on-danger: #ffffff;
|
|
4645
|
+
--dg-success: #687a5a;
|
|
4646
|
+
--dg-success-text: #5d6c50;
|
|
4647
|
+
--dg-on-success: #ffffff;
|
|
4271
4648
|
--dg-warning: #8a6220; /* nord13 family */
|
|
4272
4649
|
}
|
|
4273
4650
|
|
|
@@ -4296,6 +4673,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
|
|
|
4296
4673
|
/* nord11 is a muted red, so the label on it has to go further down than the
|
|
4297
4674
|
usual near-black: #2b1113 measured 4.31:1 and this is 5.17:1. */
|
|
4298
4675
|
--dg-on-danger: #170709;
|
|
4676
|
+
--dg-success: #a3be8c;
|
|
4677
|
+
--dg-success-text: #adc599;
|
|
4678
|
+
--dg-on-success: #1d2219;
|
|
4299
4679
|
--dg-warning: #ebcb8b; /* nord13 */
|
|
4300
4680
|
--dg-overlay: rgba(24, 28, 36, 0.72);
|
|
4301
4681
|
}
|
|
@@ -4329,6 +4709,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
|
|
|
4329
4709
|
--dg-danger: #b03a5b; /* Pink #ff79c6 / Red #ff5555 family */
|
|
4330
4710
|
--dg-danger-text: #98304d;
|
|
4331
4711
|
--dg-on-danger: #ffffff;
|
|
4712
|
+
--dg-success: #2a8441;
|
|
4713
|
+
--dg-success-text: #257339;
|
|
4714
|
+
--dg-on-success: #ffffff;
|
|
4332
4715
|
--dg-warning: #8a5a1c;
|
|
4333
4716
|
}
|
|
4334
4717
|
|
|
@@ -4355,6 +4738,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
|
|
|
4355
4738
|
--dg-danger: #ff5555; /* Red */
|
|
4356
4739
|
--dg-danger-text: #ff8a8a;
|
|
4357
4740
|
--dg-on-danger: #3b0000;
|
|
4741
|
+
--dg-success: #50fa7b;
|
|
4742
|
+
--dg-success-text: #50fa7b;
|
|
4743
|
+
--dg-on-success: #0e2d16;
|
|
4358
4744
|
--dg-warning: #f1fa8c; /* Yellow */
|
|
4359
4745
|
--dg-overlay: rgba(18, 19, 26, 0.74);
|
|
4360
4746
|
}
|
|
@@ -4388,6 +4774,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
|
|
|
4388
4774
|
--dg-danger: #b3372c; /* red #dc322f, deepened */
|
|
4389
4775
|
--dg-danger-text: #9c2f25;
|
|
4390
4776
|
--dg-on-danger: #ffffff;
|
|
4777
|
+
--dg-success: #6c7c00;
|
|
4778
|
+
--dg-success-text: #5a6800;
|
|
4779
|
+
--dg-on-success: #ffffff;
|
|
4391
4780
|
--dg-warning: #8a5a00; /* yellow #b58900, deepened */
|
|
4392
4781
|
}
|
|
4393
4782
|
|
|
@@ -4414,6 +4803,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
|
|
|
4414
4803
|
--dg-danger: #e07a72;
|
|
4415
4804
|
--dg-danger-text: #f0a49e;
|
|
4416
4805
|
--dg-on-danger: #34110d;
|
|
4806
|
+
--dg-success: #859900;
|
|
4807
|
+
--dg-success-text: #a4b240;
|
|
4808
|
+
--dg-on-success: #181c00;
|
|
4417
4809
|
--dg-warning: #d5a63b;
|
|
4418
4810
|
--dg-overlay: rgba(0, 20, 26, 0.74);
|
|
4419
4811
|
}
|
|
@@ -4446,6 +4838,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
|
|
|
4446
4838
|
--dg-danger: #9d0006; /* light red */
|
|
4447
4839
|
--dg-danger-text: #9d0006;
|
|
4448
4840
|
--dg-on-danger: #ffffff;
|
|
4841
|
+
--dg-success: #79740e;
|
|
4842
|
+
--dg-success-text: #605c0b;
|
|
4843
|
+
--dg-on-success: #ffffff;
|
|
4449
4844
|
/* The scheme's light yellow (#b57614) is 3.33:1 on this cream ground — the
|
|
4450
4845
|
warmth that makes Gruvbox work is also what makes its yellow weak here.
|
|
4451
4846
|
Same hue, two steps down, 4.72:1. */
|
|
@@ -4475,6 +4870,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
|
|
|
4475
4870
|
--dg-danger: #fb4934; /* dark red */
|
|
4476
4871
|
--dg-danger-text: #fb8b7f;
|
|
4477
4872
|
--dg-on-danger: #2c0500;
|
|
4873
|
+
--dg-success: #b8bb26;
|
|
4874
|
+
--dg-success-text: #bfc23c;
|
|
4875
|
+
--dg-on-success: #212207;
|
|
4478
4876
|
--dg-warning: #fabd2f; /* dark yellow */
|
|
4479
4877
|
--dg-overlay: rgba(20, 20, 20, 0.74);
|
|
4480
4878
|
}
|
|
@@ -4508,6 +4906,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
|
|
|
4508
4906
|
--dg-danger: #c4304a; /* red #d20f39, deepened for white text */
|
|
4509
4907
|
--dg-danger-text: #b02540;
|
|
4510
4908
|
--dg-on-danger: #ffffff;
|
|
4909
|
+
--dg-success: #358524;
|
|
4910
|
+
--dg-success-text: #2d701e;
|
|
4911
|
+
--dg-on-success: #ffffff;
|
|
4511
4912
|
--dg-warning: #995f14; /* peach, deepened */
|
|
4512
4913
|
}
|
|
4513
4914
|
|
|
@@ -4534,6 +4935,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
|
|
|
4534
4935
|
--dg-danger: #f38ba8; /* red */
|
|
4535
4936
|
--dg-danger-text: #f5a3ba;
|
|
4536
4937
|
--dg-on-danger: #3d0b1a;
|
|
4938
|
+
--dg-success: #a6e3a1;
|
|
4939
|
+
--dg-success-text: #a6e3a1;
|
|
4940
|
+
--dg-on-success: #1e291d;
|
|
4537
4941
|
--dg-warning: #fab387; /* peach */
|
|
4538
4942
|
--dg-overlay: rgba(14, 14, 22, 0.74);
|
|
4539
4943
|
}
|
|
@@ -4570,6 +4974,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
|
|
|
4570
4974
|
--dg-danger: #b1364a;
|
|
4571
4975
|
--dg-danger-text: #9d2c3f;
|
|
4572
4976
|
--dg-on-danger: #ffffff;
|
|
4977
|
+
--dg-success: #587539;
|
|
4978
|
+
--dg-success-text: #455b2c;
|
|
4979
|
+
--dg-on-success: #ffffff;
|
|
4573
4980
|
--dg-warning: #8a5a12;
|
|
4574
4981
|
}
|
|
4575
4982
|
|
|
@@ -4596,6 +5003,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
|
|
|
4596
5003
|
--dg-danger: #f7768e; /* red */
|
|
4597
5004
|
--dg-danger-text: #f993a6;
|
|
4598
5005
|
--dg-on-danger: #3a0713;
|
|
5006
|
+
--dg-success: #9ece6a;
|
|
5007
|
+
--dg-success-text: #9ece6a;
|
|
5008
|
+
--dg-on-success: #1c2513;
|
|
4599
5009
|
--dg-warning: #e0af68; /* yellow */
|
|
4600
5010
|
--dg-overlay: rgba(10, 11, 18, 0.76);
|
|
4601
5011
|
}
|