@auto-engineer/generate-react-client 1.95.0 → 1.96.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 (47) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/dist/starter/index.html +4 -1
  3. package/dist/starter/src/App.tsx +2 -2
  4. package/dist/starter/src/components/ui/Accordion.tsx +1 -1
  5. package/dist/starter/src/components/ui/AlertDialog.tsx +1 -3
  6. package/dist/starter/src/components/ui/AspectRatio.tsx +0 -2
  7. package/dist/starter/src/components/ui/Badge.tsx +1 -1
  8. package/dist/starter/src/components/ui/Button.tsx +1 -1
  9. package/dist/starter/src/components/ui/Carousel.tsx +0 -2
  10. package/dist/starter/src/components/ui/Checkbox.tsx +1 -3
  11. package/dist/starter/src/components/ui/Combobox.tsx +1 -3
  12. package/dist/starter/src/components/ui/Command.tsx +0 -2
  13. package/dist/starter/src/components/ui/ContextMenu.tsx +0 -2
  14. package/dist/starter/src/components/ui/DesignSystem-Overview.stories.tsx +0 -2
  15. package/dist/starter/src/components/ui/Dialog.tsx +1 -1
  16. package/dist/starter/src/components/ui/Direction.tsx +0 -2
  17. package/dist/starter/src/components/ui/Drawer.tsx +1 -1
  18. package/dist/starter/src/components/ui/DropdownMenu.tsx +0 -2
  19. package/dist/starter/src/components/ui/Field.tsx +0 -2
  20. package/dist/starter/src/components/ui/Input.tsx +1 -1
  21. package/dist/starter/src/components/ui/InputGroup.tsx +1 -1
  22. package/dist/starter/src/components/ui/InputOTP.tsx +1 -3
  23. package/dist/starter/src/components/ui/Item.tsx +1 -1
  24. package/dist/starter/src/components/ui/Menubar.tsx +1 -3
  25. package/dist/starter/src/components/ui/NativeSelect.tsx +1 -1
  26. package/dist/starter/src/components/ui/NavigationMenu.tsx +3 -3
  27. package/dist/starter/src/components/ui/Progress.tsx +1 -3
  28. package/dist/starter/src/components/ui/RadioGroup.tsx +1 -1
  29. package/dist/starter/src/components/ui/Resizable.tsx +0 -2
  30. package/dist/starter/src/components/ui/ScrollArea.tsx +1 -1
  31. package/dist/starter/src/components/ui/Select.tsx +1 -3
  32. package/dist/starter/src/components/ui/Sheet.tsx +1 -3
  33. package/dist/starter/src/components/ui/Sidebar.tsx +1 -1
  34. package/dist/starter/src/components/ui/Slider.tsx +1 -1
  35. package/dist/starter/src/components/ui/Sonner.tsx +0 -2
  36. package/dist/starter/src/components/ui/Switch.tsx +1 -1
  37. package/dist/starter/src/components/ui/Table.tsx +1 -3
  38. package/dist/starter/src/components/ui/Tabs.tsx +2 -2
  39. package/dist/starter/src/components/ui/Textarea.tsx +1 -1
  40. package/dist/starter/src/components/ui/Toast.tsx +3 -5
  41. package/dist/starter/src/components/ui/Toaster.tsx +0 -2
  42. package/dist/starter/src/components/ui/Toggle.tsx +1 -3
  43. package/dist/starter/src/components/ui/ToggleGroup.tsx +0 -2
  44. package/dist/starter/src/hooks/use-mobile.ts +4 -4
  45. package/dist/starter/src/hooks/use-toast.ts +0 -2
  46. package/dist/starter/src/index.css +37 -0
  47. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,77 @@
1
1
  # @auto-engineer/generate-react-client
2
2
 
3
+ ## 1.96.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`81f38b5`](https://github.com/BeOnAuto/auto-engineer/commit/81f38b57044f9556a9f90dca2cd5fc945c9cd34c) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **packages/pipeline**: add getRunStats method to PipelineReadModel
8
+
9
+ - [`26e7f3e`](https://github.com/BeOnAuto/auto-engineer/commit/26e7f3e445149e3eef2e4872686aff841ff25a70) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **narrative**: add scene field to NarrativeSchema
10
+
11
+ - [`4a24c5a`](https://github.com/BeOnAuto/auto-engineer/commit/4a24c5a1e62a943760e7d855434e5e2b9a9d9a22) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **dev-server**: add preWarmed flag to install client dependencies
12
+
13
+ - [`b227607`](https://github.com/BeOnAuto/auto-engineer/commit/b227607fb4cc5e23b4ee12073d48058d6d6031e1) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **server-generator-apollo-emmett**: remove --ignore-workspace from install command
14
+
15
+ - [`f42888d`](https://github.com/BeOnAuto/auto-engineer/commit/f42888de73e6167e92316b657da7834869e6cf39) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **narrative**: add JourneyPlanningSchema progressive disclosure variant
16
+
17
+ - [`2709e66`](https://github.com/BeOnAuto/auto-engineer/commit/2709e6650ae277a7abacc4c4b4cbfd5fdc1cbc86) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **narrative**: export Journey, SceneClassification, SceneRoute, JourneyPlanning types
18
+
19
+ - [`b1a635a`](https://github.com/BeOnAuto/auto-engineer/commit/b1a635aa5845d270086e354685d8277106e9d633) Thanks [@osamanar](https://github.com/osamanar)! - Based on the diff analysis, here's the changelog:
20
+ - Upgraded AI prompt system with detailed, role-based prompts for component, test, story, and reconciler generation
21
+ - Added a reconciliation step that harmonizes generated component code with its Storybook story
22
+ - Introduced an automated improvement loop that evaluates output quality across multiple spec scenarios and iteratively refines prompts
23
+ - Consolidated shared types and spec-building logic into reusable modules, reducing duplication across generators
24
+ - Added sample component specs (action button, data card, search input, and more) for benchmarking prompt quality
25
+
26
+ - [`032349d`](https://github.com/BeOnAuto/auto-engineer/commit/032349d475dd3cea19fe440bf4f903bd473dec60) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **typical**: pass preWarmed flag from DEPS_PRE_WARMED env var and remove --ignore-workspace
27
+
28
+ - [`a177d2a`](https://github.com/BeOnAuto/auto-engineer/commit/a177d2a07e71e7c6f98146ce8f6287a4d2829c37) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **narrative**: add SceneRouteSchema and SceneClassificationSchema
29
+
30
+ - [`42d7111`](https://github.com/BeOnAuto/auto-engineer/commit/42d711159577d6844e74955a10361d57b154ca44) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **packages/pipeline**: add getAllItemStatuses and getAllNodeStatuses to PipelineReadModel
31
+
32
+ - [`19d3375`](https://github.com/BeOnAuto/auto-engineer/commit/19d33751bc6912c1e2745e0f06b860f16bd2056e) Thanks [@github-actions[bot]](https://github.com/github-actions%5Bbot%5D)! - - **server-generator-apollo-emmett**: add null-document guidance to projection template
33
+ - **server-generator-apollo-emmett**: add discriminated union guidance to evolve template
34
+ - **server-generator-apollo-emmett**: fill missing inline object fields with type defaults
35
+ - **server-implementer**: add discriminated union narrowing guidance to prompts
36
+ - **server-implementer**: load full shared directory into implementer context
37
+
38
+ - [`981285d`](https://github.com/BeOnAuto/auto-engineer/commit/981285d9d5fa747a9d924d9388e111750453e0be) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **dev-server**: add preWarmed flag to install server dependencies
39
+
40
+ - [`267cb9f`](https://github.com/BeOnAuto/auto-engineer/commit/267cb9fd83c90bd4a7e3a9b38c2577b3d744ad61) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **narrative**: add journeys to modelSchema and JourneyPlanningSchema
41
+
42
+ - [`056ef79`](https://github.com/BeOnAuto/auto-engineer/commit/056ef797bd70346b47f0f0ad2a48a2c567204d46) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **packages/pipeline**: add GET /run-stats endpoint with pipeline status
43
+
44
+ - [`a6cb7ec`](https://github.com/BeOnAuto/auto-engineer/commit/a6cb7ec9460bc4412e5ce022473815e668774f44) Thanks [@osamanar](https://github.com/osamanar)! - - Improved the starter template for generated React clients
45
+ - Added a run script for easier project execution
46
+
47
+ - [`2e7404e`](https://github.com/BeOnAuto/auto-engineer/commit/2e7404e5ce5f222d0931e63d8adb2f8acbeec494) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **narrative**: add JourneySchema
48
+
49
+ ### Patch Changes
50
+
51
+ - [`6dfd6cc`](https://github.com/BeOnAuto/auto-engineer/commit/6dfd6ccac984f3f85cfdfd8de9c0771083e1be8d) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **typical**: add server deps to root for workspace pre-warming
52
+
53
+ - [`991cb70`](https://github.com/BeOnAuto/auto-engineer/commit/991cb70914a145e20f174698418a16e81782221c) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **typical**: convert typical example to pnpm workspace
54
+
55
+ - [`cf8c874`](https://github.com/BeOnAuto/auto-engineer/commit/cf8c874347eff977663c5f958c9fcba06a65921e) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **narrative**: add ketchup plan for journey-narrative consolidation RFC
56
+
57
+ - [`f02782d`](https://github.com/BeOnAuto/auto-engineer/commit/f02782d419431234046b0f0bd91ead278f9a1b07) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **packages/pipeline**: add correlationId query param and use runStats for hasActivity in /run-stats
58
+
59
+ - [`02bf378`](https://github.com/BeOnAuto/auto-engineer/commit/02bf378c5f26061efef1636abdffa472600b8103) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **pipeline**: sort exports to fix biome organizeImports error
60
+
61
+ - [`b1d6595`](https://github.com/BeOnAuto/auto-engineer/commit/b1d6595116b32332e38ee7b34a2b274ada8d173e) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - Updated esbuild build tool dependencies to latest versions
62
+
63
+ - [`c756f3f`](https://github.com/BeOnAuto/auto-engineer/commit/c756f3fed9c48547b2709128c76ab81262ce25c6) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **narrative**: update ketchup-plan and apply linter fixes
64
+
65
+ - [`06efd83`](https://github.com/BeOnAuto/auto-engineer/commit/06efd83cb0c813fc5e869ac9f3ff7811a3857940) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **cli**: increase server test timeouts for CI reliability
66
+
67
+ - [`a5cb16c`](https://github.com/BeOnAuto/auto-engineer/commit/a5cb16ccf7b3758e39b8bf2d96ce164b7e3d2bc6) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **typical**: update lockfile for server deps
68
+
69
+ - [`784c650`](https://github.com/BeOnAuto/auto-engineer/commit/784c6504222da8bd8557cfde80252866fc2b69ef) Thanks [@SamHatoum](https://github.com/SamHatoum)! - - **pipeline**: export RunStats type from package index
70
+
71
+ - Updated dependencies [[`81f38b5`](https://github.com/BeOnAuto/auto-engineer/commit/81f38b57044f9556a9f90dca2cd5fc945c9cd34c), [`26e7f3e`](https://github.com/BeOnAuto/auto-engineer/commit/26e7f3e445149e3eef2e4872686aff841ff25a70), [`4a24c5a`](https://github.com/BeOnAuto/auto-engineer/commit/4a24c5a1e62a943760e7d855434e5e2b9a9d9a22), [`6dfd6cc`](https://github.com/BeOnAuto/auto-engineer/commit/6dfd6ccac984f3f85cfdfd8de9c0771083e1be8d), [`b227607`](https://github.com/BeOnAuto/auto-engineer/commit/b227607fb4cc5e23b4ee12073d48058d6d6031e1), [`f42888d`](https://github.com/BeOnAuto/auto-engineer/commit/f42888de73e6167e92316b657da7834869e6cf39), [`991cb70`](https://github.com/BeOnAuto/auto-engineer/commit/991cb70914a145e20f174698418a16e81782221c), [`2709e66`](https://github.com/BeOnAuto/auto-engineer/commit/2709e6650ae277a7abacc4c4b4cbfd5fdc1cbc86), [`b1a635a`](https://github.com/BeOnAuto/auto-engineer/commit/b1a635aa5845d270086e354685d8277106e9d633), [`032349d`](https://github.com/BeOnAuto/auto-engineer/commit/032349d475dd3cea19fe440bf4f903bd473dec60), [`cf8c874`](https://github.com/BeOnAuto/auto-engineer/commit/cf8c874347eff977663c5f958c9fcba06a65921e), [`a177d2a`](https://github.com/BeOnAuto/auto-engineer/commit/a177d2a07e71e7c6f98146ce8f6287a4d2829c37), [`f02782d`](https://github.com/BeOnAuto/auto-engineer/commit/f02782d419431234046b0f0bd91ead278f9a1b07), [`02bf378`](https://github.com/BeOnAuto/auto-engineer/commit/02bf378c5f26061efef1636abdffa472600b8103), [`42d7111`](https://github.com/BeOnAuto/auto-engineer/commit/42d711159577d6844e74955a10361d57b154ca44), [`19d3375`](https://github.com/BeOnAuto/auto-engineer/commit/19d33751bc6912c1e2745e0f06b860f16bd2056e), [`b1d6595`](https://github.com/BeOnAuto/auto-engineer/commit/b1d6595116b32332e38ee7b34a2b274ada8d173e), [`981285d`](https://github.com/BeOnAuto/auto-engineer/commit/981285d9d5fa747a9d924d9388e111750453e0be), [`c756f3f`](https://github.com/BeOnAuto/auto-engineer/commit/c756f3fed9c48547b2709128c76ab81262ce25c6), [`267cb9f`](https://github.com/BeOnAuto/auto-engineer/commit/267cb9fd83c90bd4a7e3a9b38c2577b3d744ad61), [`056ef79`](https://github.com/BeOnAuto/auto-engineer/commit/056ef797bd70346b47f0f0ad2a48a2c567204d46), [`06efd83`](https://github.com/BeOnAuto/auto-engineer/commit/06efd83cb0c813fc5e869ac9f3ff7811a3857940), [`a5cb16c`](https://github.com/BeOnAuto/auto-engineer/commit/a5cb16ccf7b3758e39b8bf2d96ce164b7e3d2bc6), [`784c650`](https://github.com/BeOnAuto/auto-engineer/commit/784c6504222da8bd8557cfde80252866fc2b69ef), [`a6cb7ec`](https://github.com/BeOnAuto/auto-engineer/commit/a6cb7ec9460bc4412e5ce022473815e668774f44), [`2e7404e`](https://github.com/BeOnAuto/auto-engineer/commit/2e7404e5ce5f222d0931e63d8adb2f8acbeec494)]:
72
+ - @auto-engineer/file-upload@1.96.0
73
+ - @auto-engineer/message-bus@1.96.0
74
+
3
75
  ## 1.95.0
4
76
 
5
77
  ### Minor Changes
@@ -2,7 +2,10 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
+ <meta name="color-scheme" content="light dark" />
7
+ <meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)" />
8
+ <meta name="theme-color" content="#0a0a0a" media="(prefers-color-scheme: dark)" />
6
9
  <title>React App</title>
7
10
  </head>
8
11
  <body>
@@ -6,14 +6,14 @@ import { Separator } from '@/components/ui/Separator';
6
6
  const queryClient = new QueryClient();
7
7
 
8
8
  const LandingPage = () => (
9
- <div className="min-h-screen flex items-center justify-center pb-32 bg-gradient-to-br from-background to-muted/50">
9
+ <main className="min-h-screen flex items-center justify-center pb-32 bg-gradient-to-br from-background to-muted/50">
10
10
  <Card className="border-0 shadow-none bg-transparent">
11
11
  <CardContent className="flex flex-col items-center gap-6">
12
12
  <h1 className="text-5xl md:text-7xl font-extralight tracking-tight text-foreground">Your ideas, on Auto.</h1>
13
13
  <Separator className="w-16 bg-muted-foreground/30" />
14
14
  </CardContent>
15
15
  </Card>
16
- </div>
16
+ </main>
17
17
  );
18
18
 
19
19
  export const App = () => (
@@ -27,7 +27,7 @@ function AccordionTrigger({ className, children, ...props }: React.ComponentProp
27
27
  <AccordionPrimitive.Trigger
28
28
  data-slot="accordion-trigger"
29
29
  className={cn(
30
- 'focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180',
30
+ 'focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-[color,box-shadow] outline-hidden hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180',
31
31
  className,
32
32
  )}
33
33
  {...props}
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { AlertDialog as AlertDialogPrimitive } from 'radix-ui';
4
2
  import type * as React from 'react';
5
3
  import { Button } from '@/components/ui/Button';
@@ -52,7 +50,7 @@ function AlertDialogContent({
52
50
  data-slot="alert-dialog-content"
53
51
  data-size={size}
54
52
  className={cn(
55
- 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 group/alert-dialog-content fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-lg',
53
+ 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 group/alert-dialog-content fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 overscroll-contain data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-lg',
56
54
  className,
57
55
  )}
58
56
  {...props}
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { AspectRatio as AspectRatioPrimitive } from 'radix-ui';
4
2
 
5
3
  /**
@@ -5,7 +5,7 @@ import type * as React from 'react';
5
5
  import { cn } from '@/lib/utils';
6
6
 
7
7
  const badgeVariants = cva(
8
- 'inline-flex items-center justify-center rounded-full border border-transparent px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden',
8
+ 'inline-flex items-center justify-center rounded-full border border-transparent px-2 py-0.5 text-xs font-medium tabular-nums w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden',
9
9
  {
10
10
  variants: {
11
11
  variant: {
@@ -5,7 +5,7 @@ import type * as React from 'react';
5
5
  import { cn } from '@/lib/utils';
6
6
 
7
7
  const buttonVariants = cva(
8
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
8
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-hidden focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
9
9
  {
10
10
  variants: {
11
11
  variant: {
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import useEmblaCarousel, { type UseEmblaCarouselType } from 'embla-carousel-react';
4
2
  import { ArrowLeft, ArrowRight } from 'lucide-react';
5
3
  import * as React from 'react';
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { CheckIcon } from 'lucide-react';
4
2
  import { Checkbox as CheckboxPrimitive } from 'radix-ui';
5
3
  import type * as React from 'react';
@@ -12,7 +10,7 @@ function Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxP
12
10
  <CheckboxPrimitive.Root
13
11
  data-slot="checkbox"
14
12
  className={cn(
15
- 'peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',
13
+ 'peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive relative size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-hidden focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 after:absolute after:-inset-2 after:content-[""]',
16
14
  className,
17
15
  )}
18
16
  {...props}
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { Combobox as ComboboxPrimitive } from '@base-ui/react';
4
2
  import { CheckIcon, ChevronDownIcon, XIcon } from 'lucide-react';
5
3
  import * as React from 'react';
@@ -264,7 +262,7 @@ function ComboboxChipsInput({ className, children, ...props }: ComboboxPrimitive
264
262
  return (
265
263
  <ComboboxPrimitive.Input
266
264
  data-slot="combobox-chip-input"
267
- className={cn('min-w-16 flex-1 outline-none', className)}
265
+ className={cn('min-w-16 flex-1 outline-hidden', className)}
268
266
  {...props}
269
267
  />
270
268
  );
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { Command as CommandPrimitive } from 'cmdk';
4
2
  import { SearchIcon } from 'lucide-react';
5
3
  import type * as React from 'react';
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react';
4
2
  import { ContextMenu as ContextMenuPrimitive } from 'radix-ui';
5
3
  import type * as React from 'react';
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import type { Meta, StoryObj } from '@storybook/react-vite';
4
2
  import {
5
3
  ArchiveIcon,
@@ -57,7 +57,7 @@ function DialogContent({
57
57
  <DialogPrimitive.Content
58
58
  data-slot="dialog-content"
59
59
  className={cn(
60
- 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg',
60
+ 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-hidden overscroll-contain sm:max-w-lg',
61
61
  className,
62
62
  )}
63
63
  {...props}
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { Direction } from 'radix-ui';
4
2
  import type * as React from 'react';
5
3
 
@@ -53,7 +53,7 @@ function DrawerContent({ className, children, ...props }: React.ComponentProps<t
53
53
  <DrawerPrimitive.Content
54
54
  data-slot="drawer-content"
55
55
  className={cn(
56
- 'group/drawer-content bg-background fixed z-50 flex h-auto flex-col',
56
+ 'group/drawer-content bg-background fixed z-50 flex h-auto flex-col overscroll-contain',
57
57
  'data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:border-b',
58
58
  'data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=bottom]:border-t',
59
59
  'data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm',
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react';
4
2
  import { DropdownMenu as DropdownMenuPrimitive } from 'radix-ui';
5
3
  import type * as React from 'react';
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { cva, type VariantProps } from 'class-variance-authority';
4
2
  import { useMemo } from 'react';
5
3
  import { Label } from '@/components/ui/Label';
@@ -9,7 +9,7 @@ function Input({ className, type, ...props }: React.ComponentProps<'input'>) {
9
9
  type={type}
10
10
  data-slot="input"
11
11
  className={cn(
12
- 'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
12
+ 'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-hidden file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
13
13
  'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
14
14
  'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
15
15
  className,
@@ -12,7 +12,7 @@ function InputGroup({ className, ...props }: React.ComponentProps<'div'>) {
12
12
  data-slot="input-group"
13
13
  role="group"
14
14
  className={cn(
15
- 'group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none',
15
+ 'group/input-group border-input dark:bg-input/30 relative flex w-full items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-hidden',
16
16
  'h-9 min-w-0 has-[>textarea]:h-auto',
17
17
 
18
18
  // Variants based on alignment.
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { OTPInput, OTPInputContext } from 'input-otp';
4
2
  import { MinusIcon } from 'lucide-react';
5
3
  import * as React from 'react';
@@ -45,7 +43,7 @@ function InputOTPSlot({
45
43
  data-slot="input-otp-slot"
46
44
  data-active={isActive}
47
45
  className={cn(
48
- 'data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]',
46
+ 'data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive dark:bg-input/30 border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm shadow-xs transition-[border-color,box-shadow] outline-hidden first:rounded-l-md first:border-l last:rounded-r-md data-[active=true]:z-10 data-[active=true]:ring-[3px]',
49
47
  className,
50
48
  )}
51
49
  {...props}
@@ -17,7 +17,7 @@ function ItemSeparator({ className, ...props }: React.ComponentProps<typeof Sepa
17
17
  }
18
18
 
19
19
  const itemVariants = cva(
20
- 'group/item flex items-center border border-transparent text-sm rounded-md transition-colors [a]:hover:bg-accent/50 [a]:transition-colors duration-100 flex-wrap outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
20
+ 'group/item flex items-center border border-transparent text-sm rounded-md transition-colors [a]:hover:bg-accent/50 [a]:transition-colors duration-100 flex-wrap outline-hidden focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
21
21
  {
22
22
  variants: {
23
23
  variant: {
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { CheckIcon, ChevronRightIcon, CircleIcon } from 'lucide-react';
4
2
  import { Menubar as MenubarPrimitive } from 'radix-ui';
5
3
  import type * as React from 'react';
@@ -206,7 +204,7 @@ function MenubarSubTrigger({
206
204
  data-slot="menubar-sub-trigger"
207
205
  data-inset={inset}
208
206
  className={cn(
209
- 'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-none select-none data-[inset]:pl-8',
207
+ 'focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8',
210
208
  className,
211
209
  )}
212
210
  {...props}
@@ -21,7 +21,7 @@ function NativeSelect({
21
21
  data-slot="native-select"
22
22
  data-size={size}
23
23
  className={cn(
24
- 'border-input placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 dark:hover:bg-input/50 h-9 w-full min-w-0 appearance-none rounded-md border bg-transparent px-3 py-2 pr-9 text-sm shadow-xs transition-[color,box-shadow] outline-none disabled:pointer-events-none disabled:cursor-not-allowed data-[size=sm]:h-8 data-[size=sm]:py-1',
24
+ 'border-input placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 dark:hover:bg-input/50 h-9 w-full min-w-0 appearance-none rounded-md border bg-transparent px-3 py-2 pr-9 text-sm shadow-xs transition-[color,box-shadow] outline-hidden disabled:pointer-events-none disabled:cursor-not-allowed data-[size=sm]:h-8 data-[size=sm]:py-1',
25
25
  'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
26
26
  'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
27
27
  className,
@@ -49,7 +49,7 @@ function NavigationMenuItem({ className, ...props }: React.ComponentProps<typeof
49
49
  }
50
50
 
51
51
  const navigationMenuTriggerStyle = cva(
52
- 'group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 outline-none transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1',
52
+ 'group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 outline-hidden transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1',
53
53
  );
54
54
 
55
55
  /** The button that opens a NavigationMenuContent dropdown, with an animated chevron indicator. */
@@ -80,7 +80,7 @@ function NavigationMenuContent({ className, ...props }: React.ComponentProps<typ
80
80
  data-slot="navigation-menu-content"
81
81
  className={cn(
82
82
  'data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 top-0 left-0 w-full p-2 pr-2.5 md:absolute md:w-auto',
83
- 'group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0 group-data-[viewport=false]/navigation-menu:top-full group-data-[viewport=false]/navigation-menu:mt-1.5 group-data-[viewport=false]/navigation-menu:overflow-hidden group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:border group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:duration-200 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none',
83
+ 'group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0 group-data-[viewport=false]/navigation-menu:top-full group-data-[viewport=false]/navigation-menu:mt-1.5 group-data-[viewport=false]/navigation-menu:overflow-hidden group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:border group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:duration-200 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-hidden',
84
84
  className,
85
85
  )}
86
86
  {...props}
@@ -112,7 +112,7 @@ function NavigationMenuLink({ className, ...props }: React.ComponentProps<typeof
112
112
  <NavigationMenuPrimitive.Link
113
113
  data-slot="navigation-menu-link"
114
114
  className={cn(
115
- "data-[active=true]:focus:bg-accent data-[active=true]:hover:bg-accent data-[active=true]:bg-accent/50 data-[active=true]:text-accent-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus-visible:ring-ring/50 [&_svg:not([class*='text-'])]:text-muted-foreground flex flex-col gap-1 rounded-sm p-2 text-sm transition-all outline-none focus-visible:ring-[3px] focus-visible:outline-1 [&_svg:not([class*='size-'])]:size-4",
115
+ "data-[active=true]:focus:bg-accent data-[active=true]:hover:bg-accent data-[active=true]:bg-accent/50 data-[active=true]:text-accent-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus-visible:ring-ring/50 [&_svg:not([class*='text-'])]:text-muted-foreground flex flex-col gap-1 rounded-sm p-2 text-sm transition-colors outline-hidden focus-visible:ring-[3px] focus-visible:outline-1 [&_svg:not([class*='size-'])]:size-4",
116
116
  className,
117
117
  )}
118
118
  {...props}
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { Progress as ProgressPrimitive } from 'radix-ui';
4
2
  import type * as React from 'react';
5
3
 
@@ -15,7 +13,7 @@ function Progress({ className, value, ...props }: React.ComponentProps<typeof Pr
15
13
  >
16
14
  <ProgressPrimitive.Indicator
17
15
  data-slot="progress-indicator"
18
- className="bg-primary h-full w-full flex-1 transition-all"
16
+ className="bg-primary h-full w-full flex-1 transition-transform"
19
17
  style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
20
18
  />
21
19
  </ProgressPrimitive.Root>
@@ -18,7 +18,7 @@ function RadioGroupItem({ className, ...props }: React.ComponentProps<typeof Rad
18
18
  <RadioGroupPrimitive.Item
19
19
  data-slot="radio-group-item"
20
20
  className={cn(
21
- 'border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',
21
+ 'border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 relative aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-hidden focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 after:absolute after:-inset-2 after:content-[""]',
22
22
  className,
23
23
  )}
24
24
  {...props}
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { GripVerticalIcon } from 'lucide-react';
4
2
  import * as ResizablePrimitive from 'react-resizable-panels';
5
3
 
@@ -12,7 +12,7 @@ function ScrollArea({ className, children, ...props }: React.ComponentProps<type
12
12
  <ScrollAreaPrimitive.Root data-slot="scroll-area" className={cn('relative', className)} {...props}>
13
13
  <ScrollAreaPrimitive.Viewport
14
14
  data-slot="scroll-area-viewport"
15
- className="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
15
+ className="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-hidden focus-visible:ring-[3px] focus-visible:outline-1"
16
16
  >
17
17
  {children}
18
18
  </ScrollAreaPrimitive.Viewport>
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-react';
4
2
  import { Select as SelectPrimitive } from 'radix-ui';
5
3
  import type * as React from 'react';
@@ -37,7 +35,7 @@ function SelectTrigger({
37
35
  data-slot="select-trigger"
38
36
  data-size={size}
39
37
  className={cn(
40
- "border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
38
+ "border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-hidden focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
41
39
  className,
42
40
  )}
43
41
  {...props}
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { XIcon } from 'lucide-react';
4
2
  import { Dialog as SheetPrimitive } from 'radix-ui';
5
3
  import type * as React from 'react';
@@ -59,7 +57,7 @@ function SheetContent({
59
57
  <SheetPrimitive.Content
60
58
  data-slot="sheet-content"
61
59
  className={cn(
62
- 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
60
+ 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out overscroll-contain data-[state=closed]:duration-200 data-[state=open]:duration-300',
63
61
  side === 'right' &&
64
62
  'data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',
65
63
  side === 'left' &&
@@ -277,7 +277,7 @@ function SidebarRail({ className, ...props }: React.ComponentProps<'button'>) {
277
277
  onClick={toggleSidebar}
278
278
  title="Toggle Sidebar"
279
279
  className={cn(
280
- 'hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex',
280
+ 'hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-colors ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex',
281
281
  'in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize',
282
282
  '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',
283
283
  'hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full',
@@ -46,7 +46,7 @@ function Slider({
46
46
  data-slot="slider-thumb"
47
47
  // biome-ignore lint/suspicious/noArrayIndexKey: Slider thumbs are positional and have no unique identifiers
48
48
  key={index}
49
- className="border-primary ring-ring/50 block size-4 shrink-0 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50"
49
+ className="border-primary ring-ring/50 relative block size-4 shrink-0 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50 after:absolute after:-inset-3 after:content-['']"
50
50
  />
51
51
  ))}
52
52
  </SliderPrimitive.Root>
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { CircleCheckIcon, InfoIcon, Loader2Icon, OctagonXIcon, TriangleAlertIcon } from 'lucide-react';
4
2
  import { useTheme } from 'next-themes';
5
3
  import { Toaster as Sonner, type ToasterProps } from 'sonner';
@@ -17,7 +17,7 @@ function Switch({
17
17
  data-slot="switch"
18
18
  data-size={size}
19
19
  className={cn(
20
- 'peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 group/switch inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-[1.15rem] data-[size=default]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6',
20
+ 'peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 group/switch inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-colors outline-hidden focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-[1.15rem] data-[size=default]:w-8 data-[size=sm]:h-3.5 data-[size=sm]:w-6',
21
21
  className,
22
22
  )}
23
23
  {...props}
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import type * as React from 'react';
4
2
 
5
3
  import { cn } from '@/lib/utils';
@@ -68,7 +66,7 @@ function TableCell({ className, ...props }: React.ComponentProps<'td'>) {
68
66
  <td
69
67
  data-slot="table-cell"
70
68
  className={cn(
71
- 'p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',
69
+ 'tabular-nums p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',
72
70
  className,
73
71
  )}
74
72
  {...props}
@@ -56,7 +56,7 @@ function TabsTrigger({ className, ...props }: React.ComponentProps<typeof TabsPr
56
56
  <TabsPrimitive.Trigger
57
57
  data-slot="tabs-trigger"
58
58
  className={cn(
59
- "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/60 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
59
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/60 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,background-color,border-color,box-shadow] group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
60
60
  'group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:border-transparent dark:group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent',
61
61
  'data-[state=active]:bg-background dark:data-[state=active]:text-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 data-[state=active]:text-foreground',
62
62
  'after:bg-foreground after:absolute after:opacity-0 after:transition-opacity group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5 group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100',
@@ -69,7 +69,7 @@ function TabsTrigger({ className, ...props }: React.ComponentProps<typeof TabsPr
69
69
 
70
70
  /** The content panel associated with a tab trigger, shown when its corresponding trigger is active. */
71
71
  function TabsContent({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Content>) {
72
- return <TabsPrimitive.Content data-slot="tabs-content" className={cn('flex-1 outline-none', className)} {...props} />;
72
+ return <TabsPrimitive.Content data-slot="tabs-content" className={cn('flex-1 outline-hidden', className)} {...props} />;
73
73
  }
74
74
 
75
75
  export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };
@@ -11,7 +11,7 @@ function Textarea({ className, ...props }: React.ComponentProps<'textarea'>) {
11
11
  <textarea
12
12
  data-slot="textarea"
13
13
  className={cn(
14
- 'border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
14
+ 'border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-hidden focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
15
15
  className,
16
16
  )}
17
17
  {...props}
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { cva, type VariantProps } from 'class-variance-authority';
4
2
  import { XIcon } from 'lucide-react';
5
3
  import { Toast as ToastPrimitive } from 'radix-ui';
@@ -29,7 +27,7 @@ function ToastViewport({ className, ...props }: React.ComponentProps<typeof Toas
29
27
  }
30
28
 
31
29
  const toastVariants = cva(
32
- 'group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full',
30
+ 'group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-transform data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full',
33
31
  {
34
32
  variants: {
35
33
  variant: {
@@ -58,7 +56,7 @@ function ToastAction({ className, ...props }: React.ComponentProps<typeof ToastP
58
56
  <ToastPrimitive.Action
59
57
  data-slot="toast-action"
60
58
  className={cn(
61
- 'inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive',
59
+ 'inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-hidden focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive',
62
60
  className,
63
61
  )}
64
62
  {...props}
@@ -72,7 +70,7 @@ function ToastClose({ className, ...props }: React.ComponentProps<typeof ToastPr
72
70
  <ToastPrimitive.Close
73
71
  data-slot="toast-close"
74
72
  className={cn(
75
- 'absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600',
73
+ 'absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-hidden focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600',
76
74
  className,
77
75
  )}
78
76
  toast-close=""
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { Toast, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from '@/components/ui/Toast';
4
2
  import { useToast } from '@/hooks/use-toast';
5
3
 
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import { cva, type VariantProps } from 'class-variance-authority';
4
2
  import { Toggle as TogglePrimitive } from 'radix-ui';
5
3
  import type * as React from 'react';
@@ -7,7 +5,7 @@ import type * as React from 'react';
7
5
  import { cn } from '@/lib/utils';
8
6
 
9
7
  const toggleVariants = cva(
10
- "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap",
8
+ "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-hidden transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap",
11
9
  {
12
10
  variants: {
13
11
  variant: {
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import type { VariantProps } from 'class-variance-authority';
4
2
  import { ToggleGroup as ToggleGroupPrimitive } from 'radix-ui';
5
3
  import * as React from 'react';
@@ -3,17 +3,17 @@ import * as React from 'react';
3
3
  const MOBILE_BREAKPOINT = 768;
4
4
 
5
5
  export function useIsMobile() {
6
- const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined);
6
+ const [isMobile, setIsMobile] = React.useState(false);
7
7
 
8
8
  React.useEffect(() => {
9
9
  const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
10
10
  const onChange = () => {
11
- setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
11
+ setIsMobile(mql.matches);
12
12
  };
13
+ onChange();
13
14
  mql.addEventListener('change', onChange);
14
- setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
15
15
  return () => mql.removeEventListener('change', onChange);
16
16
  }, []);
17
17
 
18
- return !!isMobile;
18
+ return isMobile;
19
19
  }
@@ -1,5 +1,3 @@
1
- 'use client';
2
-
3
1
  import * as React from 'react';
4
2
 
5
3
  import type { ToastActionElement, ToastProps } from '@/components/ui/Toast';
@@ -118,4 +118,41 @@
118
118
  body {
119
119
  @apply bg-background text-foreground;
120
120
  }
121
+
122
+ /* Heading typography */
123
+ h1, h2, h3, h4, h5, h6 {
124
+ text-wrap: balance;
125
+ }
126
+
127
+ /* Touch interaction improvements */
128
+ button, a, input, select, textarea, [role="button"] {
129
+ -webkit-tap-highlight-color: transparent;
130
+ touch-action: manipulation;
131
+ }
132
+
133
+ /* Color scheme for native controls */
134
+ :root {
135
+ color-scheme: light;
136
+ scrollbar-gutter: stable;
137
+ }
138
+ .dark {
139
+ color-scheme: dark;
140
+ }
141
+
142
+ /* Reduced motion: respect user preference globally */
143
+ @media (prefers-reduced-motion: reduce) {
144
+ *, *::before, *::after {
145
+ animation-duration: 0.01ms !important;
146
+ animation-iteration-count: 1 !important;
147
+ transition-duration: 0.01ms !important;
148
+ scroll-behavior: auto !important;
149
+ }
150
+ }
151
+
152
+ /* Safe area insets for notched devices */
153
+ body {
154
+ padding-left: env(safe-area-inset-left);
155
+ padding-right: env(safe-area-inset-right);
156
+ padding-bottom: env(safe-area-inset-bottom);
157
+ }
121
158
  }
package/package.json CHANGED
@@ -19,13 +19,13 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "debug": "^4.4.1",
22
- "@auto-engineer/file-upload": "1.95.0",
23
- "@auto-engineer/message-bus": "1.95.0"
22
+ "@auto-engineer/file-upload": "1.96.0",
23
+ "@auto-engineer/message-bus": "1.96.0"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@types/debug": "^4.1.12"
27
27
  },
28
- "version": "1.95.0",
28
+ "version": "1.96.0",
29
29
  "scripts": {
30
30
  "build": "tsc && tsx ../../scripts/fix-esm-imports.ts && cp -r starter dist/",
31
31
  "test-cli": "tsx test-cli.ts",