@astryxdesign/core 0.1.3 → 0.1.4-canary.02643db
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -0
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +29 -8
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +49 -20
- package/dist/Calendar/dayCellUtils.d.ts +67 -5
- package/dist/Calendar/dayCellUtils.d.ts.map +1 -1
- package/dist/Calendar/dayCellUtils.js +139 -18
- package/dist/CheckboxInput/CheckboxInput.d.ts +6 -1
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +7 -1
- package/dist/Code/Code.d.ts +15 -1
- package/dist/Code/Code.d.ts.map +1 -1
- package/dist/Code/Code.js +32 -2
- package/dist/Code/index.d.ts +1 -1
- package/dist/Code/index.d.ts.map +1 -1
- package/dist/CodeBlock/index.d.ts +1 -1
- package/dist/CodeBlock/index.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteEmpty.d.ts +1 -1
- package/dist/CommandPalette/CommandPaletteEmpty.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteEmpty.js +24 -4
- package/dist/ContextMenu/ContextMenu.d.ts +9 -1
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +6 -3
- package/dist/DateRangeInput/DateRangeInput.js +2 -2
- package/dist/DateTimeInput/DateTimeInput.d.ts +0 -5
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/Divider/Divider.d.ts +0 -22
- package/dist/Divider/Divider.d.ts.map +1 -1
- package/dist/Markdown/parser.d.ts +7 -0
- package/dist/Markdown/parser.d.ts.map +1 -1
- package/dist/Markdown/parser.js +300 -6
- package/dist/MultiSelector/MultiSelector.d.ts +7 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +10 -1
- package/dist/RadioList/RadioList.d.ts +7 -1
- package/dist/RadioList/RadioList.d.ts.map +1 -1
- package/dist/RadioList/RadioList.js +3 -1
- package/dist/RadioList/RadioListItem.d.ts.map +1 -1
- package/dist/RadioList/RadioListItem.js +6 -1
- package/dist/Selector/Selector.d.ts +6 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +9 -0
- package/dist/Slider/Slider.d.ts +6 -0
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +10 -1
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +1 -1
- package/dist/Switch/Switch.d.ts +6 -1
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +7 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +8 -1
- package/dist/Table/TableCell.d.ts.map +1 -1
- package/dist/Table/TableCell.js +73 -4
- package/dist/Table/index.d.ts +2 -0
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +1 -0
- package/dist/Table/plugins/rowExpansion/index.d.ts +3 -0
- package/dist/Table/plugins/rowExpansion/index.d.ts.map +1 -0
- package/dist/Table/plugins/rowExpansion/index.js +3 -0
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +90 -0
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -0
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +398 -0
- package/dist/Table/tableContextMenu.d.ts +5 -1
- package/dist/Table/tableContextMenu.d.ts.map +1 -1
- package/dist/Table/tableContextMenu.js +10 -3
- package/dist/Text/Text.d.ts +1 -1
- package/dist/Text/Text.d.ts.map +1 -1
- package/dist/Text/Text.js +4 -3
- package/dist/Text/text.stylex.d.ts +35 -0
- package/dist/Text/text.stylex.d.ts.map +1 -1
- package/dist/Text/text.stylex.js +52 -1
- package/dist/Tokenizer/Tokenizer.d.ts +6 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +10 -1
- package/dist/astryx.css +16 -0
- package/dist/astryx.umd.js +51 -49
- package/dist/astryx.umd.js.map +4 -4
- package/dist/docs-types.d.ts +12 -0
- package/dist/docs-types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/AspectRatio/AspectRatio.doc.mjs +1 -1
- package/src/Avatar/Avatar.doc.mjs +2 -2
- package/src/Button/Button.tsx +39 -6
- package/src/ButtonGroup/ButtonGroup.doc.mjs +1 -1
- package/src/Calendar/Calendar.test.tsx +106 -0
- package/src/Calendar/Calendar.tsx +59 -22
- package/src/Calendar/dayCellUtils.test.ts +306 -1
- package/src/Calendar/dayCellUtils.ts +206 -13
- package/src/Card/Card.doc.mjs +1 -1
- package/src/Chat/useChatNewMessages.test.tsx +4 -4
- package/src/CheckboxInput/CheckboxInput.doc.mjs +9 -1
- package/src/CheckboxInput/CheckboxInput.test.tsx +36 -0
- package/src/CheckboxInput/CheckboxInput.tsx +11 -0
- package/src/CheckboxList/CheckboxList.doc.mjs +1 -1
- package/src/Code/Code.test.tsx +54 -0
- package/src/Code/Code.tsx +48 -4
- package/src/Code/index.ts +1 -1
- package/src/CodeBlock/index.ts +1 -1
- package/src/CommandPalette/CommandPaletteEmpty.tsx +15 -1
- package/src/ContextMenu/ContextMenu.tsx +17 -1
- package/src/DateInput/DateInput.doc.mjs +6 -1
- package/src/DateRangeInput/DateRangeInput.doc.mjs +1 -1
- package/src/DateRangeInput/DateRangeInput.tsx +2 -2
- package/src/DateTimeInput/DateTimeInput.doc.mjs +1 -1
- package/src/DateTimeInput/DateTimeInput.tsx +1 -6
- package/src/Divider/Divider.tsx +1 -23
- package/src/DropdownMenu/DropdownMenu.test.tsx +5 -3
- package/src/EmptyState/EmptyState.doc.mjs +1 -1
- package/src/Field/Field.doc.mjs +1 -1
- package/src/FileInput/FileInput.doc.mjs +1 -1
- package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +0 -3
- package/src/Grid/Grid.doc.mjs +3 -3
- package/src/Layout/__tests__/edgeCompensation.test.tsx +72 -0
- package/src/Markdown/Markdown.test.tsx +23 -0
- package/src/Markdown/incremental.test.ts +36 -0
- package/src/Markdown/parser.test.ts +210 -0
- package/src/Markdown/parser.ts +301 -6
- package/src/MobileNav/MobileNav.doc.mjs +20 -0
- package/src/MultiSelector/MultiSelector.doc.mjs +14 -1
- package/src/MultiSelector/MultiSelector.test.tsx +33 -0
- package/src/MultiSelector/MultiSelector.tsx +20 -0
- package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
- package/src/RadioList/RadioList.doc.mjs +7 -1
- package/src/RadioList/RadioList.test.tsx +46 -0
- package/src/RadioList/RadioList.tsx +10 -1
- package/src/RadioList/RadioListItem.tsx +4 -0
- package/src/Section/Section.test.tsx +4 -10
- package/src/SegmentedControl/SegmentedControl.doc.mjs +1 -1
- package/src/Selector/Selector.doc.mjs +12 -1
- package/src/Selector/Selector.test.tsx +30 -0
- package/src/Selector/Selector.tsx +18 -0
- package/src/Slider/Slider.doc.mjs +14 -2
- package/src/Slider/Slider.test.tsx +30 -0
- package/src/Slider/Slider.tsx +20 -0
- package/src/Spinner/Spinner.tsx +1 -0
- package/src/Switch/Switch.doc.mjs +14 -2
- package/src/Switch/Switch.test.tsx +38 -0
- package/src/Switch/Switch.tsx +12 -0
- package/src/TabList/TabList.doc.mjs +3 -3
- package/src/Table/BaseTable.tsx +9 -1
- package/src/Table/Table.test.tsx +23 -0
- package/src/Table/TableCell.tsx +87 -8
- package/src/Table/index.ts +5 -0
- package/src/Table/plugins/rowExpansion/index.ts +7 -0
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +155 -0
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +590 -0
- package/src/Table/tableContextMenu.test.tsx +27 -3
- package/src/Table/tableContextMenu.tsx +20 -2
- package/src/Table/useTablePagination.doc.mjs +4 -1
- package/src/Table/useTableRowExpansion.doc.mjs +80 -0
- package/src/Table/useTableSortable.doc.mjs +4 -1
- package/src/Text/Text.doc.mjs +2 -2
- package/src/Text/Text.test.tsx +11 -0
- package/src/Text/Text.tsx +4 -2
- package/src/Text/text.stylex.ts +41 -0
- package/src/TextArea/TextArea.doc.mjs +1 -1
- package/src/TextInput/TextInput.doc.mjs +1 -1
- package/src/TimeInput/TimeInput.doc.mjs +11 -6
- package/src/Tokenizer/Tokenizer.doc.mjs +14 -2
- package/src/Tokenizer/Tokenizer.test.tsx +33 -0
- package/src/Tokenizer/Tokenizer.tsx +19 -0
- package/src/Toolbar/Toolbar.test.tsx +1 -1
- package/src/Typeahead/BaseTypeahead.doc.mjs +10 -0
- package/src/Typeahead/Typeahead.doc.mjs +6 -1
- package/src/docs-types.ts +12 -0
- package/src/hooks/useKeyboardHint.doc.mjs +6 -6
package/dist/docs-types.d.ts
CHANGED
|
@@ -210,6 +210,11 @@ export interface ComponentEntry {
|
|
|
210
210
|
examples?: ExampleDoc[];
|
|
211
211
|
/** When true, this sub-component is excluded from the overview page. */
|
|
212
212
|
isHiddenFromOverview?: boolean;
|
|
213
|
+
/** Playground configuration for this specific component. Falls back to
|
|
214
|
+
* the directory doc's `playground` when omitted — declare one here when
|
|
215
|
+
* siblings must not share it (e.g. an overlay drawer whose toggle
|
|
216
|
+
* sub-component should not inherit `overlay: true`). */
|
|
217
|
+
playground?: PlaygroundConfig;
|
|
213
218
|
}
|
|
214
219
|
/**
|
|
215
220
|
* Code example for a component or sub-component.
|
|
@@ -377,6 +382,13 @@ export interface PlaygroundConfig {
|
|
|
377
382
|
/** Initial prop values for the playground preview.
|
|
378
383
|
* Keys are prop names. Values are primitives or ElementDescriptors. */
|
|
379
384
|
defaults?: Record<string, unknown>;
|
|
385
|
+
/** The component opens as a full-viewport overlay (e.g. via
|
|
386
|
+
* `dialog.showModal()`) and renders nothing inline while closed. The
|
|
387
|
+
* interactive preview shows an open-trigger placeholder instead of an
|
|
388
|
+
* empty stage while `isOpen` is false, and lets the real overlay render
|
|
389
|
+
* when opened. Include `isOpen: false` in `defaults` so the preview can
|
|
390
|
+
* bridge `onOpenChange` back into playground state. */
|
|
391
|
+
overlay?: boolean;
|
|
380
392
|
/** Required parent wrapper for sub-components that depend on a parent
|
|
381
393
|
* context provider (e.g. `Tab` calls `useTabListContext()` and throws
|
|
382
394
|
* standalone). The preview wraps the component in this parent before
|
package/dist/docs-types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs-types.d.ts","sourceRoot":"","sources":["../src/docs-types.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,OAAO;IACtB;;yEAEqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;wCAOoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb;;;;6CAIyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB;;;8EAG0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,YAAY,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACpC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,aAAa;IAC5B;;gFAE4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;sBAMkB;IAClB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;;4EAIwE;IACxE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,WAAW,UAAU;IACzB;+DAC2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB;sEACkE;IAClE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;wEACoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY;IAC3B,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC7B;kDAC8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb;;iFAE6E;IAC7E,WAAW,EAAE,MAAM,CAAC;IACpB;8EAC0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,wEAAwE;IACxE,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IACxB,wDAAwD;IACxD,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,+DAA+D;IAC/D,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,kDAAkD;IAClD,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IACxB,wEAAwE;IACxE,oBAAoB,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"docs-types.d.ts","sourceRoot":"","sources":["../src/docs-types.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,OAAO;IACtB;;yEAEqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;wCAOoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb;;;;6CAIyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB;;;8EAG0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,YAAY,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACpC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,aAAa;IAC5B;;gFAE4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;sBAMkB;IAClB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;;4EAIwE;IACxE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,WAAW,UAAU;IACzB;+DAC2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB;sEACkE;IAClE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;wEACoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY;IAC3B,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC7B;kDAC8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb;;iFAE6E;IAC7E,WAAW,EAAE,MAAM,CAAC;IACpB;8EAC0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,wEAAwE;IACxE,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IACxB,wDAAwD;IACxD,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,+DAA+D;IAC/D,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,kDAAkD;IAClD,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IACxB,wEAAwE;IACxE,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;6DAGyD;IACzD,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC7B,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,QAAQ,EAAE,OAAO,CAAC;IAClB,mFAAmF;IACnF,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;mDAM+C;IAC/C,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,QAAQ;IACvB;;;;;;;;;yBASqB;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB;+EAC2E;IAC3E,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B;;wFAEoF;IACpF,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAAG,CAAC,MAAM,GAAG,iBAAiB,CAAC,EAAE,CAAC;CACxE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,MAAM,WAAW,gBAAgB;IAC/B;4EACwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC;;;;;4DAKwD;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE;QACR,qFAAqF;QACrF,SAAS,EAAE,MAAM,CAAC;QAClB,iFAAiF;QACjF,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACjC,CAAC;CACH;AAED;;;GAGG;AACH,UAAU,OAAO;IACf;kEAC8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;4DAMwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB;;;;iFAI6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;;iCAI6B;IAC7B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B;;;;wCAIoC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;yCAGqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;;;;;;;;wEAgBoE;IACpE,QAAQ,CAAC,EACL,QAAQ,GACR,MAAM,GACN,WAAW,GACX,SAAS,GACT,YAAY,GACZ,oBAAoB,GACpB,mBAAmB,GACnB,QAAQ,GACR,YAAY,GACZ,SAAS,GACT,cAAc,GACd,SAAS,CAAC;IACd;;;uEAGmE;IACnE,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;qEAEiE;IACjE,OAAO,CAAC,EAAE;QACR;;;;uEAI+D;QAC/D,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB;8EACsE;QACtE,OAAO,EAAE,aAAa,EAAE,CAAC;QACzB,iDAAiD;QACjD,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC;QACtB;;;;8BAIsB;QACtB,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;KACxB,CAAC;IACF;uCACmC;IACnC,KAAK,EAAE,QAAQ,CAAC;IAChB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IAExB;0EACsE;IACtE,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAmB,SAAQ,OAAO;IACjD,0CAA0C;IAC1C,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B;4EACwE;IACxE,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAkB,SAAQ,OAAO;IAChD;gFAC4E;IAC5E,UAAU,EAAE,CAAC,cAAc,GAAG,YAAY,CAAC,EAAE,CAAC;CAC/C;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC;IAC7D;;4EAEwE;IACxE,cAAc,EAAE,MAAM,CAAC;IACvB;yCACqC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB;;4EAEwE;IACxE,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,YAAY,GACpB,kBAAkB,GAClB,iBAAiB,GACjB,eAAe,CAAC;AAEpB;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uFAAuF;IACvF,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,oEAAoE;IACpE,KAAK,CAAC,EAAE;QACN,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;QAC/B,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;KAC5B,CAAC;IACF,4FAA4F;IAC5F,UAAU,CAAC,EAAE;QACX,8CAA8C;QAC9C,IAAI,EAAE,MAAM,CAAC;QACb;;;;+CAIuC;QACvC,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,uDAAuD;QACvD,WAAW,EAAE,MAAM,CAAC;QACpB,4CAA4C;QAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1C,wEAAwE;QACxE,oBAAoB,CAAC,EAAE,OAAO,CAAC;KAChC,EAAE,CAAC;CACL;AAMD;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,YAAY,GACpB;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,GAC7B;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,GAC1D;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAA;CAAC,GACpD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,GAAG,WAAW,GAAG,IAAI,GAAG,MAAM,CAAC;IAC/C,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,GACD;IACE;;;gEAG4D;IAC5D,IAAI,EAAE,WAAW,CAAC;IAClB,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEN;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,gBAAgB,GACxB,QAAQ,GACR,YAAY,GACZ,YAAY,GACZ,aAAa,GACb,UAAU,GACV,aAAa,GACb,cAAc,GACd,cAAc,GACd,aAAa,CAAC;AAElB;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB;;+DAE2D;IAC3D,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,YAAY;IAC3B,mFAAmF;IACnF,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B;;;gEAG4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,uBAAuB;IACtC,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,QAAQ,EAAE;QACR,gCAAgC;QAChC,KAAK,EAAE,MAAM,CAAC;QACd;mEAC2D;QAC3D,OAAO,EAAE,CACL;YAAC,IAAI,EAAE,OAAO,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAC,GAC7B;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,EAAE,CAAA;SAAC,GAC/B,IAAI,CACP,EAAE,CAAC;KACL,EAAE,CAAC;CACL;AAED;;;;;;;;;;GAUG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,gBAAgB,GAExB,uBAAuB,GACvB,yBAAyB,GACzB,wBAAwB,GACxB,+BAA+B,GAC/B,yBAAyB,GACzB,mBAAmB,GACnB,oBAAoB,GACpB,wBAAwB,GACxB,uBAAuB,GAEvB,eAAe,GACf,iBAAiB,GACjB,sBAAsB,GACtB,oBAAoB,GACpB,sBAAsB,GACtB,mBAAmB,GACnB,gCAAgC,GAChC,uBAAuB,GACvB,eAAe,GACf,iBAAiB,GAEjB,cAAc,GACd,aAAa,GACb,iBAAiB,GACjB,mBAAmB,GACnB,eAAe,GACf,sBAAsB,GACtB,mBAAmB,GACnB,qBAAqB,GACrB,iBAAiB,GAEjB,UAAU,GACV,mBAAmB,GACnB,oBAAoB,GACpB,mBAAmB,GACnB,iBAAiB,GAEjB,eAAe,GACf,cAAc,GACd,aAAa,GACb,eAAe,GAEf,uBAAuB,GACvB,qBAAqB,GACrB,aAAa,GACb,sBAAsB,GACtB,8BAA8B,GAC9B,6BAA6B,GAC7B,6BAA6B,GAE7B,qBAAqB,GACrB,wBAAwB,GACxB,0BAA0B,GAC1B,wBAAwB,GACxB,iCAAiC,GACjC,gCAAgC,GAChC,mCAAmC,GACnC,gCAAgC,GAChC,oBAAoB,GACpB,wBAAwB,GAExB,wBAAwB,GACxB,mBAAmB,GACnB,yBAAyB,GAEzB,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,gBAAgB,GAChB,mBAAmB,GAEnB,sBAAsB,GACtB,iBAAiB,GACjB,gCAAgC,GAChC,kCAAkC,GAClC,eAAe,CAAC;AAEpB,UAAU,eAAe;IACvB;;;8CAG0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb;;;;;4CAKwC;IACxC,WAAW,EAAE,MAAM,CAAC;IAEpB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;iEAC6D;IAC7D,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;+DAE2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;yEAEqE;IACrE,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAE5B;;;;yDAIqD;IACrD,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,IAAI,EAAE,OAAO,CAAC;IACd;;mFAE+E;IAC/E,UAAU,EAAE,MAAM,CAAC;IACnB;;2DAEuD;IACvD,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;oFAEgF;IAChF,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,wEAAwE;IACxE,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;kFAC8E;IAC9E,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,6EAA6E;IAC7E,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG,gBAAgB,CAAC;AAM7D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,QAAQ;IACvB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb;;;wDAGoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB;gEAC4D;IAC5D,WAAW,EAAE,MAAM,CAAC;CACrB;AAMD;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,OAAO;IACtB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb;;gFAE4E;IAC5E,WAAW,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,gDAAgD;IAChD,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB;qDACiD;IACjD,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,yDAAyD;IACzD,KAAK,EAAE,QAAQ,CAAC;IAChB;;+DAE2D;IAC3D,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,+CAA+C;IAC/C,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,wBAAwB;IACxB,KAAK,CAAC,EAAE;QACN,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;KAChC,CAAC;CACH"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4-canary.02643db",
|
|
4
4
|
"displayName": "XDS 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",
|
|
@@ -55,8 +55,8 @@ export const docs = {
|
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
name: 'size',
|
|
58
|
-
type: '
|
|
59
|
-
description:
|
|
58
|
+
type: "'tiny' | 'xsmall' | 'small' | 'medium' | 'large' | number",
|
|
59
|
+
description: "Avatar size. Use a named size ('tiny', 'xsmall', 'small', 'medium', 'large') or a numeric pixel value. Note: short names like 'sm', 'md', 'lg' are NOT valid; use the full words.",
|
|
60
60
|
default: "'small'",
|
|
61
61
|
},
|
|
62
62
|
{
|
package/src/Button/Button.tsx
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
import {useRef, useTransition, type ReactNode} from 'react';
|
|
22
22
|
import type {BaseProps} from '../BaseProps';
|
|
23
23
|
import * as stylex from '@stylexjs/stylex';
|
|
24
|
+
import {useTooltip} from '../Tooltip/useTooltip';
|
|
24
25
|
import {
|
|
25
26
|
colorVars,
|
|
26
27
|
sizeVars,
|
|
@@ -32,14 +33,13 @@ import {
|
|
|
32
33
|
fontWeightVars,
|
|
33
34
|
typeScaleVars,
|
|
34
35
|
} from '../theme/tokens.stylex';
|
|
35
|
-
import {Tooltip} from '../Tooltip/Tooltip';
|
|
36
36
|
import {Spinner} from '../Spinner';
|
|
37
37
|
import {VisuallyHidden} from '../VisuallyHidden';
|
|
38
38
|
|
|
39
39
|
import {EDGE_COMP_ATTR} from '../Layout/edgeCompensation.stylex';
|
|
40
40
|
import {useSize} from '../SizeContext/SizeContext';
|
|
41
41
|
import {useButtonGroup} from '../ButtonGroup/ButtonGroupContext';
|
|
42
|
-
import {mergeProps} from '../utils';
|
|
42
|
+
import {mergeProps, mergeRefs} from '../utils';
|
|
43
43
|
import {useLinkComponent} from '../Link/useLinkComponent';
|
|
44
44
|
import type {LinkComponentType} from '../Link/types';
|
|
45
45
|
import {themeProps} from '../utils/themeProps';
|
|
@@ -580,6 +580,16 @@ export function Button({
|
|
|
580
580
|
// for keyboard users to reach the tooltip. Otherwise use native disabled.
|
|
581
581
|
const useAriaDisabled = tooltip != null && buttonDisabled;
|
|
582
582
|
|
|
583
|
+
// Attach tooltip behavior via the hook rather than wrapping the button in a
|
|
584
|
+
// <Tooltip> element. The hook adds hover/focus triggers to the button itself,
|
|
585
|
+
// so no extra DOM node is inserted — the button stays a direct child of its
|
|
586
|
+
// container (no layout shift, and edge-compensation markers remain
|
|
587
|
+
// discoverable through the container's direct-child `:has()` selector).
|
|
588
|
+
const tooltipHook = useTooltip({
|
|
589
|
+
placement: 'above',
|
|
590
|
+
isEnabled: tooltip != null,
|
|
591
|
+
});
|
|
592
|
+
|
|
583
593
|
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
|
|
584
594
|
// The ref guard dedupes fire-once actions. Interruptible callers skip it so
|
|
585
595
|
// a re-click while pending starts a fresh action that interrupts the prior.
|
|
@@ -696,18 +706,39 @@ export function Button({
|
|
|
696
706
|
(children != null && children !== label);
|
|
697
707
|
const ariaLabelProp = needsAriaLabel ? {'aria-label': label} : null;
|
|
698
708
|
|
|
709
|
+
// When a tooltip is attached via the hook, point aria-describedby at the
|
|
710
|
+
// tooltip content (composing with any consumer-provided value).
|
|
711
|
+
const describedByProp =
|
|
712
|
+
tooltip != null
|
|
713
|
+
? {
|
|
714
|
+
'aria-describedby':
|
|
715
|
+
[props['aria-describedby'], tooltipHook.describedBy]
|
|
716
|
+
.filter(Boolean)
|
|
717
|
+
.join(' ') || undefined,
|
|
718
|
+
}
|
|
719
|
+
: null;
|
|
720
|
+
|
|
721
|
+
// Merge the consumer ref with the tooltip hook's trigger ref so both point at
|
|
722
|
+
// the same element. mergeRefs tolerates undefined, so this is a no-op for the
|
|
723
|
+
// tooltip side when no tooltip is set.
|
|
724
|
+
const mergedButtonRef = mergeRefs(
|
|
725
|
+
ref,
|
|
726
|
+
tooltip != null ? tooltipHook.ref : undefined,
|
|
727
|
+
);
|
|
728
|
+
|
|
699
729
|
let element: ReactNode;
|
|
700
730
|
|
|
701
731
|
if (renderAsLink) {
|
|
702
732
|
element = (
|
|
703
733
|
<LinkComponent
|
|
704
|
-
ref={
|
|
734
|
+
ref={mergedButtonRef as React.Ref<HTMLAnchorElement>}
|
|
705
735
|
href={href}
|
|
706
736
|
target={target}
|
|
707
737
|
rel={rel}
|
|
708
738
|
{...sharedMergedProps}
|
|
709
739
|
{...props}
|
|
710
740
|
{...ariaLabelProp}
|
|
741
|
+
{...describedByProp}
|
|
711
742
|
{...edgeCompAttr}
|
|
712
743
|
onClick={handleClick}>
|
|
713
744
|
{buttonContent}
|
|
@@ -716,12 +747,13 @@ export function Button({
|
|
|
716
747
|
} else {
|
|
717
748
|
element = (
|
|
718
749
|
<button
|
|
719
|
-
ref={
|
|
750
|
+
ref={mergedButtonRef}
|
|
720
751
|
type={type}
|
|
721
752
|
disabled={useAriaDisabled ? undefined : buttonDisabled}
|
|
722
753
|
{...sharedMergedProps}
|
|
723
754
|
{...props}
|
|
724
755
|
{...ariaLabelProp}
|
|
756
|
+
{...describedByProp}
|
|
725
757
|
{...edgeCompAttr}
|
|
726
758
|
aria-busy={isLoadingState || undefined}
|
|
727
759
|
aria-disabled={useAriaDisabled || undefined}
|
|
@@ -734,9 +766,10 @@ export function Button({
|
|
|
734
766
|
|
|
735
767
|
if (tooltip) {
|
|
736
768
|
return (
|
|
737
|
-
|
|
769
|
+
<>
|
|
738
770
|
{element}
|
|
739
|
-
|
|
771
|
+
{tooltipHook.renderTooltip(tooltip)}
|
|
772
|
+
</>
|
|
740
773
|
);
|
|
741
774
|
}
|
|
742
775
|
|
|
@@ -215,6 +215,33 @@ describe('Calendar', () => {
|
|
|
215
215
|
expect(screen.getByText(/February 2026.*March 2026/)).toBeInTheDocument();
|
|
216
216
|
});
|
|
217
217
|
|
|
218
|
+
it('clamps out-of-range numberOfMonths to a single month', () => {
|
|
219
|
+
// 1000 would otherwise try to render 1000 month grids and lock the page up.
|
|
220
|
+
render(
|
|
221
|
+
<Calendar
|
|
222
|
+
numberOfMonths={1000 as unknown as 1 | 2}
|
|
223
|
+
focusDate="2026-01-01"
|
|
224
|
+
/>,
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
// Only the focused month renders — no second month, no range separator.
|
|
228
|
+
expect(screen.getByText('January 2026')).toBeInTheDocument();
|
|
229
|
+
expect(screen.queryByText(/February 2026/)).not.toBeInTheDocument();
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it('clamps numberOfMonths={0} to a single month', () => {
|
|
233
|
+
render(
|
|
234
|
+
<Calendar
|
|
235
|
+
numberOfMonths={0 as unknown as 1 | 2}
|
|
236
|
+
focusDate="2026-01-01"
|
|
237
|
+
/>,
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
// 0 previously rendered no months at all; now falls back to one.
|
|
241
|
+
expect(screen.getByText('January 2026')).toBeInTheDocument();
|
|
242
|
+
expect(screen.getAllByRole('gridcell').length).toBeGreaterThan(0);
|
|
243
|
+
});
|
|
244
|
+
|
|
218
245
|
// ─── Display Options ─────────────────────────────────────────
|
|
219
246
|
|
|
220
247
|
it('shows week numbers when hasWeekNumbers is true', () => {
|
|
@@ -315,6 +342,85 @@ describe('Calendar', () => {
|
|
|
315
342
|
expect(day15).toHaveAttribute('aria-selected', 'true');
|
|
316
343
|
});
|
|
317
344
|
|
|
345
|
+
it('caps the range highlight next to a disabled mid-range day (#2715)', () => {
|
|
346
|
+
// Disable Jan 13. With Jan 10–15 selected, day 12 (immediately before the
|
|
347
|
+
// disabled day) should get a rounded end cap on its right edge, and day 14
|
|
348
|
+
// (immediately after) a rounded cap on its left edge — so the highlight
|
|
349
|
+
// reads as terminating at the disabled gap rather than running square-edged
|
|
350
|
+
// into it.
|
|
351
|
+
const disableJan13 = (d: Date) =>
|
|
352
|
+
!(d.getFullYear() === 2026 && d.getMonth() === 0 && d.getDate() === 13);
|
|
353
|
+
render(
|
|
354
|
+
<Calendar
|
|
355
|
+
mode="range"
|
|
356
|
+
value={{start: '2026-01-10', end: '2026-01-15'}}
|
|
357
|
+
focusDate="2026-01-01"
|
|
358
|
+
dateConstraints={[disableJan13]}
|
|
359
|
+
/>,
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
// The range background is an absolutely-positioned sibling div inside the
|
|
363
|
+
// same gridcell as the day button.
|
|
364
|
+
const rangeBgFor = (day: number): HTMLElement => {
|
|
365
|
+
const button = getDayButton(day);
|
|
366
|
+
const cell = button.closest('[role="gridcell"]') as HTMLElement;
|
|
367
|
+
// First child div is the range background (rendered before the button).
|
|
368
|
+
return cell.firstElementChild as HTMLElement;
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
const day12Bg = rangeBgFor(12);
|
|
372
|
+
const day14Bg = rangeBgFor(14);
|
|
373
|
+
|
|
374
|
+
// Capped edges have a border radius; the un-capped edge stays square.
|
|
375
|
+
expect(getComputedStyle(day12Bg).borderTopRightRadius).not.toBe('');
|
|
376
|
+
expect(getComputedStyle(day12Bg).borderTopRightRadius).not.toBe('0px');
|
|
377
|
+
expect(getComputedStyle(day14Bg).borderTopLeftRadius).not.toBe('');
|
|
378
|
+
expect(getComputedStyle(day14Bg).borderTopLeftRadius).not.toBe('0px');
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
it('does not range-highlight adjacent-month spillover days in two-month view', () => {
|
|
382
|
+
// #2715: with July 1–31 selected and July+August visible, July 26–31 also
|
|
383
|
+
// render as outside days in the August pane. Those spillover copies must
|
|
384
|
+
// not carry the range-highlight state (data-in-range) even though their
|
|
385
|
+
// dates fall inside the selected range.
|
|
386
|
+
render(
|
|
387
|
+
<Calendar
|
|
388
|
+
mode="range"
|
|
389
|
+
numberOfMonths={2}
|
|
390
|
+
focusDate="2026-07-01"
|
|
391
|
+
value={{start: '2026-07-01', end: '2026-07-31'}}
|
|
392
|
+
/>,
|
|
393
|
+
);
|
|
394
|
+
|
|
395
|
+
const spillover = [
|
|
396
|
+
'2026-07-26',
|
|
397
|
+
'2026-07-27',
|
|
398
|
+
'2026-07-28',
|
|
399
|
+
'2026-07-29',
|
|
400
|
+
'2026-07-30',
|
|
401
|
+
'2026-07-31',
|
|
402
|
+
];
|
|
403
|
+
|
|
404
|
+
const allDayButtons = Array.from(
|
|
405
|
+
document.querySelectorAll<HTMLButtonElement>('button[data-date]'),
|
|
406
|
+
);
|
|
407
|
+
|
|
408
|
+
for (const iso of spillover) {
|
|
409
|
+
const matches = allDayButtons.filter(
|
|
410
|
+
b => b.getAttribute('data-date') === iso,
|
|
411
|
+
);
|
|
412
|
+
// Renders once in the July pane and once as a spillover in August.
|
|
413
|
+
expect(matches.length).toBeGreaterThanOrEqual(2);
|
|
414
|
+
const outsideCopies = matches.filter(
|
|
415
|
+
b => b.getAttribute('aria-disabled') === 'true',
|
|
416
|
+
);
|
|
417
|
+
expect(outsideCopies.length).toBeGreaterThanOrEqual(1);
|
|
418
|
+
for (const b of outsideCopies) {
|
|
419
|
+
expect(b).not.toHaveAttribute('data-in-range');
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
|
|
318
424
|
// ─── Accessibility ───────────────────────────────────────────
|
|
319
425
|
|
|
320
426
|
it('has accessible grid structure', () => {
|
|
@@ -61,7 +61,9 @@ import {
|
|
|
61
61
|
computeDayCellState,
|
|
62
62
|
computeRangeRounding,
|
|
63
63
|
computePreviewRounding,
|
|
64
|
+
computeDayNeighborContinuity,
|
|
64
65
|
isEndpoint,
|
|
66
|
+
type DayNeighborContinuity,
|
|
65
67
|
} from './dayCellUtils';
|
|
66
68
|
|
|
67
69
|
// =============================================================================
|
|
@@ -201,7 +203,7 @@ export function Calendar({ref, ...props}: CalendarProps) {
|
|
|
201
203
|
value,
|
|
202
204
|
defaultValue,
|
|
203
205
|
onChange,
|
|
204
|
-
numberOfMonths = 1,
|
|
206
|
+
numberOfMonths: numberOfMonthsProp = 1,
|
|
205
207
|
min,
|
|
206
208
|
max,
|
|
207
209
|
dateConstraints,
|
|
@@ -221,6 +223,11 @@ export function Calendar({ref, ...props}: CalendarProps) {
|
|
|
221
223
|
// DayOfWeek so all downstream date math keeps working with an index.
|
|
222
224
|
const weekStartsOn = normalizeDayOfWeek(weekStartsOnProp);
|
|
223
225
|
|
|
226
|
+
// `numberOfMonths` is typed `1 | 2`; defensively clamp anything else that
|
|
227
|
+
// slips through at runtime to 1 so `Array.from({length})` can't render an
|
|
228
|
+
// absurd number of month grids (e.g. `numberOfMonths={1000}`).
|
|
229
|
+
const numberOfMonths = numberOfMonthsProp === 2 ? 2 : 1;
|
|
230
|
+
|
|
224
231
|
// Today's date (memoized)
|
|
225
232
|
const today = useMemo(() => plainDateToday(), []);
|
|
226
233
|
|
|
@@ -784,25 +791,42 @@ function MonthGrid({
|
|
|
784
791
|
{weekNum}
|
|
785
792
|
</div>
|
|
786
793
|
)}
|
|
787
|
-
{week.map((day, dayIndex) =>
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
isDisabled
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
794
|
+
{week.map((day, dayIndex) => {
|
|
795
|
+
// Whether the previous/next day in this week row continues the
|
|
796
|
+
// highlighted run (range and preview). A disabled or
|
|
797
|
+
// adjacent-month neighbour breaks continuity, so this day gets
|
|
798
|
+
// an end cap on that side (#2715).
|
|
799
|
+
const neighbors = computeDayNeighborContinuity({
|
|
800
|
+
week,
|
|
801
|
+
dayIndex,
|
|
802
|
+
mode,
|
|
803
|
+
rangeStart,
|
|
804
|
+
rangeEnd,
|
|
805
|
+
previewStart,
|
|
806
|
+
previewEnd,
|
|
807
|
+
isDisabled: isDateDisabled,
|
|
808
|
+
});
|
|
809
|
+
return (
|
|
810
|
+
<DayCell
|
|
811
|
+
key={day.iso}
|
|
812
|
+
day={day}
|
|
813
|
+
dayIndex={dayIndex}
|
|
814
|
+
mode={mode}
|
|
815
|
+
selectedDate={selectedDate}
|
|
816
|
+
rangeStart={rangeStart}
|
|
817
|
+
rangeEnd={rangeEnd}
|
|
818
|
+
previewStart={previewStart}
|
|
819
|
+
previewEnd={previewEnd}
|
|
820
|
+
today={today}
|
|
821
|
+
hasOutsideDays={hasOutsideDays}
|
|
822
|
+
isDisabled={isDateDisabled(day.date)}
|
|
823
|
+
neighbors={neighbors}
|
|
824
|
+
isTabbable={day.iso === seedTabbableIso}
|
|
825
|
+
onDayClick={onDayClick}
|
|
826
|
+
onDayHover={onDayHover}
|
|
827
|
+
/>
|
|
828
|
+
);
|
|
829
|
+
})}
|
|
806
830
|
</div>
|
|
807
831
|
);
|
|
808
832
|
})}
|
|
@@ -827,6 +851,12 @@ interface DayCellProps {
|
|
|
827
851
|
today: PlainDate;
|
|
828
852
|
hasOutsideDays: boolean;
|
|
829
853
|
isDisabled: boolean;
|
|
854
|
+
/**
|
|
855
|
+
* Whether the previous/next day in the same week continues the highlighted
|
|
856
|
+
* run (range and preview). When a neighbour is disabled or outside the month
|
|
857
|
+
* it breaks the run, so this day gets an end cap on that side (#2715).
|
|
858
|
+
*/
|
|
859
|
+
neighbors: DayNeighborContinuity;
|
|
830
860
|
/**
|
|
831
861
|
* Whether this day seeds the initial roving tab stop. useGridFocus
|
|
832
862
|
* (`hasRovingTabIndex`) owns the live tab stop thereafter — it honors an
|
|
@@ -849,6 +879,7 @@ function DayCell({
|
|
|
849
879
|
today,
|
|
850
880
|
hasOutsideDays,
|
|
851
881
|
isDisabled,
|
|
882
|
+
neighbors,
|
|
852
883
|
isTabbable: isTabbableDay,
|
|
853
884
|
onDayClick,
|
|
854
885
|
onDayHover,
|
|
@@ -876,8 +907,14 @@ function DayCell({
|
|
|
876
907
|
});
|
|
877
908
|
|
|
878
909
|
const endpoint = isEndpoint(state);
|
|
879
|
-
const rangeRounding = computeRangeRounding(state
|
|
880
|
-
|
|
910
|
+
const rangeRounding = computeRangeRounding(state, {
|
|
911
|
+
prevInRange: neighbors.prevInRange,
|
|
912
|
+
nextInRange: neighbors.nextInRange,
|
|
913
|
+
});
|
|
914
|
+
const previewRounding = computePreviewRounding(state, {
|
|
915
|
+
prevInPreview: neighbors.prevInPreview,
|
|
916
|
+
nextInPreview: neighbors.nextInPreview,
|
|
917
|
+
});
|
|
881
918
|
|
|
882
919
|
return (
|
|
883
920
|
<div role="gridcell" {...stylex.props(dayCellStyles.cell)}>
|