@astryxdesign/core 0.4.6 → 0.4.7-canary.29be96d

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.
Files changed (197) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/BottomSheet/BottomSheet.d.ts +1 -0
  3. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  4. package/dist/BottomSheet/BottomSheet.js +54 -15
  5. package/dist/BottomSheet/BottomSheetEdgeTint.d.ts +6 -0
  6. package/dist/BottomSheet/BottomSheetEdgeTint.d.ts.map +1 -0
  7. package/dist/BottomSheet/BottomSheetEdgeTint.js +62 -0
  8. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  9. package/dist/BottomSheet/BottomSheetPanel.js +1 -0
  10. package/dist/BottomSheet/BottomSheetSwitcher.d.ts +1 -0
  11. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  12. package/dist/BottomSheet/BottomSheetSwitcher.js +10 -4
  13. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  14. package/dist/BottomSheet/useSheetGestures.js +23 -5
  15. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  16. package/dist/Breadcrumbs/BreadcrumbItem.js +5 -5
  17. package/dist/Calendar/Calendar.d.ts +3 -1
  18. package/dist/Calendar/Calendar.d.ts.map +1 -1
  19. package/dist/Calendar/Calendar.js +13 -14
  20. package/dist/Calendar/getInitialFocusDate.d.ts +46 -0
  21. package/dist/Calendar/getInitialFocusDate.d.ts.map +1 -0
  22. package/dist/Calendar/getInitialFocusDate.js +62 -0
  23. package/dist/Chat/ChatMessageList.d.ts +22 -3
  24. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  25. package/dist/Chat/ChatMessageList.js +6 -3
  26. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  27. package/dist/DateInput/TouchDateField.js +34 -1
  28. package/dist/Dialog/Dialog.d.ts +7 -1
  29. package/dist/Dialog/Dialog.d.ts.map +1 -1
  30. package/dist/Dialog/Dialog.js +48 -22
  31. package/dist/Heading/Heading.d.ts.map +1 -1
  32. package/dist/Heading/Heading.js +6 -2
  33. package/dist/Kbd/Kbd.d.ts.map +1 -1
  34. package/dist/Kbd/Kbd.js +10 -3
  35. package/dist/Markdown/index.d.ts +1 -1
  36. package/dist/Markdown/index.d.ts.map +1 -1
  37. package/dist/Markdown/parser.d.ts +38 -1
  38. package/dist/Markdown/parser.d.ts.map +1 -1
  39. package/dist/Markdown/parser.js +149 -23
  40. package/dist/MultiSelector/MultiSelector.d.ts +15 -1
  41. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  42. package/dist/MultiSelector/MultiSelector.js +17 -6
  43. package/dist/MultiSelector/index.d.ts +1 -1
  44. package/dist/MultiSelector/index.d.ts.map +1 -1
  45. package/dist/Selector/Selector.d.ts.map +1 -1
  46. package/dist/Selector/Selector.js +5 -0
  47. package/dist/Stepper/Step.d.ts +140 -0
  48. package/dist/Stepper/Step.d.ts.map +1 -0
  49. package/dist/Stepper/Step.js +1045 -0
  50. package/dist/Stepper/StepStatus.d.ts +24 -0
  51. package/dist/Stepper/StepStatus.d.ts.map +1 -0
  52. package/dist/Stepper/StepStatus.js +1 -0
  53. package/dist/Stepper/Stepper.d.ts +93 -0
  54. package/dist/Stepper/Stepper.d.ts.map +1 -0
  55. package/dist/Stepper/Stepper.js +184 -0
  56. package/dist/Stepper/StepperContext.d.ts +41 -0
  57. package/dist/Stepper/StepperContext.d.ts.map +1 -0
  58. package/dist/Stepper/StepperContext.js +34 -0
  59. package/dist/Stepper/index.d.ts +8 -0
  60. package/dist/Stepper/index.d.ts.map +1 -0
  61. package/dist/Stepper/index.js +7 -0
  62. package/dist/Stepper/stepper.stylex.d.ts +15 -0
  63. package/dist/Stepper/stepper.stylex.d.ts.map +1 -0
  64. package/dist/Stepper/stepper.stylex.js +20 -0
  65. package/dist/TabList/Tab.d.ts.map +1 -1
  66. package/dist/TabList/Tab.js +5 -1
  67. package/dist/Table/BaseTable.d.ts.map +1 -1
  68. package/dist/Table/BaseTable.js +4 -1
  69. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  70. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +20 -8
  71. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
  72. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +10 -3
  73. package/dist/Table/plugins/selection/useTableSelection.d.ts +16 -0
  74. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  75. package/dist/Table/plugins/selection/useTableSelection.js +19 -5
  76. package/dist/Table/types.d.ts +22 -4
  77. package/dist/Table/types.d.ts.map +1 -1
  78. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  79. package/dist/Table/useBaseTablePlugins.js +5 -0
  80. package/dist/Text/Text.d.ts.map +1 -1
  81. package/dist/Text/Text.js +6 -2
  82. package/dist/astryx.css +41 -1
  83. package/dist/hooks/index.d.ts +1 -0
  84. package/dist/hooks/index.d.ts.map +1 -1
  85. package/dist/hooks/index.js +1 -0
  86. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  87. package/dist/hooks/useHotkeys.js +10 -3
  88. package/dist/hooks/useListFocus.d.ts +5 -2
  89. package/dist/hooks/useListFocus.d.ts.map +1 -1
  90. package/dist/hooks/useListFocus.js +12 -6
  91. package/dist/hooks/useMergedRefs.d.ts +18 -0
  92. package/dist/hooks/useMergedRefs.d.ts.map +1 -0
  93. package/dist/hooks/useMergedRefs.js +25 -0
  94. package/dist/index.d.ts +1 -0
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +1 -0
  97. package/dist/utils/timeParser.d.ts +1 -1
  98. package/dist/utils/timeParser.d.ts.map +1 -1
  99. package/dist/utils/timeParser.js +26 -12
  100. package/locales/en.json +14 -6
  101. package/locales/pseudo.json +6 -0
  102. package/package.json +8 -3
  103. package/src/Avatar/Avatar.doc.mjs +2 -1
  104. package/src/BottomSheet/BottomSheet.test.tsx +123 -0
  105. package/src/BottomSheet/BottomSheet.tsx +36 -4
  106. package/src/BottomSheet/BottomSheetEdgeTint.test.tsx +225 -0
  107. package/src/BottomSheet/BottomSheetEdgeTint.tsx +82 -0
  108. package/src/BottomSheet/BottomSheetPanel.test.tsx +66 -0
  109. package/src/BottomSheet/BottomSheetPanel.tsx +19 -0
  110. package/src/BottomSheet/BottomSheetSwitcher.tsx +13 -0
  111. package/src/BottomSheet/useSheetGestures.test.ts +27 -0
  112. package/src/BottomSheet/useSheetGestures.ts +25 -5
  113. package/src/Breadcrumbs/BreadcrumbItem.tsx +2 -1
  114. package/src/Button/Button.doc.mjs +22 -0
  115. package/src/Calendar/Calendar.doc.mjs +4 -3
  116. package/src/Calendar/Calendar.test.tsx +52 -0
  117. package/src/Calendar/Calendar.tsx +18 -15
  118. package/src/Calendar/getInitialFocusDate.test.ts +94 -0
  119. package/src/Calendar/getInitialFocusDate.ts +93 -0
  120. package/src/Chat/ChatMessageList.doc.mjs +9 -1
  121. package/src/Chat/ChatMessageList.test.tsx +46 -0
  122. package/src/Chat/ChatMessageList.tsx +28 -4
  123. package/src/CodeBlock/CodeBlock.doc.mjs +6 -0
  124. package/src/ContextMenu/ContextMenu.doc.mjs +5 -0
  125. package/src/DateInput/DateInputTouch.test.tsx +36 -0
  126. package/src/DateInput/TouchDateField.tsx +35 -1
  127. package/src/Dialog/Dialog.doc.mjs +8 -3
  128. package/src/Dialog/Dialog.test.tsx +71 -0
  129. package/src/Dialog/Dialog.tsx +72 -20
  130. package/src/Field/Field.doc.mjs +11 -0
  131. package/src/Heading/Heading.test.tsx +23 -1
  132. package/src/Heading/Heading.tsx +6 -2
  133. package/src/Kbd/Kbd.test.tsx +17 -0
  134. package/src/Kbd/Kbd.tsx +10 -3
  135. package/src/Link/Link.doc.mjs +11 -0
  136. package/src/Markdown/index.ts +1 -0
  137. package/src/Markdown/parser.perf.test.ts +71 -1
  138. package/src/Markdown/parser.test.ts +145 -2
  139. package/src/Markdown/parser.ts +208 -22
  140. package/src/MoreMenu/MoreMenu.doc.mjs +7 -1
  141. package/src/MultiSelector/MultiSelector.doc.mjs +10 -0
  142. package/src/MultiSelector/MultiSelector.test.tsx +105 -0
  143. package/src/MultiSelector/MultiSelector.tsx +50 -6
  144. package/src/MultiSelector/index.ts +1 -0
  145. package/src/NumberInput/NumberInput.doc.mjs +5 -0
  146. package/src/Popover/Popover.test.tsx +27 -1
  147. package/src/PowerSearch/PowerSearch.doc.mjs +10 -0
  148. package/src/Selector/Selector.doc.mjs +11 -0
  149. package/src/Selector/Selector.test.tsx +21 -0
  150. package/src/Selector/Selector.tsx +11 -1
  151. package/src/Stepper/Step.doc.mjs +98 -0
  152. package/src/Stepper/Step.tsx +1638 -0
  153. package/src/Stepper/StepStatus.ts +26 -0
  154. package/src/Stepper/Stepper.doc.mjs +370 -0
  155. package/src/Stepper/Stepper.test.tsx +1024 -0
  156. package/src/Stepper/Stepper.tsx +258 -0
  157. package/src/Stepper/StepperContext.ts +71 -0
  158. package/src/Stepper/index.ts +18 -0
  159. package/src/Stepper/stepper.stylex.ts +19 -0
  160. package/src/TabList/Tab.tsx +5 -1
  161. package/src/TabList/TabList.test.tsx +21 -4
  162. package/src/Table/BaseTable.tsx +6 -3
  163. package/src/Table/Table.test.tsx +35 -0
  164. package/src/Table/plugins/groupedRows/useTableGroupedRows-perf.test.tsx +112 -0
  165. package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +100 -0
  166. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +17 -8
  167. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +13 -7
  168. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +12 -3
  169. package/src/Table/plugins/selection/useTableSelection.test.tsx +76 -0
  170. package/src/Table/plugins/selection/useTableSelection.tsx +40 -7
  171. package/src/Table/types.ts +22 -4
  172. package/src/Table/useBaseTablePlugins.ts +5 -0
  173. package/src/Table/useTableGroupedRows.doc.mjs +5 -4
  174. package/src/Table/useTableRowStatus.doc.mjs +1 -1
  175. package/src/Table/useTableSelection.doc.mjs +31 -0
  176. package/src/Text/Text.test.tsx +23 -1
  177. package/src/Text/Text.tsx +6 -2
  178. package/src/TextInput/TextInput.doc.mjs +10 -0
  179. package/src/Toast/Toast.doc.mjs +6 -0
  180. package/src/Tokenizer/Tokenizer.doc.mjs +10 -0
  181. package/src/Toolbar/Toolbar.doc.mjs +5 -0
  182. package/src/__tests__/apiContractDrift.test.tsx +80 -0
  183. package/src/__tests__/fieldContract.test.tsx +24 -0
  184. package/src/__tests__/structuralComponentContract.test.tsx +39 -0
  185. package/src/hooks/index.ts +2 -0
  186. package/src/hooks/useHotkeys.test.ts +18 -0
  187. package/src/hooks/useHotkeys.ts +10 -3
  188. package/src/hooks/useListFocus.doc.mjs +2 -2
  189. package/src/hooks/useListFocus.test.tsx +65 -3
  190. package/src/hooks/useListFocus.ts +15 -7
  191. package/src/hooks/useMergedRefs.doc.mjs +79 -0
  192. package/src/hooks/useMergedRefs.test.tsx +62 -0
  193. package/src/hooks/useMergedRefs.ts +36 -0
  194. package/src/index.ts +1 -0
  195. package/src/theme/MediaTheme.doc.mjs +5 -5
  196. package/src/utils/timeParser.test.ts +6 -1
  197. package/src/utils/timeParser.ts +35 -13
@@ -11,6 +11,7 @@
11
11
  *
12
12
  * SYNC: When modified, update these files to stay in sync:
13
13
  * - /packages/core/src/Calendar/Calendar.doc.mjs (props table, features, implementation notes)
14
+ * - /packages/core/src/Calendar/getInitialFocusDate.ts (which month the calendar opens on)
14
15
  * - /packages/core/src/Calendar/Calendar.test.tsx (tests for new/changed behavior)
15
16
  * - /packages/core/src/Calendar/index.ts (exports if types change)
16
17
  * - /apps/storybook/stories/Calendar.stories.tsx (storybook stories)
@@ -26,6 +27,7 @@ import { calendarStyles, monthGridStyles, dayCellStyles, dayCellTheme } from "./
26
27
  import { plainDateFromISO, plainDateToISO, plainDateToDate, plainDateToday, plainDateSetFirstOfMonth, plainDateAddMonths, plainDateAddDays, plainDateIsBefore, plainDateIsEqual, plainDateGetWeekNumber, plainDateFormat, DATE_FORMAT_WITH_WEEKDAY, DATE_FORMAT_MONTH_YEAR } from "../utils/plainDate.js";
27
28
  import { mergeProps, composeEventHandlers, rtlStyles } from "../utils/index.js";
28
29
  import { focusOutlineProps } from "../utils/focusOutline.stylex.js";
30
+ import { getInitialFocusDate } from "./getInitialFocusDate.js";
29
31
  import { computeDayCellState, computeRangeRounding, computePreviewRounding, computeDayNeighborContinuity, isEndpoint } from "./dayCellUtils.js";
30
32
 
31
33
  // =============================================================================
@@ -114,20 +116,17 @@ export function Calendar({
114
116
  // Determine effective value
115
117
  const effectiveValue = value !== undefined ? value : internalValue;
116
118
 
117
- // Focus date state (which month is visible)
118
- const [internalFocusDate, setInternalFocusDate] = useState(() => {
119
- if (focusDateProp) {
120
- return plainDateFromISO(focusDateProp);
121
- }
122
- if (effectiveValue) {
123
- if (typeof effectiveValue === 'string') {
124
- return plainDateFromISO(effectiveValue);
125
- } else {
126
- return plainDateFromISO(effectiveValue.start);
127
- }
128
- }
129
- return plainDateToday();
130
- });
119
+ // Focus date state (which month is visible). Falls back to today, clamped
120
+ // into the min/max window so a window that doesn't contain today doesn't
121
+ // open on an all-disabled month.
122
+ const [internalFocusDate, setInternalFocusDate] = useState(() => getInitialFocusDate({
123
+ focusDate: focusDateProp,
124
+ value: effectiveValue,
125
+ min,
126
+ max,
127
+ numberOfMonths,
128
+ today
129
+ }));
131
130
 
132
131
  // Use controlled focusDate if callback is provided, otherwise use internal state
133
132
  const isControlledFocus = focusDateProp !== undefined && onFocusDateChange !== undefined;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @file getInitialFocusDate.ts
3
+ * @input PlainDate utilities, min/max bounds, today
4
+ * @output Exports getInitialFocusDate — the month Calendar opens on
5
+ * @position Calendar-specific helper; used by Calendar.tsx
6
+ *
7
+ * SYNC: When modified, update:
8
+ * - /packages/core/src/Calendar/getInitialFocusDate.test.ts
9
+ * - /packages/core/src/Calendar/Calendar.tsx (the only caller)
10
+ */
11
+ import type { ISODateString, DateRange } from '../utils/dateTypes';
12
+ import { type PlainDate } from '../utils/plainDate';
13
+ export interface InitialFocusDateOptions {
14
+ /** Controlled visible month, if the consumer supplied one. */
15
+ focusDate?: ISODateString;
16
+ /** Selected value (single date or range), controlled or uncontrolled. */
17
+ value?: ISODateString | DateRange;
18
+ /** Earliest selectable date. */
19
+ min?: ISODateString;
20
+ /** Latest selectable date. */
21
+ max?: ISODateString;
22
+ /** How many month panes the calendar renders (1 or 2). */
23
+ numberOfMonths: number;
24
+ /** Today, injected so the caller keeps a single memoized source of "now". */
25
+ today: PlainDate;
26
+ }
27
+ /**
28
+ * Picks the date whose month the calendar opens on.
29
+ *
30
+ * An explicit `focusDate` wins, then the selected value — both are the
31
+ * consumer's own instruction about where to look, so neither is second-guessed
32
+ * against `min`/`max`.
33
+ *
34
+ * Otherwise the calendar opens on today, clamped into the `min`/`max` window.
35
+ * Without the clamp a window that doesn't contain today (a 2019 audit range, a
36
+ * booking window opening next spring) opened on today's month with every day
37
+ * disabled, leaving prev/next clicking as the only way in.
38
+ *
39
+ * When clamping forward to `min`, that month leads: the whole selectable window
40
+ * runs ahead of it. When clamping back to `max`, the last pane lands on `max`'s
41
+ * month instead — with `numberOfMonths={2}` opening on `[max, max + 1]` would
42
+ * spend half the calendar on a month that is entirely out of bounds. That
43
+ * shift never crosses `min`'s month.
44
+ */
45
+ export declare function getInitialFocusDate(options: InitialFocusDateOptions): PlainDate;
46
+ //# sourceMappingURL=getInitialFocusDate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getInitialFocusDate.d.ts","sourceRoot":"","sources":["../../src/Calendar/getInitialFocusDate.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAC,aAAa,EAAE,SAAS,EAAC,MAAM,oBAAoB,CAAC;AACjE,OAAO,EACL,KAAK,SAAS,EAMf,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,uBAAuB;IACtC,8DAA8D;IAC9D,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,yEAAyE;IACzE,KAAK,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAClC,gCAAgC;IAChC,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,8BAA8B;IAC9B,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,0DAA0D;IAC1D,cAAc,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,KAAK,EAAE,SAAS,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,uBAAuB,GAC/B,SAAS,CAkCX"}
@@ -0,0 +1,62 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file getInitialFocusDate.ts
5
+ * @input PlainDate utilities, min/max bounds, today
6
+ * @output Exports getInitialFocusDate — the month Calendar opens on
7
+ * @position Calendar-specific helper; used by Calendar.tsx
8
+ *
9
+ * SYNC: When modified, update:
10
+ * - /packages/core/src/Calendar/getInitialFocusDate.test.ts
11
+ * - /packages/core/src/Calendar/Calendar.tsx (the only caller)
12
+ */
13
+
14
+ import { plainDateFromISO, plainDateSetFirstOfMonth, plainDateAddMonths, plainDateIsBefore, plainDateIsAfter } from "../utils/plainDate.js";
15
+ /**
16
+ * Picks the date whose month the calendar opens on.
17
+ *
18
+ * An explicit `focusDate` wins, then the selected value — both are the
19
+ * consumer's own instruction about where to look, so neither is second-guessed
20
+ * against `min`/`max`.
21
+ *
22
+ * Otherwise the calendar opens on today, clamped into the `min`/`max` window.
23
+ * Without the clamp a window that doesn't contain today (a 2019 audit range, a
24
+ * booking window opening next spring) opened on today's month with every day
25
+ * disabled, leaving prev/next clicking as the only way in.
26
+ *
27
+ * When clamping forward to `min`, that month leads: the whole selectable window
28
+ * runs ahead of it. When clamping back to `max`, the last pane lands on `max`'s
29
+ * month instead — with `numberOfMonths={2}` opening on `[max, max + 1]` would
30
+ * spend half the calendar on a month that is entirely out of bounds. That
31
+ * shift never crosses `min`'s month.
32
+ */
33
+ export function getInitialFocusDate(options) {
34
+ const {
35
+ focusDate,
36
+ value,
37
+ min,
38
+ max,
39
+ numberOfMonths,
40
+ today
41
+ } = options;
42
+ if (focusDate) {
43
+ return plainDateFromISO(focusDate);
44
+ }
45
+ if (value) {
46
+ return plainDateFromISO(typeof value === 'string' ? value : value.start);
47
+ }
48
+ const minDate = min ? plainDateFromISO(min) : null;
49
+ const maxDate = max ? plainDateFromISO(max) : null;
50
+ if (minDate && plainDateIsBefore(today, minDate)) {
51
+ return minDate;
52
+ }
53
+ if (maxDate && plainDateIsAfter(today, maxDate)) {
54
+ const lastPaneOffset = Math.max(0, numberOfMonths - 1);
55
+ const shifted = plainDateAddMonths(plainDateSetFirstOfMonth(maxDate), -lastPaneOffset);
56
+ if (minDate && plainDateIsBefore(shifted, plainDateSetFirstOfMonth(minDate))) {
57
+ return minDate;
58
+ }
59
+ return shifted;
60
+ }
61
+ return today;
62
+ }
@@ -6,7 +6,8 @@
6
6
  *
7
7
  * Renders a container with role="log" for chat message histories.
8
8
  * Handles density context, configurable gap, empty state,
9
- * a spacer that pushes messages to the bottom, and an infinite scroll sentinel.
9
+ * a configurable spacer (align) that pushes messages to the bottom,
10
+ * and an infinite scroll sentinel.
10
11
  *
11
12
  * Auto-scroll and the scroll-to-bottom button are owned by
12
13
  * ChatLayout. When used standalone (without a layout), the list
@@ -52,6 +53,23 @@ export interface ChatMessageListProps extends BaseProps<HTMLDivElement> {
52
53
  * be grouped) and row spacing should be tuned separately from density.
53
54
  */
54
55
  gap?: SpacingStep;
56
+ /**
57
+ * Vertical alignment of messages when the list is shorter than its
58
+ * container.
59
+ *
60
+ * - `'bottom'` (default): a spacer fills the free space and pushes
61
+ * messages to the bottom, so a short conversation sits just above the
62
+ * composer — the familiar messaging-app layout.
63
+ * - `'top'`: the spacer is omitted, so messages start at the top and grow
64
+ * downward — better for document-style or log-style lists.
65
+ *
66
+ * This only changes the resting position of a non-full list. Once messages
67
+ * overflow the container the spacer collapses to zero in both modes, so
68
+ * ChatLayout auto-scroll-to-bottom behavior is identical either way.
69
+ *
70
+ * @default 'bottom'
71
+ */
72
+ align?: 'top' | 'bottom';
55
73
  /**
56
74
  * Whether an assistant message is actively streaming into the list.
57
75
  *
@@ -71,7 +89,8 @@ export interface ChatMessageListProps extends BaseProps<HTMLDivElement> {
71
89
  *
72
90
  * Renders messages in a flex column with density-based spacing.
73
91
  * Override gap to tune row spacing separately from density.
74
- * A spacer pushes content to the bottom when the list isn't full.
92
+ * By default a spacer pushes content to the bottom when the list isn't full;
93
+ * set `align='top'` to start messages at the top instead.
75
94
  * Supports loading older messages via `scrollToTopAction`.
76
95
  *
77
96
  * Auto-scroll and the scroll-to-bottom button are owned by
@@ -86,7 +105,7 @@ export interface ChatMessageListProps extends BaseProps<HTMLDivElement> {
86
105
  * </ChatMessageList>
87
106
  * ```
88
107
  */
89
- export declare function ChatMessageList({ children, emptyState, scrollToTopAction, density, gap, isStreaming, xstyle, className, style, 'data-testid': testId, ref, ...rest }: ChatMessageListProps): import("react").JSX.Element;
108
+ export declare function ChatMessageList({ children, emptyState, scrollToTopAction, density, gap, align, isStreaming, xstyle, className, style, 'data-testid': testId, ref, ...rest }: ChatMessageListProps): import("react").JSX.Element;
90
109
  export declare namespace ChatMessageList {
91
110
  var displayName: string;
92
111
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ChatMessageList.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatMessageList.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAC,KAAK,SAAS,EAA4C,MAAM,OAAO,CAAC;AAGhF,OAAO,EAEL,KAAK,WAAW,EAEjB,MAAM,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAGhD,MAAM,WAAW,oBAAqB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACrE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAEhC;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IAEvB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,WAAW,CAAC;IAElB;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA4FD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,OAAoB,EACpB,GAAG,EACH,WAAmB,EACnB,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,oBAAoB,+BA6FtB;yBA1Ge,eAAe"}
1
+ {"version":3,"file":"ChatMessageList.d.ts","sourceRoot":"","sources":["../../src/Chat/ChatMessageList.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAC,KAAK,SAAS,EAA4C,MAAM,OAAO,CAAC;AAGhF,OAAO,EAEL,KAAK,WAAW,EAEjB,MAAM,eAAe,CAAC;AAGvB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAGhD,MAAM,WAAW,oBAAqB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACrE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAEhC;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IAEvB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,WAAW,CAAC;IAElB;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAEzB;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA4FD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,OAAoB,EACpB,GAAG,EACH,KAAgB,EAChB,WAAmB,EACnB,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,oBAAoB,+BAgGtB;yBA9Ge,eAAe"}
@@ -10,7 +10,8 @@
10
10
  *
11
11
  * Renders a container with role="log" for chat message histories.
12
12
  * Handles density context, configurable gap, empty state,
13
- * a spacer that pushes messages to the bottom, and an infinite scroll sentinel.
13
+ * a configurable spacer (align) that pushes messages to the bottom,
14
+ * and an infinite scroll sentinel.
14
15
  *
15
16
  * Auto-scroll and the scroll-to-bottom button are owned by
16
17
  * ChatLayout. When used standalone (without a layout), the list
@@ -124,7 +125,8 @@ const gapStyles = {
124
125
  *
125
126
  * Renders messages in a flex column with density-based spacing.
126
127
  * Override gap to tune row spacing separately from density.
127
- * A spacer pushes content to the bottom when the list isn't full.
128
+ * By default a spacer pushes content to the bottom when the list isn't full;
129
+ * set `align='top'` to start messages at the top instead.
128
130
  * Supports loading older messages via `scrollToTopAction`.
129
131
  *
130
132
  * Auto-scroll and the scroll-to-bottom button are owned by
@@ -145,6 +147,7 @@ export function ChatMessageList({
145
147
  scrollToTopAction,
146
148
  density = 'balanced',
147
149
  gap,
150
+ align = 'bottom',
148
151
  isStreaming = false,
149
152
  xstyle,
150
153
  className,
@@ -217,7 +220,7 @@ export function ChatMessageList({
217
220
  children: /*#__PURE__*/_jsx(Spinner, {
218
221
  size: "md"
219
222
  })
220
- }), /*#__PURE__*/_jsx("div", {
223
+ }), align === 'bottom' && /*#__PURE__*/_jsx("div", {
221
224
  ...{
222
225
  className: "x98rzlu x2lwn1j"
223
226
  },
@@ -1 +1 @@
1
- {"version":3,"file":"TouchDateField.d.ts","sourceRoot":"","sources":["../../src/DateInput/TouchDateField.tsx"],"names":[],"mappings":"AA4DA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,aAAa,CAAC;AAichD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,aAAqB,EACrB,WAAW,EACX,UAAkB,EAClB,UAAkB,EAClB,UAAkB,EAClB,eAAe,EACf,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,SAAiB,EACjB,GAAG,EACH,GAAG,EACH,eAAe,EACf,WAAW,EAAE,oBAAoB,EACjC,IAAI,EAAE,QAAQ,EACd,MAAM,EACN,aAA0B,EAC1B,YAAY,EACZ,QAAgB,EAIhB,cAAc,EAAE,eAAe,EAC/B,YAAY,EAAE,gBAAoB,EAClC,MAAoB,EACpB,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,IAAI,EACR,EAAE,cAAc,+BAkqBhB;yBAnsBe,cAAc"}
1
+ {"version":3,"file":"TouchDateField.d.ts","sourceRoot":"","sources":["../../src/DateInput/TouchDateField.tsx"],"names":[],"mappings":"AA4DA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,aAAa,CAAC;AAichD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,aAAqB,EACrB,WAAW,EACX,UAAkB,EAClB,UAAkB,EAClB,UAAkB,EAClB,eAAe,EACf,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,SAAiB,EACjB,GAAG,EACH,GAAG,EACH,eAAe,EACf,WAAW,EAAE,oBAAoB,EACjC,IAAI,EAAE,QAAQ,EACd,MAAM,EACN,aAA0B,EAC1B,YAAY,EACZ,QAAgB,EAIhB,cAAc,EAAE,eAAe,EAC/B,YAAY,EAAE,gBAAoB,EAClC,MAAoB,EACpB,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,IAAI,EACR,EAAE,cAAc,+BAosBhB;yBAruBe,cAAc"}
@@ -274,6 +274,13 @@ export function TouchDateField({
274
274
  const [isSheetOpen, setIsSheetOpen] = useState(false);
275
275
  const [isWheelOpen, setIsWheelOpen] = useState(false);
276
276
  const scrollerHandleRef = useRef(null);
277
+ // Pending focus handoff from the clear button; see handleClear.
278
+ const clearFocusTimerRef = useRef(null);
279
+ useEffect(() => () => {
280
+ if (clearFocusTimerRef.current != null) {
281
+ clearTimeout(clearFocusTimerRef.current);
282
+ }
283
+ }, []);
277
284
  const today = useMemo(() => plainDateToday(), []);
278
285
  const selectedDate = useMemo(() => optimisticValue != null && /^\d{4}-\d{2}-\d{2}$/.test(optimisticValue) ? plainDateFromISO(optimisticValue) : null, [optimisticValue]);
279
286
 
@@ -350,7 +357,33 @@ export function TouchDateField({
350
357
  }, [isEffectivelyDisabled]);
351
358
  const handleClear = useCallback(() => {
352
359
  fireChange(undefined);
353
- inputRef.current?.focus();
360
+ // Focus goes back to the field on the NEXT task, not synchronously.
361
+ //
362
+ // Clearing unmounts this button (it only renders while there is a value),
363
+ // and focusing another element in the same task as that unmount makes iOS
364
+ // Safari scroll the whole document to the top — the user is thrown from
365
+ // wherever the field sat to the start of the page. Measured on the iOS 26
366
+ // simulator against the live docsite, field at scrollY 2055: synchronous
367
+ // focus lands at 0, deferred focus stays at 2055.
368
+ //
369
+ // `preventScroll` alone does NOT fix it (verified: still 0) — this is not
370
+ // the browser's ordinary scroll-the-focused-element-into-view step, so the
371
+ // deferral is the load-bearing half. It is kept because the reveal scroll
372
+ // is real too, and unwanted for the same reason: the field the user just
373
+ // tapped is already on screen (+12px on a plain page without it).
374
+ //
375
+ // Skipping the focus entirely would also stop the scroll, but then focus
376
+ // dies with the unmounting button and lands on <body>.
377
+ const field = inputRef.current;
378
+ if (field == null) {
379
+ return;
380
+ }
381
+ clearFocusTimerRef.current = window.setTimeout(() => {
382
+ clearFocusTimerRef.current = null;
383
+ field.focus({
384
+ preventScroll: true
385
+ });
386
+ }, 0);
354
387
  }, [fireChange]);
355
388
 
356
389
  /**
@@ -4,6 +4,12 @@
4
4
  * @output Exports Dialog component, DialogProps, DialogVariant, DialogPurpose types
5
5
  * @position Core implementation; consumed by index.ts, tested by Dialog.test.tsx
6
6
  *
7
+ * The standard variant treats `width` as the preferred surface width, then
8
+ * clamps it to the dynamic viewport with spacing-token gutters so narrow
9
+ * viewports keep content and controls on screen without changing the public API.
10
+ * Fullscreen dialogs preserve the same padding floor while honoring safe-area
11
+ * insets, and fade in without the centered-dialog translate/scale motion.
12
+ *
7
13
  * SYNC: When modified, update these files to stay in sync:
8
14
  * - /packages/core/src/Dialog/Dialog.doc.mjs (props table, features, implementation notes)
9
15
  * - /packages/core/src/Dialog/Dialog.test.tsx (tests for new/changed behavior)
@@ -99,7 +105,7 @@ export interface DialogProps extends BaseProps<HTMLDialogElement> {
99
105
  * The actual height will be the height of its content.
100
106
  * Numbers are treated as pixels, strings are used as-is.
101
107
  * Ignored when variant is 'fullscreen'.
102
- * @default '75vh'
108
+ * @default '75dvh'
103
109
  */
104
110
  maxHeight?: number | string;
105
111
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../src/Dialog/Dialog.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAsB5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAKhD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,SAAS,CAAC;AAsB9C;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzD,4EAA4E;AAC5E,UAAU,mBAAmB;IAC3B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAe,SAAQ,mBAAmB;IACzD,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAuHD;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,cAAc;;;;;EAUpE;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC/D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;;;;OAOG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;IAE3C;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IAEpC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,QAAgB,EAChB,YAAY,EACZ,KAAW,EACX,SAAkB,EAClB,QAAQ,EACR,OAAoB,EACpB,OAAgB,EAChB,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,sCA6Sb;yBA7Te,MAAM"}
1
+ {"version":3,"file":"Dialog.d.ts","sourceRoot":"","sources":["../../src/Dialog/Dialog.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAuB5C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAKhD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,SAAS,CAAC;AAsB9C;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzD,4EAA4E;AAC5E,UAAU,mBAAmB;IAC3B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAe,SAAQ,mBAAmB;IACzD,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AA8JD;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,cAAc;;;;;EAUpE;AAED,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC/D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;;;;OAOG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;IAE3C;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IAEpC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,QAAgB,EAChB,YAAY,EACZ,KAAW,EACX,SAAmB,EACnB,QAAQ,EACR,OAAoB,EACpB,OAAgB,EAChB,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,sCAmTb;yBAnUe,MAAM"}
@@ -8,6 +8,12 @@
8
8
  * @output Exports Dialog component, DialogProps, DialogVariant, DialogPurpose types
9
9
  * @position Core implementation; consumed by index.ts, tested by Dialog.test.tsx
10
10
  *
11
+ * The standard variant treats `width` as the preferred surface width, then
12
+ * clamps it to the dynamic viewport with spacing-token gutters so narrow
13
+ * viewports keep content and controls on screen without changing the public API.
14
+ * Fullscreen dialogs preserve the same padding floor while honoring safe-area
15
+ * insets, and fade in without the centered-dialog translate/scale motion.
16
+ *
11
17
  * SYNC: When modified, update these files to stay in sync:
12
18
  * - /packages/core/src/Dialog/Dialog.doc.mjs (props table, features, implementation notes)
13
19
  * - /packages/core/src/Dialog/Dialog.test.tsx (tests for new/changed behavior)
@@ -21,7 +27,7 @@ import { useScrollLock } from "../hooks/useScrollLock.js";
21
27
  import { hasActiveFocusTrapEscape } from "../hooks/useFocusTrap.js";
22
28
  import { isImeKeyEvent } from "../utils/ime.js";
23
29
  import "../theme/tokens.stylex.js";
24
- import { colorVars, radiusVars, durationVars, easeVars, shadowVars } from "../theme/tokens.stylex.js";
30
+ import { colorVars, radiusVars, durationVars, easeVars, shadowVars, spacingVars } from "../theme/tokens.stylex.js";
25
31
  import { container } from "../Layout/container.stylex.js";
26
32
  import { paddingStyles, containerPaddingInlineVarStyles, containerPaddingBlockStartVarStyles, containerPaddingBlockEndVarStyles, spacingStepToToken, overlayPaddingReset } from "../Layout/padding.stylex.js";
27
33
  import { mergeProps, mergeRefs } from "../utils/index.js";
@@ -72,6 +78,7 @@ function getDialogDirection(triggerEl, distance = 16) {
72
78
  */
73
79
 
74
80
  const enterDirectional = "x11lauxq-B";
81
+ const enterFullscreen = "x18re5ia-B";
75
82
 
76
83
  /**
77
84
  * Dialog styles using native <dialog> element
@@ -117,6 +124,17 @@ const styles = {
117
124
  kpwlN0: "x10a8y8t",
118
125
  $$css: true
119
126
  },
127
+ fullscreenOpen: {
128
+ kKVMdj: "xqcmdr3 x1aquc0h",
129
+ $$css: true
130
+ },
131
+ fullscreenSafeArea: {
132
+ kLKAdn: "x1wv8a48",
133
+ kGO01o: "x143jlsb",
134
+ kZCmMZ: "x17j1249",
135
+ kwRFfy: "x57p45w",
136
+ $$css: true
137
+ },
120
138
  inner: {
121
139
  k1xSpc: "x78zum5",
122
140
  kXwgrk: "xdt5ytf",
@@ -139,26 +157,35 @@ const styles = {
139
157
  $$css: true
140
158
  }
141
159
  };
142
-
143
- // Dynamic styles for width, maxHeight, and position
160
+ const STANDARD_DIALOG_VIEWPORT_GUTTER = spacingVars['--spacing-4'];
161
+ const STANDARD_DIALOG_VIEWPORT_MAX_WIDTH = `calc(100dvw - ${STANDARD_DIALOG_VIEWPORT_GUTTER} - ${STANDARD_DIALOG_VIEWPORT_GUTTER})`;
162
+ const STANDARD_DIALOG_MAX_WIDTH = `min(100%, ${STANDARD_DIALOG_VIEWPORT_MAX_WIDTH})`;
163
+ function formatSizeValue(value) {
164
+ return typeof value === 'number' ? `${value}px` : value;
165
+ }
166
+ function resolveDialogSizing(width, maxHeight) {
167
+ return {
168
+ width: formatSizeValue(width),
169
+ maxWidth: STANDARD_DIALOG_MAX_WIDTH,
170
+ maxHeight: formatSizeValue(maxHeight)
171
+ };
172
+ }
144
173
  const _temp = {
145
- ks0D6T: "x95b5qq",
146
- "$$css": true
147
- };
148
- const _temp2 = {
149
174
  kogj98: "x1ghz6dp",
150
175
  "$$css": true
151
176
  };
152
177
  const dynamicStyles = {
153
- sizing: (width, maxHeight) => [_temp, {
154
- kzqmXN: (typeof width === 'number' ? `${width}px` : width) != null ? "x5lhr3w" : typeof width === 'number' ? `${width}px` : width,
155
- kskxy: (typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight) != null ? "x1jols5v" : typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight,
178
+ sizing: (width, maxWidth, maxHeight) => [{
179
+ kzqmXN: width != null ? "x5lhr3w" : width,
180
+ ks0D6T: maxWidth != null ? "xf68679" : maxWidth,
181
+ kskxy: maxHeight != null ? "x1jols5v" : maxHeight,
156
182
  $$css: true
157
183
  }, {
158
- "--x-width": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(typeof width === 'number' ? `${width}px` : width),
159
- "--x-maxHeight": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight)
184
+ "--x-width": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(width),
185
+ "--x-maxWidth": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(maxWidth),
186
+ "--x-maxHeight": (val => typeof val === "number" ? val + "px" : val != null ? val : undefined)(maxHeight)
160
187
  }],
161
- position: (top, insetInlineStart, insetInlineEnd, bottom) => [_temp2, {
188
+ position: (top, insetInlineStart, insetInlineEnd, bottom) => [_temp, {
162
189
  k87sOh: top != null ? "xjbys53" : top,
163
190
  kLqNvP: insetInlineStart != null ? "x1lxsm33" : insetInlineStart,
164
191
  kt4wiu: insetInlineEnd != null ? "xqxgn94" : insetInlineEnd,
@@ -230,7 +257,7 @@ export function Dialog({
230
257
  isInline = false,
231
258
  onOpenChange,
232
259
  width = 400,
233
- maxHeight = '75vh',
260
+ maxHeight = '75dvh',
234
261
  position,
235
262
  variant = 'standard',
236
263
  purpose = 'info',
@@ -247,6 +274,7 @@ export function Dialog({
247
274
  const effectivePadding = padding ?? 4;
248
275
  const paddingToken = spacingStepToToken[effectivePadding];
249
276
  const isFullscreen = variant === 'fullscreen';
277
+ const standardSizing = isFullscreen ? null : resolveDialogSizing(width, maxHeight);
250
278
 
251
279
  // Default accessible name: publish a title id through DialogContext so a
252
280
  // DialogHeader applies it to its heading (mirrors AlertDialog's explicit
@@ -400,19 +428,17 @@ export function Dialog({
400
428
  onOpenChange(false);
401
429
  }
402
430
  };
403
-
404
- // Shared inner content wrapper
405
431
  const innerContent = /*#__PURE__*/_jsx("div", {
406
432
  ...stylex.props(styles.inner, ...container(useThemeDefault ? {
407
433
  useThemeDefault: 'dialog',
408
- maxHeight: isFullscreen ? undefined : typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight
434
+ maxHeight: standardSizing?.maxHeight
409
435
  } : {
410
436
  paddingInnerX: paddingToken,
411
437
  paddingInnerY: paddingToken,
412
438
  paddingOuterX: paddingToken,
413
439
  paddingOuterY: paddingToken,
414
- maxHeight: isFullscreen ? undefined : typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight
415
- }), !useThemeDefault && effectivePadding !== 4 && paddingStyles[effectivePadding], !useThemeDefault && effectivePadding !== 4 && containerPaddingInlineVarStyles[effectivePadding], !useThemeDefault && effectivePadding !== 4 && containerPaddingBlockStartVarStyles[effectivePadding], !useThemeDefault && effectivePadding !== 4 && containerPaddingBlockEndVarStyles[effectivePadding]),
440
+ maxHeight: standardSizing?.maxHeight
441
+ }), !useThemeDefault && effectivePadding !== 4 && paddingStyles[effectivePadding], !useThemeDefault && effectivePadding !== 4 && containerPaddingInlineVarStyles[effectivePadding], !useThemeDefault && effectivePadding !== 4 && containerPaddingBlockStartVarStyles[effectivePadding], !useThemeDefault && effectivePadding !== 4 && containerPaddingBlockEndVarStyles[effectivePadding], isFullscreen && styles.fullscreenSafeArea),
416
442
  children: /*#__PURE__*/_jsx(DialogContext, {
417
443
  value: dialogContextValue,
418
444
  children: children
@@ -435,7 +461,7 @@ export function Dialog({
435
461
  ...safeProps,
436
462
  ...mergeProps(themeProps('dialog', {
437
463
  variant
438
- }), stylex.props(styles.inlineWrapper, overlayPaddingReset.reset, !isFullscreen && dynamicStyles.sizing(width, maxHeight), isFullscreen && styles.fullscreen, xstyle), className, style),
464
+ }), stylex.props(styles.inlineWrapper, overlayPaddingReset.reset, standardSizing && dynamicStyles.sizing(standardSizing.width, standardSizing.maxWidth, standardSizing.maxHeight), isFullscreen && styles.fullscreen, xstyle), className, style),
439
465
  "data-testid": props['data-testid'],
440
466
  children: innerContent
441
467
  });
@@ -448,10 +474,10 @@ export function Dialog({
448
474
  ...safeProps,
449
475
  ...mergeProps(themeProps('dialog', {
450
476
  variant
451
- }), focusOutlineProps.focusVisible(styles.dialog, overlayPaddingReset.reset, isOpen && styles.open, styles.backdrop, !isFullscreen && dynamicStyles.sizing(width, maxHeight), hasPosition && (() => {
477
+ }), focusOutlineProps.focusVisible(styles.dialog, overlayPaddingReset.reset, isOpen && styles.open, styles.backdrop, standardSizing && dynamicStyles.sizing(standardSizing.width, standardSizing.maxWidth, standardSizing.maxHeight), hasPosition && (() => {
452
478
  const o = resolveDialogPositionOffsets(position);
453
479
  return dynamicStyles.position(o.top, o.insetInlineStart, o.insetInlineEnd, o.bottom);
454
- })(), isFullscreen && styles.fullscreen, xstyle), className, style),
480
+ })(), isFullscreen && styles.fullscreen, isFullscreen && isOpen && styles.fullscreenOpen, xstyle), className, style),
455
481
  onClick: handleClick,
456
482
  onCancel: handleCancel,
457
483
  "aria-modal": "true"
@@ -1 +1 @@
1
- {"version":3,"file":"Heading.d.ts","sourceRoot":"","sources":["../../src/Heading/Heading.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAyB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAE7D,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,WAAW,EACX,SAAS,EACT,QAAQ,EACT,MAAM,gBAAgB,CAAC;AAiBxB,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,UAAU,CAAC;AAE7C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAO5C;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEjD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;AAElE,MAAM,WAAW,YAAa,SAAQ,IAAI,CACxC,SAAS,CAAC,kBAAkB,CAAC,EAC7B,UAAU,CACX;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACpC;;;OAGG;IACH,KAAK,EAAE,YAAY,CAAC;IAEpB;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IAEnB;;;;;;;;;;;OAWG;IACH,kBAAkB,CAAC,EAAE,YAAY,CAAC;IAElC;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC;IAE9C;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAWD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,IAAI,EACJ,kBAAkB,EAClB,KAAiB,EACjB,OAAiB,EACjB,QAAY,EACZ,kBAAyB,EACzB,SAAS,EACT,QAAQ,EACR,OAAiB,EACjB,UAAkB,EAClB,gBAAwB,EACxB,MAAM,EACN,SAAS,EACT,KAAK,EACL,QAAQ,EACR,GAAG,EACH,GAAG,KAAK,EACT,EAAE,YAAY,+BAmFd;yBAtGe,OAAO"}
1
+ {"version":3,"file":"Heading.d.ts","sourceRoot":"","sources":["../../src/Heading/Heading.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAyB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAE7D,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,WAAW,EACX,SAAS,EACT,QAAQ,EACT,MAAM,gBAAgB,CAAC;AAiBxB,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,UAAU,CAAC;AAG7C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAO5C;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEjD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;AAElE,MAAM,WAAW,YAAa,SAAQ,IAAI,CACxC,SAAS,CAAC,kBAAkB,CAAC,EAC7B,UAAU,CACX;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACpC;;;OAGG;IACH,KAAK,EAAE,YAAY,CAAC;IAEpB;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IAEnB;;;;;;;;;;;OAWG;IACH,kBAAkB,CAAC,EAAE,YAAY,CAAC;IAElC;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC;IAE9C;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAWD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,IAAI,EACJ,kBAAkB,EAClB,KAAiB,EACjB,OAAiB,EACjB,QAAY,EACZ,kBAAyB,EACzB,SAAS,EACT,QAAQ,EACR,OAAiB,EACjB,UAAkB,EAClB,gBAAwB,EACxB,MAAM,EACN,SAAS,EACT,KAAK,EACL,QAAQ,EACR,GAAG,EACH,GAAG,KAAK,EACT,EAAE,YAAY,+BAsFd;yBAzGe,OAAO"}
@@ -21,7 +21,8 @@ import * as stylex from '@stylexjs/stylex';
21
21
  import { colorStyles, sizeByLevelStyles, sizeByTypeStyles, defaultWeightByTypeStyles, displayStyles, justifyStyles, truncationStyles, wordBreakStyles, textWrapStyles, capsizeStyles, decorationStyles, truncationTooltipStyles } from "../Text/text.stylex.js";
22
22
  import { useTruncation } from "../Text/useTruncation.js";
23
23
  import { resolveStyleColor } from "../Text/Text.js";
24
- import { mergeProps, mergeRefs } from "../utils/index.js";
24
+ import { mergeProps } from "../utils/index.js";
25
+ import { useMergedRefs } from "../hooks/useMergedRefs.js";
25
26
  import { themeProps } from "../utils/themeProps.js";
26
27
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
27
28
  const LazyXDSTooltip = /*#__PURE__*/lazy(async () => import("../Tooltip/Tooltip.js").then(mod => ({
@@ -107,13 +108,16 @@ export function Heading({
107
108
  // Ref for the heading element (used as tooltip anchor)
108
109
  const headingRef = useRef(null);
109
110
 
111
+ // Keep the merged ref stable across rerenders.
112
+ const mergedRef = useMergedRefs(ref, truncation.ref, headingRef);
113
+
110
114
  // Build inline style for -webkit-line-clamp (dynamic value)
111
115
  const inlineStyle = maxLines > 1 ? {
112
116
  WebkitLineClamp: maxLines
113
117
  } : undefined;
114
118
  return /*#__PURE__*/_jsxs(_Fragment, {
115
119
  children: [/*#__PURE__*/_jsx(Component, {
116
- ref: mergeRefs(ref, truncation.ref, headingRef),
120
+ ref: mergedRef,
117
121
  ...mergeProps(themeProps('heading', {
118
122
  level,
119
123
  color,
@@ -1 +1 @@
1
- {"version":3,"file":"Kbd.d.ts","sourceRoot":"","sources":["../../src/Kbd/Kbd.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,OAAO,KAA6B,MAAM,OAAO,CAAC;AAGlD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AA4H5C,MAAM,WAAW,QAAS,SAAQ,SAAS,CAAC,eAAe,CAAC;IAC1D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACjC;;;;;;;;;;;;OAYG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,GAAG,CAAC,EAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,EAAC,EAAE,QAAQ,qBAgC3E;yBAhCe,GAAG"}
1
+ {"version":3,"file":"Kbd.d.ts","sourceRoot":"","sources":["../../src/Kbd/Kbd.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,OAAO,KAA6B,MAAM,OAAO,CAAC;AAGlD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAmI5C,MAAM,WAAW,QAAS,SAAQ,SAAS,CAAC,eAAe,CAAC;IAC1D,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACjC;;;;;;;;;;;;OAYG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,GAAG,CAAC,EAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,EAAC,EAAE,QAAQ,qBAgC3E;yBAhCe,GAAG"}
package/dist/Kbd/Kbd.js CHANGED
@@ -101,8 +101,9 @@ function getServerPlatformSnapshot() {
101
101
 
102
102
  /**
103
103
  * Detects whether the current platform is macOS/iOS.
104
- * Prefers the User-Agent Client Hints API when available (modern Chrome/Edge),
105
- * falls back to navigator.platform (deprecated but universally supported).
104
+ * Prefers the User-Agent Client Hints API when it names a platform (modern
105
+ * Chrome/Edge), falls back to navigator.platform (deprecated but universally
106
+ * supported) when it is absent or blank.
106
107
  */
107
108
  function detectMac() {
108
109
  if (typeof navigator === 'undefined') {
@@ -111,7 +112,13 @@ function detectMac() {
111
112
  // Prefer User-Agent Client Hints API (not deprecated)
112
113
  const uaData = 'userAgentData' in navigator ? navigator.userAgentData : null;
113
114
  if (uaData && typeof uaData === 'object' && 'platform' in uaData) {
114
- return /mac/i.test(uaData.platform ?? '');
115
+ const uaPlatform = uaData.platform;
116
+ // A blank platform is no answer, not a negative one. Builds that rewrite
117
+ // their client-hints identity ship '', so fall through rather than
118
+ // reading it as "not Apple".
119
+ if (typeof uaPlatform === 'string' && uaPlatform.trim() !== '') {
120
+ return /mac/i.test(uaPlatform);
121
+ }
115
122
  }
116
123
  // Fallback: navigator.platform (deprecated but still shipped everywhere)
117
124
  return /Mac|iPhone|iPad|iPod/.test(navigator.platform ?? '');
@@ -6,5 +6,5 @@
6
6
  export { Markdown } from './Markdown';
7
7
  export type { MarkdownProps, MarkdownSource, MarkdownComponents, MarkdownInlinePlugin, } from './Markdown';
8
8
  export { parseMarkdown, parseMarkdownIncremental, createIncrementalState, parseInline, } from './parser';
9
- export type { BlockNode, InlineNode, ListItemNode, TableCellNode, TableAlignment, IncrementalState as IncrementalParseState, } from './parser';
9
+ export type { BlockNode, InlineNode, SourceRange, ListItemNode, TableCellNode, TableAlignment, IncrementalState as IncrementalParseState, } from './parser';
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Markdown/index.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AACpC,YAAY,EACV,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,EACb,wBAAwB,EACxB,sBAAsB,EACtB,WAAW,GACZ,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,SAAS,EACT,UAAU,EACV,YAAY,EACZ,aAAa,EACb,cAAc,EACd,gBAAgB,IAAI,qBAAqB,GAC1C,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Markdown/index.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AACpC,YAAY,EACV,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,aAAa,EACb,wBAAwB,EACxB,sBAAsB,EACtB,WAAW,GACZ,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,SAAS,EACT,UAAU,EACV,WAAW,EACX,YAAY,EACZ,aAAa,EACb,cAAc,EACd,gBAAgB,IAAI,qBAAqB,GAC1C,MAAM,UAAU,CAAC"}