@assure-one/design-system 1.35.0 → 1.37.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/README.md +52 -0
- package/codemods/README.md +155 -12
- package/codemods/lib/registry.mjs +5 -0
- package/codemods/transforms/cm-07-input-size.mjs +104 -0
- package/codemods/transforms/cm-08-search-select-to-combobox.mjs +236 -0
- package/codemods/transforms/cm-09-side-drawer-to-sheet.mjs +348 -0
- package/codemods/transforms/cm-10-date-picker-value-change.mjs +416 -0
- package/codemods/transforms/cm-13-tooltip-delay.mjs +99 -0
- package/codemods/transforms/cm-14-hidden-mirrors.mjs +2 -2
- package/dist/css/components.css +1 -1
- package/dist/css/legacy-aliases.css +25 -1
- package/dist/css/shadcn.css +2 -2
- package/dist/css/tailwind.css +9 -0
- package/dist/css/tokens.css +64 -38
- package/dist/design-system-provider-C8UlFe52.d.ts +549 -0
- package/dist/icons/index.d.ts +2 -2
- package/dist/icons/index.js +6 -2
- package/dist/icons/index.js.map +1 -1
- package/dist/{index-B3OiMlQv.d.ts → index-vztxMSfl.d.ts} +7 -4
- package/dist/index.d.ts +2259 -345
- package/dist/index.js +7229 -3057
- package/dist/index.js.map +1 -1
- package/dist/next/index.d.ts +20 -0
- package/dist/next/index.js +16 -0
- package/dist/next/index.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/{system-lyhOUTpa.d.ts → system-CyAVbHhM.d.ts} +17 -17
- package/dist/testing/index.cjs +133 -11
- package/dist/testing/index.d.cts +98 -2
- package/dist/testing/index.d.ts +98 -2
- package/dist/testing/index.js +132 -12
- package/dist/tokens/index.d.ts +1 -1
- package/dist/tokens/index.js +8 -8
- package/dist/tokens/index.js.map +1 -1
- package/docs/components.md +606 -0
- package/docs/components.registry.json +1604 -0
- package/docs/for-ai-agents.md +153 -0
- package/package.json +15 -3
|
@@ -33,7 +33,7 @@ declare const colors: {
|
|
|
33
33
|
readonly proDisabled: "#b7a7f3";
|
|
34
34
|
readonly proLine: "#7b5bd8";
|
|
35
35
|
readonly fgDisabled: "#a7a7ac";
|
|
36
|
-
readonly bgDisabled: "#
|
|
36
|
+
readonly bgDisabled: "#f1f2f6";
|
|
37
37
|
readonly successFg: "#1f7a3d";
|
|
38
38
|
readonly successBg: "#eaf6ee";
|
|
39
39
|
readonly successLine: "#c5e5cf";
|
|
@@ -58,7 +58,7 @@ declare const typography: {
|
|
|
58
58
|
readonly semibold: 600;
|
|
59
59
|
readonly bold: 700;
|
|
60
60
|
};
|
|
61
|
-
readonly ease: "cubic-bezier(0.
|
|
61
|
+
readonly ease: "cubic-bezier(0.25, 1, 0.5, 1)";
|
|
62
62
|
};
|
|
63
63
|
declare const radii: {
|
|
64
64
|
readonly btn: "7px";
|
|
@@ -69,14 +69,14 @@ declare const radii: {
|
|
|
69
69
|
readonly full: "9999px";
|
|
70
70
|
};
|
|
71
71
|
declare const shadows: {
|
|
72
|
-
readonly quiet: "0 1px
|
|
73
|
-
readonly card: "0 1px 2px rgba(16, 20, 36, 0.04), 0 4px
|
|
74
|
-
readonly pop: "0 0 0 1px rgba(16, 20, 36, 0.
|
|
72
|
+
readonly quiet: "0 1px 1px rgba(16, 20, 36, 0.03), 0 1px 3px rgba(16, 20, 36, 0.05)";
|
|
73
|
+
readonly card: "0 1px 2px rgba(16, 20, 36, 0.04), 0 2px 4px -2px rgba(16, 20, 36, 0.04), 0 8px 16px -6px rgba(16, 20, 36, 0.08)";
|
|
74
|
+
readonly pop: "0 0 0 1px rgba(16, 20, 36, 0.04), 0 2px 4px -1px rgba(16, 20, 36, 0.05), 0 6px 12px -3px rgba(16, 20, 36, 0.07), 0 16px 32px -8px rgba(16, 20, 36, 0.12)";
|
|
75
75
|
readonly focusRing: "0 0 0 2px #ffffff, 0 0 0 4px #6c42f8";
|
|
76
76
|
};
|
|
77
77
|
declare const overlays: {
|
|
78
|
-
readonly hover: "rgba(
|
|
79
|
-
readonly active: "rgba(
|
|
78
|
+
readonly hover: "rgba(16, 20, 36, 0.04)";
|
|
79
|
+
readonly active: "rgba(16, 20, 36, 0.07)";
|
|
80
80
|
};
|
|
81
81
|
declare const layout: {
|
|
82
82
|
readonly shellSidebarWidth: "200px";
|
|
@@ -115,7 +115,7 @@ declare const surfaces: {
|
|
|
115
115
|
};
|
|
116
116
|
declare const motion: {
|
|
117
117
|
readonly ease: {
|
|
118
|
-
readonly outQuart: "cubic-bezier(0.
|
|
118
|
+
readonly outQuart: "cubic-bezier(0.25, 1, 0.5, 1)";
|
|
119
119
|
readonly out: "cubic-bezier(0.16, 1, 0.3, 1)";
|
|
120
120
|
readonly in: "cubic-bezier(0.7, 0, 0.84, 0)";
|
|
121
121
|
readonly inOut: "cubic-bezier(0.65, 0, 0.35, 1)";
|
|
@@ -195,7 +195,7 @@ declare const reference: {
|
|
|
195
195
|
readonly proDisabled: "#b7a7f3";
|
|
196
196
|
readonly proLine: "#7b5bd8";
|
|
197
197
|
readonly fgDisabled: "#a7a7ac";
|
|
198
|
-
readonly bgDisabled: "#
|
|
198
|
+
readonly bgDisabled: "#f1f2f6";
|
|
199
199
|
readonly successFg: "#1f7a3d";
|
|
200
200
|
readonly successBg: "#eaf6ee";
|
|
201
201
|
readonly successLine: "#c5e5cf";
|
|
@@ -220,7 +220,7 @@ declare const reference: {
|
|
|
220
220
|
readonly semibold: 600;
|
|
221
221
|
readonly bold: 700;
|
|
222
222
|
};
|
|
223
|
-
readonly ease: "cubic-bezier(0.
|
|
223
|
+
readonly ease: "cubic-bezier(0.25, 1, 0.5, 1)";
|
|
224
224
|
};
|
|
225
225
|
readonly radii: {
|
|
226
226
|
readonly btn: "7px";
|
|
@@ -231,14 +231,14 @@ declare const reference: {
|
|
|
231
231
|
readonly full: "9999px";
|
|
232
232
|
};
|
|
233
233
|
readonly shadows: {
|
|
234
|
-
readonly quiet: "0 1px
|
|
235
|
-
readonly card: "0 1px 2px rgba(16, 20, 36, 0.04), 0 4px
|
|
236
|
-
readonly pop: "0 0 0 1px rgba(16, 20, 36, 0.
|
|
234
|
+
readonly quiet: "0 1px 1px rgba(16, 20, 36, 0.03), 0 1px 3px rgba(16, 20, 36, 0.05)";
|
|
235
|
+
readonly card: "0 1px 2px rgba(16, 20, 36, 0.04), 0 2px 4px -2px rgba(16, 20, 36, 0.04), 0 8px 16px -6px rgba(16, 20, 36, 0.08)";
|
|
236
|
+
readonly pop: "0 0 0 1px rgba(16, 20, 36, 0.04), 0 2px 4px -1px rgba(16, 20, 36, 0.05), 0 6px 12px -3px rgba(16, 20, 36, 0.07), 0 16px 32px -8px rgba(16, 20, 36, 0.12)";
|
|
237
237
|
readonly focusRing: "0 0 0 2px #ffffff, 0 0 0 4px #6c42f8";
|
|
238
238
|
};
|
|
239
239
|
readonly overlays: {
|
|
240
|
-
readonly hover: "rgba(
|
|
241
|
-
readonly active: "rgba(
|
|
240
|
+
readonly hover: "rgba(16, 20, 36, 0.04)";
|
|
241
|
+
readonly active: "rgba(16, 20, 36, 0.07)";
|
|
242
242
|
};
|
|
243
243
|
readonly layout: {
|
|
244
244
|
readonly shellSidebarWidth: "200px";
|
|
@@ -247,7 +247,7 @@ declare const reference: {
|
|
|
247
247
|
};
|
|
248
248
|
readonly motion: {
|
|
249
249
|
readonly ease: {
|
|
250
|
-
readonly outQuart: "cubic-bezier(0.
|
|
250
|
+
readonly outQuart: "cubic-bezier(0.25, 1, 0.5, 1)";
|
|
251
251
|
readonly out: "cubic-bezier(0.16, 1, 0.3, 1)";
|
|
252
252
|
readonly in: "cubic-bezier(0.7, 0, 0.84, 0)";
|
|
253
253
|
readonly inOut: "cubic-bezier(0.65, 0, 0.35, 1)";
|
|
@@ -556,4 +556,4 @@ declare const systemTokens: {
|
|
|
556
556
|
};
|
|
557
557
|
type SystemTokens = typeof systemTokens;
|
|
558
558
|
|
|
559
|
-
export { type ColorName as C, type ReferenceTokens as R, type SystemTokens as S, reference as a,
|
|
559
|
+
export { type ColorName as C, type ReferenceTokens as R, type SystemTokens as S, reference as a, spacing as b, colors as c, surfaces as d, systemTokens as e, breakpoints as f, iconSizes as i, layout as l, motion as m, overlays as o, radii as r, shadows as s, typography as t, zIndex as z };
|
package/dist/testing/index.cjs
CHANGED
|
@@ -312,14 +312,28 @@ function accessibleText(element) {
|
|
|
312
312
|
function isDisabled(element) {
|
|
313
313
|
return element.hasAttribute("disabled") || element.getAttribute("aria-disabled") === "true" || element.hasAttribute("data-disabled");
|
|
314
314
|
}
|
|
315
|
+
function isQueries(target) {
|
|
316
|
+
return typeof target.getByRole === "function";
|
|
317
|
+
}
|
|
315
318
|
function press(target, key) {
|
|
316
319
|
const view = target.ownerDocument.defaultView ?? window;
|
|
317
320
|
const init = { key, code: key === " " ? "Space" : key, bubbles: true, cancelable: true };
|
|
318
321
|
target.dispatchEvent(new view.KeyboardEvent("keydown", init));
|
|
319
322
|
target.dispatchEvent(new view.KeyboardEvent("keyup", init));
|
|
320
323
|
}
|
|
324
|
+
async function run(fn) {
|
|
325
|
+
const actEnvironment = globalThis.IS_REACT_ACT_ENVIRONMENT;
|
|
326
|
+
if (actEnvironment) {
|
|
327
|
+
await react.act(async () => {
|
|
328
|
+
await fn();
|
|
329
|
+
});
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
await fn();
|
|
333
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
334
|
+
}
|
|
321
335
|
async function flush() {
|
|
322
|
-
await
|
|
336
|
+
await run(async () => {
|
|
323
337
|
await Promise.resolve();
|
|
324
338
|
});
|
|
325
339
|
}
|
|
@@ -332,7 +346,7 @@ async function waitUntil(find, maxFlushes) {
|
|
|
332
346
|
return null;
|
|
333
347
|
}
|
|
334
348
|
function resolveTrigger(target, name, role) {
|
|
335
|
-
if (
|
|
349
|
+
if (isQueries(target)) {
|
|
336
350
|
if (name === void 0)
|
|
337
351
|
throw new Error(`A ${role} name is required when passing a query object.`);
|
|
338
352
|
return target.getByRole(role, { name });
|
|
@@ -350,8 +364,33 @@ function popupOf(trigger, role) {
|
|
|
350
364
|
}
|
|
351
365
|
return null;
|
|
352
366
|
}
|
|
367
|
+
function isTextControl(element) {
|
|
368
|
+
const tag = element.tagName;
|
|
369
|
+
return tag === "TEXTAREA" || tag === "INPUT" && !/^(checkbox|radio|file|button|submit|reset|image|hidden)$/i.test(
|
|
370
|
+
element.type
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
async function typeInto(control, text2, commit) {
|
|
374
|
+
const view = control.ownerDocument.defaultView ?? window;
|
|
375
|
+
const proto = control.tagName === "TEXTAREA" ? view.HTMLTextAreaElement.prototype : view.HTMLInputElement.prototype;
|
|
376
|
+
const setter = Object.getOwnPropertyDescriptor(proto, "value")?.set;
|
|
377
|
+
await run(() => {
|
|
378
|
+
control.focus();
|
|
379
|
+
if (setter) setter.call(control, text2);
|
|
380
|
+
else control.value = text2;
|
|
381
|
+
control.dispatchEvent(new view.Event("input", { bubbles: true }));
|
|
382
|
+
});
|
|
383
|
+
if (commit) {
|
|
384
|
+
await run(() => {
|
|
385
|
+
control.blur();
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
await flush();
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// src/testing/interactions.ts
|
|
353
392
|
async function selectOption(target, ...rest) {
|
|
354
|
-
const byQuery =
|
|
393
|
+
const byQuery = isQueries(target);
|
|
355
394
|
const label = byQuery ? rest[0] : void 0;
|
|
356
395
|
const option = byQuery ? rest[1] : rest[0];
|
|
357
396
|
const settings = (byQuery ? rest[2] : rest[1]) ?? {};
|
|
@@ -363,7 +402,7 @@ async function selectOption(target, ...rest) {
|
|
|
363
402
|
);
|
|
364
403
|
}
|
|
365
404
|
if (trigger.getAttribute("aria-expanded") !== "true") {
|
|
366
|
-
await
|
|
405
|
+
await run(() => {
|
|
367
406
|
trigger.focus();
|
|
368
407
|
press(trigger, "Enter");
|
|
369
408
|
});
|
|
@@ -378,16 +417,16 @@ async function selectOption(target, ...rest) {
|
|
|
378
417
|
const wanted = all.find((el) => matches(accessibleText(el), option));
|
|
379
418
|
if (!wanted) {
|
|
380
419
|
const available = all.map((el) => JSON.stringify(accessibleText(el))).join(", ");
|
|
381
|
-
await
|
|
420
|
+
await run(() => press(listbox, "Escape"));
|
|
382
421
|
throw new Error(
|
|
383
422
|
`selectOption: no option matches ${describe(option)}. Options: ${available || "(none)"}.`
|
|
384
423
|
);
|
|
385
424
|
}
|
|
386
425
|
if (isDisabled(wanted)) {
|
|
387
|
-
await
|
|
426
|
+
await run(() => press(listbox, "Escape"));
|
|
388
427
|
throw new Error(`selectOption: the option ${describe(option)} is disabled.`);
|
|
389
428
|
}
|
|
390
|
-
await
|
|
429
|
+
await run(() => {
|
|
391
430
|
wanted.focus();
|
|
392
431
|
press(wanted, "Enter");
|
|
393
432
|
});
|
|
@@ -396,7 +435,7 @@ async function selectOption(target, ...rest) {
|
|
|
396
435
|
throw new Error(`selectOption: the list stayed open after choosing ${describe(option)}.`);
|
|
397
436
|
}
|
|
398
437
|
async function openMenu(target, ...rest) {
|
|
399
|
-
const byQuery =
|
|
438
|
+
const byQuery = isQueries(target);
|
|
400
439
|
const name = byQuery ? rest[0] : void 0;
|
|
401
440
|
const settings = (byQuery ? rest[1] : rest[0]) ?? {};
|
|
402
441
|
const maxFlushes = settings.maxFlushes ?? 20;
|
|
@@ -407,7 +446,7 @@ async function openMenu(target, ...rest) {
|
|
|
407
446
|
);
|
|
408
447
|
}
|
|
409
448
|
if (trigger.getAttribute("aria-expanded") !== "true") {
|
|
410
|
-
await
|
|
449
|
+
await run(() => {
|
|
411
450
|
trigger.focus();
|
|
412
451
|
press(trigger, "ArrowDown");
|
|
413
452
|
});
|
|
@@ -445,21 +484,104 @@ async function openMenu(target, ...rest) {
|
|
|
445
484
|
const item = getItem(itemName);
|
|
446
485
|
if (isDisabled(item))
|
|
447
486
|
throw new Error(`openMenu: the item ${describe(itemName)} is disabled.`);
|
|
448
|
-
await
|
|
487
|
+
await run(() => {
|
|
449
488
|
item.focus();
|
|
450
489
|
press(item, "Enter");
|
|
451
490
|
});
|
|
452
491
|
await waitUntil(() => menu.isConnected ? null : true, maxFlushes);
|
|
453
492
|
},
|
|
454
493
|
async close() {
|
|
455
|
-
await
|
|
494
|
+
await run(() => press(menu, "Escape"));
|
|
456
495
|
await waitClosed("Escape");
|
|
457
496
|
}
|
|
458
497
|
};
|
|
459
498
|
}
|
|
460
499
|
|
|
500
|
+
// src/testing/helpers/fill-field.ts
|
|
501
|
+
var TEXT_ROLES = ["textbox", "spinbutton", "combobox"];
|
|
502
|
+
function resolveByLabel(queries, label) {
|
|
503
|
+
const errors = [];
|
|
504
|
+
for (const role of TEXT_ROLES) {
|
|
505
|
+
try {
|
|
506
|
+
return queries.getByRole(role, { name: label });
|
|
507
|
+
} catch (error) {
|
|
508
|
+
errors.push(error instanceof Error ? error.message : String(error));
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
throw new Error(
|
|
512
|
+
`fillField: no text control is labelled ${describe(label)} (looked for roles ${TEXT_ROLES.join(", ")}).
|
|
513
|
+
${errors[0] ?? ""}`
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
async function fillField(target, ...rest) {
|
|
517
|
+
const byQuery = isQueries(target);
|
|
518
|
+
const label = byQuery ? rest[0] : void 0;
|
|
519
|
+
const value = byQuery ? rest[1] : rest[0];
|
|
520
|
+
const settings = (byQuery ? rest[2] : rest[1]) ?? {};
|
|
521
|
+
const control = byQuery ? resolveByLabel(target, label) : target;
|
|
522
|
+
const name = label ?? accessibleText(control);
|
|
523
|
+
if (!isTextControl(control)) {
|
|
524
|
+
throw new Error(
|
|
525
|
+
`fillField: ${describe(name)} is a <${control.tagName.toLowerCase()}>, not a text input or textarea. Use selectOption for a Select and pickDate for a DatePicker.`
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
if (isDisabled(control)) throw new Error(`fillField: the control ${describe(name)} is disabled.`);
|
|
529
|
+
if (control.readOnly || control.getAttribute("aria-readonly") === "true") {
|
|
530
|
+
throw new Error(`fillField: the control ${describe(name)} is read-only.`);
|
|
531
|
+
}
|
|
532
|
+
await typeInto(control, value, settings.commit ?? true);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// src/testing/helpers/pick-date.ts
|
|
536
|
+
var ISO = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
537
|
+
var DEFAULT_PATTERN = "MM/DD/YYYY";
|
|
538
|
+
function looksLikePattern(text2) {
|
|
539
|
+
return !!text2 && /YYYY/.test(text2) && /MM/.test(text2) === /DD/.test(text2);
|
|
540
|
+
}
|
|
541
|
+
function formatIso(iso, pattern) {
|
|
542
|
+
const match = ISO.exec(iso);
|
|
543
|
+
if (!match) {
|
|
544
|
+
throw new Error(
|
|
545
|
+
`pickDate: expected an ISO date (YYYY-MM-DD), received ${JSON.stringify(iso)}.`
|
|
546
|
+
);
|
|
547
|
+
}
|
|
548
|
+
const [, year, month, day] = match;
|
|
549
|
+
return pattern.replace("YYYY", year).replace("MM", month).replace("DD", day);
|
|
550
|
+
}
|
|
551
|
+
async function pickDate(target, ...rest) {
|
|
552
|
+
const byQuery = isQueries(target);
|
|
553
|
+
const label = byQuery ? rest[0] : void 0;
|
|
554
|
+
const iso = byQuery ? rest[1] : rest[0];
|
|
555
|
+
const settings = (byQuery ? rest[2] : rest[1]) ?? {};
|
|
556
|
+
const input = byQuery ? target.getByRole("textbox", { name: label }) : target;
|
|
557
|
+
const name = label ?? accessibleText(input);
|
|
558
|
+
if (!isTextControl(input) || input.tagName !== "INPUT") {
|
|
559
|
+
throw new Error(
|
|
560
|
+
`pickDate: ${describe(name)} is not a DatePicker text input (a <${input.tagName.toLowerCase()}>).`
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
if (isDisabled(input))
|
|
564
|
+
throw new Error(`pickDate: the date picker ${describe(name)} is disabled.`);
|
|
565
|
+
if (input.readOnly) throw new Error(`pickDate: the date picker ${describe(name)} is read-only.`);
|
|
566
|
+
const placeholder = input.getAttribute("placeholder");
|
|
567
|
+
const pattern = settings.dateFormat ?? (looksLikePattern(placeholder) ? placeholder : DEFAULT_PATTERN);
|
|
568
|
+
const yearOnly = !/MM|DD/.test(pattern);
|
|
569
|
+
let display = "";
|
|
570
|
+
if (iso !== "") {
|
|
571
|
+
display = yearOnly ? formatIso(iso, "YYYY") : formatIso(iso, pattern);
|
|
572
|
+
}
|
|
573
|
+
await typeInto(input, display, true);
|
|
574
|
+
if (input.value !== display) {
|
|
575
|
+
throw new Error(
|
|
576
|
+
`pickDate: typed ${JSON.stringify(display)} into ${describe(name)} but it shows ${JSON.stringify(input.value)}. The picker's pattern is probably not ${JSON.stringify(pattern)}; pass { dateFormat } with the pattern the picker uses.`
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
461
581
|
exports.createToastRecorder = createToastRecorder;
|
|
582
|
+
exports.fillField = fillField;
|
|
462
583
|
exports.installDomPolyfills = installDomPolyfills;
|
|
463
584
|
exports.openMenu = openMenu;
|
|
585
|
+
exports.pickDate = pickDate;
|
|
464
586
|
exports.selectOption = selectOption;
|
|
465
587
|
exports.withAssureDesignSystem = withAssureDesignSystem;
|
package/dist/testing/index.d.cts
CHANGED
|
@@ -182,11 +182,22 @@ interface RoleQueries {
|
|
|
182
182
|
}
|
|
183
183
|
/** Text matcher: exact text (after trimming and collapsing whitespace) or a pattern. @experimental */
|
|
184
184
|
type TextMatch = string | RegExp;
|
|
185
|
-
/** Options for
|
|
185
|
+
/** Options for the interaction helpers. @experimental */
|
|
186
186
|
interface InteractionOptions {
|
|
187
187
|
/** How many render passes to wait for the popup to appear or close. Default 20. */
|
|
188
188
|
maxFlushes?: number;
|
|
189
189
|
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Interaction helpers that drive design-system components the way a keyboard
|
|
193
|
+
* user does, so tests do not encode Radix internals (ADR-014).
|
|
194
|
+
*
|
|
195
|
+
* They use only the DOM (roles, `aria-*`, keyboard events) and React's `act`,
|
|
196
|
+
* so they work with any renderer and any query library. This repository tests
|
|
197
|
+
* them against the real components; if a component's markup changes, those
|
|
198
|
+
* tests fail here rather than in a consumer.
|
|
199
|
+
*/
|
|
200
|
+
|
|
190
201
|
/**
|
|
191
202
|
* Open a design-system `Select` and choose an option by its visible text.
|
|
192
203
|
*
|
|
@@ -250,4 +261,89 @@ declare function openMenu(trigger: HTMLElement, options?: InteractionOptions): P
|
|
|
250
261
|
*/
|
|
251
262
|
declare function openMenu(queries: RoleQueries, name: TextMatch, options?: InteractionOptions): Promise<MenuHandle>;
|
|
252
263
|
|
|
253
|
-
|
|
264
|
+
/**
|
|
265
|
+
* `fillField` — type a value into a design-system text control found by its
|
|
266
|
+
* Field label (ADR-014, W4-26).
|
|
267
|
+
*/
|
|
268
|
+
|
|
269
|
+
/** Options for `fillField`. @experimental */
|
|
270
|
+
interface FillFieldOptions {
|
|
271
|
+
/**
|
|
272
|
+
* Blur the control after typing so controls that commit on blur
|
|
273
|
+
* (`NumberInput` formatting) settle. Default `true`; pass `false` to keep
|
|
274
|
+
* focus, for example before pressing Enter yourself.
|
|
275
|
+
*/
|
|
276
|
+
commit?: boolean;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Type `value` into a text control — `Input`, `Textarea`, `SearchInput`,
|
|
280
|
+
* `NumberInput`, a `DatePicker`'s text input — replacing what it holds.
|
|
281
|
+
*
|
|
282
|
+
* ```ts
|
|
283
|
+
* await fillField(screen, "Full name", "Ada Lovelace"); // control named by its Field label
|
|
284
|
+
* await fillField(screen.getByRole("textbox", { name: "Notes" }), "Late filing");
|
|
285
|
+
* ```
|
|
286
|
+
*
|
|
287
|
+
* The control is found by its accessible name, which inside a `<Field>` is
|
|
288
|
+
* the `Label` text. React's `onChange` fires once with the new value; the
|
|
289
|
+
* control's own masking or formatting applies as it would for a user. Throws
|
|
290
|
+
* when the control is disabled or read-only, or when nothing is labelled
|
|
291
|
+
* `label`.
|
|
292
|
+
*
|
|
293
|
+
* @experimental
|
|
294
|
+
*/
|
|
295
|
+
declare function fillField(control: HTMLElement, value: string, options?: FillFieldOptions): Promise<void>;
|
|
296
|
+
/**
|
|
297
|
+
* Type `value` into the text control whose accessible name is `label`, found
|
|
298
|
+
* through `queries` (for example Testing Library's `screen`).
|
|
299
|
+
*
|
|
300
|
+
* @experimental
|
|
301
|
+
*/
|
|
302
|
+
declare function fillField(queries: RoleQueries, label: TextMatch, value: string, options?: FillFieldOptions): Promise<void>;
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* `pickDate` — set a design-system `DatePicker` to an ISO date by typing into
|
|
306
|
+
* its masked text input (ADR-014, W4-26).
|
|
307
|
+
*/
|
|
308
|
+
|
|
309
|
+
/** Options for `pickDate`. @experimental */
|
|
310
|
+
interface PickDateOptions {
|
|
311
|
+
/**
|
|
312
|
+
* The picker's display pattern — `MM`, `DD` and `YYYY` around literal
|
|
313
|
+
* separators, as passed to `DatePicker`'s `dateFormat` — when the helper
|
|
314
|
+
* cannot read it from the input's placeholder (a custom `placeholder`).
|
|
315
|
+
* Default: the placeholder, else `"MM/DD/YYYY"`.
|
|
316
|
+
*/
|
|
317
|
+
dateFormat?: string;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Set a `DatePicker` to `iso` (`YYYY-MM-DD`) by typing the date into its text
|
|
321
|
+
* input in the picker's own display pattern. `""` clears it.
|
|
322
|
+
*
|
|
323
|
+
* ```ts
|
|
324
|
+
* await pickDate(screen, "Due date", "2025-03-14"); // input named by its Field label
|
|
325
|
+
* await pickDate(screen.getByRole("textbox", { name: "Due date" }), "2025-03-14");
|
|
326
|
+
* await pickDate(screen, "Fällig am", "2025-03-14", { dateFormat: "DD.MM.YYYY" });
|
|
327
|
+
* ```
|
|
328
|
+
*
|
|
329
|
+
* The pattern is read from the input's placeholder, which `DatePicker` sets to
|
|
330
|
+
* its pattern (`MM/DD/YYYY` for `en-US`, `DD.MM.YYYY` for `de-DE`, a custom
|
|
331
|
+
* `dateFormat`); pass `dateFormat` when the picker has its own placeholder. A
|
|
332
|
+
* year picker (`picker="year"`, placeholder `YYYY`) receives the year. The
|
|
333
|
+
* helper checks that the input shows the typed date afterwards, so a picker
|
|
334
|
+
* that masked it differently — a pattern mismatch — throws instead of
|
|
335
|
+
* submitting a wrong value. `onValueChange` / `onChange` fire and a `name`d
|
|
336
|
+
* picker updates its form value, as for a real user.
|
|
337
|
+
*
|
|
338
|
+
* @experimental
|
|
339
|
+
*/
|
|
340
|
+
declare function pickDate(input: HTMLElement, iso: string, options?: PickDateOptions): Promise<void>;
|
|
341
|
+
/**
|
|
342
|
+
* Set the `DatePicker` whose text input has the accessible name `label`
|
|
343
|
+
* (found through `queries`, for example Testing Library's `screen`) to `iso`.
|
|
344
|
+
*
|
|
345
|
+
* @experimental
|
|
346
|
+
*/
|
|
347
|
+
declare function pickDate(queries: RoleQueries, label: TextMatch, iso: string, options?: PickDateOptions): Promise<void>;
|
|
348
|
+
|
|
349
|
+
export { type AssureJestOptions, type DomPolyfill, type DomPolyfillOptions, type FillFieldOptions, type InteractionOptions, type JestConfigInput, type JestConfigLike, type MenuHandle, type PickDateOptions, type RecordedToast, type RecordedToastVariant, type RoleQueries, type TextMatch, type ToastRecorder, type ToastRecorderOptions, type WithAssureDesignSystem, createToastRecorder, fillField, installDomPolyfills, openMenu, pickDate, selectOption, withAssureDesignSystem };
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -182,11 +182,22 @@ interface RoleQueries {
|
|
|
182
182
|
}
|
|
183
183
|
/** Text matcher: exact text (after trimming and collapsing whitespace) or a pattern. @experimental */
|
|
184
184
|
type TextMatch = string | RegExp;
|
|
185
|
-
/** Options for
|
|
185
|
+
/** Options for the interaction helpers. @experimental */
|
|
186
186
|
interface InteractionOptions {
|
|
187
187
|
/** How many render passes to wait for the popup to appear or close. Default 20. */
|
|
188
188
|
maxFlushes?: number;
|
|
189
189
|
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Interaction helpers that drive design-system components the way a keyboard
|
|
193
|
+
* user does, so tests do not encode Radix internals (ADR-014).
|
|
194
|
+
*
|
|
195
|
+
* They use only the DOM (roles, `aria-*`, keyboard events) and React's `act`,
|
|
196
|
+
* so they work with any renderer and any query library. This repository tests
|
|
197
|
+
* them against the real components; if a component's markup changes, those
|
|
198
|
+
* tests fail here rather than in a consumer.
|
|
199
|
+
*/
|
|
200
|
+
|
|
190
201
|
/**
|
|
191
202
|
* Open a design-system `Select` and choose an option by its visible text.
|
|
192
203
|
*
|
|
@@ -250,4 +261,89 @@ declare function openMenu(trigger: HTMLElement, options?: InteractionOptions): P
|
|
|
250
261
|
*/
|
|
251
262
|
declare function openMenu(queries: RoleQueries, name: TextMatch, options?: InteractionOptions): Promise<MenuHandle>;
|
|
252
263
|
|
|
253
|
-
|
|
264
|
+
/**
|
|
265
|
+
* `fillField` — type a value into a design-system text control found by its
|
|
266
|
+
* Field label (ADR-014, W4-26).
|
|
267
|
+
*/
|
|
268
|
+
|
|
269
|
+
/** Options for `fillField`. @experimental */
|
|
270
|
+
interface FillFieldOptions {
|
|
271
|
+
/**
|
|
272
|
+
* Blur the control after typing so controls that commit on blur
|
|
273
|
+
* (`NumberInput` formatting) settle. Default `true`; pass `false` to keep
|
|
274
|
+
* focus, for example before pressing Enter yourself.
|
|
275
|
+
*/
|
|
276
|
+
commit?: boolean;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Type `value` into a text control — `Input`, `Textarea`, `SearchInput`,
|
|
280
|
+
* `NumberInput`, a `DatePicker`'s text input — replacing what it holds.
|
|
281
|
+
*
|
|
282
|
+
* ```ts
|
|
283
|
+
* await fillField(screen, "Full name", "Ada Lovelace"); // control named by its Field label
|
|
284
|
+
* await fillField(screen.getByRole("textbox", { name: "Notes" }), "Late filing");
|
|
285
|
+
* ```
|
|
286
|
+
*
|
|
287
|
+
* The control is found by its accessible name, which inside a `<Field>` is
|
|
288
|
+
* the `Label` text. React's `onChange` fires once with the new value; the
|
|
289
|
+
* control's own masking or formatting applies as it would for a user. Throws
|
|
290
|
+
* when the control is disabled or read-only, or when nothing is labelled
|
|
291
|
+
* `label`.
|
|
292
|
+
*
|
|
293
|
+
* @experimental
|
|
294
|
+
*/
|
|
295
|
+
declare function fillField(control: HTMLElement, value: string, options?: FillFieldOptions): Promise<void>;
|
|
296
|
+
/**
|
|
297
|
+
* Type `value` into the text control whose accessible name is `label`, found
|
|
298
|
+
* through `queries` (for example Testing Library's `screen`).
|
|
299
|
+
*
|
|
300
|
+
* @experimental
|
|
301
|
+
*/
|
|
302
|
+
declare function fillField(queries: RoleQueries, label: TextMatch, value: string, options?: FillFieldOptions): Promise<void>;
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* `pickDate` — set a design-system `DatePicker` to an ISO date by typing into
|
|
306
|
+
* its masked text input (ADR-014, W4-26).
|
|
307
|
+
*/
|
|
308
|
+
|
|
309
|
+
/** Options for `pickDate`. @experimental */
|
|
310
|
+
interface PickDateOptions {
|
|
311
|
+
/**
|
|
312
|
+
* The picker's display pattern — `MM`, `DD` and `YYYY` around literal
|
|
313
|
+
* separators, as passed to `DatePicker`'s `dateFormat` — when the helper
|
|
314
|
+
* cannot read it from the input's placeholder (a custom `placeholder`).
|
|
315
|
+
* Default: the placeholder, else `"MM/DD/YYYY"`.
|
|
316
|
+
*/
|
|
317
|
+
dateFormat?: string;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Set a `DatePicker` to `iso` (`YYYY-MM-DD`) by typing the date into its text
|
|
321
|
+
* input in the picker's own display pattern. `""` clears it.
|
|
322
|
+
*
|
|
323
|
+
* ```ts
|
|
324
|
+
* await pickDate(screen, "Due date", "2025-03-14"); // input named by its Field label
|
|
325
|
+
* await pickDate(screen.getByRole("textbox", { name: "Due date" }), "2025-03-14");
|
|
326
|
+
* await pickDate(screen, "Fällig am", "2025-03-14", { dateFormat: "DD.MM.YYYY" });
|
|
327
|
+
* ```
|
|
328
|
+
*
|
|
329
|
+
* The pattern is read from the input's placeholder, which `DatePicker` sets to
|
|
330
|
+
* its pattern (`MM/DD/YYYY` for `en-US`, `DD.MM.YYYY` for `de-DE`, a custom
|
|
331
|
+
* `dateFormat`); pass `dateFormat` when the picker has its own placeholder. A
|
|
332
|
+
* year picker (`picker="year"`, placeholder `YYYY`) receives the year. The
|
|
333
|
+
* helper checks that the input shows the typed date afterwards, so a picker
|
|
334
|
+
* that masked it differently — a pattern mismatch — throws instead of
|
|
335
|
+
* submitting a wrong value. `onValueChange` / `onChange` fire and a `name`d
|
|
336
|
+
* picker updates its form value, as for a real user.
|
|
337
|
+
*
|
|
338
|
+
* @experimental
|
|
339
|
+
*/
|
|
340
|
+
declare function pickDate(input: HTMLElement, iso: string, options?: PickDateOptions): Promise<void>;
|
|
341
|
+
/**
|
|
342
|
+
* Set the `DatePicker` whose text input has the accessible name `label`
|
|
343
|
+
* (found through `queries`, for example Testing Library's `screen`) to `iso`.
|
|
344
|
+
*
|
|
345
|
+
* @experimental
|
|
346
|
+
*/
|
|
347
|
+
declare function pickDate(queries: RoleQueries, label: TextMatch, iso: string, options?: PickDateOptions): Promise<void>;
|
|
348
|
+
|
|
349
|
+
export { type AssureJestOptions, type DomPolyfill, type DomPolyfillOptions, type FillFieldOptions, type InteractionOptions, type JestConfigInput, type JestConfigLike, type MenuHandle, type PickDateOptions, type RecordedToast, type RecordedToastVariant, type RoleQueries, type TextMatch, type ToastRecorder, type ToastRecorderOptions, type WithAssureDesignSystem, createToastRecorder, fillField, installDomPolyfills, openMenu, pickDate, selectOption, withAssureDesignSystem };
|