@charcuterie/ui 4.13.1 → 4.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +2 -0
  2. package/dist/Chart/Chart.d.ts +10 -0
  3. package/dist/Chart/Chart.d.ts.map +1 -0
  4. package/dist/Chart/Chart.js +42 -0
  5. package/dist/Chart/Chart.js.map +1 -0
  6. package/dist/ScheduleBoard/ScheduleBoard.d.ts +33 -0
  7. package/dist/ScheduleBoard/ScheduleBoard.d.ts.map +1 -0
  8. package/dist/ScheduleBoard/ScheduleBoard.js +30 -0
  9. package/dist/ScheduleBoard/ScheduleBoard.js.map +1 -0
  10. package/dist/ScheduleBoard/ScheduleDayCards.d.ts +9 -0
  11. package/dist/ScheduleBoard/ScheduleDayCards.d.ts.map +1 -0
  12. package/dist/ScheduleBoard/ScheduleDayCards.js +8 -0
  13. package/dist/ScheduleBoard/ScheduleDayCards.js.map +1 -0
  14. package/dist/ScheduleBoard/ScheduleHourGrid.d.ts +12 -0
  15. package/dist/ScheduleBoard/ScheduleHourGrid.d.ts.map +1 -0
  16. package/dist/ScheduleBoard/ScheduleHourGrid.js +40 -0
  17. package/dist/ScheduleBoard/ScheduleHourGrid.js.map +1 -0
  18. package/dist/ScheduleBoard/ScheduleItem.d.ts +20 -0
  19. package/dist/ScheduleBoard/ScheduleItem.d.ts.map +1 -0
  20. package/dist/ScheduleBoard/ScheduleItem.js +18 -0
  21. package/dist/ScheduleBoard/ScheduleItem.js.map +1 -0
  22. package/dist/ScheduleBoard/scheduleGeometry.d.ts +12 -0
  23. package/dist/ScheduleBoard/scheduleGeometry.d.ts.map +1 -0
  24. package/dist/ScheduleBoard/scheduleGeometry.js +35 -0
  25. package/dist/ScheduleBoard/scheduleGeometry.js.map +1 -0
  26. package/dist/WeekdayIndicator/WeekdayIndicator.d.ts +12 -0
  27. package/dist/WeekdayIndicator/WeekdayIndicator.d.ts.map +1 -0
  28. package/dist/WeekdayIndicator/WeekdayIndicator.js +18 -0
  29. package/dist/WeekdayIndicator/WeekdayIndicator.js.map +1 -0
  30. package/dist/index.d.ts +7 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +3 -0
  33. package/dist/index.js.map +1 -1
  34. package/package.json +2 -2
  35. package/src/Chart/Chart.mdx +16 -0
  36. package/src/Chart/Chart.stories.tsx +92 -0
  37. package/src/Chart/Chart.test.tsx +37 -0
  38. package/src/Chart/Chart.tsx +129 -0
  39. package/src/ScheduleBoard/ScheduleBoard.mdx +29 -0
  40. package/src/ScheduleBoard/ScheduleBoard.stories.tsx +187 -0
  41. package/src/ScheduleBoard/ScheduleBoard.test.tsx +98 -0
  42. package/src/ScheduleBoard/ScheduleBoard.tsx +215 -0
  43. package/src/ScheduleBoard/ScheduleDayCards.tsx +44 -0
  44. package/src/ScheduleBoard/ScheduleHourGrid.tsx +146 -0
  45. package/src/ScheduleBoard/ScheduleItem.tsx +88 -0
  46. package/src/ScheduleBoard/scheduleGeometry.test.ts +23 -0
  47. package/src/ScheduleBoard/scheduleGeometry.ts +56 -0
  48. package/src/VirtualizedGrid/VirtualizedGrid.stories.tsx +6 -0
  49. package/src/WeekdayIndicator/WeekdayIndicator.mdx +29 -0
  50. package/src/WeekdayIndicator/WeekdayIndicator.stories.tsx +71 -0
  51. package/src/WeekdayIndicator/WeekdayIndicator.test.tsx +34 -0
  52. package/src/WeekdayIndicator/WeekdayIndicator.tsx +57 -0
  53. package/src/index.ts +12 -0
  54. package/src/sourceRules.test.ts +4 -1
@@ -0,0 +1,34 @@
1
+ import { composeStories } from "@storybook/react"
2
+ import { expect, userEvent } from "storybook/test"
3
+ import { test } from "vitest"
4
+
5
+ import { expectNoAxeViolations } from "../expectNoAxeViolations.testHelpers.ts"
6
+ import { mountStory } from "../mountStory.testHelpers.ts"
7
+ import { expectAgentDrivable } from "../testing/index.ts"
8
+ import * as stories from "./WeekdayIndicator.stories.tsx"
9
+
10
+ const { Playground, Interactive } = composeStories(stories)
11
+ test("the pattern reads Monday first and exposes the filled days in words", async () => {
12
+ const { canvas, canvasElement } =
13
+ await mountStory(Playground)
14
+ const pattern = expectAgentDrivable(canvas, {
15
+ role: "img",
16
+ name: "Repeats: Monday, Tuesday, Wednesday, Thursday",
17
+ })
18
+ await expect(pattern.textContent).toBe("MTWTFSS")
19
+ await expectNoAxeViolations(canvasElement)
20
+ })
21
+ test("a changed pattern updates its accessible description", async () => {
22
+ const { canvas } = await mountStory(Interactive)
23
+ const button = expectAgentDrivable(canvas, {
24
+ role: "button",
25
+ name: "Switch pattern",
26
+ })
27
+ button.focus()
28
+ await userEvent.keyboard("{Enter}")
29
+ await expect(
30
+ canvas.getByRole("img", {
31
+ name: "Repeats: Saturday, Sunday",
32
+ }),
33
+ ).toBeInTheDocument()
34
+ })
@@ -0,0 +1,57 @@
1
+ import type { CategoricalIndex } from "@charcuterie/tokens"
2
+ import type { ReactNode } from "react"
3
+
4
+ import { CATEGORICAL_APPEARANCE_CLASS } from "../categoricalStyles.ts"
5
+ import { toClassName } from "../toClassName.ts"
6
+
7
+ export type WeekdayIndicatorProps = {
8
+ /** Monday is 0, Sunday is 6. These are observed weekdays, not an RRULE. */
9
+ days: readonly number[]
10
+ categorical?: CategoricalIndex
11
+ className?: string
12
+ label?: string
13
+ }
14
+
15
+ const DAYS = [
16
+ "Monday",
17
+ "Tuesday",
18
+ "Wednesday",
19
+ "Thursday",
20
+ "Friday",
21
+ "Saturday",
22
+ "Sunday",
23
+ ] as const
24
+
25
+ /** A named, noninteractive seven-day pattern, with letters as well as color. */
26
+ export const WeekdayIndicator = ({
27
+ days,
28
+ categorical = 1,
29
+ className,
30
+ label = "Repeats",
31
+ }: WeekdayIndicatorProps): ReactNode => (
32
+ <span
33
+ aria-label={`${label}: ${DAYS.filter((_day, index) => days.includes(index)).join(", ") || "no weekdays"}`}
34
+ className={toClassName(
35
+ "inline-flex flex-wrap gap-1",
36
+ className,
37
+ )}
38
+ role="img"
39
+ title={`${label}: ${DAYS.filter((_day, index) => days.includes(index)).join(", ") || "no weekdays"}`}
40
+ >
41
+ {DAYS.map((day, index) => (
42
+ <span
43
+ aria-hidden="true"
44
+ className={toClassName(
45
+ "flex size-6 items-center justify-center rounded-full border text-xs font-medium",
46
+ days.includes(index)
47
+ ? CATEGORICAL_APPEARANCE_CLASS[categorical]
48
+ .solid
49
+ : "border-border-subtle text-content-muted",
50
+ )}
51
+ key={day}
52
+ >
53
+ {day.slice(0, 1)}
54
+ </span>
55
+ ))}
56
+ </span>
57
+ )
package/src/index.ts CHANGED
@@ -117,6 +117,8 @@ export type {
117
117
  } from "./Card/Card.tsx"
118
118
  export { Card } from "./Card/Card.tsx"
119
119
  export type { CardAccentEdge } from "./Card/cardAccentEdge.ts"
120
+ export type { ChartProps } from "./Chart/Chart.tsx"
121
+ export { Chart } from "./Chart/Chart.tsx"
120
122
  export type { CheckboxProps } from "./Checkbox/Checkbox.tsx"
121
123
  export { Checkbox } from "./Checkbox/Checkbox.tsx"
122
124
  export type { ColorSchemeSwitcherProps } from "./ColorSchemeSwitcher/ColorSchemeSwitcher.tsx"
@@ -417,6 +419,14 @@ export type {
417
419
  export { getIsRoutedHref } from "./RouterLink/routerLink.ts"
418
420
  export type { UnstyledLinkProps } from "./RouterLink/UnstyledLink.tsx"
419
421
  export { UnstyledLink } from "./RouterLink/UnstyledLink.tsx"
422
+ export type {
423
+ ScheduleBand,
424
+ ScheduleBoardProps,
425
+ ScheduleDay,
426
+ ScheduleLayout,
427
+ } from "./ScheduleBoard/ScheduleBoard.tsx"
428
+ export { ScheduleBoard } from "./ScheduleBoard/ScheduleBoard.tsx"
429
+ export type { ScheduleEntry } from "./ScheduleBoard/ScheduleItem.tsx"
420
430
  export type { SearchInputProps } from "./SearchInput/SearchInput.tsx"
421
431
  export { SearchInput } from "./SearchInput/SearchInput.tsx"
422
432
  export type {
@@ -542,3 +552,5 @@ export type { VirtualizedGridProps } from "./VirtualizedGrid/VirtualizedGrid.tsx
542
552
  export { VirtualizedGrid } from "./VirtualizedGrid/VirtualizedGrid.tsx"
543
553
  export type { VisuallyHiddenProps } from "./VisuallyHidden/VisuallyHidden.tsx"
544
554
  export { VisuallyHidden } from "./VisuallyHidden/VisuallyHidden.tsx"
555
+ export type { WeekdayIndicatorProps } from "./WeekdayIndicator/WeekdayIndicator.tsx"
556
+ export { WeekdayIndicator } from "./WeekdayIndicator/WeekdayIndicator.tsx"
@@ -253,6 +253,7 @@ test("a container-query component is never storied in a shrink-to-fit cell", ()
253
253
  "PortraitTiles",
254
254
  // Metrics query the space remaining beside the media, not the entire card.
255
255
  "ProgressCard",
256
+ "ScheduleBoard",
256
257
  // `Stepper`'s container is the one that decides whether a
257
258
  // `horizontal` sequence is actually horizontal. Below `--cq-md`
258
259
  // it falls back to the vertical column, because four steps side
@@ -618,7 +619,8 @@ test("the barrel is the only place components are re-exported", async () => {
618
619
  // Breadcrumbs composes TextLink for the path back up a hierarchy.
619
620
  // ActionMenu composes IconButton and Menu for the overflow control.
620
621
  // ValuePairs owns compact label-over-value summaries.
621
- expect(componentNames.length).toBe(70)
622
+ // Chart shares portable SVG geometry with Preact and image consumers.
623
+ expect(componentNames.length).toBe(73)
622
624
 
623
625
  for (const name of componentNames) {
624
626
  expect(barrel).toContain(`export { ${name} }`)
@@ -731,6 +733,7 @@ const ENTRY_POINT_RUNTIMES: Record<
731
733
  // browser, and it does so through this subpath so the coupling
732
734
  // is named rather than smuggled in through the main entry.
733
735
  "@charcuterie/logic/browser",
736
+ "@charcuterie/logic/core",
734
737
  "@charcuterie/tokens",
735
738
  "@floating-ui/react",
736
739
  // `Combobox`'s virtualization — the second runtime dependency