Commit 44becae
authored
Add ShadCN primitives and showcase the design system at /components (#869)
### Summary & Motivation
Introduce a complete `/components` design system reference page that
renders every primitive in `@repo/ui` with live, interactive previews.
The custom `SideMenu`, `AppLayout`, and `SidePane` are removed and
rebuilt on top of ShadCN's `Sidebar` (ported to BaseUI), giving the
application shell, the Account, Main, and Back-Office side menus, and
the showcase page itself a single shared foundation. The shared
`@repo/ui` library grows by roughly 30 new primitives — including
charts, drawers, sliders, resizable splits, drop zones, hover cards, and
command palettes — with rich keyboard support across the date inputs.
- **`/components` showcase page** — A dedicated route under
`application/main/WebApp/routes/components/` with live previews for
every primitive: `AccordionPreview`, `AlertDialogsPreview`,
`AlertsBadgesPreview`, `AspectRatioPreview`, `AvatarPreview`,
`ButtonGroupPreview`, `ButtonsPreview`, `CardsPreview`, `ChartsPreview`
(six chart variants), `CommandPreview`, `ControlsPreview`,
`DateFormatPreview`, `DialogsPreview`, `DrawerPreview`,
`DropzonePreview`, `EmptyPreview`, `ExamplesPreview`,
`HoverCardPreview`, `InlineCalendarPreview`, `ItemPreview`,
`KbdPreview`, `LinkPreview`, `NavigationMenuPreview`,
`NavigationPreview`, `OverlaysPreview`, `ProgressPreview`,
`ResizablePreview`, `SheetPreview`, `SidePanePreview`, `SidebarPreview`,
`SkeletonPreview`, `SpinnerPreview`, `TablePreview`, `TabsPreview`, and
`TogglesPreview`. Includes a dedicated mobile menu, settings flyouts,
side menu with nested sub-items, and end-to-end recipe / dish examples
(`RecipeEditorDialog`, `ShareRecipeDialog`, `DishDetailsSidePane`,
`DishMultiSelectSidePane`, multi-step wizards) that exercise the
primitives in real flows.
- **App shell rebuilt on ShadCN `Sidebar`** — The 1250-line custom
`SideMenu` (plus `useResponsiveMenu`, `useSideMenuLayout`, and the
federated `MobileMenuContent`) is deleted. A new 1100-line `Sidebar.tsx`
ported from ShadCN to BaseUI replaces it, with icon-collapsed mode,
drag-to-resize on the rail with localStorage persistence, viewport-aware
overlay mode, mobile sheet with floating hamburger trigger,
single-expand coordination across collapsible groups, hover flyouts in
collapsed mode, inert sub-menu animations, banner-aware top offset, and
the standard `Cmd/Ctrl+B` toggle shortcut. `AccountSideMenu`,
`MainSideMenu`, `BackOfficeSideMenu`, and the `/components`
`ComponentsSideMenu` are ported to the new primitives. `AppLayout` is
rewritten on `Sidebar` + `SidebarInset`, and `SidePane` becomes a
fixed-docked right panel with overlay backdrop and auto-close on
cross-route navigation.
- **New layout primitives** — `Drawer` (vaul-based mobile bottom sheet
with snap points and swipe-to-dismiss), `Sheet` (BaseUI side-anchored
modal), `Resizable` (`react-resizable-panels` with horizontal/vertical
and nested splits), `AspectRatio`, `Collapsible`, `Accordion`,
`NavigationMenu` (marketing-style dropdown nav), and `Item`/`ItemGroup`
(composable list-row primitive for settings, members, notifications).
- **New form controls** — `Combobox` + `ComboboxField`, `MultiSelect`,
`Slider` + `SliderField`, `Switch` + `SwitchField`, `Checkbox` +
`CheckboxField`, `RadioGroup` + `RadioGroupField`, `Select` +
`SelectField`, `Toggle` + `ToggleGroup` + `ToggleGroupField`,
`NumberField` (locale decimal separator, stepper buttons, long-press
repeat), `TimeField`, `TimeZonePicker`, `InputOtpField`. A shared
`useFieldError` hook unifies error clearing across
`FormValidationContext` and inline `errorMessage` props. `Field` is
updated to contain BaseUI hidden inputs and stop the phantom document
scroll.
- **DatePicker, DateRangePicker, and Calendar** — Full keyboard input is
now supported: typing characters into the date input runs through a
locale-aware mask (`useDateField` / `useDateRangeField` /
`dateFieldInternals`) that auto-inserts separators, validates partial
input as the user types, and commits on blur or Enter. The mask is
shared with the standalone `DateInput` (no popover) so all three
components behave identically. `Calendar` is rewired with an explicit
public API and unified shell dimensions, 44px cells,
weekStartsOn=Monday, locale from app context, and arrow-key navigation.
`DateRangePicker` accepts two synchronized inputs with the same mask.
`useSmartDate` is extended with relative formatting helpers.
- **Chart primitive** — A new `Chart.tsx` wraps `recharts` and exports
`ChartContainer`, `ChartTooltip`, `ChartTooltipContent`, `ChartLegend`,
`ChartLegendContent`, `ChartStyle`, and the `ChartConfig` type. Six
chart variants are showcased: `ChartAreaInteractive`,
`ChartBarInteractive`, `ChartBarStacked`, `ChartPieDonutText`,
`ChartRadialShape`, `ChartRadialStacked`.
- **Other primitives** — `HoverCard` (BaseUI PreviewCard for user
mentions and link previews), `Command` (cmdk-based palette), `Dropzone`
(`react-dropzone` with drag-and-drop, `accept`, `maxSize`, `maxFiles`,
`multiple`, custom preview children), `Spinner` (lucide Loader2),
`Progress` (linear determinate bar), `Kbd` (keyboard hint chip with
`KbdGroup`), `ButtonGroup` (visually-grouped independent action
buttons). `TenantLogoPicker` and `UserAvatarPicker` gain drag-and-drop
via `Dropzone`.
- **Table** — `stickyHeader` prop, roving-tabindex keyboard navigation
(`selectedIndex` / `onNavigate` on `Table`, `index` on `TableRow`),
Enter/Space dispatches click on focused row, hover suppression during
keyboard navigation, expanded checkbox click target across the full
column, restored selected-row contrast in light mode.
- **Dialog and form pattern refactor** — Every dialog is split into a
wrapper (owns only `isOpen`) and a body (owns state, mutation, form).
The body lives inside `<DialogContent>` and unmounts on close, so state
and mutation errors reset automatically with no `handleCloseComplete`,
`mutation.reset()`, or `setIsFormDirty(false)` plumbing. Body signals
dirtiness via `useDialogSetDirty()` from `DirtyDialogContext`.
`DialogClose` with `type="reset"` bypasses the unsaved-changes warning.
All in-tree dialogs (invite user, change role, billing info, edit
billing info, account fields, user profile, etc.) are migrated to the
pattern. Frontend rules in `.claude/rules/frontend/` are updated to
document the wrapper/body split, validation behavior, and
`useDialogSetDirty()` usage.
- **Tokens and theming** — `theme.css` and `tailwind.css` add new
control-height tokens (`--control-height`, `--control-height-sm`,
`--control-height-xs`, `--control-height-lg`). The custom focus ring
(`outline-ring` / `outline-primary` / `outline-destructive` with
`focus-visible:outline focus-visible:outline-2
focus-visible:outline-offset-2`) replaces ShadCN's default
`focus-visible:ring-*`. Logo-mark refreshed to a rounded-square shape.
Component inventory and divergence patterns are tracked centrally in
`application/shared-webapp/ui/components/README.md`.
- **Backend** — `IdGenerator.cs` falls back to a random generator ID
when no IPv4 address is available.
### Checklist
- [x] I have added tests, or done manual regression tests
- [x] I have updated the documentation, if necessary249 files changed
Lines changed: 20992 additions & 3538 deletions
File tree
- .claude/rules/frontend
- application
- account/WebApp
- federated-modules
- common
- sideMenu
- userMenu
- routes
- account
- billing/-components
- settings
- -components
- users
- -components
- -hooks
- recycle-bin/-components
- components
- -components
- login
- signup
- user
- preferences
- -components
- profile
- sessions/-components
- welcome
- back-office/WebApp
- routes
- main/WebApp
- routes
- dashboard
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
10 | | - | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
11 | 14 | | |
12 | | - | |
13 | | - | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
| 15 | + | |
18 | 16 | | |
19 | | - | |
| 17 | + | |
20 | 18 | | |
21 | | - | |
22 | | - | |
23 | | - | |
| 19 | + | |
| 20 | + | |
24 | 21 | | |
25 | | - | |
| 22 | + | |
26 | 23 | | |
27 | | - | |
| 24 | + | |
28 | 25 | | |
29 | | - | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
30 | 30 | | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
| 31 | + | |
37 | 32 | | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
44 | | - | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
75 | 39 | | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
89 | | - | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
101 | 45 | | |
102 | | - | |
103 | | - | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
112 | 54 | | |
113 | 55 | | |
114 | | - | |
115 | 56 | | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
132 | | - | |
133 | | - | |
134 | | - | |
135 | | - | |
136 | | - | |
137 | | - | |
138 | | - | |
139 | | - | |
140 | | - | |
141 | | - | |
142 | | - | |
143 | | - | |
144 | | - | |
145 | | - | |
146 | | - | |
147 | | - | |
148 | | - | |
149 | | - | |
150 | | - | |
151 | | - | |
152 | | - | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
153 | 61 | | |
154 | | - | |
| 62 | + | |
155 | 63 | | |
156 | 64 | | |
157 | | - | |
| 65 | + | |
| 66 | + | |
158 | 67 | | |
159 | | - | |
160 | 68 | | |
161 | | - | |
162 | | - | |
163 | | - | |
164 | | - | |
165 | | - | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
166 | 80 | | |
167 | 81 | | |
168 | 82 | | |
169 | 83 | | |
170 | 84 | | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
0 commit comments