@astryxdesign/core 0.7.2 → 0.7.3-canary.b1e1936
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Selector/SelectorOption.d.ts.map +1 -1
- package/dist/Selector/SelectorOption.js +1 -0
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +11 -2
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +14 -2
- package/dist/astryx.css +1 -0
- package/package.json +4 -4
- package/src/BottomSheet/BottomSheet.spec.md +13 -6
- package/src/BottomSheet/BottomSheetSwitcher.spec.md +121 -51
- package/src/DateRangeInput/DateRangeInput.spec.md +13 -13
- package/src/Selector/Selector.spec.md +11 -11
- package/src/Selector/Selector.test.tsx +16 -0
- package/src/Selector/SelectorOption.tsx +4 -0
- package/src/Slider/Slider.spec.md +11 -11
- package/src/Table/Table.spec.md +2 -0
- package/src/Table/plugins/infiniteScroll/useTableInfiniteScroll.spec.md +244 -0
- package/src/Table/plugins/virtualization/useTableVirtualization.spec.md +266 -0
- package/src/Tokenizer/Tokenizer.spec.md +28 -28
- package/src/Tooltip/__tests__/TooltipHoverBridge.a11y.chromium.spec.ts +74 -0
- package/src/Tooltip/useTooltip.test.tsx +23 -0
- package/src/Tooltip/useTooltip.tsx +22 -9
- package/src/Typeahead/Typeahead.test.tsx +89 -0
- package/src/Typeahead/Typeahead.tsx +15 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectorOption.d.ts","sourceRoot":"","sources":["../../src/Selector/SelectorOption.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAErC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAiB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"SelectorOption.d.ts","sourceRoot":"","sources":["../../src/Selector/SelectorOption.tsx"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAErC,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAiB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AAkBtD,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAE5B;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IAExB;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAE9B;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IAEvB;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,KAAK,EACL,WAAW,EACX,MAAM,EACN,UAAU,EACV,MAAM,EACN,SAAS,EACT,KAAK,GACN,EAAE,mBAAmB,+BAoBrB;yBA7Be,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTooltip.d.ts","sourceRoot":"","sources":["../../src/Tooltip/useTooltip.tsx"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,WAAW,EACjB,MAAM,OAAO,CAAC;AAEf,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AA2ClC;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE9D;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AAEpD,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAEnC;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAEnC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,GAAG,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAE9B;;;OAGG;IACH,WAAW,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAEtC;;;;OAIG;IACH,cAAc,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAEzC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;;;;OAOG;IACH,aAAa,EAAE,CACb,QAAQ,EAAE,SAAS,EACnB,KAAK,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,aAAa,CAAC,KAC5C,SAAS,CAAC;CAChB;AAyBD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,cAAmB,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"useTooltip.d.ts","sourceRoot":"","sources":["../../src/Tooltip/useTooltip.tsx"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,WAAW,EACjB,MAAM,OAAO,CAAC;AAEf,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AA2ClC;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE9D;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AAEpD,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAEnC;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAEnC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,GAAG,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAE9B;;;OAGG;IACH,WAAW,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAEtC;;;;OAIG;IACH,cAAc,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAEzC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;;;;OAOG;IACH,aAAa,EAAE,CACb,QAAQ,EAAE,SAAS,EACnB,KAAK,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,aAAa,CAAC,KAC5C,SAAS,CAAC;CAChB;AAyBD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,cAAmB,GAAG,aAAa,CAqYtE"}
|
|
@@ -221,15 +221,24 @@ export function useTooltip(options = {}) {
|
|
|
221
221
|
}
|
|
222
222
|
scheduleShow();
|
|
223
223
|
}, [isTouchPointerRef, scheduleShow]);
|
|
224
|
-
const handleMouseLeave = useCallback(
|
|
224
|
+
const handleMouseLeave = useCallback(event => {
|
|
225
225
|
// On touch the synthesized mouseleave arrives with the next tap elsewhere,
|
|
226
226
|
// which the outside-tap dismissal already handles — and handling it here
|
|
227
227
|
// too would close the tooltip behind the tap-open bookkeeping's back.
|
|
228
228
|
if (isTouchPointerRef.current) {
|
|
229
229
|
return;
|
|
230
230
|
}
|
|
231
|
+
// Leaving straight onto the tooltip: the surface's onMouseEnter already
|
|
232
|
+
// ran, because React dispatches it from the mouseout that precedes this
|
|
233
|
+
// mouseleave, so a hide scheduled now would never be cancelled. The
|
|
234
|
+
// surface's own mouse leave schedules the hide instead.
|
|
235
|
+
const next = event.relatedTarget;
|
|
236
|
+
const surface = next == null ? null : next.ownerDocument?.getElementById(layerId);
|
|
237
|
+
if (surface != null && surface.contains(next)) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
231
240
|
scheduleHide();
|
|
232
|
-
}, [isTouchPointerRef, scheduleHide]);
|
|
241
|
+
}, [isTouchPointerRef, layerId, scheduleHide]);
|
|
233
242
|
const handleFocusIn = useCallback(e => {
|
|
234
243
|
if (!isEnabled) {
|
|
235
244
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Typeahead.d.ts","sourceRoot":"","sources":["../../src/Typeahead/Typeahead.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"Typeahead.d.ts","sourceRoot":"","sources":["../../src/Typeahead/Typeahead.tsx"],"names":[],"mappings":"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"}
|
|
@@ -285,12 +285,24 @@ export function Typeahead({
|
|
|
285
285
|
}
|
|
286
286
|
}, [onChange]);
|
|
287
287
|
|
|
288
|
-
// Handle clear (explicit X button on token)
|
|
288
|
+
// Handle clear (explicit X button on token). Edit mode copied the label into
|
|
289
|
+
// the base's query, and the base only resets that query on a selection, so
|
|
290
|
+
// clearing the value has to empty it the way entering edit mode filled it
|
|
291
|
+
// (#7038): a native set plus a synthetic input event, which reaches the
|
|
292
|
+
// base's own change handler and its onChangeQuery.
|
|
289
293
|
const handleClear = useCallback(() => {
|
|
294
|
+
const input = inputRef.current;
|
|
295
|
+
if (input && input.value !== '') {
|
|
296
|
+
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')?.set;
|
|
297
|
+
nativeInputValueSetter?.call(input, '');
|
|
298
|
+
input.dispatchEvent(new Event('input', {
|
|
299
|
+
bubbles: true
|
|
300
|
+
}));
|
|
301
|
+
}
|
|
290
302
|
setIsEditing(false);
|
|
291
303
|
setEditingValue(null);
|
|
292
304
|
onChange(null);
|
|
293
|
-
|
|
305
|
+
input?.focus();
|
|
294
306
|
}, [onChange]);
|
|
295
307
|
|
|
296
308
|
// Handle Escape during edit mode — restore token
|
package/dist/astryx.css
CHANGED
|
@@ -79,6 +79,7 @@
|
|
|
79
79
|
:root, .x1qqxm5o{--astryx-press-alpha:0;}
|
|
80
80
|
:root, .xafi2nm{--border-width:1px;}
|
|
81
81
|
:root, .xj0fimd{--color-accent:light-dark(#0064E0, #2694FE);--color-accent-muted:light-dark(#0082FB33, #0082FB3F);--color-on-accent:light-dark(#FFFFFF, #FFFFFF);--color-neutral:light-dark(rgba(5, 54, 89, 0.1), rgba(223, 226, 229, 0.2));--color-background-surface:light-dark(#FFFFFF, #1F1F22);--color-background-body:light-dark(#F1F4F7, #111112);--color-overlay:light-dark(#01122866, #11111299);--color-overlay-hover:light-dark(#0536590C, #FFFFFF0C);--color-overlay-pressed:light-dark(#05365919, #FFFFFF19);--color-background-muted:light-dark(#0536590C, #1111127F);--color-text-primary:light-dark(#0A1317, #DFE2E5);--color-text-secondary:light-dark(#4E606F, #AAAFB5);--color-text-disabled:light-dark(#A4B0BC, #6F747C);--color-text-accent:light-dark(#0064E0, #3E9EFB);--color-on-dark:light-dark(#FFFFFF, #FFFFFF);--color-on-light:light-dark(#000000, #000000);--color-icon-accent:light-dark(#0064E0, #2694FE);--color-icon-primary:light-dark(#0A1317, #DFE2E5);--color-icon-secondary:light-dark(#4E606F, #AAAFB5);--color-icon-disabled:light-dark(#A4B0BC, #6F747C);--color-background-card:light-dark(#FFFFFF, #1F1F22);--color-background-popover:light-dark(#FFFFFF, #28292C);--color-background-inverted:light-dark(#0A1317, #FFFFFF);--color-background-error-inverted:light-dark(#AA071E, #E3193B);--color-success:light-dark(#0D8626, #0D8626);--color-success-muted:light-dark(#0B991F33, #0B991F3F);--color-on-success:light-dark(#FFFFFF, #FFFFFF);--color-error:light-dark(#E3193B, #F5394F);--color-error-muted:light-dark(#E3193B33, #F5394F3F);--color-on-error:light-dark(#FFFFFF, #FFFFFF);--color-warning:light-dark(#E9AF08, #F2C00B);--color-warning-muted:light-dark(#E2A40033, #E2A4003F);--color-on-warning:light-dark(#0A1317, #0A1317);--color-border:light-dark(#05365919, #F2F4F619);--color-border-emphasized:light-dark(#CCD3DB, #494D53);--color-skeleton:light-dark(#CCD3DB, #5A5E66);--color-track:light-dark(#CCD3DB, #5A5E66);--color-shadow:light-dark(rgba(5, 54, 89, 0.1), rgba(0, 0, 0, 0.3));--color-tint-hover:light-dark(black, white);--color-background-blue:light-dark(#0171E333, #0171E333);--color-border-blue:light-dark(#0064E0, #2694FE);--color-icon-blue:light-dark(#0064E0, #2694FE);--color-text-blue:light-dark(#042F97, #AFD7FF);--color-background-cyan:light-dark(#03A7D733, #03A7D733);--color-border-cyan:light-dark(#089DD0, #0171A4);--color-icon-cyan:light-dark(#00ACC1, #26C6DA);--color-text-cyan:light-dark(#014975, #A1EEF9);--color-background-gray:light-dark(#0A131733, #666A724C);--color-border-gray:light-dark(#647685, #748695);--color-icon-gray:light-dark(#4E606F, #AAAFB5);--color-text-gray:light-dark(#0A1317, #E7EAED);--color-background-green:light-dark(#24BB5E33, #24BB5E33);--color-border-green:light-dark(#0D8626, #0B991F);--color-icon-green:light-dark(#0D8626, #26A756);--color-text-green:light-dark(#09441F, #A5F690);--color-background-orange:light-dark(#F2790233, #F2790233);--color-border-orange:light-dark(#EB6E00, #B34A01);--color-icon-orange:light-dark(#E9690B, #FB8C00);--color-text-orange:light-dark(#6B2203, #FDB876);--color-background-pink:light-dark(#E638B333, #E638B333);--color-border-pink:light-dark(#F351C0, #C02294);--color-icon-pink:light-dark(#C2185B, #EC407A);--color-text-pink:light-dark(#650053, #FEADE3);--color-background-purple:light-dark(#7952FF33, #7952FF33);--color-border-purple:light-dark(#9081FF, #7340FE);--color-icon-purple:light-dark(#5B08D8, #7952FF);--color-text-purple:light-dark(#3E0697, #B3B0FE);--color-background-red:light-dark(#E3193B33, #E3193B33);--color-border-red:light-dark(#E3193B, #F5394F);--color-icon-red:light-dark(#D31130, #E3193B);--color-text-red:light-dark(#7B0210, #FFB2B8);--color-background-teal:light-dark(#0DB7AF33, #0DB7AF33);--color-border-teal:light-dark(#08A3A3, #08767D);--color-icon-teal:light-dark(#009688, #26A69A);--color-text-teal:light-dark(#083943, #40DCCD);--color-background-yellow:light-dark(#E2A40033, #E2A40033);--color-border-yellow:light-dark(#C58600, #B47700);--color-icon-yellow:light-dark(#FBC02D, #FFEE58);--color-text-yellow:light-dark(#753F07, #FBCE03);}
|
|
82
|
+
:root, .x7j7z01{--color-data-categorical-blue:light-dark(#0171E3, #0171E3);--color-data-categorical-orange:light-dark(#EB6E00, #EB6E00);--color-data-categorical-purple:light-dark(#6B1EFD, #6B1EFD);--color-data-categorical-green:light-dark(#0B991F, #0B991F);--color-data-categorical-pink:light-dark(#F351C0, #F351C0);--color-data-categorical-cyan:light-dark(#0171A4, #0171A4);--color-data-categorical-red:light-dark(#F5394F, #F5394F);--color-data-categorical-teal:light-dark(#08A3A3, #08A3A3);--color-data-categorical-brown:light-dark(#965E03, #965E03);--color-data-categorical-indigo:light-dark(#6F8AFF, #6F8AFF);--color-data-neutral:light-dark(#8494A3, #8C939B);--color-data-blue-5:light-dark(#02165E, #02165E);--color-data-blue-4:light-dark(#004CBC, #004CBC);--color-data-blue-3:light-dark(#2694FE, #2694FE);--color-data-blue-2:light-dark(#78BEFF, #78BEFF);--color-data-blue-1:light-dark(#DBECFF, #DBECFF);--color-data-shamrock-5:light-dark(#0B603D, #0B603D);--color-data-shamrock-4:light-dark(#138546, #138546);--color-data-shamrock-3:light-dark(#24BB5E, #24BB5E);--color-data-shamrock-2:light-dark(#8EF7AA, #8EF7AA);--color-data-shamrock-1:light-dark(#D6FEE4, #D6FEE4);--color-data-orange-5:light-dark(#A13F04, #A13F04);--color-data-orange-4:light-dark(#D66100, #D66100);--color-data-orange-3:light-dark(#FD9537, #FD9537);--color-data-orange-2:light-dark(#FDB876, #FDB876);--color-data-orange-1:light-dark(#FFE6CF, #FFE6CF);--color-data-pink-5:light-dark(#8E1073, #8E1073);--color-data-pink-4:light-dark(#D123A1, #D123A1);--color-data-pink-3:light-dark(#F989D3, #F989D3);--color-data-pink-2:light-dark(#FEADE3, #FEADE3);--color-data-pink-1:light-dark(#FCE3F4, #FCE3F4);--color-data-purple-5:light-dark(#3E0697, #3E0697);--color-data-purple-4:light-dark(#6B1EFD, #6B1EFD);--color-data-purple-3:light-dark(#9081FF, #9081FF);--color-data-purple-2:light-dark(#B3B0FE, #B3B0FE);--color-data-purple-1:light-dark(#E8E8FB, #E8E8FB);--color-data-red-5:light-dark(#9D0519, #9D0519);--color-data-red-4:light-dark(#D31130, #D31130);--color-data-red-3:light-dark(#FB7D87, #FB7D87);--color-data-red-2:light-dark(#FFB2B8, #FFB2B8);--color-data-red-1:light-dark(#FEE4E6, #FEE4E6);--color-data-teal-5:light-dark(#08767D, #08767D);--color-data-teal-4:light-dark(#0C9293, #0C9293);--color-data-teal-3:light-dark(#0DB7AF, #0DB7AF);--color-data-teal-2:light-dark(#6CE6D8, #6CE6D8);--color-data-teal-1:light-dark(#D7FCF8, #D7FCF8);--color-data-yellow-5:light-dark(#8A5001, #8A5001);--color-data-yellow-4:light-dark(#D69804, #D69804);--color-data-yellow-3:light-dark(#FBCE03, #FBCE03);--color-data-yellow-2:light-dark(#FCEC85, #FCEC85);--color-data-yellow-1:light-dark(#FDF6BA, #FDF6BA);--color-data-gray-5:light-dark(#25363F, #333338);--color-data-gray-4:light-dark(#5D6C7B, #666A72);--color-data-gray-3:light-dark(#AFB9C4, #B2B8BE);--color-data-gray-2:light-dark(#CCD3DB, #D0D3D6);--color-data-gray-1:light-dark(#F1F4F7, #F2F4F6);}
|
|
82
83
|
:root, .x14lkjui{--duration-fast-min:130ms;--duration-fast:175ms;--duration-fast-max:230ms;--duration-medium-min:310ms;--duration-medium:410ms;--duration-medium-max:550ms;--duration-slow-min:730ms;--duration-slow:975ms;--duration-slow-max:1300ms;}
|
|
83
84
|
:root, .xf09i69{--ease-standard:cubic-bezier(0.24, 1, 0.4, 1);}
|
|
84
85
|
:root, .xzxs3qz{--focus-outline-width:2px;--focus-outline-style:solid;--focus-outline-color:var(--color-accent);--focus-outline-offset:3px;}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/core",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3-canary.b1e1936",
|
|
4
4
|
"displayName": "Astryx Core",
|
|
5
5
|
"description": "The component library. Accessible, themeable React components with built-in spacing, dark mode, and StyleX styling.",
|
|
6
6
|
"author": "Meta Open Source",
|
|
@@ -792,6 +792,8 @@
|
|
|
792
792
|
"react-dom": ">=19.0.0"
|
|
793
793
|
},
|
|
794
794
|
"devDependencies": {
|
|
795
|
+
"@astryxdesign/a11y-spec": "0.7.3-canary.b1e1936",
|
|
796
|
+
"@astryxdesign/cli": "0.7.3-canary.b1e1936",
|
|
795
797
|
"@babel/cli": "^7.29.7",
|
|
796
798
|
"@babel/core": "^7.29.7",
|
|
797
799
|
"@babel/preset-react": "^7.29.7",
|
|
@@ -802,9 +804,7 @@
|
|
|
802
804
|
"@testing-library/jest-dom": "^6.6.0",
|
|
803
805
|
"@testing-library/react": "^16.3.2",
|
|
804
806
|
"@types/babel__core": "^7.20.5",
|
|
805
|
-
"tailwindcss": "^4.3.2"
|
|
806
|
-
"@astryxdesign/a11y-spec": "0.0.0",
|
|
807
|
-
"@astryxdesign/cli": "0.7.2"
|
|
807
|
+
"tailwindcss": "^4.3.2"
|
|
808
808
|
},
|
|
809
809
|
"dependencies": {
|
|
810
810
|
"intl-messageformat": "^11.2.9"
|
|
@@ -15,6 +15,7 @@ verified_by:
|
|
|
15
15
|
packages/core/src/BottomSheet/BottomSheet.test.tsx,
|
|
16
16
|
packages/core/src/BottomSheet/BottomSheetPanel.test.tsx,
|
|
17
17
|
packages/core/src/BottomSheet/BottomSheetKeyboard.test.tsx,
|
|
18
|
+
packages/core/src/BottomSheet/__tests__/BottomSheetNativeModal.a11y.browser.spec.ts,
|
|
18
19
|
packages/core/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts,
|
|
19
20
|
apps/storybook/stories/BottomSheet.stories.tsx,
|
|
20
21
|
scripts/check-knowledge.mjs,
|
|
@@ -93,14 +94,17 @@ Consumer migration instructions belong in consumer docs and release notes.
|
|
|
93
94
|
- The Content area's container padding, published per
|
|
94
95
|
`architecture:container-padding`.
|
|
95
96
|
- Standalone sheet presentation, including its optional native-dialog Scrim.
|
|
97
|
+
- The native dialog every sheet renders, standalone or switcher-managed
|
|
98
|
+
(`component:BottomSheetSwitcher` DEC-1's decided structure).
|
|
96
99
|
|
|
97
100
|
**Does not own / non-goals**
|
|
98
101
|
|
|
99
102
|
- Caller-provided content rendered inside the Content area.
|
|
100
103
|
- A separate target for Content area, Handle, or Scrim; none exists on current
|
|
101
104
|
`main`.
|
|
102
|
-
-
|
|
103
|
-
participates in
|
|
105
|
+
- The presentation lifecycle of its dialog and the flow's scrim ownership when
|
|
106
|
+
the sheet participates in a BottomSheetSwitcher — owned by BottomSheetSwitcher
|
|
107
|
+
(`component:BottomSheetSwitcher` DEC-1's decided structure).
|
|
104
108
|
- Shared layer hosting or dismissal policy.
|
|
105
109
|
|
|
106
110
|
## Public concepts
|
|
@@ -128,8 +132,10 @@ in `BottomSheet.doc.mjs`.
|
|
|
128
132
|
- A standalone modal sheet renders Sheet panel, Content area, Handle, and Scrim.
|
|
129
133
|
- A standalone non-modal sheet renders Sheet panel, Content area, and Handle
|
|
130
134
|
without a Scrim.
|
|
131
|
-
- A switcher-managed sheet renders the same panel anatomy while
|
|
132
|
-
BottomSheetSwitcher
|
|
135
|
+
- A switcher-managed sheet renders the same panel anatomy in its own dialog while
|
|
136
|
+
BottomSheetSwitcher coordinates that dialog's lifecycle and the flow's one Scrim
|
|
137
|
+
(`component:BottomSheetSwitcher` DEC-1's decided structure, not shipped
|
|
138
|
+
anatomy).
|
|
133
139
|
|
|
134
140
|
### Transformation and precedence order
|
|
135
141
|
|
|
@@ -184,7 +190,7 @@ a decision that they must remain unthemeable.
|
|
|
184
190
|
},
|
|
185
191
|
"Scrim": {
|
|
186
192
|
"none": {
|
|
187
|
-
"reason": "reachability-gap: No BottomSheet public target reaches the native dialog backdrop or switcher-
|
|
193
|
+
"reason": "reachability-gap: No BottomSheet public target reaches the native dialog backdrop, standalone or switcher-coordinated."
|
|
188
194
|
}
|
|
189
195
|
}
|
|
190
196
|
}
|
|
@@ -210,7 +216,8 @@ a decision that they must remain unthemeable.
|
|
|
210
216
|
| ------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- | --------------------------------- |
|
|
211
217
|
| FR1 | `BottomSheet.test.tsx` render, content, Handle, and scrim behavior suites | Modal, non-modal, and switcher presentations | Removing a documented part fails existing content, structure, or dismissal assertions. | `audit:BottomSheet/anatomy` |
|
|
212
218
|
| FR2 | Panel target assertion, source inspection, and theming target inventories | Sheet panel, Content area, Handle, and Scrim | Removing the panel target or documenting an unshipped child target fails evidence or inventory. | `audit:BottomSheet/theming` |
|
|
213
|
-
| FR3, AR1–AR2 | `BottomSheetKeyboard.test.tsx`; `BottomSheetKeyboard.a11y.browser.spec.ts`; open Storybook stories | fitting/overflow, plain text, usable/unusable/dynamic descendants, focus | Missing/duplicate keyboard access, stale ownership, focus movement, or broken content-box layout fails. | `audit:BottomSheet/accessibility` |
|
|
219
|
+
| FR3, AR1–AR2 | `BottomSheetKeyboard.test.tsx`; `BottomSheetKeyboard.a11y.browser.spec.ts`; open Storybook stories | fitting/overflow, plain text, usable/unusable/dynamic descendants, focus | Missing/duplicate keyboard access, stale ownership, focus movement, or broken content-box layout fails. | `audit:BottomSheet/accessibility` |
|
|
220
|
+
| Layout evidence | `BottomSheetPanel.test.tsx` | Floating Handle and scrolling Content area | Reordering or merging the stable parts fails existing panel structure and style assertions. | `audit:BottomSheet/anatomy` |
|
|
214
221
|
| FR4 | `BottomSheetPanel.test.tsx` container padding tests; `derivedVarRegistry.test.ts` | default, `padding` prop, theme `padding`, lone padded Section child | The published inset differs from the applied padding, or a lone padded Section changes geometry. | `audit:BottomSheet/anatomy` |
|
|
215
222
|
| Theming anatomy map | `scripts/check-knowledge.mjs` | Canonical anatomy and current target inventory | Missing, extra, prefixed, stale, or multiply assigned mappings fail repository validation. | `audit:BottomSheet/theming` |
|
|
216
223
|
|
|
@@ -13,6 +13,7 @@ review_triggers: [public-api, behavior, layout, theming, accessibility]
|
|
|
13
13
|
verified_by:
|
|
14
14
|
[
|
|
15
15
|
packages/core/src/BottomSheet/BottomSheetSwitcher.test.tsx,
|
|
16
|
+
packages/core/src/BottomSheet/__tests__/BottomSheetNativeModal.a11y.browser.spec.ts,
|
|
16
17
|
apps/storybook/stories/BottomSheetSwitcher.stories.tsx,
|
|
17
18
|
scripts/check-knowledge.mjs,
|
|
18
19
|
]
|
|
@@ -34,16 +35,21 @@ system_specs: [spec:AST-002, spec:AST-027]
|
|
|
34
35
|
## Intent
|
|
35
36
|
|
|
36
37
|
BottomSheetSwitcher coordinates a mutually exclusive sequence of BottomSheet
|
|
37
|
-
children
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
children. This draft records verified shipped and remediated behavior, and the
|
|
39
|
+
hosting requirements its decision log decides — each child presented in its own
|
|
40
|
+
native dialog — without adding a prop, changing a default, or settling the
|
|
41
|
+
open modality, identifier, or theming decisions below. A row whose review state
|
|
42
|
+
is "Owner decision" is the decided requirement, not shipped behavior; the
|
|
43
|
+
representative states that name a sheet's own dialog, the retained dialog, or
|
|
44
|
+
the flow wrapper describe DEC-1's decided structure in the same way.
|
|
40
45
|
|
|
41
46
|
## Compatibility and migration
|
|
42
47
|
|
|
43
48
|
- Released default preserved: `yes`
|
|
44
|
-
- Compatibility class:
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
- Compatibility class: nonbreaking; public props, defaults, exports, visual
|
|
50
|
+
output, and transition behavior stay unchanged. The element the `ref` resolves
|
|
51
|
+
to, and that it changes on a handoff, is implementation rather than public
|
|
52
|
+
contract (DEC-2)
|
|
47
53
|
- Controlled/uncontrolled behavior: `activeSheet` remains fully controlled
|
|
48
54
|
- Migration decision: none
|
|
49
55
|
|
|
@@ -53,10 +59,16 @@ Consumer migration instructions belong in consumer docs and release notes.
|
|
|
53
59
|
|
|
54
60
|
**Owns**
|
|
55
61
|
|
|
56
|
-
-
|
|
62
|
+
- The presentation lifecycle of every directly nested BottomSheet child's native
|
|
63
|
+
dialog: which is presented, retained during a handoff, or closed.
|
|
57
64
|
- Which child sheet is active, retained during a handoff, or hidden.
|
|
58
|
-
-
|
|
59
|
-
and
|
|
65
|
+
- Which sheet dialog hosts the flow (its ref, `id`, and dismissal
|
|
66
|
+
registration) and which paints the flow's one scrim, plus
|
|
67
|
+
Escape/platform-close routing and final focus return for the flow. Focus
|
|
68
|
+
containment is the native modal dialog's; the flow's one page scroll lock is
|
|
69
|
+
held for the whole modal flow (DEC-1).
|
|
70
|
+
- The flow wrapper: the isolated surface that orders non-modal sheet dialogs
|
|
71
|
+
locally (`spec:AST-027` FR2).
|
|
60
72
|
|
|
61
73
|
**Does not own / non-goals**
|
|
62
74
|
|
|
@@ -69,30 +81,30 @@ Consumer migration instructions belong in consumer docs and release notes.
|
|
|
69
81
|
|
|
70
82
|
## Public concepts
|
|
71
83
|
|
|
72
|
-
| Concept | Closed values or states | Meaning
|
|
73
|
-
| ------------------- | ---------------------------------------------------- |
|
|
74
|
-
| Active sheet | `null` or one nested BottomSheet `sheetId` | Selects the only interactive child, or closes the flow
|
|
75
|
-
| Shared presentation | `true` / `false` through `hasScrim` | Selects the current modal scrim-backed host or non-modal no-scrim host
|
|
76
|
-
| Child identity | Non-empty `sheetId` on each direct BottomSheet child | Associates controlled selection, labeling, purpose, and transition state with a child
|
|
77
|
-
| Dismissal request | `onActiveSheetChange(null)` | Reports an allowed implicit close without taking control from the caller
|
|
78
|
-
| Dialog surface | inherited dialog props plus `ref` and `onCancel` |
|
|
84
|
+
| Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability | Invalid-value behavior |
|
|
85
|
+
| ------------------- | ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | -------------------------------------- | ------------------------------------------------------------------------- | --------- | ------------------------------------------------------------------------------------------ |
|
|
86
|
+
| Active sheet | `null` or one nested BottomSheet `sheetId` | Selects the only interactive child, or closes the flow | All presentations | `null` is closed; the prop is required | `component:BottomSheetSwitcher` | released | A non-matching or duplicate id is not given a safe public fallback by the current contract |
|
|
87
|
+
| Shared presentation | `true` / `false` through `hasScrim` | Selects the current modal scrim-backed host or non-modal no-scrim host | Entire flow | `true` | `component:BottomSheetSwitcher` | released | Boolean only |
|
|
88
|
+
| Child identity | Non-empty `sheetId` on each direct BottomSheet child | Associates controlled selection, labeling, purpose, and transition state with a child | Direct nested BottomSheet children | none | `component:BottomSheet` | released | Empty ids warn and stay hidden; duplicate-id behavior is not specified |
|
|
89
|
+
| Dismissal request | `onActiveSheetChange(null)` | Reports an allowed implicit close without taking control from the caller | Escape/platform close, scrim click, or swipe according to active child purpose | none | `component:BottomSheetSwitcher`; `family:overlay-dismissal` owns ordering | released | The caller may retain its controlled value |
|
|
90
|
+
| Dialog surface | inherited dialog props plus `ref` and `onCancel` | Dialog props and handlers, `onCancel` included, reach every sheet dialog; `ref`, `id`, and `data-testid` resolve to the host dialog, which is never null for an object ref while a sheet is mounted (owner decision, DEC-2) | Entire flow | none | `component:BottomSheetSwitcher` | released | Component-owned semantics and handlers retain precedence |
|
|
79
91
|
|
|
80
92
|
## Behavioral and layout contract
|
|
81
93
|
|
|
82
94
|
Draft requirements identify their basis so observed code is not mistaken for an
|
|
83
95
|
intentional decision. This draft cannot clear the gaps it records.
|
|
84
96
|
|
|
85
|
-
| ID | Candidate invariant
|
|
86
|
-
| --- |
|
|
87
|
-
| FR1 | Zero or one child sheet is interactive for each controlled `activeSheet` value; all other children are hidden or retained inert and `aria-hidden` during a transition.
|
|
88
|
-
| FR2 |
|
|
89
|
-
| FR3 | During a handoff, the entering sheet is above the retained sheet. A taller retained sheet aligns down to a shorter entering sheet, and the retained sheet fades only after required transform motion completes.
|
|
90
|
-
| FR4 | Closing retains the outgoing sheet through its exit, then closes the dialog. A modal flow restores focus to the element captured when that modal flow opened.
|
|
91
|
-
| FR5 | `hasScrim=true` uses `showModal()`, a native backdrop, focus containment, and page scroll lock. `hasScrim=false` uses `show()` without a backdrop or scroll lock and leaves the page interactive.
|
|
92
|
-
| FR6 | The active child purpose governs implicit dismissal: `info` allows Escape, scrim click, and swipe; `form` allows Escape; `required` blocks all three and exposes `alertdialog`.
|
|
93
|
-
| FR7 | While visible, the switcher participates in `family:overlay-dismissal`; one Escape or platform close request reaches only the topmost present layer, and descendants receive a deeper logical layer scope.
|
|
94
|
-
| FR8 | A stale gesture from an outgoing sheet cannot change the
|
|
95
|
-
| FR9 | The switcher forwards
|
|
97
|
+
| ID | Candidate invariant | Basis | Draft review state |
|
|
98
|
+
| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
99
|
+
| FR1 | Zero or one child sheet is interactive for each controlled `activeSheet` value; all other children are hidden or retained inert and `aria-hidden` during a transition. | Current source, docs, and tests | Verified shipped behavior |
|
|
100
|
+
| FR2 | Each child sheet owns one native dialog. Opening a sheet presents its dialog once; a handoff presents the entering sheet's dialog above the retained one and closes the retained dialog only after its panel has faded. Returning to a sheet whose dialog is still open beneath a newer one re-presents it so the interactive sheet is the topmost layer. | DEC-1 | Owner decision |
|
|
101
|
+
| FR3 | During a handoff, the entering sheet is above the retained sheet. A taller retained sheet aligns down to a shorter entering sheet, and the retained sheet fades only after required transform motion completes. | Current source and transition tests | Verified shipped behavior; exact visual treatment remains human-reviewed |
|
|
102
|
+
| FR4 | Closing retains the outgoing sheet through its exit, then closes the dialog. A modal flow restores focus to the element captured when that modal flow opened. | Current source and focus tests | Verified shipped behavior |
|
|
103
|
+
| FR5 | `hasScrim=true` uses `showModal()`, a native backdrop, and native focus containment, and locks page scroll: the page does not scroll while a modal flow is presented; the lock is held continuously across a handoff, never released and re-acquired between steps; it still holds beneath a `Dialog` opened from a step; it is released after the flow's exit (owner decision, DEC-1). `hasScrim=false` uses `show()` without a backdrop or scroll lock and leaves the page interactive (verified current behavior). In a non-modal flow the sheet dialogs order themselves with local values inside the switcher's isolated flow wrapper (owner decision, DEC-1); the page-level value that wrapper carries remains a `spec:AST-027` conformance gap. | DEC-1; `spec:AST-027` FR2, FR4, FR8 | Modal host and the wrapper's local ordering: owner decision. Non-modal `show()` host: verified current behavior. The wrapper's page-level value remains a `spec:AST-027` conformance gap |
|
|
104
|
+
| FR6 | The active child purpose governs implicit dismissal: `info` allows Escape, scrim click, and swipe; `form` allows Escape; `required` blocks all three and exposes `alertdialog`. | Current BottomSheet docs and switcher tests | Verified shipped behavior |
|
|
105
|
+
| FR7 | While visible, the switcher participates in `family:overlay-dismissal`; one Escape or platform close request reaches only the topmost present layer, and descendants receive a deeper logical layer scope. | `family:overlay-dismissal` and the audit regression test | Settled remediation in this audit |
|
|
106
|
+
| FR8 | One backdrop paints the flow's scrim at a time: the retained sheet's dialog keeps it through a handoff and the entering dialog takes it over without a fade when the retained dialog closes. A stale gesture from an outgoing sheet cannot change the flow's scrim, and unmounting a retained sheet cannot keep its dialog open or the flow's modal layer held. | DEC-1; current tests | Owner decision |
|
|
107
|
+
| FR9 | The switcher forwards neutral dialog attributes, styling inputs, and composed handlers, `onCancel` included, to every sheet dialog, so a handler fires for whichever sheet dialog raises the event; renders `id` and `data-testid` on the host dialog only, so each appears once in the document; attaches its ref to the host dialog; and preserves its owned ARIA and dismissal behavior. An object ref's `current` is never `null` while a sheet is mounted. A callback ref follows React's semantics on a handoff: a cleanup it returned runs when it detaches from the old host; a callback ref without a cleanup is called with `null` on detach, then with the new host. | DEC-1, DEC-2; `architecture:public-component-api` INV8 | Owner decision |
|
|
96
108
|
|
|
97
109
|
### Allowed variation
|
|
98
110
|
|
|
@@ -104,14 +116,17 @@ intentional decision. This draft cannot clear the gaps it records.
|
|
|
104
116
|
|
|
105
117
|
### Representative states
|
|
106
118
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
|
111
|
-
|
|
|
112
|
-
|
|
|
113
|
-
|
|
|
114
|
-
|
|
|
119
|
+
The states below describe DEC-1's decided structure where they name a sheet's
|
|
120
|
+
own dialog, the retained dialog, or the flow wrapper.
|
|
121
|
+
|
|
122
|
+
| State | Required invariant | Allowed variation |
|
|
123
|
+
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
124
|
+
| Closed | Every sheet dialog is closed and no child is interactive. | Child panels may remain mounted but hidden. |
|
|
125
|
+
| First open | Matching child is visible and interactive in its own dialog. | Child-owned height and content. |
|
|
126
|
+
| Handoff | Entering child is interactive in its own dialog; retained child's dialog stays open, inert, and hidden from accessibility APIs until it fades, and keeps painting the one scrim. | Alignment offset depends on measured panel geometry. |
|
|
127
|
+
| Closing | Outgoing child is retained inert while exit motion completes; modal focus and scroll ownership remain until close. | Theme-controlled duration. |
|
|
128
|
+
| Modal | Native modal host, backdrop, native focus containment, and the page scroll lock are active. | Active child's `purpose` controls implicit dismissal. |
|
|
129
|
+
| Non-modal | Native non-modal host has no backdrop or scroll lock and background content remains interactive. | The current clipping/stacking limitation is a conformance gap, not an allowed exception. |
|
|
115
130
|
|
|
116
131
|
### Transformation and precedence order
|
|
117
132
|
|
|
@@ -124,8 +139,12 @@ intentional decision. This draft cannot clear the gaps it records.
|
|
|
124
139
|
|
|
125
140
|
### Performance and resources
|
|
126
141
|
|
|
127
|
-
- **PR1 — One
|
|
128
|
-
|
|
142
|
+
- **PR1 — One painted scrim.** In a modal flow, at rest exactly one sheet
|
|
143
|
+
dialog is presented; during a handoff two are, with one backdrop painted.
|
|
144
|
+
Native modality holds across a modal flow's child handoffs because a sheet
|
|
145
|
+
dialog is modal throughout, and the one page scroll lock is held for the
|
|
146
|
+
whole flow rather than per step. A non-modal flow paints no backdrop and
|
|
147
|
+
holds no lock.
|
|
129
148
|
- **PR2 — Stable child registration.** Parent rerenders and changing consumer ref
|
|
130
149
|
identities do not unregister a mounted child or cancel an active handoff.
|
|
131
150
|
|
|
@@ -141,11 +160,11 @@ intentional decision. This draft cannot clear the gaps it records.
|
|
|
141
160
|
|
|
142
161
|
## Design relationships
|
|
143
162
|
|
|
144
|
-
| Anatomy or state | Design requirement
|
|
145
|
-
| ---------------- |
|
|
146
|
-
| Shared dialog | Transparent host for the flow's interaction and accessibility boundary
|
|
147
|
-
| Sheet panels | Delegate visible panel, content, handle, and gesture presentation to BottomSheet
|
|
148
|
-
| Scrim | Optional native backdrop that dims and blocks the page in modal presentation
|
|
163
|
+
| Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
|
|
164
|
+
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | -------------- | ------------------ |
|
|
165
|
+
| Shared dialog | Transparent host for the flow's interaction and accessibility boundary; DEC-1 decides one such host per child sheet | Current source and public docs; DEC-1 for the per-sheet clause | Structural | FR2, FR5, AR1 |
|
|
166
|
+
| Sheet panels | Delegate visible panel, content, handle, and gesture presentation to BottomSheet | `component:BottomSheet` draft as observational context | Prominent | FR1, FR3 |
|
|
167
|
+
| Scrim | Optional native backdrop that dims and blocks the page in modal presentation; DEC-1 decides that one sheet dialog paints it at a time | Current source and public docs; DEC-1 for the one-painter clause | Supporting | FR5, FR8 |
|
|
149
168
|
|
|
150
169
|
### Theming anatomy
|
|
151
170
|
|
|
@@ -163,7 +182,7 @@ intentional decision. This draft cannot clear the gaps it records.
|
|
|
163
182
|
},
|
|
164
183
|
"Scrim": {
|
|
165
184
|
"none": {
|
|
166
|
-
"reason": "reachability-gap: The switcher-
|
|
185
|
+
"reason": "reachability-gap: The switcher-coordinated native backdrop paints the scrim but has no current public theming target."
|
|
167
186
|
}
|
|
168
187
|
}
|
|
169
188
|
}
|
|
@@ -183,17 +202,68 @@ intentional decision. This draft cannot clear the gaps it records.
|
|
|
183
202
|
|
|
184
203
|
## Verification map
|
|
185
204
|
|
|
186
|
-
| Contract | Verification
|
|
187
|
-
| ---------------- |
|
|
188
|
-
| FR1–FR4, FR8 | `BottomSheetSwitcher.test.tsx`
|
|
189
|
-
| FR5–FR7, AR1–AR3 | `BottomSheetSwitcher.test.tsx`;
|
|
190
|
-
| FR9 | `BottomSheetSwitcher.test.tsx`; export checks
|
|
191
|
-
| Theming anatomy | `scripts/check-knowledge.mjs`; theming tests
|
|
205
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
206
|
+
| ---------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
|
|
207
|
+
| FR1–FR4, FR8 | `BottomSheetSwitcher.test.tsx` | closed, first open, handoffs in either completion order, rapid replacement, unmount, close | A child becomes interactive at the wrong time, a retained child disappears early, a second backdrop paints, or a sheet dialog's lifecycle breaks. | `audit:BottomSheetSwitcher/behavior` |
|
|
208
|
+
| FR5–FR7, AR1–AR3 | `BottomSheetSwitcher.test.tsx`; `BottomSheetNativeModal.a11y.browser.spec.ts` | modal/non-modal, info/form/required, nested layer, IME, focus return, scroll lock in engines, non-modal local ordering | Modality, dismissal order, naming, inertness, scroll lock, or focus behavior diverges, or a sheet dialog takes a page-level z-index. | `audit:BottomSheetSwitcher/accessibility` |
|
|
209
|
+
| FR9 | `BottomSheetSwitcher.test.tsx`; export checks | ref across open/handoff/close/unmount, callback-ref cleanup, `id` once, DOM/ARIA/data/events, class, style, xstyle | A supported input is dropped or duplicated, an object ref is null while a sheet is mounted or skips a cleanup, or an input overrides component-owned semantics accidentally. | `audit:BottomSheetSwitcher/api` |
|
|
210
|
+
| Theming anatomy | `scripts/check-knowledge.mjs`; theming tests | dialog, delegated sheet panel, scrim | A non-painting host gains a target, a delegated panel loses its owner, or the scrim gap disappears without review. | `audit:BottomSheetSwitcher/theming` |
|
|
192
211
|
|
|
193
212
|
## Decision log
|
|
194
213
|
|
|
195
|
-
|
|
196
|
-
|
|
214
|
+
### DEC-1 — Each step owns its native dialog; the switcher coordinates
|
|
215
|
+
|
|
216
|
+
**Reference:** `component:BottomSheetSwitcher/DEC-1`
|
|
217
|
+
**Decider:** imdreamrunner, 2026-10-20
|
|
218
|
+
|
|
219
|
+
A switcher step is a BottomSheet with its own native dialog, presented and
|
|
220
|
+
closed like a standalone sheet, so one DOM shape serves standalone sheets and
|
|
221
|
+
switcher steps alike and the browser supplies modality per step: an inert
|
|
222
|
+
page, focus containment, `cancel` for Escape and the platform close, and the
|
|
223
|
+
backdrop. The switcher owns only what no single dialog can decide: which dialog
|
|
224
|
+
is presented, retained, or closed; the one scrim handed from the retained
|
|
225
|
+
dialog to the entering one without a fade; re-presenting a sheet that is still
|
|
226
|
+
open beneath a newer one when the flow returns to it; focus kept in the active
|
|
227
|
+
sheet when a retained dialog closes; focus returned to the flow's opener;
|
|
228
|
+
`cancel` gated by the active step's `purpose` through the shared dismissal
|
|
229
|
+
stack; and the flow's one page scroll lock, held from the moment a modal flow
|
|
230
|
+
is presented until after its exit, so a handoff between two open dialogs never
|
|
231
|
+
releases and re-acquires it. The switcher's one element is a flow wrapper with
|
|
232
|
+
no box in a modal flow and, in a non-modal flow, the isolated surface inside
|
|
233
|
+
which the sheet dialogs order themselves with local values.
|
|
234
|
+
Rejected: one switcher-owned dialog hosting every step as a panel, because a
|
|
235
|
+
step is then not a sheet and every standalone-sheet mechanism needs a second,
|
|
236
|
+
switcher-only implementation.
|
|
237
|
+
Rejected: a script focus trap on top of native containment, because the
|
|
238
|
+
browser already contains focus in a modal dialog and the trap fights its
|
|
239
|
+
inertness.
|
|
240
|
+
Rejected: a page-level `z-index` on a non-modal step's dialog, because
|
|
241
|
+
`spec:AST-027` FR4 forbids a new page band; the wrapper is the isolation owner.
|
|
242
|
+
|
|
243
|
+
### DEC-2 — The host dialog's identity is implementation, not contract
|
|
244
|
+
|
|
245
|
+
**Reference:** `component:BottomSheetSwitcher/DEC-2`
|
|
246
|
+
**Decider:** imdreamrunner, 2026-10-20
|
|
247
|
+
|
|
248
|
+
The `ref`, `id`, and `data-testid` of the switcher reach the dialog hosting
|
|
249
|
+
the flow: the active sheet's, the exiting sheet's through its exit, and, while
|
|
250
|
+
the flow is closed, the dialog that hosted it last or the first mounted
|
|
251
|
+
sheet's, so an object ref is never `null` while a sheet is mounted and the
|
|
252
|
+
identifying attributes appear once. Which element that is, and that it changes
|
|
253
|
+
on a handoff, is implementation. The released documentation (v0.7.1
|
|
254
|
+
`BottomSheetSwitcher.doc.mjs`) describes the ref as "Ref forwarded to the one
|
|
255
|
+
shared native dialog." and the switcher as "Its ref and shared DOM props
|
|
256
|
+
target that dialog." Code that copies `ref.current` once at mount keeps a
|
|
257
|
+
real `<dialog>`, but after a handoff that element may no longer be the host;
|
|
258
|
+
read `ref.current` at use time, or use a callback ref, to follow the flow. DOM
|
|
259
|
+
props and handlers given to the switcher (`className`, `style`, `onCancel`,
|
|
260
|
+
`onToggle`, `aria-*`, and the rest) reach every sheet dialog, with `id` and
|
|
261
|
+
`data-testid` on the host only, so a handler fires for whichever sheet dialog
|
|
262
|
+
raises the event. The owner rules this hosting — the moving host and the
|
|
263
|
+
per-dialog props alike — nonbreaking under `spec:AST-017` FR3 because no
|
|
264
|
+
visual output and no public API surface changes.
|
|
265
|
+
Rejected: classifying the moving ref as a breaking change, because no public
|
|
266
|
+
API, documented interaction, or visual output changes.
|
|
197
267
|
|
|
198
268
|
## Open questions
|
|
199
269
|
|
|
@@ -90,12 +90,12 @@ preset-list anatomy and its additive theming surface.
|
|
|
90
90
|
|
|
91
91
|
### Representative states
|
|
92
92
|
|
|
93
|
-
| State | Required invariant
|
|
94
|
-
| ----------------- |
|
|
95
|
-
| No presets | No preset group or preset-button target renders.
|
|
96
|
-
| Presets, no match | Every button carries the preset target with no selected state.
|
|
97
|
-
| Applied preset | The matching button carries `aria-current="true"` and the target's selected state.
|
|
98
|
-
| Disabled preset | A preset that violates an endpoint date constraint or a range-span constraint is
|
|
93
|
+
| State | Required invariant | Allowed variation |
|
|
94
|
+
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- |
|
|
95
|
+
| No presets | No preset group or preset-button target renders. | Calendar configuration |
|
|
96
|
+
| Presets, no match | Every button carries the preset target with no selected state. | Preset count and labels |
|
|
97
|
+
| Applied preset | The matching button carries `aria-current="true"` and the target's selected state. | Selected range |
|
|
98
|
+
| Disabled preset | A preset that violates an endpoint date constraint or a range-span constraint is disabled per `spec:AST-085` and carries the target's disabled state. | Constraint source |
|
|
99
99
|
|
|
100
100
|
### Transformation and precedence order
|
|
101
101
|
|
|
@@ -120,8 +120,8 @@ No new performance or resource constraint is introduced.
|
|
|
120
120
|
- **AR2 — Current state.** The applied preset remains exposed with
|
|
121
121
|
`aria-current="true"`; theme state reflection is additive.
|
|
122
122
|
- **AR3 — Disabled state.** A preset that violates an endpoint date constraint or
|
|
123
|
-
a range-span constraint
|
|
124
|
-
not replace that behavior.
|
|
123
|
+
a range-span constraint is disabled and stays focusable (`spec:AST-085`); theme
|
|
124
|
+
state reflection does not replace that behavior.
|
|
125
125
|
|
|
126
126
|
## Design relationships
|
|
127
127
|
|
|
@@ -172,11 +172,11 @@ No new performance or resource constraint is introduced.
|
|
|
172
172
|
|
|
173
173
|
## Verification map
|
|
174
174
|
|
|
175
|
-
| Contract | Verification
|
|
176
|
-
| ------------------- |
|
|
177
|
-
| FR1, FR2, AR1–AR3 | `DateRangeInput.test.tsx
|
|
178
|
-
| FR3, FR4 | `DateRangeInput.test.tsx`, `themingTargets.test.ts`, generated probe theme
|
|
179
|
-
| Theming anatomy map | `scripts/check-knowledge.mjs`
|
|
175
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
176
|
+
| ------------------- | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------- | ------------------------------ |
|
|
177
|
+
| FR1, FR2, AR1–AR3 | `DateRangeInput.test.tsx`; disabled-preset focusability (AR3) pending conformance | no match, applied preset, endpoint-invalid preset, span-invalid preset | Semantics or state attributes disappear | `audit:DateRangeInput/presets` |
|
|
178
|
+
| FR3, FR4 | `DateRangeInput.test.tsx`, `themingTargets.test.ts`, generated probe theme | group target, selected button, disabled button | Target class/state is missing, undocumented, or placed on the wrong element | `audit:DateRangeInput/theming` |
|
|
179
|
+
| Theming anatomy map | `scripts/check-knowledge.mjs` | all documented anatomy | Target ownership or anatomy names drift | `audit:DateRangeInput/theming` |
|
|
180
180
|
|
|
181
181
|
## Decision log
|
|
182
182
|
|