apex-grid 3.2.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +78 -0
- package/README.md +200 -52
- package/components/cell.d.ts +14 -1
- package/components/cell.js +48 -6
- package/components/cell.js.map +1 -1
- package/components/filter-row.d.ts +3 -6
- package/components/filter-row.js +79 -109
- package/components/filter-row.js.map +1 -1
- package/components/grid.d.ts +416 -77
- package/components/grid.js +398 -11
- package/components/grid.js.map +1 -1
- package/components/group-header-row.d.ts +34 -0
- package/components/group-header-row.js +125 -0
- package/components/group-header-row.js.map +1 -0
- package/components/header-row.d.ts +13 -2
- package/components/header-row.js +33 -18
- package/components/header-row.js.map +1 -1
- package/components/header.d.ts +11 -0
- package/components/header.js +135 -5
- package/components/header.js.map +1 -1
- package/components/paginator.d.ts +6 -1
- package/components/paginator.js +17 -11
- package/components/paginator.js.map +1 -1
- package/components/row.d.ts +28 -0
- package/components/row.js +100 -3
- package/components/row.js.map +1 -1
- package/components/toolbar.d.ts +8 -1
- package/components/toolbar.js +25 -7
- package/components/toolbar.js.map +1 -1
- package/controllers/data-operation.js +1 -0
- package/controllers/data-operation.js.map +1 -1
- package/controllers/dom.d.ts +24 -6
- package/controllers/dom.js +62 -5
- package/controllers/dom.js.map +1 -1
- package/controllers/editing.d.ts +68 -1
- package/controllers/editing.js +129 -44
- package/controllers/editing.js.map +1 -1
- package/controllers/filter.d.ts +1 -1
- package/controllers/filter.js +16 -5
- package/controllers/filter.js.map +1 -1
- package/controllers/history.d.ts +86 -0
- package/controllers/history.js +118 -0
- package/controllers/history.js.map +1 -0
- package/controllers/navigation.d.ts +15 -0
- package/controllers/navigation.js +53 -0
- package/controllers/navigation.js.map +1 -1
- package/controllers/reorder.js +3 -1
- package/controllers/reorder.js.map +1 -1
- package/controllers/row-pin.d.ts +59 -0
- package/controllers/row-pin.js +75 -0
- package/controllers/row-pin.js.map +1 -0
- package/controllers/row-reorder.d.ts +161 -0
- package/controllers/row-reorder.js +332 -0
- package/controllers/row-reorder.js.map +1 -0
- package/controllers/sort.js +9 -1
- package/controllers/sort.js.map +1 -1
- package/controllers/state.d.ts +33 -0
- package/controllers/state.js +37 -2
- package/controllers/state.js.map +1 -1
- package/controllers/tree.d.ts +8 -0
- package/controllers/tree.js +0 -0
- package/controllers/tree.js.map +1 -1
- package/custom-elements.json +4411 -886
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/highlight.css +28 -0
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/functions/custom.html +3 -0
- package/docs/functions/interpolate.html +4 -0
- package/docs/functions/localize.html +8 -0
- package/docs/functions/max.html +3 -0
- package/docs/functions/min.html +3 -0
- package/docs/functions/pattern.html +3 -0
- package/docs/functions/required.html +3 -0
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +184 -54
- package/docs/interfaces/ApexCellValidationFailedEvent.html +13 -0
- package/docs/interfaces/ApexCellValueChangedEvent.html +1 -1
- package/docs/interfaces/ApexCellValueChangingEvent.html +2 -2
- package/docs/interfaces/ApexColumnGroupContext.html +6 -0
- package/docs/interfaces/ApexColumnMovedEvent.html +2 -2
- package/docs/interfaces/ApexColumnMovingEvent.html +1 -1
- package/docs/interfaces/ApexDetailContext.html +2 -2
- package/docs/interfaces/ApexGridEventMap.html +37 -9
- package/docs/interfaces/ApexHistoryChangedEvent.html +6 -0
- package/docs/interfaces/ApexPageChangedEvent.html +1 -1
- package/docs/interfaces/ApexRowMovingEvent.html +9 -0
- package/docs/interfaces/ApexRowPinningEvent.html +8 -0
- package/docs/interfaces/ApexStateChangedEvent.html +4 -0
- package/docs/interfaces/BaseApexCellContext.html +1 -1
- package/docs/interfaces/BaseApexEditorContext.html +1 -1
- package/docs/interfaces/BaseColumnConfiguration.html +42 -17
- package/docs/interfaces/CSVExportOptions.html +2 -2
- package/docs/interfaces/ColumnGroupConfiguration.html +12 -0
- package/docs/interfaces/ColumnLayoutState.html +2 -0
- package/docs/interfaces/ColumnSchema.html +22 -0
- package/docs/interfaces/DataPipelineConfiguration.html +2 -2
- package/docs/interfaces/EditingHistoryConfiguration.html +10 -0
- package/docs/interfaces/ExportFormat.html +2 -2
- package/docs/interfaces/ExportOptions.html +1 -1
- package/docs/interfaces/FilterStateSnapshot.html +4 -0
- package/docs/interfaces/GetStateOptions.html +4 -0
- package/docs/interfaces/GridCapabilities.html +8 -0
- package/docs/interfaces/GridEditingConfiguration.html +4 -2
- package/docs/interfaces/GridRowPinningConfiguration.html +5 -0
- package/docs/interfaces/GridRowReorderingConfiguration.html +22 -0
- package/docs/interfaces/GridSchema.html +19 -0
- package/docs/interfaces/GridState.html +41 -0
- package/docs/interfaces/GridTreeConfiguration.html +2 -2
- package/docs/interfaces/PaginationConfiguration.html +1 -1
- package/docs/interfaces/PaginationState.html +1 -1
- package/docs/interfaces/SetStateOptions.html +9 -0
- package/docs/interfaces/SetStateResult.html +11 -0
- package/docs/interfaces/SortStateSnapshot.html +2 -0
- package/docs/interfaces/ValidatorContext.html +8 -0
- package/docs/media/_tokens.scss +70 -81
- package/docs/media/package.json +1 -1
- package/docs/media/state-persistence.html +189 -0
- package/docs/modules.html +1 -1
- package/docs/types/DataPipelineParams.html +2 -2
- package/docs/types/EditMode.html +2 -2
- package/docs/types/GridLocaleKey.html +3 -0
- package/docs/types/GridLocaleText.html +5 -0
- package/docs/types/LocaleParams.html +2 -0
- package/docs/types/PaginationMode.html +1 -1
- package/docs/types/RowDropPosition.html +2 -0
- package/docs/types/RowPinPosition.html +2 -0
- package/docs/types/RowRef.html +3 -0
- package/docs/types/Validator.html +4 -0
- package/docs/variables/EN_LOCALE.html +9 -0
- package/docs/variables/esLocale.html +8 -0
- package/i18n/en.d.ts +151 -0
- package/i18n/en.js +125 -0
- package/i18n/en.js.map +1 -0
- package/i18n/es.d.ts +18 -0
- package/i18n/es.js +125 -0
- package/i18n/es.js.map +1 -0
- package/i18n/index.d.ts +3 -0
- package/i18n/index.js +4 -0
- package/i18n/index.js.map +1 -0
- package/i18n/localize.d.ts +23 -0
- package/i18n/localize.js +15 -0
- package/i18n/localize.js.map +1 -0
- package/index.d.ts +8 -2
- package/index.js +2 -0
- package/index.js.map +1 -1
- package/internal/feature-module.d.ts +46 -0
- package/internal/feature-module.js +11 -0
- package/internal/feature-module.js.map +1 -1
- package/internal/flip.js +1 -1
- package/internal/flip.js.map +1 -1
- package/internal/icons.d.ts +9 -7
- package/internal/icons.js +75 -35
- package/internal/icons.js.map +1 -1
- package/internal/index.d.ts +5 -3
- package/internal/index.js +2 -1
- package/internal/index.js.map +1 -1
- package/internal/state-schema.d.ts +85 -0
- package/internal/state-schema.js +27 -0
- package/internal/state-schema.js.map +1 -0
- package/internal/state-snapshot.d.ts +152 -0
- package/internal/state-snapshot.js +115 -0
- package/internal/state-snapshot.js.map +1 -0
- package/internal/tags.d.ts +1 -0
- package/internal/tags.js +1 -0
- package/internal/tags.js.map +1 -1
- package/internal/types.d.ts +162 -2
- package/internal/types.js.map +1 -1
- package/internal/utils.d.ts +12 -0
- package/internal/utils.js +17 -0
- package/internal/utils.js.map +1 -1
- package/internal/validators.d.ts +31 -0
- package/internal/validators.js +44 -0
- package/internal/validators.js.map +1 -0
- package/package.json +1 -1
- package/styles/_tokens.css.js +1 -1
- package/styles/_tokens.css.js.map +1 -1
- package/styles/body-cell/body-cell.css.js +1 -1
- package/styles/body-cell/body-cell.css.js.map +1 -1
- package/styles/body-row/body-row.css.js +1 -1
- package/styles/body-row/body-row.css.js.map +1 -1
- package/styles/filter-row/filter-row.css.js +1 -1
- package/styles/filter-row/filter-row.css.js.map +1 -1
- package/styles/grid/_grid.base.css.js +1 -1
- package/styles/grid/_grid.base.css.js.map +1 -1
- package/styles/grid/grid.css.js +1 -1
- package/styles/grid/grid.css.js.map +1 -1
- package/styles/group-header-row/group-header-row.css.d.ts +1 -0
- package/styles/group-header-row/group-header-row.css.js +3 -0
- package/styles/group-header-row/group-header-row.css.js.map +1 -0
- package/styles/header-cell/header-cell.css.js +1 -1
- package/styles/header-cell/header-cell.css.js.map +1 -1
- package/styles/header-row/header-row.base.css.js +1 -1
- package/styles/header-row/header-row.base.css.js.map +1 -1
- package/styles/toolbar/toolbar.css.js +1 -1
- package/styles/toolbar/toolbar.css.js.map +1 -1
- package/docs/classes/ApexGrid.html +0 -399
package/docs/media/_tokens.scss
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
// ─────────────────────────────────────────────────────────────────────────
|
|
2
2
|
// Premium default design tokens (`--ag-*`).
|
|
3
|
-
//
|
|
4
3
|
// These land on the `<apex-grid>` host (this file is `@use`d by
|
|
5
4
|
// `grid/_grid.base.scss`, which ships inside every theme). CSS custom
|
|
6
5
|
// properties inherit across shadow boundaries, so every child component
|
|
7
6
|
// (`apex-grid-row`, `apex-grid-cell`, `apex-grid-header`, …) can read them.
|
|
8
|
-
//
|
|
9
7
|
// This is the single rebrand surface: override ~12 values on `apex-grid` and
|
|
10
8
|
// the whole grid re-skins. Values fall back to self-contained literals, so a
|
|
11
9
|
// grid mounted with zero consumer CSS already looks premium; the brand tokens
|
|
12
10
|
// additionally re-tint from the igniteui palette when it is present.
|
|
13
|
-
//
|
|
14
11
|
// No `!important`, no downstream hardcoded numerics — every rule resolves here.
|
|
15
12
|
// ─────────────────────────────────────────────────────────────────────────
|
|
16
13
|
|
|
@@ -20,22 +17,25 @@
|
|
|
20
17
|
// auto-matches an igniteui host app), and falls back to the self-contained
|
|
21
18
|
// premium blue otherwise. This igniteui hook used to live in the per-theme
|
|
22
19
|
// files; folding it here keeps that integration without named themes.
|
|
23
|
-
--ag-brand: var(--ig-primary-500, #0d6fd3);
|
|
24
|
-
--ag-brand-strong: var(--ig-primary-700, #0a56b8);
|
|
20
|
+
--ag-brand: var(--ig-primary-500, #0d6fd3); /* primary blue */
|
|
21
|
+
--ag-brand-strong: var(--ig-primary-700, #0a56b8); /* hover / pressed */
|
|
25
22
|
|
|
26
23
|
// Brand-derived washes are mixed from `--ag-brand` so a one-line rebrand
|
|
27
24
|
// cascades to every tint. With the default brand these resolve to the
|
|
28
25
|
// spec's exact rgba(13, 111, 211, …) values.
|
|
29
|
-
--ag-brand-soft: color-mix(in srgb, var(--ag-brand) 10%, transparent);
|
|
30
|
-
--ag-brand-softer: color-mix(in srgb, var(--ag-brand) 7%, transparent);
|
|
31
|
-
--ag-brand-line: color-mix(in srgb, var(--ag-brand) 18%, transparent);
|
|
26
|
+
--ag-brand-soft: color-mix(in srgb, var(--ag-brand) 10%, transparent); /* selected row / chip wash */
|
|
27
|
+
--ag-brand-softer: color-mix(in srgb, var(--ag-brand) 7%, transparent); /* chip / control wash */
|
|
28
|
+
--ag-brand-line: color-mix(in srgb, var(--ag-brand) 18%, transparent); /* chip / search borders */
|
|
32
29
|
|
|
33
30
|
// ── Neutral chrome ───────────────────────────────────────────────────
|
|
34
31
|
// The grid's chrome (surfaces, gridlines, row hover) is grayscale so the
|
|
35
32
|
// grid reads as a calm, neutral table; `--ag-brand` is reserved for genuine
|
|
36
33
|
// state (selection, focus, checkboxes, active sort) and accents (chips).
|
|
37
|
-
--ag-hairline:
|
|
38
|
-
--ag-
|
|
34
|
+
--ag-hairline: rgb(15 23 42 / 8%); /* header / structural gridlines */
|
|
35
|
+
--ag-border: rgb(15 23 42 / 8%); /* row separators — same weight as hairline */
|
|
36
|
+
--ag-pin-line: rgb(15 23 42 / 18%); /* 1px vertical line at pinned-column edge */
|
|
37
|
+
--ag-header-separator: rgb(15 23 42 / 12%); /* opt-in per-column header divider (columnSeparator) */
|
|
38
|
+
--ag-row-hover: color-mix(in srgb, #0f172a 5%, var(--ag-surface)); /* neutral hover wash (opaque) */
|
|
39
39
|
|
|
40
40
|
// ── Surfaces ─────────────────────────────────────────────────────────
|
|
41
41
|
// These back sticky/pinned regions (header, footer, frozen columns) which
|
|
@@ -47,78 +47,68 @@
|
|
|
47
47
|
// gradient while sticky surfaces stay flat/opaque. Dark themes override it
|
|
48
48
|
// with a flat color. The host paints THIS, so dark mode is impossible
|
|
49
49
|
// without it being a token.
|
|
50
|
-
--ag-grid-bg:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
rgba(248, 250, 254, 0.94) 100%
|
|
55
|
-
);
|
|
56
|
-
--ag-surface: #fff; // grid card background
|
|
57
|
-
--ag-surface-alt: #f9fafb; // alternating row tint (neutral, opaque)
|
|
58
|
-
--ag-surface-elevated: linear-gradient(180deg, #fbfcfd 0%, #f6f7f8 100%); // header bg (neutral, opaque)
|
|
50
|
+
--ag-grid-bg: #fff; /* flat white — gradients are dated in modern data grids */
|
|
51
|
+
--ag-surface: #fff; /* grid card background */
|
|
52
|
+
--ag-surface-alt: var(--ag-surface); /* no zebra stripes — rely on hover + hairline borders */
|
|
53
|
+
--ag-surface-elevated: #f8f9fb; /* flat header/toolbar/footer surface */
|
|
59
54
|
|
|
60
55
|
// ── Text ─────────────────────────────────────────────────────────────
|
|
61
|
-
--ag-text: #111827;
|
|
62
|
-
--ag-text-body: #1f2937;
|
|
63
|
-
--ag-text-muted: #6b7280;
|
|
64
|
-
--ag-text-subtle: #9ca3af;
|
|
56
|
+
--ag-text: #111827; /* primary */
|
|
57
|
+
--ag-text-body: #1f2937; /* row text */
|
|
58
|
+
--ag-text-muted: #6b7280; /* roles, labels */
|
|
59
|
+
--ag-text-subtle: #9ca3af; /* placeholder, ellipsis */
|
|
65
60
|
--ag-text-on-brand: #fff;
|
|
66
61
|
|
|
67
|
-
--ag-border: rgba(15, 23, 42, 0.05); // row separators
|
|
68
|
-
|
|
69
62
|
// ── State ────────────────────────────────────────────────────────────
|
|
70
|
-
--ag-good: #10b981;
|
|
63
|
+
--ag-good: #10b981; /* health > 80, Active */
|
|
71
64
|
--ag-good-text: #047857;
|
|
72
|
-
--ag-good-soft:
|
|
73
|
-
--ag-watch: #f59e0b;
|
|
65
|
+
--ag-good-soft: rgb(16 185 129 / 10%);
|
|
66
|
+
--ag-watch: #f59e0b; /* health 65–80, Trial */
|
|
74
67
|
--ag-watch-text: #b45309;
|
|
75
|
-
--ag-watch-soft:
|
|
76
|
-
--ag-risk: #ef4444;
|
|
68
|
+
--ag-watch-soft: rgb(245 158 11 / 10%);
|
|
69
|
+
--ag-risk: #ef4444; /* health < 65, Churn */
|
|
77
70
|
--ag-risk-text: #b91c1c;
|
|
78
|
-
--ag-risk-soft:
|
|
79
|
-
|
|
80
|
-
--ag-gold: #fef3c7; // Enterprise pill bg
|
|
71
|
+
--ag-risk-soft: rgb(239 68 68 / 10%);
|
|
72
|
+
--ag-gold: #fef3c7; /* Enterprise pill bg */
|
|
81
73
|
--ag-gold-line: #fde68a;
|
|
82
74
|
--ag-gold-text: #92400e;
|
|
83
|
-
|
|
84
75
|
--ag-shadow-card:
|
|
85
|
-
0 16px 38px
|
|
86
|
-
0 0 0 1px
|
|
87
|
-
0 1px 0
|
|
76
|
+
0 16px 38px rgb(15 23 42 / 12%),
|
|
77
|
+
0 0 0 1px rgb(15 23 42 / 6%),
|
|
78
|
+
0 1px 0 rgb(255 255 255 / 90%) inset; /* soft neutral floating shadow */
|
|
88
79
|
|
|
89
80
|
// ── Typography ───────────────────────────────────────────────────────
|
|
90
81
|
--ag-font: 'Inter', -apple-system, blinkmacsystemfont, sans-serif;
|
|
91
|
-
--ag-fs-cell:
|
|
92
|
-
--ag-fs-cell-secondary:
|
|
93
|
-
--ag-fs-tiny: 10px;
|
|
82
|
+
--ag-fs-cell: 13px;
|
|
83
|
+
--ag-fs-cell-secondary: 11.5px; /* role line, header labels */
|
|
84
|
+
--ag-fs-tiny: 10px; /* tags, page ellipsis */
|
|
94
85
|
--ag-fw-regular: 500;
|
|
95
86
|
--ag-fw-semibold: 600;
|
|
96
87
|
--ag-fw-bold: 700;
|
|
97
88
|
--ag-tracking-tight: -0.005em;
|
|
98
|
-
--ag-tracking-header: 0.05em;
|
|
89
|
+
--ag-tracking-header: 0.05em; /* uppercase header labels */
|
|
99
90
|
--ag-leading: 1.4;
|
|
100
91
|
|
|
101
92
|
// ── Spacing & sizing ─────────────────────────────────────────────────
|
|
102
93
|
--ag-cell-pad-x: 10px;
|
|
103
|
-
--ag-row-h: 36px;
|
|
104
|
-
--ag-header-h:
|
|
94
|
+
--ag-row-h: 36px; /* dense but readable */
|
|
95
|
+
--ag-header-h: 40px; /* taller than rows to accommodate 3-icon header */
|
|
105
96
|
--ag-toolbar-pad: 12px 14px;
|
|
106
97
|
--ag-footer-pad: 10px 14px;
|
|
107
|
-
--ag-radius:
|
|
108
|
-
--ag-radius-sm: 6px;
|
|
109
|
-
--ag-radius-xs: 4px;
|
|
110
|
-
--ag-radius-pill: 20px;
|
|
98
|
+
--ag-radius: 8px; /* outer card — tighter matches modern table libraries */
|
|
99
|
+
--ag-radius-sm: 6px; /* chips, page buttons */
|
|
100
|
+
--ag-radius-xs: 4px; /* checkboxes, expand button */
|
|
101
|
+
--ag-radius-pill: 20px; /* status badges */
|
|
111
102
|
|
|
112
103
|
// ── Motion ───────────────────────────────────────────────────────────
|
|
113
104
|
--ag-ease: cubic-bezier(0.2, 0.8, 0.2, 1);
|
|
114
|
-
--ag-dur-fast: 120ms;
|
|
115
|
-
--ag-dur-med: 180ms;
|
|
116
|
-
--ag-dur-slow: 240ms;
|
|
105
|
+
--ag-dur-fast: 120ms; /* hover, focus */
|
|
106
|
+
--ag-dur-med: 180ms; /* chevron rotate */
|
|
107
|
+
--ag-dur-slow: 240ms; /* health bar fill */
|
|
117
108
|
}
|
|
118
109
|
|
|
119
110
|
// ─────────────────────────────────────────────────────────────────────────
|
|
120
111
|
// Built-in dark theme. Opt in with `<apex-grid theme="dark">`.
|
|
121
|
-
//
|
|
122
112
|
// Only color/surface tokens are flipped to a neutral slate palette; geometry,
|
|
123
113
|
// typography, motion, and the brand hue (which still auto-tints from the
|
|
124
114
|
// igniteui palette when present) are inherited from the light block above.
|
|
@@ -133,72 +123,71 @@
|
|
|
133
123
|
--ag-brand-strong: var(--ig-primary-400, #60a5fa);
|
|
134
124
|
|
|
135
125
|
// ── Surfaces ── flat, opaque slate (sticky regions paint these).
|
|
136
|
-
--ag-grid-bg: #0f172a;
|
|
137
|
-
--ag-surface: #0f172a;
|
|
138
|
-
--ag-surface-alt:
|
|
139
|
-
--ag-surface-elevated: #
|
|
126
|
+
--ag-grid-bg: #0f172a; /* host card (flat in dark) */
|
|
127
|
+
--ag-surface: #0f172a; /* grid body / row bg */
|
|
128
|
+
--ag-surface-alt: var(--ag-surface); /* no stripes in dark mode either */
|
|
129
|
+
--ag-surface-elevated: #1e2532; /* header / footer / toolbar — slightly lifted */
|
|
140
130
|
|
|
141
131
|
// ── Chrome ── light-on-dark gridlines + a hover wash that mixes toward
|
|
142
132
|
// white (the light default mixes toward #0f172a, which is invisible here).
|
|
143
|
-
--ag-hairline:
|
|
144
|
-
--ag-border:
|
|
145
|
-
--ag-
|
|
133
|
+
--ag-hairline: rgb(255 255 255 / 12%); /* structural gridlines */
|
|
134
|
+
--ag-border: rgb(255 255 255 / 12%); /* row separators — same weight as hairline */
|
|
135
|
+
--ag-pin-line: rgb(255 255 255 / 28%); /* 1px vertical line at pinned-column edge */
|
|
136
|
+
--ag-header-separator: rgb(255 255 255 / 18%); /* opt-in per-column header divider (columnSeparator) */
|
|
137
|
+
--ag-row-hover: color-mix(in srgb, #fff 7%, var(--ag-surface));
|
|
146
138
|
|
|
147
139
|
// ── Text ──
|
|
148
|
-
--ag-text: #f1f5f9;
|
|
149
|
-
--ag-text-body: #e2e8f0;
|
|
150
|
-
--ag-text-muted: #94a3b8;
|
|
151
|
-
--ag-text-subtle: #64748b;
|
|
140
|
+
--ag-text: #f1f5f9; /* primary */
|
|
141
|
+
--ag-text-body: #e2e8f0; /* row text */
|
|
142
|
+
--ag-text-muted: #94a3b8; /* roles, labels */
|
|
143
|
+
--ag-text-subtle: #64748b; /* placeholder, ellipsis */
|
|
152
144
|
|
|
153
145
|
// ── State ── brighter text + slightly stronger washes for legibility on
|
|
154
146
|
// the dark surface.
|
|
155
147
|
--ag-good-text: #34d399;
|
|
156
|
-
--ag-good-soft:
|
|
148
|
+
--ag-good-soft: rgb(16 185 129 / 18%);
|
|
157
149
|
--ag-watch-text: #fbbf24;
|
|
158
|
-
--ag-watch-soft:
|
|
150
|
+
--ag-watch-soft: rgb(245 158 11 / 18%);
|
|
159
151
|
--ag-risk-text: #f87171;
|
|
160
|
-
--ag-risk-soft:
|
|
161
|
-
|
|
162
|
-
--ag-gold:
|
|
163
|
-
--ag-gold-line: rgba(245, 158, 11, 0.35);
|
|
152
|
+
--ag-risk-soft: rgb(239 68 68 / 18%);
|
|
153
|
+
--ag-gold: rgb(245 158 11 / 16%); /* Enterprise pill bg (dark amber wash) */
|
|
154
|
+
--ag-gold-line: rgb(245 158 11 / 35%);
|
|
164
155
|
--ag-gold-text: #fcd34d;
|
|
165
156
|
|
|
166
157
|
// Drop the light-mode white inset highlight; deepen the drop shadow.
|
|
167
158
|
--ag-shadow-card:
|
|
168
|
-
0 16px 38px
|
|
169
|
-
0 0 0 1px
|
|
170
|
-
0 1px 0
|
|
159
|
+
0 16px 38px rgb(0 0 0 / 55%),
|
|
160
|
+
0 0 0 1px rgb(255 255 255 / 6%),
|
|
161
|
+
0 1px 0 rgb(255 255 255 / 4%) inset;
|
|
171
162
|
}
|
|
172
163
|
|
|
173
164
|
// ─────────────────────────────────────────────────────────────────────────
|
|
174
165
|
// Optional brand-tinted chrome. Opt in with `theme="tinted"` (composes with
|
|
175
166
|
// dark as `theme="dark tinted"`).
|
|
176
|
-
//
|
|
177
167
|
// By default the chrome is neutral grayscale and `--ag-brand` only shows on
|
|
178
168
|
// interactive state (selection, focus, active sort). This variant mixes a
|
|
179
169
|
// little brand into the surfaces/gridlines so the grid wears its brand even
|
|
180
|
-
// at rest,
|
|
170
|
+
// at rest, a brand-tinted variant. Because every value is `color-mix(... var
|
|
181
171
|
// (--ag-brand) ...)`, it follows whatever brand is in effect (including the
|
|
182
172
|
// igniteui auto-tint) with no per-brand CSS.
|
|
183
|
-
//
|
|
184
173
|
// The light variant mixes into the white neutrals; the dark variant (higher
|
|
185
174
|
// specificity, so it wins under `theme="dark tinted"`) mixes the SAME token
|
|
186
175
|
// set into the slate neutrals. Body row surface stays untinted for legibility.
|
|
187
176
|
// ─────────────────────────────────────────────────────────────────────────
|
|
188
177
|
:host([theme~='tinted']) {
|
|
189
|
-
--ag-surface-alt: color-mix(in srgb, var(--ag-brand) 4%, #fff);
|
|
190
|
-
--ag-surface-elevated: color-mix(in srgb, var(--ag-brand) 11%, #fbfcfd);
|
|
191
|
-
--ag-hairline: color-mix(in srgb, var(--ag-brand) 24%,
|
|
192
|
-
--ag-border: color-mix(in srgb, var(--ag-brand) 12%, transparent);
|
|
178
|
+
--ag-surface-alt: color-mix(in srgb, var(--ag-brand) 4%, #fff); /* zebra */
|
|
179
|
+
--ag-surface-elevated: color-mix(in srgb, var(--ag-brand) 11%, #fbfcfd); /* header / footer / toolbar */
|
|
180
|
+
--ag-hairline: color-mix(in srgb, var(--ag-brand) 24%, rgb(15 23 42 / 7%)); /* gridlines */
|
|
181
|
+
--ag-border: color-mix(in srgb, var(--ag-brand) 12%, transparent); /* row separators */
|
|
193
182
|
--ag-row-hover: color-mix(in srgb, var(--ag-brand) 9%, var(--ag-surface));
|
|
194
|
-
--ag-text-muted: color-mix(in srgb, var(--ag-brand) 32%, #6b7280);
|
|
183
|
+
--ag-text-muted: color-mix(in srgb, var(--ag-brand) 32%, #6b7280); /* header labels pick up the brand */
|
|
195
184
|
}
|
|
196
185
|
|
|
197
186
|
:host([theme~='dark'][theme~='tinted']) {
|
|
198
187
|
--ag-surface-alt: color-mix(in srgb, var(--ag-brand) 10%, #172033);
|
|
199
188
|
--ag-surface-elevated: color-mix(in srgb, var(--ag-brand) 20%, #1e293b);
|
|
200
|
-
--ag-hairline: color-mix(in srgb, var(--ag-brand) 30%,
|
|
201
|
-
--ag-border: color-mix(in srgb, var(--ag-brand) 16%,
|
|
189
|
+
--ag-hairline: color-mix(in srgb, var(--ag-brand) 30%, rgb(255 255 255 / 12%));
|
|
190
|
+
--ag-border: color-mix(in srgb, var(--ag-brand) 16%, rgb(255 255 255 / 7%));
|
|
202
191
|
--ag-row-hover: color-mix(in srgb, var(--ag-brand) 12%, var(--ag-surface));
|
|
203
192
|
--ag-text-muted: color-mix(in srgb, var(--ag-brand) 28%, #94a3b8);
|
|
204
193
|
}
|
package/docs/media/package.json
CHANGED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>State Persistence (getState / setState) - ApexGrid</title>
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
8
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
9
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet" />
|
|
10
|
+
<script src="../apex-grid.min.js"></script>
|
|
11
|
+
<style>
|
|
12
|
+
body {
|
|
13
|
+
max-width: 1000px;
|
|
14
|
+
margin: 0 auto;
|
|
15
|
+
font-family: 'Inter', sans-serif;
|
|
16
|
+
background: #fff;
|
|
17
|
+
padding: 20px;
|
|
18
|
+
}
|
|
19
|
+
h2 {
|
|
20
|
+
font-size: 22px;
|
|
21
|
+
font-weight: 700;
|
|
22
|
+
color: #1a1a2e;
|
|
23
|
+
margin: 0 0 4px 0;
|
|
24
|
+
line-height: 1.3;
|
|
25
|
+
}
|
|
26
|
+
.subtitle {
|
|
27
|
+
font-size: 13px;
|
|
28
|
+
color: #888;
|
|
29
|
+
margin-bottom: 16px;
|
|
30
|
+
}
|
|
31
|
+
.toolbar {
|
|
32
|
+
display: flex;
|
|
33
|
+
gap: 8px;
|
|
34
|
+
margin-bottom: 12px;
|
|
35
|
+
flex-wrap: wrap;
|
|
36
|
+
}
|
|
37
|
+
.toolbar button {
|
|
38
|
+
padding: 6px 12px;
|
|
39
|
+
font: inherit;
|
|
40
|
+
font-size: 13px;
|
|
41
|
+
border: 1px solid #d0d5dd;
|
|
42
|
+
background: #fff;
|
|
43
|
+
border-radius: 4px;
|
|
44
|
+
cursor: pointer;
|
|
45
|
+
}
|
|
46
|
+
.toolbar button:hover {
|
|
47
|
+
background: #f7f9fc;
|
|
48
|
+
}
|
|
49
|
+
.layout {
|
|
50
|
+
display: grid;
|
|
51
|
+
grid-template-columns: 1fr 320px;
|
|
52
|
+
gap: 16px;
|
|
53
|
+
align-items: start;
|
|
54
|
+
}
|
|
55
|
+
apex-grid {
|
|
56
|
+
min-height: 420px;
|
|
57
|
+
--ig-size: 2;
|
|
58
|
+
}
|
|
59
|
+
.snapshot {
|
|
60
|
+
margin: 0;
|
|
61
|
+
padding: 10px 12px;
|
|
62
|
+
background: #0f172a;
|
|
63
|
+
color: #cbd5e1;
|
|
64
|
+
border-radius: 6px;
|
|
65
|
+
font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
|
|
66
|
+
font-size: 11px;
|
|
67
|
+
line-height: 1.5;
|
|
68
|
+
max-height: 460px;
|
|
69
|
+
overflow: auto;
|
|
70
|
+
white-space: pre-wrap;
|
|
71
|
+
word-break: break-word;
|
|
72
|
+
}
|
|
73
|
+
.panel-title {
|
|
74
|
+
font-size: 12px;
|
|
75
|
+
font-weight: 600;
|
|
76
|
+
color: #475569;
|
|
77
|
+
margin: 0 0 6px 0;
|
|
78
|
+
text-transform: uppercase;
|
|
79
|
+
letter-spacing: 0.04em;
|
|
80
|
+
}
|
|
81
|
+
</style>
|
|
82
|
+
<script type="module">
|
|
83
|
+
try {
|
|
84
|
+
const resp = await fetch('https://cdn.jsdelivr.net/npm/igniteui-webcomponents@5/themes/light/bootstrap.css');
|
|
85
|
+
const css = await resp.text();
|
|
86
|
+
const style = document.createElement('style');
|
|
87
|
+
style.textContent = css.replaceAll(':root', 'apex-grid');
|
|
88
|
+
document.head.appendChild(style);
|
|
89
|
+
} catch (e) { /* theme is cosmetic */ }
|
|
90
|
+
</script>
|
|
91
|
+
</head>
|
|
92
|
+
<body>
|
|
93
|
+
<h2>State Persistence — getState / setState</h2>
|
|
94
|
+
<p class="subtitle">
|
|
95
|
+
The grid serializes its restorable view (column layout, sort, filter, pagination, selection, pinned rows, manual order) with <code>getState()</code> and restores it with <code>setState()</code>. The <code>stateChanged</code> event fires after every settled change, so saving to <code>localStorage</code> is a one-liner. Reorder/sort/filter/select, then reload the page — your view is restored.
|
|
96
|
+
</p>
|
|
97
|
+
<div class="toolbar">
|
|
98
|
+
<button id="save">Save view</button>
|
|
99
|
+
<button id="restore">Restore saved</button>
|
|
100
|
+
<button id="reset">Reset to default</button>
|
|
101
|
+
</div>
|
|
102
|
+
<div class="layout">
|
|
103
|
+
<apex-grid id="grid"></apex-grid>
|
|
104
|
+
<div>
|
|
105
|
+
<p class="panel-title">Live snapshot (getState)</p>
|
|
106
|
+
<pre class="snapshot" id="snapshot"></pre>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
<script type="module">
|
|
110
|
+
const KEY = 'apex-grid:saved-view';
|
|
111
|
+
const data = [
|
|
112
|
+
{ id: '1', name: 'Wireless Headphones', category: 'Audio', price: 299.00, stock: 14 },
|
|
113
|
+
{ id: '2', name: 'USB-C Hub', category: 'Connectivity', price: 49.99, stock: 28 },
|
|
114
|
+
{ id: '3', name: 'Mechanical Keyboard', category: 'Input', price: 189.00, stock: 5 },
|
|
115
|
+
{ id: '4', name: 'Ergonomic Mouse', category: 'Input', price: 79.95, stock: 22 },
|
|
116
|
+
{ id: '5', name: 'Monitor Stand', category: 'Furniture', price: 59.99, stock: 17 },
|
|
117
|
+
{ id: '6', name: '4K Webcam', category: 'Video', price: 149.00, stock: 9 },
|
|
118
|
+
{ id: '7', name: 'Laptop Sleeve', category: 'Accessories', price: 34.99, stock: 31 },
|
|
119
|
+
{ id: '8', name: 'Desk Lamp', category: 'Furniture', price: 44.50, stock: 12 },
|
|
120
|
+
{ id: '9', name: 'True Wireless Earbuds', category: 'Audio', price: 249.00, stock: 20 },
|
|
121
|
+
{ id: '10', name: 'Portable Charger', category: 'Connectivity', price: 39.99, stock: 45 },
|
|
122
|
+
{ id: '11', name: 'Ultrawide Monitor', category: 'Video', price: 649.00, stock: 6 },
|
|
123
|
+
{ id: '12', name: 'Noise-Cancelling Headset', category: 'Audio', price: 219.00, stock: 11 },
|
|
124
|
+
{ id: '13', name: 'Wireless Charging Pad', category: 'Connectivity', price: 29.99, stock: 38 },
|
|
125
|
+
{ id: '14', name: 'LED Desk Light', category: 'Furniture', price: 54.99, stock: 24 },
|
|
126
|
+
{ id: '15', name: 'Laptop Stand', category: 'Accessories', price: 49.99, stock: 18 },
|
|
127
|
+
{ id: '16', name: 'Compact Keyboard', category: 'Input', price: 99.00, stock: 13 },
|
|
128
|
+
{ id: '17', name: 'USB-C Docking Station', category: 'Connectivity', price: 199.00, stock: 8 },
|
|
129
|
+
{ id: '18', name: 'Trackball Mouse', category: 'Input', price: 119.99, stock: 16 },
|
|
130
|
+
{ id: '19', name: 'Monitor Light Bar', category: 'Furniture', price: 79.00, stock: 21 },
|
|
131
|
+
{ id: '20', name: 'Phone Mount for Desk', category: 'Accessories', price: 24.99, stock: 50 },
|
|
132
|
+
];
|
|
133
|
+
|
|
134
|
+
// A sensible starting view, applied on first load (empty storage). Pins a
|
|
135
|
+
// row to the top and sorts by price so the snapshot panel is illustrative.
|
|
136
|
+
const DEFAULT_VIEW = {
|
|
137
|
+
sort: [{ key: 'price', direction: 'descending' }],
|
|
138
|
+
rowPinning: { top: [{ index: 0 }], bottom: [] },
|
|
139
|
+
selection: [{ index: 2 }],
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const grid = document.getElementById('grid');
|
|
143
|
+
grid.columns = [
|
|
144
|
+
{ key: 'id', headerText: 'ID' },
|
|
145
|
+
{ key: 'name', headerText: 'Name', sort: true, filter: true },
|
|
146
|
+
{ key: 'category', headerText: 'Category', sort: true, filter: true },
|
|
147
|
+
{ key: 'price', headerText: 'Price', sort: true, type: 'number' },
|
|
148
|
+
{ key: 'stock', headerText: 'Stock', sort: true, type: 'number' },
|
|
149
|
+
];
|
|
150
|
+
grid.data = data;
|
|
151
|
+
grid.selection = { enabled: true, mode: 'multiple' };
|
|
152
|
+
grid.rowPinning = { enabled: true };
|
|
153
|
+
grid.rowReordering = { enabled: true };
|
|
154
|
+
|
|
155
|
+
const snapshotEl = document.getElementById('snapshot');
|
|
156
|
+
const render = () => {
|
|
157
|
+
snapshotEl.textContent = JSON.stringify(grid.getState(), null, 2);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
document.getElementById('save').addEventListener('click', () => {
|
|
161
|
+
localStorage.setItem(KEY, JSON.stringify(grid.getState()));
|
|
162
|
+
});
|
|
163
|
+
document.getElementById('restore').addEventListener('click', () => {
|
|
164
|
+
const saved = localStorage.getItem(KEY);
|
|
165
|
+
if (saved) grid.setState(JSON.parse(saved));
|
|
166
|
+
});
|
|
167
|
+
document.getElementById('reset').addEventListener('click', () => {
|
|
168
|
+
localStorage.removeItem(KEY);
|
|
169
|
+
grid.setState(DEFAULT_VIEW);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
await customElements.whenDefined('apex-grid');
|
|
173
|
+
// Apply the saved (or default) view after the grid's first render settles,
|
|
174
|
+
// so it isn't clobbered by the initial data/columns pipeline.
|
|
175
|
+
await grid.updateComplete;
|
|
176
|
+
const saved = localStorage.getItem(KEY);
|
|
177
|
+
grid.setState(saved ? JSON.parse(saved) : DEFAULT_VIEW);
|
|
178
|
+
await grid.updateComplete;
|
|
179
|
+
render();
|
|
180
|
+
|
|
181
|
+
// Persistence in one line: save the snapshot whenever state settles. Wired
|
|
182
|
+
// after the initial view is in place so it captures real user changes.
|
|
183
|
+
grid.addEventListener('stateChanged', (e) => {
|
|
184
|
+
localStorage.setItem(KEY, JSON.stringify(e.detail.state));
|
|
185
|
+
render();
|
|
186
|
+
});
|
|
187
|
+
</script>
|
|
188
|
+
</body>
|
|
189
|
+
</html>
|