@elasticias/ui 1.0.28 → 1.0.30
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/fesm2022/elasticias-ui.mjs +51 -19
- package/fesm2022/elasticias-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/styles/_comptoir.scss +40 -0
- package/styles/_patterns.scss +25 -4
- package/types/elasticias-ui.d.ts +37 -5
package/package.json
CHANGED
package/styles/_comptoir.scss
CHANGED
|
@@ -119,6 +119,37 @@
|
|
|
119
119
|
--text-soft: var(--ink-400);
|
|
120
120
|
--ink-active: var(--ink-900);
|
|
121
121
|
|
|
122
|
+
/* `--ink-soft` is not a ramp step and was never defined anywhere; it is an
|
|
123
|
+
alias, added because eight call sites across three files already name it
|
|
124
|
+
as `var(--ink-soft, #64748b)`. Undefined, every one of them fell through
|
|
125
|
+
to that literal, which does not flip with the theme and measures 3.46:1
|
|
126
|
+
on `--paper-alt` in dark. Two of those call sites sit in a `.ts` and in
|
|
127
|
+
another component sheet, so one definition here is the only fix that
|
|
128
|
+
reaches them all; it also makes the hardcoded fallback dead.
|
|
129
|
+
Resolves to 4.82:1 (light) / 6.63:1 (dark) on `--paper-alt`. */
|
|
130
|
+
--ink-soft: var(--text-mute);
|
|
131
|
+
|
|
132
|
+
/* Foreground for anything painted on the tenant accent.
|
|
133
|
+
|
|
134
|
+
`setTenantAccent()` writes the ramp onto `documentElement.style` at
|
|
135
|
+
runtime, so `--tenant-500` can be any hue at any lightness. A hardcoded
|
|
136
|
+
`#fff` fails on a light accent, and `var(--paper)` fails differently:
|
|
137
|
+
paper flips with the theme while the accent does not, which is how the
|
|
138
|
+
avatar ended up at 2.04:1 on the default maroon in dark mode.
|
|
139
|
+
|
|
140
|
+
So: black or white, whichever the accent's own lightness calls for.
|
|
141
|
+
Choosing the better of those two against *any* background is guaranteed
|
|
142
|
+
to clear AA. White scores 1.05/(Y+0.05) and black scores (Y+0.05)/0.05,
|
|
143
|
+
and the two are equal only at Y = 0.179, where both land on 4.58:1. The
|
|
144
|
+
OKLCH lightness matching that luminance is 0.623, so the clamp collapses
|
|
145
|
+
to 1 (white) below it and 0 (black) above it; `* -infinity` is what
|
|
146
|
+
forces a pure 0 or 1 instead of a gradient between them.
|
|
147
|
+
|
|
148
|
+
The plain value below is the fallback for engines without relative
|
|
149
|
+
colour syntax; the `@supports` block after this rule is what actually
|
|
150
|
+
tracks the accent. */
|
|
151
|
+
--on-tenant: #fff;
|
|
152
|
+
|
|
122
153
|
/* ── Spatial scale (s-1 = 4px → s-10 = 96px) ─────────────────── */
|
|
123
154
|
--s-1: 4px;
|
|
124
155
|
--s-2: 8px;
|
|
@@ -142,6 +173,15 @@
|
|
|
142
173
|
}
|
|
143
174
|
|
|
144
175
|
/* ── Semantic aliases (dark) — toggled by .p-dark on <html> ────── */
|
|
176
|
+
/* Relative colour syntax resolves `--tenant-500` at computed-value time on
|
|
177
|
+
<html>, the same element `setTenantAccent()` writes the accent onto, so
|
|
178
|
+
this tracks a runtime accent change with no JS of its own. */
|
|
179
|
+
@supports (color: oklch(from #000 l c h)) {
|
|
180
|
+
:root {
|
|
181
|
+
--on-tenant: oklch(from var(--tenant-500) clamp(0, calc((l - 0.623) * -infinity), 1) 0 h);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
145
185
|
.p-dark {
|
|
146
186
|
--paper: var(--ink-900);
|
|
147
187
|
--paper-alt: var(--ink-800);
|
package/styles/_patterns.scss
CHANGED
|
@@ -303,6 +303,12 @@
|
|
|
303
303
|
|
|
304
304
|
.avatar.tenant {
|
|
305
305
|
background: var(--tenant-500);
|
|
306
|
+
/* `.avatar` sets `color: var(--paper)`, which is right only while the
|
|
307
|
+
ground flips with it: `--ink-active` does, the tenant accent does not.
|
|
308
|
+
On a dark page that paired near-black initials with the accent at
|
|
309
|
+
2.04:1. `--on-tenant` is black or white by the accent's own lightness,
|
|
310
|
+
so it holds for a runtime accent instead of for this one maroon. */
|
|
311
|
+
color: var(--on-tenant);
|
|
306
312
|
}
|
|
307
313
|
|
|
308
314
|
.avatar.sm {
|
|
@@ -2286,9 +2292,15 @@
|
|
|
2286
2292
|
}
|
|
2287
2293
|
|
|
2288
2294
|
.dp__cal-day.out .day-num {
|
|
2289
|
-
|
|
2295
|
+
/* These are enabled buttons: the template binds `(click)="selectDay(...)"`
|
|
2296
|
+
with no `disabled`, so clicking a trailing 30 jumps to the next month.
|
|
2297
|
+
That rules out WCAG's exemption for inactive components, and
|
|
2298
|
+
`--text-soft` at half opacity resolved to 1.52:1 in light and 1.80:1 in
|
|
2299
|
+
dark. `--text-mute` at full opacity measures 4.82:1 / 6.63:1 and still
|
|
2300
|
+
reads as clearly secondary next to an in-month day at 18.9:1 / 15.65:1,
|
|
2301
|
+
which is what the de-emphasis was for. */
|
|
2302
|
+
color: var(--text-mute);
|
|
2290
2303
|
font-weight: 500;
|
|
2291
|
-
opacity: 0.5;
|
|
2292
2304
|
}
|
|
2293
2305
|
|
|
2294
2306
|
.dp__cal-day.today .day-num {
|
|
@@ -3600,7 +3612,10 @@ input.ef-input[type='number'] {
|
|
|
3600
3612
|
padding: 0;
|
|
3601
3613
|
background: transparent;
|
|
3602
3614
|
border-radius: 50%;
|
|
3603
|
-
|
|
3615
|
+
/* The ✕ is the affordance, not decoration, so it takes the 3:1 non-text
|
|
3616
|
+
bar. `--text-soft` gave it 2.49:1 in light and 3.42:1 in dark; this is
|
|
3617
|
+
4.82:1 / 6.63:1 on `--paper-alt`, and hover still lifts it to `--text`. */
|
|
3618
|
+
color: var(--text-mute);
|
|
3604
3619
|
flex-shrink: 0;
|
|
3605
3620
|
cursor: pointer;
|
|
3606
3621
|
transition: all var(--t-fast) var(--ease-out);
|
|
@@ -3952,7 +3967,10 @@ input.ef-input[type='number'] {
|
|
|
3952
3967
|
width: 10px;
|
|
3953
3968
|
height: 10px;
|
|
3954
3969
|
font-size: 10px;
|
|
3955
|
-
|
|
3970
|
+
/* The checked box is painted with the accent, so the tick lands on a ground
|
|
3971
|
+
that does not flip with the theme; `var(--paper)` put it at 2.04:1 in
|
|
3972
|
+
dark, under the 3:1 bar for a non-text glyph. */
|
|
3973
|
+
color: var(--on-tenant);
|
|
3956
3974
|
}
|
|
3957
3975
|
|
|
3958
3976
|
/* Selected check-mark for single-select (the trailing ✓) */
|
|
@@ -4365,6 +4383,9 @@ input.ef-input[type='number'] {
|
|
|
4365
4383
|
|
|
4366
4384
|
.es-dialog .es-dialog__highlight .av.tenant {
|
|
4367
4385
|
background: var(--tenant-500);
|
|
4386
|
+
/* Same bug as `.avatar.tenant`: `.av` sets `color: var(--paper)` and the
|
|
4387
|
+
accent ground does not flip with it. */
|
|
4388
|
+
color: var(--on-tenant);
|
|
4368
4389
|
}
|
|
4369
4390
|
|
|
4370
4391
|
.es-dialog .es-dialog__highlight .body {
|
package/types/elasticias-ui.d.ts
CHANGED
|
@@ -137,9 +137,6 @@ interface OrderEntity {
|
|
|
137
137
|
*/
|
|
138
138
|
interface DocumentConfig {
|
|
139
139
|
documentType: 'order' | 'invoice' | 'quote';
|
|
140
|
-
headerLabel: string;
|
|
141
|
-
dateLabel: string;
|
|
142
|
-
customerLabel: string;
|
|
143
140
|
enableTax?: boolean;
|
|
144
141
|
enableDiscount?: boolean;
|
|
145
142
|
showCatalogue?: boolean;
|
|
@@ -4412,6 +4409,10 @@ type EfTableDensity = 'compact' | 'default' | 'comfortable';
|
|
|
4412
4409
|
* "nothing to fetch" and greets a waiting user with the empty
|
|
4413
4410
|
* state. While loading with no rows yet it shimmers `ef-skeleton`
|
|
4414
4411
|
* rows (table and mobile list alike) and flags `aria-busy`.
|
|
4412
|
+
* 4. **Bind `(retry)` wherever you bind `[errorMsg]`.** An empty result
|
|
4413
|
+
* set that came from a failed request renders the error state, not
|
|
4414
|
+
* the empty one, and its "try again" button is the way out. The card
|
|
4415
|
+
* doesn't know the query, so the screen re-runs it.
|
|
4415
4416
|
*
|
|
4416
4417
|
* ```html
|
|
4417
4418
|
* <ef-data-card
|
|
@@ -4513,7 +4514,19 @@ declare class EfDataCardComponent<TRow = any> implements AfterContentInit {
|
|
|
4513
4514
|
* container is flagged `aria-busy`, as `ef-card` does.
|
|
4514
4515
|
*/
|
|
4515
4516
|
readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
4516
|
-
/**
|
|
4517
|
+
/**
|
|
4518
|
+
* Empty string = no error. Non-empty triggers the error chip in
|
|
4519
|
+
* `tbl-head` and, when the request came back with nothing, the error
|
|
4520
|
+
* state in the body.
|
|
4521
|
+
*
|
|
4522
|
+
* It is the *trigger*, not the copy: screens set it from
|
|
4523
|
+
* `err?.message`, which is whatever the HTTP layer threw. Neither the
|
|
4524
|
+
* chip nor the body state prints it — both word themselves from
|
|
4525
|
+
* translated keys, so a failed list never shows an operator a status
|
|
4526
|
+
* line or an exception string. The raw value is kept on the chip's
|
|
4527
|
+
* `data-error` attribute, which devtools can read and no reader can
|
|
4528
|
+
* see.
|
|
4529
|
+
*/
|
|
4517
4530
|
readonly errorMsg: _angular_core.InputSignal<string>;
|
|
4518
4531
|
readonly loadingKey: _angular_core.InputSignal<string>;
|
|
4519
4532
|
/**
|
|
@@ -4525,6 +4538,18 @@ declare class EfDataCardComponent<TRow = any> implements AfterContentInit {
|
|
|
4525
4538
|
readonly skeletonLines: _angular_core.Signal<number[]>;
|
|
4526
4539
|
/** First load: nothing to show yet, so the rows are placeholders. */
|
|
4527
4540
|
readonly showSkeleton: _angular_core.Signal<boolean>;
|
|
4541
|
+
/**
|
|
4542
|
+
* The request failed and brought nothing back. Without this the body
|
|
4543
|
+
* falls through to the empty state and tells the operator, calmly and
|
|
4544
|
+
* in the product's own voice, that they have no clients — a false
|
|
4545
|
+
* statement about their data that they may go on to act on.
|
|
4546
|
+
*
|
|
4547
|
+
* Third in the chain, after the skeleton and before the empty state:
|
|
4548
|
+
* a retry that is already in flight shows progress, not the error it
|
|
4549
|
+
* is busy clearing. Rows already on screen stay there and keep the
|
|
4550
|
+
* head chip as the failure signal, the way a failed refresh should.
|
|
4551
|
+
*/
|
|
4552
|
+
readonly showError: _angular_core.Signal<boolean>;
|
|
4528
4553
|
/**
|
|
4529
4554
|
* When `true`, double-clicking anywhere on a `<tr>` emits the row
|
|
4530
4555
|
* via `rowDoubleClick` and the body rows render with
|
|
@@ -4602,6 +4627,13 @@ declare class EfDataCardComponent<TRow = any> implements AfterContentInit {
|
|
|
4602
4627
|
readonly exportRequest: _angular_core.OutputEmitterRef<EfDataCardExportRequest>;
|
|
4603
4628
|
/** Raised by the empty state's "clear search" action. */
|
|
4604
4629
|
readonly clearSearch: _angular_core.OutputEmitterRef<void>;
|
|
4630
|
+
/**
|
|
4631
|
+
* Raised by the error state's "try again" button. The card knows the
|
|
4632
|
+
* request failed but not what the request was, so the screen re-runs
|
|
4633
|
+
* it — typically `(retry)="search()"` on a list screen. Unbound, the
|
|
4634
|
+
* button is a dead control, so bind it wherever `[errorMsg]` is bound.
|
|
4635
|
+
*/
|
|
4636
|
+
readonly retry: _angular_core.OutputEmitterRef<void>;
|
|
4605
4637
|
private readonly bodyTemplates;
|
|
4606
4638
|
private readonly headerTemplates;
|
|
4607
4639
|
private readonly bodyTemplateMap;
|
|
@@ -4761,7 +4793,7 @@ declare class EfDataCardComponent<TRow = any> implements AfterContentInit {
|
|
|
4761
4793
|
trackByRow: (_: number, row: TRow) => unknown;
|
|
4762
4794
|
trackByColumn: (_: number, col: EfDataCardColumn) => string;
|
|
4763
4795
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<EfDataCardComponent<any>, never>;
|
|
4764
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfDataCardComponent<any>, "ef-data-card", never, { "mobileLayout": { "alias": "mobileLayout"; "required": false; "isSignal": true; }; "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "trackByField": { "alias": "trackByField"; "required": false; "isSignal": true; }; "pageNumber": { "alias": "pageNumber"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "totalCount": { "alias": "totalCount"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "hidePager": { "alias": "hidePager"; "required": false; "isSignal": true; }; "sort": { "alias": "sort"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "errorMsg": { "alias": "errorMsg"; "required": false; "isSignal": true; }; "loadingKey": { "alias": "loadingKey"; "required": false; "isSignal": true; }; "rowDoubleClickable": { "alias": "rowDoubleClickable"; "required": false; "isSignal": true; }; "hasActionsColumn": { "alias": "hasActionsColumn"; "required": false; "isSignal": true; }; "rowActionsContext": { "alias": "rowActionsContext"; "required": false; "isSignal": true; }; "showViewAction": { "alias": "showViewAction"; "required": false; "isSignal": true; }; "showEditAction": { "alias": "showEditAction"; "required": false; "isSignal": true; }; "showDuplicateAction": { "alias": "showDuplicateAction"; "required": false; "isSignal": true; }; "showDeleteAction": { "alias": "showDeleteAction"; "required": false; "isSignal": true; }; "showDensityControl": { "alias": "showDensityControl"; "required": false; "isSignal": true; }; "showColumnPicker": { "alias": "showColumnPicker"; "required": false; "isSignal": true; }; "showExportControl": { "alias": "showExportControl"; "required": false; "isSignal": true; }; "exporting": { "alias": "exporting"; "required": false; "isSignal": true; }; "screenContext": { "alias": "screenContext"; "required": false; "isSignal": true; }; "searchTerm": { "alias": "searchTerm"; "required": false; "isSignal": true; }; "tableKey": { "alias": "tableKey"; "required": false; "isSignal": true; }; "defaultDensity": { "alias": "defaultDensity"; "required": false; "isSignal": true; }; "reorderable": { "alias": "reorderable"; "required": false; "isSignal": true; }; "fixedLayout": { "alias": "fixedLayout"; "required": false; "isSignal": true; }; }, { "pageChange": "pageChange"; "pageSizeChange": "pageSizeChange"; "sortChange": "sortChange"; "rowDoubleClick": "rowDoubleClick"; "rowAction": "rowAction"; "exportRequest": "exportRequest"; "clearSearch": "clearSearch"; "rowReorder": "rowReorder"; }, ["bodyTemplates", "headerTemplates"], ["[tbl-head-info]", "[tbl-head-actions]", "[empty-state-mobile]", "[empty-state]"], true, never>;
|
|
4796
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EfDataCardComponent<any>, "ef-data-card", never, { "mobileLayout": { "alias": "mobileLayout"; "required": false; "isSignal": true; }; "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "trackByField": { "alias": "trackByField"; "required": false; "isSignal": true; }; "pageNumber": { "alias": "pageNumber"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "totalCount": { "alias": "totalCount"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "hidePager": { "alias": "hidePager"; "required": false; "isSignal": true; }; "sort": { "alias": "sort"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "errorMsg": { "alias": "errorMsg"; "required": false; "isSignal": true; }; "loadingKey": { "alias": "loadingKey"; "required": false; "isSignal": true; }; "rowDoubleClickable": { "alias": "rowDoubleClickable"; "required": false; "isSignal": true; }; "hasActionsColumn": { "alias": "hasActionsColumn"; "required": false; "isSignal": true; }; "rowActionsContext": { "alias": "rowActionsContext"; "required": false; "isSignal": true; }; "showViewAction": { "alias": "showViewAction"; "required": false; "isSignal": true; }; "showEditAction": { "alias": "showEditAction"; "required": false; "isSignal": true; }; "showDuplicateAction": { "alias": "showDuplicateAction"; "required": false; "isSignal": true; }; "showDeleteAction": { "alias": "showDeleteAction"; "required": false; "isSignal": true; }; "showDensityControl": { "alias": "showDensityControl"; "required": false; "isSignal": true; }; "showColumnPicker": { "alias": "showColumnPicker"; "required": false; "isSignal": true; }; "showExportControl": { "alias": "showExportControl"; "required": false; "isSignal": true; }; "exporting": { "alias": "exporting"; "required": false; "isSignal": true; }; "screenContext": { "alias": "screenContext"; "required": false; "isSignal": true; }; "searchTerm": { "alias": "searchTerm"; "required": false; "isSignal": true; }; "tableKey": { "alias": "tableKey"; "required": false; "isSignal": true; }; "defaultDensity": { "alias": "defaultDensity"; "required": false; "isSignal": true; }; "reorderable": { "alias": "reorderable"; "required": false; "isSignal": true; }; "fixedLayout": { "alias": "fixedLayout"; "required": false; "isSignal": true; }; }, { "pageChange": "pageChange"; "pageSizeChange": "pageSizeChange"; "sortChange": "sortChange"; "rowDoubleClick": "rowDoubleClick"; "rowAction": "rowAction"; "exportRequest": "exportRequest"; "clearSearch": "clearSearch"; "retry": "retry"; "rowReorder": "rowReorder"; }, ["bodyTemplates", "headerTemplates"], ["[tbl-head-info]", "[tbl-head-actions]", "[empty-state-mobile]", "[empty-state]"], true, never>;
|
|
4765
4797
|
}
|
|
4766
4798
|
|
|
4767
4799
|
/**
|