@vectoriox/iox-ui 5.82.2 → 5.83.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/design-core/index.d.ts +200 -0
- package/fesm2022/vectoriox-iox-ui-design-core.mjs +215 -1
- package/fesm2022/vectoriox-iox-ui-design-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-forms-core.mjs +733 -56
- package/fesm2022/vectoriox-iox-ui-forms-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs +40 -4
- package/fesm2022/vectoriox-iox-ui-generation-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui.mjs +1547 -135
- package/fesm2022/vectoriox-iox-ui.mjs.map +1 -1
- package/forms-core/index.d.ts +366 -18
- package/generation-core/index.d.ts +3 -0
- package/index.d.ts +303 -25
- package/package.json +1 -1
- package/src/design-core/contrast-audit.ts +4 -0
- package/src/design-core/flavor-spec.generated.ts +209 -1
- package/src/forms-core/channel.ts +85 -0
- package/src/forms-core/collect.ts +63 -30
- package/src/forms-core/dates.ts +299 -0
- package/src/forms-core/field-markup.ts +159 -0
- package/src/forms-core/form-presets.ts +51 -2
- package/src/forms-core/form.model.ts +34 -2
- package/src/forms-core/messages.ts +31 -0
- package/src/forms-core/public-api.ts +3 -0
- package/src/forms-core/rule-catalog.ts +3 -2
- package/src/forms-core/submit-lifecycle.ts +42 -12
- package/src/forms-core/validate.ts +90 -4
- package/src/generation-core/audit-site.ts +9 -1
- package/src/generation-core/compose-site.ts +22 -3
- package/src/generation-core/node-baselines.generated.ts +10 -0
- package/src/generation-core/plan-wire.ts +2 -2
- package/styles/iox-design.css +10 -0
- package/styles/iox-forms.css +349 -10
package/index.d.ts
CHANGED
|
@@ -996,6 +996,11 @@ declare enum ControlType {
|
|
|
996
996
|
/** A slider over a numeric range — min/max/step ride the field. */
|
|
997
997
|
Range = "range",
|
|
998
998
|
Radio = "radio",
|
|
999
|
+
/** One or several of a few visible choices — chips (the default) or a list of radios / checkboxes (premium N1).
|
|
1000
|
+
* Its `multiple` trait picks the value's shape: a string, or a list of strings. */
|
|
1001
|
+
Choices = "choices",
|
|
1002
|
+
/** A date the visitor picks from the look's calendar (premium N8) — a button that reads the date in words and a
|
|
1003
|
+
* hidden input carrying the ISO `YYYY-MM-DD` value. Never the browser's own date box. */
|
|
999
1004
|
Date = "date",
|
|
1000
1005
|
Time = "time",
|
|
1001
1006
|
File = "file",
|
|
@@ -1015,7 +1020,19 @@ declare enum RuleName {
|
|
|
1015
1020
|
/** A checkbox that must be ticked — terms, consent. */
|
|
1016
1021
|
Accepted = "accepted",
|
|
1017
1022
|
FileType = "fileType",
|
|
1018
|
-
FileSize = "fileSize"
|
|
1023
|
+
FileSize = "fileSize",
|
|
1024
|
+
/** IMPLIED, never authored: an answer of a Choices / Radio / Dropdown must be one of the field's own options
|
|
1025
|
+
* (premium N1) — a hand-crafted POST cannot file a value the form never offered. */
|
|
1026
|
+
OneOf = "oneOf",
|
|
1027
|
+
/** IMPLIED, never authored: a Date's answer is a real `YYYY-MM-DD` day (premium N8). */
|
|
1028
|
+
ValidDate = "validDate"
|
|
1029
|
+
}
|
|
1030
|
+
/** How a Choices field draws its options (premium N1). */
|
|
1031
|
+
declare enum ChoiceAppearance {
|
|
1032
|
+
/** Each option a chip — the label is the chip; the native input inside it is visually hidden. */
|
|
1033
|
+
Chips = "chips",
|
|
1034
|
+
/** The options as rows of the look's own radio / checkbox (DS9.1). */
|
|
1035
|
+
List = "list"
|
|
1019
1036
|
}
|
|
1020
1037
|
interface ValidationRule {
|
|
1021
1038
|
name: RuleName;
|
|
@@ -1046,6 +1063,8 @@ interface FieldSpec {
|
|
|
1046
1063
|
options?: FieldOption[];
|
|
1047
1064
|
optionsSource?: FieldOptionSource;
|
|
1048
1065
|
defaultValue?: any;
|
|
1066
|
+
/** A Choices field that takes several answers: its value is a list (premium N1). */
|
|
1067
|
+
multiple?: boolean;
|
|
1049
1068
|
}
|
|
1050
1069
|
/** When a field is validated, once the author has stopped deciding it per field. */
|
|
1051
1070
|
declare enum FeedbackTiming {
|
|
@@ -1163,6 +1182,41 @@ interface ClientFormSpec {
|
|
|
1163
1182
|
fields: FieldSpec[];
|
|
1164
1183
|
}
|
|
1165
1184
|
|
|
1185
|
+
/**
|
|
1186
|
+
* DATES — the date picker's pure half (premium components N8) and the date rules' one reading.
|
|
1187
|
+
*
|
|
1188
|
+
* A Date field's value is an ISO day, `YYYY-MM-DD`, compared as a string (the format sorts as the calendar does).
|
|
1189
|
+
* Its `min` / `max` rules take an ISO day OR an offset in days from today (`{ offsetDays: 0 }` = today), so "from
|
|
1190
|
+
* today on" stays true tomorrow without a re-save. ONE reading for the validator (client AND iox-cms), the calendar
|
|
1191
|
+
* (which days it refuses) and the builder's Earliest / Latest controls.
|
|
1192
|
+
*
|
|
1193
|
+
* The calendar model (six rows of seven, roving focus, the APG keys) lives here too, so the DOM runtime only draws
|
|
1194
|
+
* what this decides — the canvas, the engine's component path and its string path draw the SAME month.
|
|
1195
|
+
*
|
|
1196
|
+
* ⚠️ Framework-free, like the rest of forms-core. Local-time `Date` objects are used only to walk the calendar; a
|
|
1197
|
+
* day leaves this file as an ISO string.
|
|
1198
|
+
*/
|
|
1199
|
+
|
|
1200
|
+
/** The calendar's own words, by the site's language — the media-core `videoWords` precedent (a string-rendered
|
|
1201
|
+
* site has no translation service; the document's `lang` picks). */
|
|
1202
|
+
interface DatePickerWords {
|
|
1203
|
+
choose: string;
|
|
1204
|
+
previousMonth: string;
|
|
1205
|
+
nextMonth: string;
|
|
1206
|
+
close: string;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
/**
|
|
1210
|
+
* A Field as its form's runtime knows it. Functions, not values: a trait edited on the canvas takes effect without
|
|
1211
|
+
* re-registering. `baseName` is the field's own key (its override, else its label's); the FORM makes it unique against
|
|
1212
|
+
* the fields before it — forms-core `uniqueFieldNames`, the rule the saved spec and the string renderer use (iox-ui#43).
|
|
1213
|
+
* `spec` is handed that unique name. A registration without `baseName` is named by its spec.
|
|
1214
|
+
*/
|
|
1215
|
+
interface RegisteredField {
|
|
1216
|
+
baseName?: () => string;
|
|
1217
|
+
spec: (name: string) => FieldSpec;
|
|
1218
|
+
getValue: () => any;
|
|
1219
|
+
}
|
|
1166
1220
|
/**
|
|
1167
1221
|
* How a message KEY becomes text a visitor reads.
|
|
1168
1222
|
*
|
|
@@ -1185,7 +1239,7 @@ declare const defaultMessageResolver: FormMessageResolver;
|
|
|
1185
1239
|
* the registered fields and the Angular-shaped API. Nothing here decides *when* an error shows.
|
|
1186
1240
|
*/
|
|
1187
1241
|
declare class FormRuntimeService {
|
|
1188
|
-
/** Registered fields, in DOM order — the order the spec and focus-first-invalid depend on. */
|
|
1242
|
+
/** Registered fields, in DOM order — the order the spec, the unique names and focus-first-invalid depend on. */
|
|
1189
1243
|
private readonly fields;
|
|
1190
1244
|
private _state;
|
|
1191
1245
|
private _spec;
|
|
@@ -1199,10 +1253,11 @@ declare class FormRuntimeService {
|
|
|
1199
1253
|
* always reads the field's current spec and value — a trait edited on the canvas takes effect
|
|
1200
1254
|
* without re-registering anything.
|
|
1201
1255
|
*/
|
|
1202
|
-
register(field:
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1256
|
+
register(field: RegisteredField): () => void;
|
|
1257
|
+
/** Every registered field's submitted name, in order — unique within the form (iox-ui#43). */
|
|
1258
|
+
private names;
|
|
1259
|
+
/** The name the form gives one registered field, or null when it is not this form's. */
|
|
1260
|
+
nameOf(field: RegisteredField): string | null;
|
|
1206
1261
|
/** The live spec, derived from what is registered right now. */
|
|
1207
1262
|
specNow(): FormSpec;
|
|
1208
1263
|
/** Current values, keyed by submitted field name. */
|
|
@@ -1326,6 +1381,7 @@ declare class IoxFormComponent implements OnChanges, OnInit {
|
|
|
1326
1381
|
* is exactly when a visitor most needs telling.
|
|
1327
1382
|
*/
|
|
1328
1383
|
private announce;
|
|
1384
|
+
/** Focus the first field that failed and shake it once (premium N2 — Emil 134; none under reduced motion). */
|
|
1329
1385
|
private focusFirstInvalid;
|
|
1330
1386
|
static ɵfac: i0.ɵɵFactoryDeclaration<IoxFormComponent, [null, null, { optional: true; }, { optional: true; }]>;
|
|
1331
1387
|
static ɵcmp: i0.ɵɵComponentDeclaration<IoxFormComponent, "form[iox-form]", never, { "nodeId": { "alias": "nodeId"; "required": false; }; "formId": { "alias": "formId"; "required": false; }; "name": { "alias": "name"; "required": false; }; "renderState": { "alias": "renderState"; "required": false; }; "feedback": { "alias": "feedback"; "required": false; }; "focusFirstProblem": { "alias": "focusFirstProblem"; "required": false; }; "announceFailure": { "alias": "announceFailure"; "required": false; }; }, { "formSubmit": "formSubmit"; "validationFailed": "validationFailed"; }, never, never, false, never>;
|
|
@@ -1345,15 +1401,24 @@ declare class IoxFormComponent implements OnChanges, OnInit {
|
|
|
1345
1401
|
*
|
|
1346
1402
|
* ⚠️ Control type is a TRAIT, not a component per type (decision D4) — one component, one config,
|
|
1347
1403
|
* and choosing `email` also chooses email validation.
|
|
1404
|
+
*
|
|
1405
|
+
* The markup is forms-core `fieldHtml`'s, element for element (the engine's string path writes it): Choices is a
|
|
1406
|
+
* fieldset of chips or rows (premium N1), Date is a button + a hidden ISO input that opens the look's calendar (N8).
|
|
1407
|
+
* The submitted name is the FORM's unique name for this field (forms-core `uniqueFieldNames`, vectoriox/iox-ui#43).
|
|
1348
1408
|
*/
|
|
1349
|
-
declare class IoxFieldComponent implements OnInit, OnDestroy {
|
|
1409
|
+
declare class IoxFieldComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
1350
1410
|
private readonly runtime;
|
|
1351
1411
|
private readonly resolveMessage;
|
|
1412
|
+
private readonly host?;
|
|
1413
|
+
private readonly isPreview?;
|
|
1414
|
+
private readonly pageScroll?;
|
|
1352
1415
|
nodeId: string;
|
|
1353
1416
|
/** The submitted key. Blank means "derive it from the label" — authors never invent keys. */
|
|
1354
1417
|
name: string;
|
|
1355
1418
|
label: string;
|
|
1356
|
-
control: ControlType | string;
|
|
1419
|
+
set control(value: ControlType | string);
|
|
1420
|
+
get control(): ControlType | string;
|
|
1421
|
+
private _control;
|
|
1357
1422
|
placeholder: string;
|
|
1358
1423
|
help: string;
|
|
1359
1424
|
required: boolean;
|
|
@@ -1365,6 +1430,15 @@ declare class IoxFieldComponent implements OnInit, OnDestroy {
|
|
|
1365
1430
|
rangeMax: number | string;
|
|
1366
1431
|
rangeStep: number | string;
|
|
1367
1432
|
accept: string;
|
|
1433
|
+
/** Choices (N1): several answers (checkboxes) or one (radios). */
|
|
1434
|
+
multiple: boolean;
|
|
1435
|
+
/** Choices (N1): `chips` (the default) or `list` — the look's radio / checkbox rows. */
|
|
1436
|
+
set appearance(value: ChoiceAppearance | string | null | undefined);
|
|
1437
|
+
get appearance(): ChoiceAppearance;
|
|
1438
|
+
private _appearance;
|
|
1439
|
+
/** Date (N8): the first and last day it takes — '' any · N days from today · an ISO day (forms-core `dates.ts`). */
|
|
1440
|
+
earliest: string;
|
|
1441
|
+
latest: string;
|
|
1368
1442
|
/** Explicit choices (bound data, a hand-built node). Wins over `optionsText`. */
|
|
1369
1443
|
set options(value: FieldOption[] | null | undefined);
|
|
1370
1444
|
get options(): FieldOption[];
|
|
@@ -1382,44 +1456,72 @@ declare class IoxFieldComponent implements OnInit, OnDestroy {
|
|
|
1382
1456
|
/**
|
|
1383
1457
|
* Forces the error appearance without a real failure — how the builder lets an author DESIGN
|
|
1384
1458
|
* the error state (decision D5). At runtime the state comes from the runtime service instead.
|
|
1459
|
+
* Turning it on shakes the field once, so the author sees the motion they are designing (N2).
|
|
1385
1460
|
*/
|
|
1386
|
-
forceInvalid: boolean;
|
|
1461
|
+
set forceInvalid(value: boolean);
|
|
1462
|
+
get forceInvalid(): boolean;
|
|
1463
|
+
private _forceInvalid;
|
|
1387
1464
|
/** Placeholder shown while designing the error state, so the block has something to style. */
|
|
1388
1465
|
designErrorText: string;
|
|
1389
1466
|
/** Only after a successful check — never on an untouched field. */
|
|
1390
1467
|
showValid: boolean;
|
|
1468
|
+
/** The builder canvas's design-time Open state for a Date (N8): the calendar drawn under the field, inert. */
|
|
1469
|
+
set designOpen(value: boolean);
|
|
1470
|
+
get designOpen(): boolean;
|
|
1471
|
+
private _designOpen;
|
|
1391
1472
|
valueChange: EventEmitter<any>;
|
|
1392
1473
|
touched: EventEmitter<void>;
|
|
1393
1474
|
/** Stable per instance so `for`/`id` and `aria-describedby` always pair up. */
|
|
1394
1475
|
readonly controlId: string;
|
|
1395
1476
|
private unregister?;
|
|
1477
|
+
private registration;
|
|
1478
|
+
private picker;
|
|
1479
|
+
private viewReady;
|
|
1396
1480
|
/**
|
|
1397
1481
|
* Classic constructor injection, not `inject()`: this library's specs construct components
|
|
1398
1482
|
* directly (its vitest setup cannot run `TestBed.createComponent`), and a field initializer
|
|
1399
1483
|
* calling `inject()` throws NG0203 outside an injection context.
|
|
1400
1484
|
*
|
|
1401
1485
|
* `runtime` is optional because a Field dropped OUTSIDE any Form must still render — it simply
|
|
1402
|
-
* has nothing to submit to. That is the same ancestry rule from the other side.
|
|
1486
|
+
* has nothing to submit to. That is the same ancestry rule from the other side. `isPreview` says the field is
|
|
1487
|
+
* LIVE (the engine, the admin's Preview): only then does its date button open a calendar — on the editing canvas
|
|
1488
|
+
* a click selects the field, and the calendar is the design-time Open state.
|
|
1403
1489
|
*/
|
|
1404
|
-
constructor(runtime: FormRuntimeService | null, resolveMessage: FormMessageResolver);
|
|
1490
|
+
constructor(runtime: FormRuntimeService | null, resolveMessage: FormMessageResolver, host?: (ElementRef<HTMLElement> | null) | undefined, isPreview?: boolean | null | undefined, pageScroll?: (PageScrollProvider | null) | undefined);
|
|
1405
1491
|
ngOnInit(): void;
|
|
1492
|
+
ngAfterViewInit(): void;
|
|
1406
1493
|
ngOnDestroy(): void;
|
|
1407
|
-
/** The submitted key: the
|
|
1494
|
+
/** The submitted key: the form's unique name for this field (iox-ui#43), else the field's own base name. */
|
|
1408
1495
|
get fieldName(): string;
|
|
1409
1496
|
/** Failing AND allowed to say so — or forced, while an author designs the state. */
|
|
1410
1497
|
get invalid(): boolean;
|
|
1411
1498
|
/** The message a visitor reads. Translation is the consumer's, via IOX_FORM_MESSAGES. */
|
|
1412
1499
|
get errorText(): string;
|
|
1500
|
+
/** The field's spec under the name its form gave it — forms-core `fieldSpecOf`, the reading the saved spec uses. */
|
|
1413
1501
|
private toSpec;
|
|
1414
1502
|
private refreshChoices;
|
|
1415
|
-
/** `file`, `
|
|
1503
|
+
/** `file`, `number`… map straight through; everything else is a text input (forms-core `inputTypeOf`). */
|
|
1416
1504
|
get inputType(): string;
|
|
1505
|
+
/** A Date's chosen day (the hidden input's value) — '' while none is. */
|
|
1506
|
+
get dateIso(): string;
|
|
1507
|
+
/** A Date's chosen day in words, in the field's language — '' while none is. */
|
|
1508
|
+
get dateWords(): string;
|
|
1509
|
+
/** What an unpicked Date says: the author's hint, else "Choose a date" in the field's language. */
|
|
1510
|
+
get datePlaceholder(): string;
|
|
1511
|
+
/** Whether a Choices option is chosen — one answer, or one of several. */
|
|
1512
|
+
isChosen(optionValue: string): boolean;
|
|
1513
|
+
/** A Choices option ticked or unticked: the answer becomes the list of ticked ones, or the one picked. */
|
|
1514
|
+
toggle(optionValue: string, checked: boolean): void;
|
|
1417
1515
|
/** Help and error are BOTH announced, in that order, when both are present. */
|
|
1418
1516
|
get describedBy(): string | null;
|
|
1419
1517
|
emit(value: any): void;
|
|
1420
|
-
touch(): void;
|
|
1421
|
-
|
|
1422
|
-
|
|
1518
|
+
touch(event?: Event): void;
|
|
1519
|
+
/** A live Date runs the ONE date picker; any other control (or the canvas) runs none. */
|
|
1520
|
+
private syncDate;
|
|
1521
|
+
/** The canvas's Open state: the calendar drawn under the field (never on a live page). */
|
|
1522
|
+
private syncDesignCalendar;
|
|
1523
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<IoxFieldComponent, [{ optional: true; }, null, { optional: true; }, { optional: true; }, { optional: true; }]>;
|
|
1524
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<IoxFieldComponent, "div[iox-field]", never, { "nodeId": { "alias": "nodeId"; "required": false; }; "name": { "alias": "name"; "required": false; }; "label": { "alias": "label"; "required": false; }; "control": { "alias": "control"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "help": { "alias": "help"; "required": false; }; "required": { "alias": "required"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "labelHidden": { "alias": "labelHidden"; "required": false; }; "requiredMark": { "alias": "requiredMark"; "required": false; }; "rows": { "alias": "rows"; "required": false; }; "rangeMin": { "alias": "rangeMin"; "required": false; }; "rangeMax": { "alias": "rangeMax"; "required": false; }; "rangeStep": { "alias": "rangeStep"; "required": false; }; "accept": { "alias": "accept"; "required": false; }; "multiple": { "alias": "multiple"; "required": false; }; "appearance": { "alias": "appearance"; "required": false; }; "earliest": { "alias": "earliest"; "required": false; }; "latest": { "alias": "latest"; "required": false; }; "options": { "alias": "options"; "required": false; }; "optionsText": { "alias": "optionsText"; "required": false; }; "value": { "alias": "value"; "required": false; }; "rules": { "alias": "rules"; "required": false; }; "forceInvalid": { "alias": "forceInvalid"; "required": false; }; "designErrorText": { "alias": "designErrorText"; "required": false; }; "showValid": { "alias": "showValid"; "required": false; }; "designOpen": { "alias": "designOpen"; "required": false; }; }, { "valueChange": "valueChange"; "touched": "touched"; }, never, never, false, never>;
|
|
1423
1525
|
}
|
|
1424
1526
|
|
|
1425
1527
|
/**
|
|
@@ -1429,19 +1531,26 @@ declare class IoxFieldComponent implements OnInit, OnDestroy {
|
|
|
1429
1531
|
* action list on the FORM (decision D9), so there is nothing here to wire and nothing to get out of
|
|
1430
1532
|
* sync. The button owns only its own appearance.
|
|
1431
1533
|
*
|
|
1432
|
-
* It follows its FORM's state (vectoriox/iox-ui#42): its
|
|
1433
|
-
*
|
|
1434
|
-
* state,
|
|
1435
|
-
* (`syncSubmitButtons`) the form's runtimes
|
|
1436
|
-
*
|
|
1534
|
+
* It follows its FORM's state (vectoriox/iox-ui#42, premium N2): its three labels — at rest, "While sending", "Sent"
|
|
1535
|
+
* with a check — are all in the markup, stacked in one cell, and the shared iox-forms.css shows the one the form's
|
|
1536
|
+
* `data-iox-state` names, swapped in place behind a 2px blur (Emil 87/139); the check draws once on Sent. Busy and
|
|
1537
|
+
* disabled are written by the ONE applier (`syncSubmitButtons`) the form's runtimes and the canvas call. The string
|
|
1538
|
+
* renderer writes the same markup (forms-core `submitButtonLabelsHtml`).
|
|
1437
1539
|
*/
|
|
1438
1540
|
declare class IoxSubmitButtonComponent {
|
|
1541
|
+
private readonly resolveMessage;
|
|
1542
|
+
private readonly host;
|
|
1439
1543
|
nodeId: string;
|
|
1440
1544
|
label: string;
|
|
1441
1545
|
loadingLabel: string;
|
|
1546
|
+
/** What it says once its form has sent (N2). Empty: the catalog's "Sent", in the host's language. */
|
|
1547
|
+
sentLabel: string;
|
|
1442
1548
|
disableWhileSubmitting: boolean;
|
|
1443
|
-
|
|
1444
|
-
|
|
1549
|
+
constructor(resolveMessage?: FormMessageResolver | null, host?: ElementRef<HTMLElement> | null);
|
|
1550
|
+
/** The author's Sent words; else the host's translation of the catalog's; else "Sent" in the page's language. */
|
|
1551
|
+
get sentWords(): string;
|
|
1552
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<IoxSubmitButtonComponent, [{ optional: true; }, { optional: true; }]>;
|
|
1553
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<IoxSubmitButtonComponent, "button[iox-submit]", never, { "nodeId": { "alias": "nodeId"; "required": false; }; "label": { "alias": "label"; "required": false; }; "loadingLabel": { "alias": "loadingLabel"; "required": false; }; "sentLabel": { "alias": "sentLabel"; "required": false; }; "disableWhileSubmitting": { "alias": "disableWhileSubmitting"; "required": false; }; }, {}, never, never, false, never>;
|
|
1445
1554
|
}
|
|
1446
1555
|
|
|
1447
1556
|
/**
|
|
@@ -3541,6 +3650,7 @@ declare class StringFormRuntime {
|
|
|
3541
3650
|
private render;
|
|
3542
3651
|
private renderError;
|
|
3543
3652
|
private announce;
|
|
3653
|
+
/** Focus the first field that failed and shake it once (premium N2 — the ONE `shakeElement`). */
|
|
3544
3654
|
private focusFirstInvalid;
|
|
3545
3655
|
private honeypotValue;
|
|
3546
3656
|
}
|
|
@@ -3560,5 +3670,173 @@ declare function attachStringForm(form: Element | null | undefined, options?: St
|
|
|
3560
3670
|
*/
|
|
3561
3671
|
declare function syncSubmitButtons(form: Element | null | undefined, state: FormRenderState | string | null | undefined): void;
|
|
3562
3672
|
|
|
3563
|
-
|
|
3564
|
-
|
|
3673
|
+
/**
|
|
3674
|
+
* THE DATE PICKER (premium components N8) — the APG date picker dialog, wearing the look. ONE DOM runtime for the
|
|
3675
|
+
* engine's component path and its string path; the builder canvas draws the same panel for its design-time Open state
|
|
3676
|
+
* (`showCalendarDesign`). The month, the keys and the bounds are forms-core's (`dates.ts`); this file only draws them,
|
|
3677
|
+
* places them and moves focus.
|
|
3678
|
+
*
|
|
3679
|
+
* - A modal `<dialog>` INSIDE the field, so it inherits the look's tokens and the section's scheme, and the field's
|
|
3680
|
+
* part styles reach it; on a laptop it is a popover under the field (above when there is no room) growing from it, on
|
|
3681
|
+
* a phone a bottom sheet (the shared CSS — `iox-forms.css` / `iox-design.css` — owns both looks and their motion).
|
|
3682
|
+
* - The grid always has six rows; a month change is instant (Emil 2/65 — rapid, keyboard-driven UI never animates).
|
|
3683
|
+
* - Roving focus: one day is the Tab stop. Arrows move a day (mirrored in RTL), Home/End the week, PageUp/PageDown a
|
|
3684
|
+
* month (Shift: a year), Enter/Space pick, Esc closes and gives focus back to the button. Refused days are
|
|
3685
|
+
* `aria-disabled` and never picked, by click or by key.
|
|
3686
|
+
*/
|
|
3687
|
+
interface DatePickerOptions {
|
|
3688
|
+
/** The site's language (words, week start, the date in words); else the nearest `[lang]`, else the document's. */
|
|
3689
|
+
lang?: string | null;
|
|
3690
|
+
/** Right-to-left; else the field's computed direction. */
|
|
3691
|
+
rtl?: boolean | null;
|
|
3692
|
+
/** Today, for a test; else the visitor's local day. */
|
|
3693
|
+
today?: () => string;
|
|
3694
|
+
/** The component path's hook: a day was picked (the hidden input is written either way). */
|
|
3695
|
+
onPick?: (iso: string) => void;
|
|
3696
|
+
/** Page scroll is held while the calendar is open (Lenis would scroll the page under a fixed panel). */
|
|
3697
|
+
lockScroll?: () => void;
|
|
3698
|
+
unlockScroll?: () => void;
|
|
3699
|
+
/** Overrides the built-in words (a host with its own translations). */
|
|
3700
|
+
words?: Partial<DatePickerWords>;
|
|
3701
|
+
}
|
|
3702
|
+
declare enum CalendarClass {
|
|
3703
|
+
Panel = "iox-cal",
|
|
3704
|
+
Grab = "iox-cal__grab",
|
|
3705
|
+
Head = "iox-cal__head",
|
|
3706
|
+
Title = "iox-cal__title",
|
|
3707
|
+
Nav = "iox-cal__nav",
|
|
3708
|
+
Prev = "iox-cal__prev",
|
|
3709
|
+
Next = "iox-cal__next",
|
|
3710
|
+
Grid = "iox-cal__grid",
|
|
3711
|
+
Weekday = "iox-cal__weekday",
|
|
3712
|
+
Cell = "iox-cal__cell",
|
|
3713
|
+
Day = "iox-cal__day"
|
|
3714
|
+
}
|
|
3715
|
+
/** On the panel while it leaves (the shared CSS plays the exit on it). */
|
|
3716
|
+
declare const CALENDAR_CLOSING_ATTRIBUTE = "data-iox-closing";
|
|
3717
|
+
/** On the panel the builder canvas draws for its design-time Open state (in the flow, inert). */
|
|
3718
|
+
declare const CALENDAR_DESIGN_ATTRIBUTE = "data-iox-cal-design";
|
|
3719
|
+
/** A phone gets the sheet (the drawer curve, the scrim) — the same width the shared CSS keys on. */
|
|
3720
|
+
declare const CALENDAR_SHEET_QUERY = "(max-width: 767px)";
|
|
3721
|
+
/** The language the field speaks: the host's, the nearest `[lang]`, the document's. */
|
|
3722
|
+
declare function fieldLanguage(field: Element, lang?: string | null): string;
|
|
3723
|
+
/** Write a day (or nothing) into a date field: the hidden input carries it, the button says it in words. */
|
|
3724
|
+
declare function setDateFieldValue(field: Element, iso: string, options?: {
|
|
3725
|
+
lang?: string | null;
|
|
3726
|
+
today?: string;
|
|
3727
|
+
placeholder?: string;
|
|
3728
|
+
}): void;
|
|
3729
|
+
/** One live date field. Built by `attachDatePicker`; idempotent per field. */
|
|
3730
|
+
declare class DatePickerRuntime {
|
|
3731
|
+
private readonly field;
|
|
3732
|
+
private readonly options;
|
|
3733
|
+
private panel;
|
|
3734
|
+
private focusIso;
|
|
3735
|
+
private closing;
|
|
3736
|
+
private readonly listeners;
|
|
3737
|
+
constructor(field: HTMLElement, options?: DatePickerOptions);
|
|
3738
|
+
get isOpen(): boolean;
|
|
3739
|
+
value(): string;
|
|
3740
|
+
destroy(): void;
|
|
3741
|
+
open(): void;
|
|
3742
|
+
/** Close with the exit the shared CSS plays (faster than the entrance — Emil 30), then give focus back. */
|
|
3743
|
+
close(): void;
|
|
3744
|
+
private pick;
|
|
3745
|
+
private dismiss;
|
|
3746
|
+
private focusDay;
|
|
3747
|
+
/** Under the field, aligned to its reading start; above when there is no room — the ONE `placeFloating`. */
|
|
3748
|
+
private place;
|
|
3749
|
+
private lang;
|
|
3750
|
+
private rtl;
|
|
3751
|
+
private today;
|
|
3752
|
+
private words;
|
|
3753
|
+
private listen;
|
|
3754
|
+
}
|
|
3755
|
+
/** The runtime already running a field, if any. */
|
|
3756
|
+
declare function datePickerOf(field: Element | null | undefined): DatePickerRuntime | null;
|
|
3757
|
+
/** Run a date field — once: a field already running is returned as is. Null when `field` holds no date button. */
|
|
3758
|
+
declare function attachDatePicker(field: Element | null | undefined, options?: DatePickerOptions): DatePickerRuntime | null;
|
|
3759
|
+
/** Run every date field under `root` (the string path: a page's or a global's markup). */
|
|
3760
|
+
declare function attachDatePickers(root: ParentNode | null | undefined, options?: DatePickerOptions): DatePickerRuntime[];
|
|
3761
|
+
/**
|
|
3762
|
+
* The builder canvas's design-time Open state: the SAME panel, drawn in the flow under the date button (a modal in the
|
|
3763
|
+
* top layer would escape the canvas's zoom and cover the builder), inert — the author selects the Field and styles
|
|
3764
|
+
* its Calendar parts; nothing in it takes focus or a click. `false` removes it.
|
|
3765
|
+
*/
|
|
3766
|
+
declare function showCalendarDesign(field: Element | null | undefined, show: boolean, options?: {
|
|
3767
|
+
lang?: string | null;
|
|
3768
|
+
rtl?: boolean | null;
|
|
3769
|
+
today?: string;
|
|
3770
|
+
}): void;
|
|
3771
|
+
|
|
3772
|
+
/**
|
|
3773
|
+
* The shake a failing field gives after a refused submit (premium components N2) — Emil 134: the named effect for
|
|
3774
|
+
* rejected input. ONE function for the component path, the string path and the canvas (a field put in its error state
|
|
3775
|
+
* on the canvas shakes once, so the author sees the motion they are designing).
|
|
3776
|
+
*
|
|
3777
|
+
* WAAPI, `composite: 'add'`, so it moves the field from wherever its own transform puts it. A second refused submit
|
|
3778
|
+
* CANCELS the running shake and starts clean — never two stacked (Emil 52/62). Under reduced motion there is no shake:
|
|
3779
|
+
* focus and the message still happen (Emil 192 — the meaning survives without the movement).
|
|
3780
|
+
*/
|
|
3781
|
+
/** ±6 → ±4 → rest: a decaying side-to-side (the prototype's, Doron-approved). */
|
|
3782
|
+
declare const SHAKE_KEYFRAMES: ReadonlyArray<Keyframe>;
|
|
3783
|
+
/** Under Emil's UI budget (28) and long enough to read as "no" (134). */
|
|
3784
|
+
declare const SHAKE_DURATION_MS = 320;
|
|
3785
|
+
/** Emil 18 — the strong ease-out. */
|
|
3786
|
+
declare const SHAKE_EASING = "cubic-bezier(0.23, 1, 0.32, 1)";
|
|
3787
|
+
/** Shake `el` once; returns the animation, or null when nothing plays (no element, no WAAPI, reduced motion). */
|
|
3788
|
+
declare function shakeElement(el: Element | null | undefined, reducedMotion?: boolean): Animation | null;
|
|
3789
|
+
|
|
3790
|
+
/**
|
|
3791
|
+
* placeFloating — where a panel anchored to a control goes (premium components N8, reused by M5's tooltip and popover).
|
|
3792
|
+
*
|
|
3793
|
+
* ONE pure decision for every floating panel: under its anchor, aligned to the anchor's reading start (the left edge in
|
|
3794
|
+
* LTR, the right in RTL); above it when there is no room below and more above; held inside the viewport with a margin;
|
|
3795
|
+
* and the transform-origin AT the anchor, so the panel grows from the control that opened it (Emil 47) — even when the
|
|
3796
|
+
* clamp moved it sideways.
|
|
3797
|
+
*
|
|
3798
|
+
* Lives in the main entry: nothing server-side places a panel, and the date picker (now) and the floating family (M5)
|
|
3799
|
+
* are DOM runtimes of the main entry. Pure — no DOM read here: the caller measures, this decides, the caller writes.
|
|
3800
|
+
*/
|
|
3801
|
+
interface FloatingRect {
|
|
3802
|
+
top: number;
|
|
3803
|
+
left: number;
|
|
3804
|
+
width: number;
|
|
3805
|
+
height: number;
|
|
3806
|
+
}
|
|
3807
|
+
interface FloatingSize {
|
|
3808
|
+
width: number;
|
|
3809
|
+
height: number;
|
|
3810
|
+
}
|
|
3811
|
+
interface FloatingViewport {
|
|
3812
|
+
width: number;
|
|
3813
|
+
height: number;
|
|
3814
|
+
}
|
|
3815
|
+
declare enum FloatingSide {
|
|
3816
|
+
Below = "below",
|
|
3817
|
+
Above = "above"
|
|
3818
|
+
}
|
|
3819
|
+
interface FloatingOptions {
|
|
3820
|
+
/** Space between the anchor and the panel. */
|
|
3821
|
+
gap?: number;
|
|
3822
|
+
/** Space the panel always keeps from the viewport's edges. */
|
|
3823
|
+
margin?: number;
|
|
3824
|
+
/** Right-to-left: the panel lines up with the anchor's right edge. */
|
|
3825
|
+
rtl?: boolean;
|
|
3826
|
+
}
|
|
3827
|
+
interface FloatingPlacement {
|
|
3828
|
+
top: number;
|
|
3829
|
+
left: number;
|
|
3830
|
+
side: FloatingSide;
|
|
3831
|
+
/** A CSS transform-origin in the panel's own box, pointing at the anchor's reading-start corner. */
|
|
3832
|
+
origin: string;
|
|
3833
|
+
}
|
|
3834
|
+
/** Emil's popover spacing: close enough to read as the control's, clear of its focus ring. */
|
|
3835
|
+
declare const FLOATING_GAP = 8;
|
|
3836
|
+
/** The viewport margin — a panel never touches the screen's edge. */
|
|
3837
|
+
declare const FLOATING_MARGIN = 12;
|
|
3838
|
+
/** Where `panel` goes beside `anchor` inside `viewport`. */
|
|
3839
|
+
declare function placeFloating(anchor: FloatingRect, panel: FloatingSize, viewport: FloatingViewport, options?: FloatingOptions): FloatingPlacement;
|
|
3840
|
+
|
|
3841
|
+
export { A11yAttribute, A11yTrait, ACCESSIBLE_NAME_TYPES, AOSService, ARIA_CURRENT_PAGE, BACKDROP_TWIN_KEY, BACKDROP_WHOLE_KEY, BREAKPOINTS, Breakpoint, BreakpointQueryKind, BuilderButtonComponent, BuilderDividerComponent, BuilderHeadingComponent, BuilderIconComponent, BuilderImageComponent, BuilderLinkComponent, BuilderSpacerComponent, ButtonBlockComponent, CALENDAR_CLOSING_ATTRIBUTE, CALENDAR_DESIGN_ATTRIBUTE, CALENDAR_SHEET_QUERY, COMPONENT_STATE_SELECTOR, CONTAINER_HTML_TAGS, CONTEXT_ACTION_TYPES, CURRENT_LINK_TYPES, CalendarClass, CardComponent, ClientGalleryComponent, ClientListComponent, ClientListItemComponent, ClientRepeaterComponent, ClientSliderContainerComponent, ClientSliderSlideComponent, ComponentInstanceRegistryService, ComponentState, ContainerComponent, ContextStore, DECORATIVE_TYPES, DEFAULT_GALLERY_SCHEDULER, DEFAULT_INTERACTION_EASING, DEFAULT_PAGE_TRANSITION, DEFAULT_PAGE_TRANSITION_DURATION, DEFAULT_PAGE_TRANSITION_EASING, DEFAULT_PAGE_TRANSITION_PERSPECTIVE, DEFAULT_PHOSPHOR_WEIGHT, DEFAULT_WIDTH_BY_TYPE, DIALOG_CLOSE_ABOVE_ATTRIBUTE, DIALOG_NODE_TYPE, DatePickerRuntime, DeclarationContext, EASING_KEYWORDS, EASING_TOKENS, ENTRANCE_ACTION_TYPES, ENTRANCE_FALLBACK_CSS, ENTRANCE_NOSCRIPT_CSS, ENTRANCE_PRESTATE_ATTRIBUTE, EXIT_ACTION_TYPES, EasingKeyword, EasingToken, FLOATING_GAP, FLOATING_MARGIN, FloatingSide, FormRenderState, FormRuntimeService, GALLERY_EFFECTS, GALLERY_EFFECT_DESCRIPTORS, GalleryLoop, HOVER_DEFAULT_TRANSITION_TRAITS, HOVER_MEDIA_QUERY, HOVER_STATES, INTERACTION_ANIMATION_ID, INTERACTION_HIDDEN_ATTRIBUTE, IOX_BUILDER_EVENTS, IOX_FORM_MESSAGES, IOX_FORM_NAVIGATOR, IOX_FORM_TRANSPORT, IS_PREVIEW, IoxAnimateContainer, IoxAosDirective, IoxAosModule, IoxBuilderComponentsModule, IoxComponentRegistryService, IoxDialogComponent, IoxFieldComponent, IoxFormComponent, IoxFormErrorComponent, IoxFormSuccessComponent, IoxPageComponent, IoxPageModule, IoxSubmitButtonComponent, IoxUiModule, IoxVideoComponent, LAST_EMITTED_STATES, LEGACY_DIRECTION_KEY, LEGACY_HOVER_TRANSITION_TRAITS, LEGACY_SWIPER_CONTROLS, LinkedContainerComponent, MANAGED_A11Y_ATTRIBUTES, MAX_LINES_KEY, NAMED_GROUP_ROLES, NO_PAGE_TRANSITION, ON_STATE_ROLES, OUTER_STYLE_PROPS, PAGE_STYLE_TOKENS, PAGE_TOKEN_FALLBACKS, PAGE_TRANSITION_CATEGORIES, PAGE_TRANSITION_PRESETS, PART_CLASS_NAMES, PART_PAGINATION_MODIFIER, PHONE_TRANSITION_QUERY, PIPE_DESCRIPTORS, PIPE_REGISTRY, PageScrollProvider, PageStyleField, PageStyleSource, PointerKind, REDUCED_MOTION_QUERY, RELATIONAL_STATE_PSEUDO, RevealActionType, SCROLLED_ATTRIBUTE, SCROLLED_STATE_ROLE, SCROLLED_THRESHOLD_PX, SCROLL_EASINGS, SELF_PLAYING_TRIGGERS, SHAKE_DURATION_MS, SHAKE_EASING, SHAKE_KEYFRAMES, SLIDER_INPUTS_ATTRIBUTE, SLIDER_INPUT_NAMES, STATE_PSEUDO_CLASS, STRUCTURAL_STATES, SUPPRESSED_STYLE_PROPS_BY_TYPE, SWIPER_A11Y_OPTIONS, SWIPER_RESPONSIVE_TRAITS, SWIPER_TRIGGER_EVENTS, ScrollEasing, SectionComponent, SettleMode, StringFormRuntime, SwiperModuleName, TARGETED_STATE_SUFFIX, TEXT_ALIGN_KEY, TEXT_DIRECTION_KEY, TRANSITION_FEELS, TRANSITION_PROPERTY_KEY, TextAlign, TextBlockComponent, VALIDATION_STATES, VALIDATION_STATE_CLASS, VIRTUAL_TRAIT_GROUPS, VIRTUAL_TRAIT_KEYS, ViewPositionDirective, ViewPositionModule, VisibilityActionType, activeActions, animateAction, applyBindingPipes, applyFeel, attachDatePicker, attachDatePickers, attachStringForm, bootSlider, breakpointDef, breakpointForWidth, breakpointQueryFor, buildInteractionKeyframes, buildPartSelector, buildSwiperBreakpoints, buildTargetedStateSelector, buildTargetedSuffixSelector, buildTransitionTimeline, cascadeChain, clearInputOverride, clearOverride, closeAboveMediaQuery, collectContextSlotKeys, compileDeclarations, compilePageStyle, componentStatesFor, composeVirtualTraits, containerHtmlTag, contextActionEffect, contextSlotKeys, countOverrides, datePickerOf, declaredInputNames, decomposeBackdropFilter, defaultHoverTransitionTraits, defaultMessageResolver, deriveSeoFromContent, describePageStyle, describeSeoFields, dialogCloseAboveMinWidth, domHasSliderParts, effectiveActionType, effectiveTransitionId, entrancePreStateStyle, entranceStartsHidden, feelFor, fieldLanguage, finalKeyframe, framesFromLiveValue, gateHoverRule, getSeoValue, hasHoverState, hasOwnPageTransition, hasOwnTransition, initialSlotValues, isActionEnabled, isContextAction, isCubicBezier, isCurrentLink, isEasingToken, isExternalOrFragment, isGradientPaint, isHoverPointer, isHoverState, isInputOverriddenAt, isInteractionEasing, isLastEmittedStateKey, isOverriddenAt, isPressFeedback, isScrolled, isStructuralState, isValidSlotKey, isWholeBackdropSet, keyframePropertyName, keyframeStyleEntries, legacyEnterToTransition, mediaQueryFor, mergeSwiperBreakpoints, migrateLegacyDirection, migrateLegacyTextAlign, motionAllowed, nearestCommonAncestorId, needsAccessibleName, needsGroupName, nodeA11yAttributes, nodeCssId, nodeTraitValue, nodeUsesContext, normalizeAppPath, normalizeGalleryImage, normalizeIconClass, orderStatesForEmit, pageTransitionOf, parentBreakpoint, parseUrlList, partClassName, placeFloating, planPartRule, planResponsiveRules, planScroll, planStateRule, planSwiperOptions, playDualLayerTransition, playInteraction, prefersReducedMotion, renderDefaultDeclarations, resetPageStyleField, resetSeoField, resolveBoundValue, resolveContextValue, resolveGalleryEffect, resolveGalleryUrls, resolveInputChain, resolveInputs, resolveInteractionEasing, resolvePageTransition, resolvePath, resolveSeo, resolveStateStyles, resolveStyleProps, resolveToggleVisibility, resolveValueChain, rewriteViewportUnits, safeSetInput, serializeA11yAttributes, setDateFieldValue, setInputOverride, setOverride, setSeoAuto, setSeoBinding, setSeoOverride, setSeoValue, settleInteraction, settleModeFor, shakeElement, showCalendarDesign, sliderControlElements, sliderInputsFromProps, sliderInputsOf, splitOuterProps, splitPressFeedback, stateNamesIn, statePseudoClass, stateSelectorSuffix, stateTransitionProperties, stringFormRuntimeOf, stripSuppressedProps, swiperAutoplayAllowed, swiperLoopOptions, swiperModuleNames, syncNodeA11yAttributes, syncSubmitButtons, targetedStateSelector, transitionPropertyList, viewportTransitionContext, watchScrolled, withContextSlots, withStateTransitions, wrapInBreakpointQuery, wrapInMediaQuery };
|
|
3842
|
+
export type { A11yNodeSource, AnimateActionOptions, BoundValueSpec, BreakpointDef, ContextActionEffect, ContextActionLike, ContextItemRef, ContextSlotDefault, ContextValueSpec, ContextWriteScope, CurrentLinkOptions, DatePickerOptions, FloatingOptions, FloatingPlacement, FloatingRect, FloatingSize, FloatingViewport, FormMessageResolver, GalleryBoundSource, GalleryDurations, GalleryEffect, GalleryEffectDescriptor, GalleryImage, GalleryLoopOptions, GalleryLoopScheduler, GalleryLoopState, GallerySlideState, IBuilderEventEmitter, InputMap, InteractionKeyframe, IoxContextSlot, IoxPipe, MatchMediaHost, NodeA11yContext, OverrideBreakpoint, PageScrollStart, PageStyleFieldState, PageStyleOptions, PageStyleSettings, PageTransitionCategory, PageTransitionCategoryMeta, PageTransitionContext, PageTransitionOptions, PageTransitionPreset, PipeArgSpec, PipeContext, PipeDescriptor, PlannedPageTransition, PressAction, RegisteredField, ResolvedPageTransition, ResponsiveLayer, ResponsiveOverrides, ResponsiveRuleSet, RouteAnimationLike, ScrollPlanContext, ScrollSource, SeoDerivedContent, SeoFieldSource, SeoFieldState, SeoResolveContext, SetContextParams, SettleOptions, SliderBootOptions, SliderControlElements, SliderInputs, StateRulePlan, StateScope, StateStyleMap, StringFormOptions, StyleMap, StyleTreeNode, SwiperBreakpointMap, SwiperModuleFlags, SwiperPlan, SwiperPlanContext, ToggleableAction, TransitionFeel, TransitionPhase, TransitionPreviewLayers, TransitionTimelineInput, TransitionViewport, ValueSource, VirtualTraitGroup };
|
package/package.json
CHANGED
|
@@ -152,6 +152,8 @@ export function auditDesignContrast(rows: ReadonlyArray<DesignTokenLike>, mode:
|
|
|
152
152
|
...(e.current ? [['current', { ...ownStyle(e), ...e.current }] as [string, StyleMap]] : []),
|
|
153
153
|
// `on` (CC4a): the active tab, on every ground it can sit on.
|
|
154
154
|
...(e.on ? [['on', { ...ownStyle(e), ...e.on }] as [string, StyleMap]] : []),
|
|
155
|
+
// `selected` (premium N1): a chosen chip — its ink on its fill, its fill as its mark.
|
|
156
|
+
...(e.selected ? [['selected', { ...ownStyle(e), ...e.selected }] as [string, StyleMap]] : []),
|
|
155
157
|
];
|
|
156
158
|
const glyph = e.group === GLYPH_GROUP;
|
|
157
159
|
for (const [state, s] of states) {
|
|
@@ -165,6 +167,8 @@ export function auditDesignContrast(rows: ReadonlyArray<DesignTokenLike>, mode:
|
|
|
165
167
|
if (mark) check(e.id, 'on mark', parseCssColour(resolveIn(values, mark), ink), bgs, WCAG_AA_UI);
|
|
166
168
|
// CC4b: a Segmented option's mark IS its on fill (no border) — the fill against the ground it sits on.
|
|
167
169
|
else if (on?.['backgroundColor']) for (const f of fill) check(e.id, 'on mark', f, bgs, WCAG_AA_UI);
|
|
170
|
+
// A chosen chip's mark is its fill (its border is the same colour) — the contract's audit, 1:1.
|
|
171
|
+
if (state === 'selected' && (e.selected as StyleMap | undefined)?.['backgroundColor']) for (const f of fill) check(e.id, 'selected mark', f, bgs, WCAG_AA_UI);
|
|
168
172
|
// What a filled element HOLDS (inkScopes): a button's or a badge's icon reads its ink.
|
|
169
173
|
if (state === 'base' && INK_SCOPES.some(sc => sc.styles.includes(e.id))) {
|
|
170
174
|
check(e.id, 'icon', parseCssColour(resolveIn(inkScoped(values, e.id), iconColour), ink), under, WCAG_AA_UI);
|