@astryxdesign/lab 0.7.9-canary.4e7823a → 0.7.9-canary.53fa237

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 (35) hide show
  1. package/blocks/CommentThreadShowcase.tsx +1 -1
  2. package/dist/Chart/formatters.d.ts +9 -6
  3. package/dist/Chart/formatters.d.ts.map +1 -1
  4. package/dist/Chart/formatters.js +16 -11
  5. package/dist/CircularProgress/CircularProgress.d.ts +4 -2
  6. package/dist/CircularProgress/CircularProgress.d.ts.map +1 -1
  7. package/dist/CircularProgress/CircularProgress.js +19 -23
  8. package/dist/Schedule/DayView.d.ts.map +1 -1
  9. package/dist/Schedule/DayView.js +7 -4
  10. package/dist/Schedule/ListView.d.ts.map +1 -1
  11. package/dist/Schedule/ListView.js +8 -9
  12. package/dist/Schedule/MonthlyView.d.ts.map +1 -1
  13. package/dist/Schedule/MonthlyView.js +25 -18
  14. package/dist/Schedule/TimeGridView.d.ts.map +1 -1
  15. package/dist/Schedule/TimeGridView.js +22 -16
  16. package/dist/Schedule/WeeklyView.d.ts.map +1 -1
  17. package/dist/Schedule/WeeklyView.js +4 -4
  18. package/dist/Schedule/shared.d.ts +19 -13
  19. package/dist/Schedule/shared.d.ts.map +1 -1
  20. package/dist/Schedule/shared.js +80 -62
  21. package/dist/lab.css +0 -8
  22. package/package.json +7 -6
  23. package/src/Chart/formatters.test.ts +36 -0
  24. package/src/Chart/formatters.ts +28 -16
  25. package/src/CircularProgress/CircularProgress.test.tsx +23 -0
  26. package/src/CircularProgress/CircularProgress.tsx +15 -42
  27. package/src/Schedule/DayView.tsx +4 -3
  28. package/src/Schedule/ListView.tsx +8 -14
  29. package/src/Schedule/MonthlyView.tsx +27 -18
  30. package/src/Schedule/Schedule.calendarSystems.test.tsx +317 -0
  31. package/src/Schedule/Schedule.doc.mjs +1 -1
  32. package/src/Schedule/Schedule.test.tsx +2 -2
  33. package/src/Schedule/TimeGridView.tsx +31 -9
  34. package/src/Schedule/WeeklyView.tsx +4 -6
  35. package/src/Schedule/shared.tsx +112 -68
@@ -36,7 +36,7 @@ export default function CommentThreadShowcase() {
36
36
  });
37
37
 
38
38
  return (
39
- <Card padding={0} width={340}>
39
+ <Card padding={0} width="100%" maxWidth={340}>
40
40
  <CommentThread
41
41
  comment={thread}
42
42
  currentUser={VIEWER}
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * @file formatters.ts
3
- * @input Tick values and optional BCP 47 locale tags
3
+ * @input Tick values, optional BCP 47 locale tags, and for dates an optional
4
+ * calendar
4
5
  * @output Built-in tick format utilities for common data types
5
6
  * @position Utility; consumed by ChartAxis via tickFormat prop
6
7
  */
7
- import type { Locale } from '@astryxdesign/core/i18n';
8
+ import type { CalendarSystem, Locale } from '@astryxdesign/core/i18n';
8
9
  /**
9
10
  * Compact number formatter (e.g. 1200 → "1.2K", 1500000 → "1.5M")
10
11
  */
@@ -25,11 +26,13 @@ export declare function currency(symbol?: string, locale?: Locale): (value: unkn
25
26
  */
26
27
  export declare function percent(value: unknown): string;
27
28
  /**
28
- * Date formatter — short date (e.g. "Jan 5", "Mar 12")
29
+ * Date formatter — short date (e.g. "Jan 5", "Mar 12"), in `calendar`
30
+ * (Gregorian by default)
29
31
  */
30
- export declare function shortDate(value: unknown, locale?: Locale): string;
32
+ export declare function shortDate(value: unknown, locale?: Locale, calendar?: CalendarSystem): string;
31
33
  /**
32
- * Date formatter — month/year (e.g. "Jan 2024", "Mar 2025")
34
+ * Date formatter — month/year (e.g. "Jan 2024", "Mar 2025"), in `calendar`
35
+ * (Gregorian by default)
33
36
  */
34
- export declare function monthYear(value: unknown, locale?: Locale): string;
37
+ export declare function monthYear(value: unknown, locale?: Locale, calendar?: CalendarSystem): string;
35
38
  //# sourceMappingURL=formatters.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/Chart/formatters.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAepD;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CACtB,MAAM,SAAM,EACZ,MAAM,GAAE,MAAa,GACpB,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAiB5B;AAQD;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAM9C;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,GAAE,MAAa,GAAG,MAAM,CAUvE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,GAAE,MAAa,GAAG,MAAM,CAUvE"}
1
+ {"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/Chart/formatters.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAC,cAAc,EAAE,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAGpE;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAepD;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CACtB,MAAM,SAAM,EACZ,MAAM,GAAE,MAAa,GACpB,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAiB5B;AAQD;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAM9C;AAED;;;GAGG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,OAAO,EACd,MAAM,GAAE,MAAa,EACrB,QAAQ,GAAE,cAA0B,GACnC,MAAM,CAUR;AAED;;;GAGG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,OAAO,EACd,MAAM,GAAE,MAAa,EACrB,QAAQ,GAAE,cAA0B,GACnC,MAAM,CAUR"}
@@ -2,11 +2,14 @@
2
2
 
3
3
  /**
4
4
  * @file formatters.ts
5
- * @input Tick values and optional BCP 47 locale tags
5
+ * @input Tick values, optional BCP 47 locale tags, and for dates an optional
6
+ * calendar
6
7
  * @output Built-in tick format utilities for common data types
7
8
  * @position Utility; consumed by ChartAxis via tickFormat prop
8
9
  */
9
10
 
11
+ import { plainDateFormat, plainDateFromDate } from '@astryxdesign/core/utils';
12
+
10
13
  /**
11
14
  * Compact number formatter (e.g. 1200 → "1.2K", 1500000 → "1.5M")
12
15
  */
@@ -74,31 +77,33 @@ export function percent(value) {
74
77
  }
75
78
 
76
79
  /**
77
- * Date formatter — short date (e.g. "Jan 5", "Mar 12")
80
+ * Date formatter — short date (e.g. "Jan 5", "Mar 12"), in `calendar`
81
+ * (Gregorian by default)
78
82
  */
79
- export function shortDate(value, locale = 'en') {
83
+ export function shortDate(value, locale = 'en', calendar = 'gregory') {
80
84
  const d = value instanceof Date ? value : new Date(Number(value));
81
85
  if (isNaN(d.getTime())) {
82
86
  return String(value);
83
87
  }
84
- return new Intl.DateTimeFormat(locale, {
88
+ return plainDateFormat(plainDateFromDate(d), {
85
89
  month: 'short',
86
90
  day: 'numeric',
87
- calendar: 'gregory'
88
- }).format(d);
91
+ calendar
92
+ }, locale);
89
93
  }
90
94
 
91
95
  /**
92
- * Date formatter — month/year (e.g. "Jan 2024", "Mar 2025")
96
+ * Date formatter — month/year (e.g. "Jan 2024", "Mar 2025"), in `calendar`
97
+ * (Gregorian by default)
93
98
  */
94
- export function monthYear(value, locale = 'en') {
99
+ export function monthYear(value, locale = 'en', calendar = 'gregory') {
95
100
  const d = value instanceof Date ? value : new Date(Number(value));
96
101
  if (isNaN(d.getTime())) {
97
102
  return String(value);
98
103
  }
99
- return new Intl.DateTimeFormat(locale, {
104
+ return plainDateFormat(plainDateFromDate(d), {
100
105
  month: 'short',
101
106
  year: 'numeric',
102
- calendar: 'gregory'
103
- }).format(d);
107
+ calendar
108
+ }, locale);
104
109
  }
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * @file CircularProgress.tsx
3
3
  * @input Uses React (useId, refs, layout effects), stylex, SVG, Web
4
- * Animations, color/spacing/duration/ease tokens
4
+ * Animations, color/spacing/duration/ease tokens, and Spinner's rotor
5
+ * (core internal/spinner-rotor) for the indeterminate ring
5
6
  * @output Exports CircularProgress component, CircularProgressProps, CircularProgressSize, CircularProgressVariant types
6
7
  * @position Core implementation; consumed by index.ts
7
8
  *
@@ -89,7 +90,8 @@ export interface CircularProgressProps extends BaseProps<HTMLDivElement> {
89
90
  */
90
91
  variant?: CircularProgressVariant;
91
92
  /**
92
- * When true, renders an animated indeterminate progress indicator.
93
+ * When true, renders an animated indeterminate progress indicator: an arc
94
+ * that turns as Spinner's does.
93
95
  * Use when the progress amount is unknown (e.g. loading, processing).
94
96
  * The `value` and `hasValueLabel` props are ignored in this mode.
95
97
  * Respects `prefers-reduced-motion` by slowing the animation.
@@ -1 +1 @@
1
- {"version":3,"file":"CircularProgress.d.ts","sourceRoot":"","sources":["../../src/CircularProgress/CircularProgress.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAiC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAYrE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAGlD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,IAAI,CAAC;IACb,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,IAAI,CAAC;IACZ,OAAO,EAAE,IAAI,CAAC;CACf;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,0BAA0B,CAAC;AAEvE,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAWtD,MAAM,WAAW,qBAAsB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACtE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1D;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE,uBAAuB,CAAC;IAClC;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAmWD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAS,EACT,GAAS,EACT,KAAK,EACL,aAAoB,EACpB,aAAqB,EACrB,gBAA0C,EAC1C,QAAQ,EACR,IAAW,EACX,OAAkB,EAClB,eAAuB,EACvB,UAAkB,EAClB,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,UAAU,EACzB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,qBAAqB,+BA+QvB;yBAjSe,gBAAgB"}
1
+ {"version":3,"file":"CircularProgress.d.ts","sourceRoot":"","sources":["../../src/CircularProgress/CircularProgress.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAiC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAiBrE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAGlD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,IAAI,CAAC;IACb,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,IAAI,CAAC;IACZ,OAAO,EAAE,IAAI,CAAC;CACf;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,0BAA0B,CAAC;AAEvE,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAWtD,MAAM,WAAW,qBAAsB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACtE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1D;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE,uBAAuB,CAAC;IAClC;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA2TD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAS,EACT,GAAS,EACT,KAAK,EACL,aAAoB,EACpB,aAAqB,EACrB,gBAA0C,EAC1C,QAAQ,EACR,IAAW,EACX,OAAkB,EAClB,eAAuB,EACvB,UAAkB,EAClB,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,UAAU,EACzB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,qBAAqB,+BAqRvB;yBAvSe,gBAAgB"}
@@ -5,7 +5,8 @@
5
5
  /**
6
6
  * @file CircularProgress.tsx
7
7
  * @input Uses React (useId, refs, layout effects), stylex, SVG, Web
8
- * Animations, color/spacing/duration/ease tokens
8
+ * Animations, color/spacing/duration/ease tokens, and Spinner's rotor
9
+ * (core internal/spinner-rotor) for the indeterminate ring
9
10
  * @output Exports CircularProgress component, CircularProgressProps, CircularProgressSize, CircularProgressVariant types
10
11
  * @position Core implementation; consumed by index.ts
11
12
  *
@@ -19,6 +20,7 @@ import { useId, useLayoutEffect, useRef } from 'react';
19
20
  import * as stylex from '@stylexjs/stylex';
20
21
  import '@astryxdesign/core/theme/tokens.stylex';
21
22
  import { colorVars, durationVars, easeVars, fontWeightVars, spacingVars, typeScaleVars } from '@astryxdesign/core/theme/tokens.stylex';
23
+ import { SPINNER_ARC_FRACTION, spinnerRotorStyles, syncRotationPhase } from '@astryxdesign/core/internal/spinner-rotor';
22
24
  import { mergeProps } from '@astryxdesign/core/utils';
23
25
  import { themeProps } from '@astryxdesign/core/utils';
24
26
 
@@ -52,16 +54,6 @@ const SIZE_CONFIG = {
52
54
  strokeWidth: 5
53
55
  }
54
56
  };
55
- // =============================================================================
56
- // Indeterminate animation
57
- // =============================================================================
58
-
59
- const indeterminateRotation = "xqng64z-B";
60
-
61
- // SVG dash percentages scale with the square viewport. A 300% gap exceeds every
62
- // ring circumference; shifting the 2% + 300% pattern by 302% closes the loop.
63
- const indeterminateDash = "x9ppb3p-B";
64
-
65
57
  // =============================================================================
66
58
  // Styles
67
59
  // =============================================================================
@@ -80,6 +72,15 @@ const styles = {
80
72
  kOIVth: "xzye2dw",
81
73
  $$css: true
82
74
  },
75
+ svg: {
76
+ k1xSpc: "x1lliihq",
77
+ k3aq6I: "x9tu13d",
78
+ $$css: true
79
+ },
80
+ svgIndeterminate: {
81
+ k1xSpc: "x1lliihq",
82
+ $$css: true
83
+ },
83
84
  track: {
84
85
  kDwRjp: "xbh8q5q",
85
86
  kjVXCG: "xpi25hw",
@@ -98,10 +99,6 @@ const styles = {
98
99
  fillIndeterminate: {
99
100
  kDwRjp: "xbh8q5q",
100
101
  kU5bRw: "x1owpc8m",
101
- kKVMdj: "x16zax3f",
102
- k44tkh: "xmg6eyc xnh0sag",
103
- kyAemX: "x4hg4is",
104
- ko0y90: "xa4qsjk",
105
102
  $$css: true
106
103
  }
107
104
  };
@@ -462,14 +459,8 @@ export function CircularProgress({
462
459
  width: diameter,
463
460
  height: diameter,
464
461
  viewBox: `0 0 ${diameter} ${diameter}`,
465
- ...{
466
- 0: {
467
- className: "x1lliihq x9tu13d"
468
- },
469
- 1: {
470
- className: "x1lliihq x1ka1v4i x1c74tu6 xy02sl2 x1esw782 xa4qsjk"
471
- }
472
- }[!!isIndeterminate << 0],
462
+ ref: isIndeterminate ? syncRotationPhase : undefined,
463
+ ...stylex.props(isIndeterminate ? styles.svgIndeterminate : styles.svg, isIndeterminate && spinnerRotorStyles.turn),
473
464
  children: [/*#__PURE__*/_jsx("circle", {
474
465
  ...mergeProps(themeProps('circular-progress-track'), stylex.props(styles.track, trackVariantStyles[trackVariant])),
475
466
  cx: center,
@@ -484,6 +475,11 @@ export function CircularProgress({
484
475
  cy: center,
485
476
  r: radius,
486
477
  strokeWidth: strokeWidth
478
+ // Spinner's arc: the same fraction of the ring, starting at 12
479
+ // o'clock.
480
+ ,
481
+ strokeDasharray: `${circumference * SPINNER_ARC_FRACTION} ${circumference * (1 - SPINNER_ARC_FRACTION)}`,
482
+ transform: `rotate(-90 ${center} ${center})`
487
483
  }) : null]
488
484
  }), isIndeterminate ? null :
489
485
  /*#__PURE__*/
@@ -1 +1 @@
1
- {"version":3,"file":"DayView.d.ts","sourceRoot":"","sources":["../../src/Schedule/DayView.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,2BAA2B,EAE3B,YAAY,EAEb,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,sBAAsB,GAAG,2BAA2B,CAAC;AAoCjE,wBAAgB,qBAAqB,CAAC,EACpC,OAAW,EACX,OAAY,EACZ,UAAgB,EAChB,aAAa,GACd,GAAE,sBAA2B,GAAG,YAAY,CAAC,sBAAsB,CAAC,CAgCpE"}
1
+ {"version":3,"file":"DayView.d.ts","sourceRoot":"","sources":["../../src/Schedule/DayView.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,2BAA2B,EAE3B,YAAY,EAEb,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,sBAAsB,GAAG,2BAA2B,CAAC;AAqCjE,wBAAgB,qBAAqB,CAAC,EACpC,OAAW,EACX,OAAY,EACZ,UAAgB,EAChB,aAAa,GACd,GAAE,sBAA2B,GAAG,YAAY,CAAC,sBAAsB,CAAC,CAgCpE"}
@@ -11,7 +11,7 @@
11
11
  import { DATE_FORMAT_WITH_WEEKDAY, plainDateAddDays, plainDateFormat } from '@astryxdesign/core/utils';
12
12
  import { enumerateDates, getScheduleRangeFromDates } from "./dateMath.js";
13
13
  import { useScheduleContext } from "./context.js";
14
- import { ScheduleMonthTitle, ScheduleFrame } from "./shared.js";
14
+ import { ScheduleMonthTitle, ScheduleFrame, useScheduleCalendar } from "./shared.js";
15
15
  import { TimeGridView } from "./TimeGridView.js";
16
16
  import { scheduleRangeToZonedDateTimeRange } from "./zonedDateTime.js";
17
17
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -35,11 +35,14 @@ function ScheduleDayView({
35
35
  } = options;
36
36
  const rangeDate = date.toPlainDate();
37
37
  const days = enumerateDates(range.startDate, range.endDate);
38
- const titleLabel = plainDateFormat(rangeDate, DATE_FORMAT_WITH_WEEKDAY, locale);
38
+ const calendar = useScheduleCalendar();
39
+ const titleLabel = plainDateFormat(rangeDate, {
40
+ ...DATE_FORMAT_WITH_WEEKDAY,
41
+ calendar
42
+ }, locale);
39
43
  return /*#__PURE__*/_jsx(ScheduleFrame, {
40
44
  title: /*#__PURE__*/_jsx(ScheduleMonthTitle, {
41
- date: rangeDate,
42
- timezoneID: timezoneID
45
+ date: rangeDate
43
46
  }),
44
47
  titleLabel: titleLabel,
45
48
  isLoading: isLoading,
@@ -1 +1 @@
1
- {"version":3,"file":"ListView.d.ts","sourceRoot":"","sources":["../../src/Schedule/ListView.tsx"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAGV,YAAY,EAEb,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA+ID,wBAAgB,sBAAsB,CAAC,EACrC,IAAI,EAAE,QAAY,GACnB,GAAE,uBAA4B,GAAG,YAAY,CAAC,uBAAuB,CAAC,CAmCtE"}
1
+ {"version":3,"file":"ListView.d.ts","sourceRoot":"","sources":["../../src/Schedule/ListView.tsx"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAGV,YAAY,EAEb,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAwID,wBAAgB,sBAAsB,CAAC,EACrC,IAAI,EAAE,QAAY,GACnB,GAAE,uBAA4B,GAAG,YAAY,CAAC,uBAAuB,CAAC,CAmCtE"}
@@ -13,7 +13,7 @@ import { plainDateAddDays, plainDateFromInstant, plainDateIsEqual, plainDateToIS
13
13
  import { Heading } from '@astryxdesign/core/Text';
14
14
  import { enumerateDates, eventOccursOnDate, getScheduleRangeFromDates, isDayEvent } from "./dateMath.js";
15
15
  import { useScheduleContext } from "./context.js";
16
- import { formatDayNumber, formatFullDate, formatWeekday, formatWeekTitle, isEventInPast, ListEventRow, ScheduleFrame, ScheduleRangeMonthTitle, styles } from "./shared.js";
16
+ import { formatDayNumber, formatFullDate, formatWeekday, formatWeekTitle, isEventInPast, ListEventRow, ScheduleFrame, ScheduleRangeMonthTitle, styles, useScheduleCalendar } from "./shared.js";
17
17
  import { useCurrentTime } from "./useCurrentTime.js";
18
18
  import { scheduleRangeToZonedDateTimeRange } from "./zonedDateTime.js";
19
19
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -26,11 +26,12 @@ function ScheduleListView(_props) {
26
26
  isLoading,
27
27
  headingLevel
28
28
  } = useScheduleContext();
29
+ const calendar = useScheduleCalendar();
29
30
  const days = enumerateDates(range.startDate, range.endDate);
30
31
  const currentTime = useCurrentTime();
31
32
  const currentPlainDate = plainDateFromInstant(currentTime, timezoneID);
32
33
  const endDate = plainDateAddDays(range.endDate, -1);
33
- const titleLabel = formatWeekTitle(range.startDate, endDate, timezoneID, locale);
34
+ const titleLabel = formatWeekTitle(range.startDate, endDate, locale, calendar);
34
35
  const visibleDays = days.map(day => {
35
36
  const isCurrentDay = plainDateIsEqual(day, currentPlainDate);
36
37
  const isBaseDay = plainDateIsEqual(day, range.startDate);
@@ -45,8 +46,7 @@ function ScheduleListView(_props) {
45
46
  return /*#__PURE__*/_jsx(ScheduleFrame, {
46
47
  title: /*#__PURE__*/_jsx(ScheduleRangeMonthTitle, {
47
48
  start: range.startDate,
48
- end: endDate,
49
- timezoneID: timezoneID
49
+ end: endDate
50
50
  }),
51
51
  titleLabel: titleLabel,
52
52
  isLoading: isLoading,
@@ -61,7 +61,6 @@ function ScheduleListView(_props) {
61
61
  children: [/*#__PURE__*/_jsx(ListDayHeading, {
62
62
  day: day,
63
63
  isCurrentDay: isCurrentDay,
64
- timezoneID: timezoneID,
65
64
  headingLevel: headingLevel
66
65
  }), /*#__PURE__*/_jsx("div", {
67
66
  ...stylex.props(styles.listEvents),
@@ -79,26 +78,26 @@ function ScheduleListView(_props) {
79
78
  function ListDayHeading({
80
79
  day,
81
80
  isCurrentDay,
82
- timezoneID,
83
81
  headingLevel
84
82
  }) {
85
83
  const {
86
84
  locale
87
85
  } = useScheduleContext();
86
+ const calendar = useScheduleCalendar();
88
87
  return /*#__PURE__*/_jsxs(Heading, {
89
88
  level: headingLevel,
90
89
  color: "secondary",
91
90
  display: "block",
92
- "aria-label": formatFullDate(day, timezoneID, locale),
91
+ "aria-label": formatFullDate(day, locale, calendar),
93
92
  "aria-current": isCurrentDay ? 'date' : undefined,
94
93
  xstyle: styles.listDayHeading,
95
94
  children: [/*#__PURE__*/_jsx("span", {
96
95
  ...stylex.props(styles.listDayNumber, isCurrentDay && styles.listDayNumberCurrent),
97
96
  children: /*#__PURE__*/_jsx("span", {
98
97
  ...stylex.props(styles.listDayNumberText),
99
- children: formatDayNumber(day, timezoneID, locale)
98
+ children: formatDayNumber(day, locale, calendar)
100
99
  })
101
- }), formatWeekday(day, timezoneID, 'short', locale)]
100
+ }), formatWeekday(day, 'short', locale, calendar)]
102
101
  });
103
102
  }
104
103
  function renderListRows({
@@ -1 +1 @@
1
- {"version":3,"file":"MonthlyView.d.ts","sourceRoot":"","sources":["../../src/Schedule/MonthlyView.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,OAAO,EAAS,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAmD7C,OAAO,KAAK,EACV,aAAa,EAEb,YAAY,EAEb,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,0BAA0B;IACzC,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzC;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,SAAS,CAAC;CACrD;AAolBD,wBAAgB,yBAAyB,CAAC,EACxC,YAAgB,EAChB,aAAa,GACd,GAAE,0BAA+B,GAAG,YAAY,CAAC,0BAA0B,CAAC,CAmC5E"}
1
+ {"version":3,"file":"MonthlyView.d.ts","sourceRoot":"","sources":["../../src/Schedule/MonthlyView.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AAEH,OAAO,EAAS,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAqD7C,OAAO,KAAK,EACV,aAAa,EAEb,YAAY,EAEb,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,0BAA0B;IACzC,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzC;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,SAAS,CAAC;CACrD;AA2lBD,wBAAgB,yBAAyB,CAAC,EACxC,YAAgB,EAChB,aAAa,GACd,GAAE,0BAA+B,GAAG,YAAY,CAAC,0BAA0B,CAAC,CAmC5E"}
@@ -21,7 +21,7 @@ import { Heading, Text } from '@astryxdesign/core/Text';
21
21
  import { enumerateDates, getScheduleRangeFromDates, isDayEvent } from "./dateMath.js";
22
22
  import { useScheduleContext } from "./context.js";
23
23
  import { getEventDateSpan, layoutMonthEvents, MONTH_VISIBLE_LEVELS } from "./monthLayout.js";
24
- import { formatDayNumber, formatEventAccessibilityLabel, formatEventTimeRange, formatFullDate, formatMonthTitle, formatWeekday, formatWeekRange, getEventCategory, isEventInPast, ListEventRow, MonthEventPill, ScheduleFrame, ScheduleMonthTitle, SchedulePopoverBody, styles } from "./shared.js";
24
+ import { formatDayNumber, formatEventAccessibilityLabel, formatEventTimeRange, formatFullDate, formatWeekday, formatWeekRange, formatWeekTitle, getEventCategory, isEventInPast, ListEventRow, MonthEventPill, ScheduleFrame, SchedulePopoverBody, ScheduleRangeMonthTitle, styles, useScheduleCalendar } from "./shared.js";
25
25
  import { useCurrentTime } from "./useCurrentTime.js";
26
26
  import { useScheduleViewPopover } from "./useScheduleViewPopover.js";
27
27
  import { scheduleRangeToZonedDateTimeRange } from "./zonedDateTime.js";
@@ -87,6 +87,7 @@ function ScheduleMonthlyView({
87
87
  isLoading,
88
88
  headingLevel
89
89
  } = useScheduleContext();
90
+ const calendar = useScheduleCalendar();
90
91
  const rangeDate = date.toPlainDate();
91
92
  const highlightedDate = focusDate.toPlainDate();
92
93
  const currentTime = useCurrentTime();
@@ -113,7 +114,11 @@ function ScheduleMonthlyView({
113
114
  // day's list named by its full date, or one event's content named by its
114
115
  // title.
115
116
  const dayByISO = new Map(days.map(day => [plainDateToISO(day), day]));
116
- const monthTitle = formatMonthTitle(rangeDate, timezoneID, locale);
117
+ // The grid shows one Gregorian month, which can span two months of the
118
+ // calendar, so its title names both.
119
+ const monthStart = plainDateSetFirstOfMonth(rangeDate);
120
+ const monthEnd = plainDateAddDays(plainDateAddMonths(monthStart, 1), -1);
121
+ const monthTitle = formatWeekTitle(monthStart, monthEnd, locale, calendar);
117
122
  const tableRef = useRef(null);
118
123
  // Where each chip painted so far starts, so focus can land on that cell if
119
124
  // the chip goes away while its popover is open.
@@ -131,7 +136,7 @@ function ScheduleMonthlyView({
131
136
  }
132
137
  if (parsed.kind === 'day') {
133
138
  const day = dayByISO.get(parsed.dayISO);
134
- return day == null ? monthTitle : formatFullDate(day, timezoneID, locale);
139
+ return day == null ? monthTitle : formatFullDate(day, locale, calendar);
135
140
  }
136
141
  return eventByID.get(parsed.eventID)?.title ?? monthTitle;
137
142
  },
@@ -163,7 +168,7 @@ function ScheduleMonthlyView({
163
168
  if (openDay != null) {
164
169
  const openDayISO = plainDateToISO(openDay);
165
170
  openContent = /*#__PURE__*/_jsx(SchedulePopoverBody, {
166
- label: `${formatFullDate(openDay, timezoneID, locale)} events`,
171
+ label: `${formatFullDate(openDay, locale, calendar)} events`,
167
172
  children: /*#__PURE__*/_jsx(MonthDayEvents, {
168
173
  day: openDay,
169
174
  events: eventsByDay.get(openDayISO) ?? EMPTY_EVENTS,
@@ -179,9 +184,9 @@ function ScheduleMonthlyView({
179
184
  });
180
185
  }
181
186
  return /*#__PURE__*/_jsxs(ScheduleFrame, {
182
- title: /*#__PURE__*/_jsx(ScheduleMonthTitle, {
183
- date: rangeDate,
184
- timezoneID: timezoneID
187
+ title: /*#__PURE__*/_jsx(ScheduleRangeMonthTitle, {
188
+ start: monthStart,
189
+ end: monthEnd
185
190
  }),
186
191
  titleLabel: monthTitle,
187
192
  isLoading: isLoading,
@@ -202,7 +207,7 @@ function ScheduleMonthlyView({
202
207
  children: "Week"
203
208
  }), days.slice(0, 7).map((day, index) => /*#__PURE__*/_jsx("div", {
204
209
  role: "columnheader",
205
- "aria-label": formatWeekday(day, timezoneID, 'long', locale),
210
+ "aria-label": formatWeekday(day, 'long', locale, calendar),
206
211
  "aria-colindex": index + 2,
207
212
  ...stylex.props(styles.weekdayLabel),
208
213
  children: /*#__PURE__*/_jsx(Heading, {
@@ -210,7 +215,7 @@ function ScheduleMonthlyView({
210
215
  color: "secondary",
211
216
  display: "block",
212
217
  xstyle: styles.weekdayHeading,
213
- children: formatWeekday(day, timezoneID, 'short', locale)
218
+ children: formatWeekday(day, 'short', locale, calendar)
214
219
  })
215
220
  }, plainDateToISO(day)))]
216
221
  }), /*#__PURE__*/_jsx("div", {
@@ -224,7 +229,7 @@ function ScheduleMonthlyView({
224
229
  role: "rowheader",
225
230
  "aria-colindex": 1,
226
231
  ...stylex.props(styles.visuallyHidden),
227
- children: formatWeekRange(week[0], week[week.length - 1], timezoneID, locale)
232
+ children: formatWeekRange(week[0], week[week.length - 1], timezoneID, locale, calendar)
228
233
  }), week.map((day, dayIndex) => {
229
234
  const index = weekIndex * 7 + dayIndex;
230
235
  const isOutsideMonth = day.month !== rangeDate.month;
@@ -233,7 +238,7 @@ function ScheduleMonthlyView({
233
238
  const hiddenCount = overflowByDay.get(index);
234
239
  return /*#__PURE__*/_jsxs("div", {
235
240
  role: "cell",
236
- "aria-label": formatFullDate(day, timezoneID, locale),
241
+ "aria-label": formatFullDate(day, locale, calendar),
237
242
  "aria-colindex": dayIndex + 2
238
243
  // Focus lands here when the day's "+N more" goes away.
239
244
  ,
@@ -248,7 +253,7 @@ function ScheduleMonthlyView({
248
253
  color: "inherit",
249
254
  weight: "medium",
250
255
  hasTabularNumbers: true,
251
- children: formatDayNumber(day, timezoneID, locale)
256
+ children: formatDayNumber(day, locale, calendar)
252
257
  })
253
258
  }), (chipsByDay.get(index) ?? EMPTY_CHIPS).map(chip => {
254
259
  const key = chipKey(chip);
@@ -256,7 +261,7 @@ function ScheduleMonthlyView({
256
261
  const startDay = days[chip.week * 7 + chip.columnStart];
257
262
  return hasPopover && startDay != null ? /*#__PURE__*/_jsx("span", {
258
263
  ...stylex.props(styles.visuallyHidden),
259
- children: formatMonthEventName(chip.event, `since ${formatFullDate(startDay, timezoneID, locale)}`, timezoneID, categories, locale)
264
+ children: formatMonthEventName(chip.event, `since ${formatFullDate(startDay, locale, calendar)}`, timezoneID, categories, locale)
260
265
  }, key) : null;
261
266
  }
262
267
  chipStartDay.set(key, dayISO);
@@ -275,7 +280,7 @@ function ScheduleMonthlyView({
275
280
  }, event.id))
276
281
  }), hiddenCount != null && /*#__PURE__*/_jsx("button", {
277
282
  type: "button",
278
- "aria-label": `${hiddenCount} more ${hiddenCount === 1 ? 'event' : 'events'}, ${formatFullDate(day, timezoneID, locale)}`,
283
+ "aria-label": `${hiddenCount} more ${hiddenCount === 1 ? 'event' : 'events'}, ${formatFullDate(day, locale, calendar)}`,
279
284
  ...monthPopover.getTriggerProps(dayKey(dayISO),
280
285
  // An event handed over from this day's list
281
286
  // keeps "+N more" as its trigger while the
@@ -321,6 +326,7 @@ function MonthChip({
321
326
  timezoneID,
322
327
  locale
323
328
  } = useScheduleContext();
329
+ const calendar = useScheduleCalendar();
324
330
  const placement = [styles.monthChip(chip.columnEnd - chip.columnStart + 1, chip.level), isLastColumn && styles.monthChipInLastColumn];
325
331
  const pill = /*#__PURE__*/_jsx(MonthEventPill, {
326
332
  event: chip.event,
@@ -335,7 +341,7 @@ function MonthChip({
335
341
  children: pill
336
342
  });
337
343
  }
338
- const name = formatMonthEventName(chip.event, formatEventDays(chip.event, timezoneID, locale), timezoneID, categories, locale);
344
+ const name = formatMonthEventName(chip.event, formatEventDays(chip.event, timezoneID, locale, calendar), timezoneID, categories, locale);
339
345
  if (renderPopover(chip.event) == null) {
340
346
  return /*#__PURE__*/_jsxs("div", {
341
347
  "data-schedule-month-chip": "",
@@ -375,8 +381,9 @@ function MonthDayEvents({
375
381
  timezoneID,
376
382
  locale
377
383
  } = useScheduleContext();
384
+ const calendar = useScheduleCalendar();
378
385
  const currentTime = useCurrentTime();
379
- const fullDate = formatFullDate(day, timezoneID, locale);
386
+ const fullDate = formatFullDate(day, locale, calendar);
380
387
  return /*#__PURE__*/_jsxs("div", {
381
388
  ...stylex.props(styles.monthDayEvents),
382
389
  children: [/*#__PURE__*/_jsx(Text, {
@@ -416,9 +423,9 @@ function formatMonthEventName(event, dayLabel, timezoneID, categories, locale) {
416
423
  }
417
424
 
418
425
  /** The event's day, or its date range when it covers several days. */
419
- function formatEventDays(event, timezoneID, locale) {
426
+ function formatEventDays(event, timezoneID, locale, calendar) {
420
427
  const [first, last] = getEventDateSpan(event, timezoneID);
421
- return plainDateIsEqual(first, last) ? formatFullDate(first, timezoneID, locale) : formatWeekRange(first, last, timezoneID, locale);
428
+ return plainDateIsEqual(first, last) ? formatFullDate(first, locale, calendar) : formatWeekRange(first, last, timezoneID, locale, calendar);
422
429
  }
423
430
  function getWeeks(days) {
424
431
  const weeks = [];
@@ -1 +1 @@
1
- {"version":3,"file":"TimeGridView.d.ts","sourceRoot":"","sources":["../../src/Schedule/TimeGridView.tsx"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,OAAO,EASL,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAMf,OAAO,EASL,KAAK,SAAS,EACf,MAAM,0BAA0B,CAAC;AAmClC,OAAO,KAAK,EACV,aAAa,EAGd,MAAM,SAAS,CAAC;AAEjB,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,MAAM,EACN,SAAS,EACT,UAAU,EACV,OAAO,EACP,OAAO,EACP,UAAU,EACV,KAAK,EACL,aAAa,GACd,EAAE;IACD,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IACrC,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,SAAS,CAAC;CACrD,+BA2kBA"}
1
+ {"version":3,"file":"TimeGridView.d.ts","sourceRoot":"","sources":["../../src/Schedule/TimeGridView.tsx"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,OAAO,EASL,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAOf,OAAO,EASL,KAAK,SAAS,EACf,MAAM,0BAA0B,CAAC;AAoClC,OAAO,KAAK,EACV,aAAa,EAGd,MAAM,SAAS,CAAC;AAEjB,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,MAAM,EACN,SAAS,EACT,UAAU,EACV,OAAO,EACP,OAAO,EACP,UAAU,EACV,KAAK,EACL,aAAa,GACd,EAAE;IACD,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IACrC,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,SAAS,CAAC;CACrD,+BAglBA"}