@thesage/ui 0.1.0 → 1.0.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 (50) hide show
  1. package/README.md +96 -61
  2. package/dist/dates.d.mts +20 -0
  3. package/dist/dates.d.ts +20 -0
  4. package/dist/dates.js +230 -0
  5. package/dist/dates.js.map +1 -0
  6. package/dist/dates.mjs +193 -0
  7. package/dist/dates.mjs.map +1 -0
  8. package/dist/dnd.d.mts +126 -0
  9. package/dist/dnd.d.ts +126 -0
  10. package/dist/dnd.js +274 -0
  11. package/dist/dnd.js.map +1 -0
  12. package/dist/dnd.mjs +250 -0
  13. package/dist/dnd.mjs.map +1 -0
  14. package/dist/forms.d.mts +38 -0
  15. package/dist/forms.d.ts +38 -0
  16. package/dist/forms.js +198 -0
  17. package/dist/forms.js.map +1 -0
  18. package/dist/forms.mjs +159 -0
  19. package/dist/forms.mjs.map +1 -0
  20. package/dist/hooks.js +6 -5
  21. package/dist/hooks.js.map +1 -1
  22. package/dist/hooks.mjs +6 -5
  23. package/dist/hooks.mjs.map +1 -1
  24. package/dist/index.d.mts +484 -352
  25. package/dist/index.d.ts +484 -352
  26. package/dist/index.js +2674 -2092
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.mjs +2548 -1966
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/providers.js +6 -5
  31. package/dist/providers.js.map +1 -1
  32. package/dist/providers.mjs +6 -5
  33. package/dist/providers.mjs.map +1 -1
  34. package/dist/tables.d.mts +10 -0
  35. package/dist/tables.d.ts +10 -0
  36. package/dist/tables.js +248 -0
  37. package/dist/tables.js.map +1 -0
  38. package/dist/tables.mjs +218 -0
  39. package/dist/tables.mjs.map +1 -0
  40. package/dist/utils.js +2 -1
  41. package/dist/utils.js.map +1 -1
  42. package/dist/utils.mjs +2 -1
  43. package/dist/utils.mjs.map +1 -1
  44. package/dist/webgl.d.mts +104 -0
  45. package/dist/webgl.d.ts +104 -0
  46. package/dist/webgl.js +226 -0
  47. package/dist/webgl.js.map +1 -0
  48. package/dist/webgl.mjs +195 -0
  49. package/dist/webgl.mjs.map +1 -0
  50. package/package.json +145 -16
package/README.md CHANGED
@@ -6,36 +6,58 @@
6
6
  [![License](https://img.shields.io/npm/l/@thesage/ui?color=blue&style=flat-square)](https://github.com/shalomormsby/ecosystem/blob/main/LICENSE)
7
7
  [![Downloads](https://img.shields.io/npm/dt/@thesage/ui?color=teal&style=flat-square)](https://www.npmjs.com/package/@thesage/ui)
8
8
 
9
- **The Design Engine for the Solopreneur.**
9
+ **Sage Make it Lovable.**
10
10
 
11
- [Documentation](https://thesage.dev) [Components](https://thesage.dev/components) [GitHub](https://github.com/shalomormsby/ecosystem)
11
+ Components that feel alive. Themes with real personality. Motion your users control. Designed for humans. Fluent with AI.
12
+
13
+ [Documentation](https://thesage.dev) | [Components](https://thesage.dev/components) | [GitHub](https://github.com/shalomormsby/ecosystem)
12
14
 
13
15
  </div>
14
16
 
15
17
  ---
16
18
 
17
- **Sage Design Engine** is not just a component library—it's a systematic design engine built for speed, consistency, and beauty. Built on top of **Radix UI** for headless accessibility and **Tailwind CSS** for styling, it provides a comprehensive suite of 45+ polished components that work together seamlessly.
19
+ **Sage Design Engine** is a component library and design system built on **Radix UI** primitives and **Tailwind CSS**. 48+ accessible components, three distinct themes with runtime switching, and a user-controlled motion system all wired through a 4-layer design token architecture.
20
+
21
+ ## Features
18
22
 
19
- ## Features
23
+ - **Accessible by default** — Built on WAI-ARIA standards via Radix UI. Keyboard navigable, screen reader compatible, WCAG AA contrast.
24
+ - **Three themes, real personality** — Studio (professional), Terra (organic), Volt (electric). Runtime switching via CSS variables, light and dark modes each.
25
+ - **User-controlled motion** — A 0–10 intensity scale that respects `prefers-reduced-motion`. Intensity 0 works perfectly — no degraded experience.
26
+ - **Modular imports** — Core stays lean. Heavy features (forms, dates, tables, drag-and-drop, WebGL) ship as optional subpath exports — install only what you use.
27
+ - **Type safe** — Written in TypeScript with full type inference. React 19 ref-as-prop pattern throughout.
28
+ - **Design token system** — Colors, typography, spacing, motion, and syntax tokens. Change one primary color, everything updates.
20
29
 
21
- - **🎨 Systematic Design**: Powered by a robust design token system (colors, typography, spacing).
22
- - **♿ Fully Accessible**: Built on WAI-ARIA standards via Radix UI primitives.
23
- - **🌗 Mode Aware**: First-class support for light and dark modes with automatic color harmonization.
24
- - **🧩 Composable**: Components designed to fit together like LEGO blocks.
25
- - **🛠️ Type Safe**: Written in TypeScript with full type inference.
30
+ ## Installation
26
31
 
27
- ## 🚀 Installation
32
+ ```bash
33
+ pnpm add @thesage/ui
34
+ ```
28
35
 
29
- ### 1. Install Dependencies
30
- Sage Design Engine is built on Tailwind CSS. You need to install the package and its peer dependencies.
36
+ Sage requires **Tailwind CSS** as a styling engine:
31
37
 
32
38
  ```bash
33
- pnpm add @thesage/ui @thesage/tokens @thesage/hooks lucide-react clsx tailwind-merge
34
39
  pnpm add -D tailwindcss@^3.4 postcss autoprefixer
35
40
  ```
36
41
 
37
- ### 2. Configure Tailwind
38
- Update your `tailwind.config.js` contents to use the preset and scan the component definitions.
42
+ ### Optional subpath exports
43
+
44
+ Install peer dependencies only for the features you need:
45
+
46
+ ```bash
47
+ # Forms (react-hook-form + zod validation)
48
+ pnpm add react-hook-form @hookform/resolvers zod
49
+
50
+ # Date picker
51
+ pnpm add react-day-picker date-fns
52
+
53
+ # Data tables
54
+ pnpm add @tanstack/react-table
55
+
56
+ # Drag and drop
57
+ pnpm add @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities
58
+ ```
59
+
60
+ ### Configure Tailwind
39
61
 
40
62
  ```js
41
63
  /** @type {import('tailwindcss').Config} */
@@ -45,69 +67,82 @@ module.exports = {
45
67
  "./src/**/*.{ts,tsx}",
46
68
  "./node_modules/@thesage/ui/dist/**/*.{js,ts,jsx,tsx}"
47
69
  ],
48
- theme: {
49
- extend: {},
50
- },
51
- plugins: [],
52
70
  }
53
71
  ```
54
72
 
55
- ### 3. Import Styles
56
- Import the global CSS file (which contains the theme variables) in your root entry file (e.g., `main.tsx` or `App.tsx`).
73
+ ### Import styles
57
74
 
58
75
  ```tsx
59
76
  import '@thesage/ui/globals.css';
60
77
  ```
61
78
 
62
- ## 💻 Usage
63
-
64
- Sage Design Engine components are designed to be dropped into any React application.
79
+ ## Usage
65
80
 
66
81
  ```tsx
67
- import { Button, Card, Text, Heading } from '@thesage/ui';
82
+ import { Button, Card, ThemeProvider } from '@thesage/ui';
68
83
 
69
- export default function WelcomeCard() {
84
+ export default function App() {
70
85
  return (
71
- <Card className="max-w-md p-6">
72
- <Heading level={3} className="mb-2">Welcome to Sage</Heading>
73
- <Text variant="muted" className="mb-4">
74
- Build faster with components that look premium out of the box.
75
- </Text>
76
- <div className="flex gap-2">
77
- <Button variant="primary">Get Started</Button>
78
- <Button variant="ghost">Documentation</Button>
79
- </div>
80
- </Card>
86
+ <ThemeProvider theme="studio" defaultMode="system">
87
+ <Card className="max-w-md p-6">
88
+ <h3 className="mb-2 text-lg font-semibold">Welcome to Sage</h3>
89
+ <p className="mb-4 text-muted-foreground">
90
+ Build beautifully with components that feel premium out of the box.
91
+ </p>
92
+ <div className="flex gap-2">
93
+ <Button>Get Started</Button>
94
+ <Button variant="ghost">Documentation</Button>
95
+ </div>
96
+ </Card>
97
+ </ThemeProvider>
81
98
  );
82
99
  }
83
100
  ```
84
101
 
85
- ## 🖌️ Theming
86
-
87
- Sage Design Engine uses a 4-layer token system. Changing a single primary color automatically updates buttons, focus rings, and chart colors across your entire application.
102
+ ### Subpath imports
88
103
 
89
104
  ```tsx
90
- // Example: Customizing the theme
91
- import { ThemeProvider } from '@thesage/ui';
92
-
93
- export default function App({ children }) {
94
- return (
95
- <ThemeProvider theme="sage" defaultMode="system">
96
- {children}
97
- </ThemeProvider>
98
- );
99
- }
105
+ import { useMotionPreference, useTheme } from '@thesage/ui/hooks'
106
+ import { ThemeProvider } from '@thesage/ui/providers'
107
+ import { cn } from '@thesage/ui/utils'
108
+
109
+ // Optional feature imports
110
+ import { Form, FormField } from '@thesage/ui/forms'
111
+ import { DatePicker } from '@thesage/ui/dates'
112
+ import { DataTable } from '@thesage/ui/tables'
113
+ import { SortableList } from '@thesage/ui/dnd'
100
114
  ```
101
115
 
102
- ## 📦 Component Categories
103
-
104
- - **Actions**: Button, Toggle, ToggleGroup
105
- - **Forms**: Input, Select, Checkbox, Switch, Slider, Form
106
- - **Navigation**: Tabs, Menubar, Breadcrumb, Pagination
107
- - **Overlays**: Dialog, Sheet, Popover, Tooltip, Toast
108
- - **Data Display**: Card, Avatar, Badge, Table, ScrollArea
109
- - **Feedback**: Alert, Progress, Skeleton, Sonner
110
-
111
- ## 📄 License
112
-
113
- MIT © [Shalom Ormsby](https://github.com/shalomormsby)
116
+ ## Component categories
117
+
118
+ | Category | Examples |
119
+ |----------|----------|
120
+ | **Actions** | Button, Toggle, ToggleGroup |
121
+ | **Forms** | Input, Select, Checkbox, Switch, Slider, SearchBar |
122
+ | **Navigation** | Tabs, Menubar, Breadcrumb, Pagination, NavigationMenu |
123
+ | **Overlays** | Dialog, Sheet, Popover, Tooltip, ContextMenu, HoverCard |
124
+ | **Data Display** | Card, Avatar, Badge, Table, ScrollArea, Carousel |
125
+ | **Feedback** | Alert, Progress, Skeleton, Toast (Sonner) |
126
+ | **Layout** | Accordion, Separator, ResizablePanels, Collapsible |
127
+ | **Features** | Customizer, ThemeSwitcher |
128
+
129
+ ## Bundle size
130
+
131
+ Core and optional entry points are independently tracked via [size-limit](https://github.com/ai/size-limit):
132
+
133
+ | Entry point | Brotli size |
134
+ |-------------|-------------|
135
+ | Core | ~146 KB |
136
+ | Hooks | ~40 KB |
137
+ | Providers | ~60 KB |
138
+ | Tokens | ~70 KB |
139
+ | Utils | ~25 KB |
140
+ | Forms | ~9.4 KB |
141
+ | Dates | ~29 KB |
142
+ | Tables | ~8.3 KB |
143
+ | DnD | ~8.3 KB |
144
+ | WebGL | ~1.1 KB |
145
+
146
+ ## License
147
+
148
+ MIT &copy; [Shalom Ormsby](https://github.com/shalomormsby)
@@ -0,0 +1,20 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { DayPicker } from 'react-day-picker';
4
+
5
+ type CalendarProps = React.ComponentProps<typeof DayPicker>;
6
+ declare function Calendar({ className, classNames, showOutsideDays, ...props }: CalendarProps): react_jsx_runtime.JSX.Element;
7
+ declare namespace Calendar {
8
+ var displayName: string;
9
+ }
10
+
11
+ interface DatePickerProps {
12
+ date?: Date;
13
+ onDateChange?: (date: Date | undefined) => void;
14
+ placeholder?: string;
15
+ className?: string;
16
+ disabled?: boolean;
17
+ }
18
+ declare function DatePicker({ date, onDateChange, placeholder, className, disabled, }: DatePickerProps): react_jsx_runtime.JSX.Element;
19
+
20
+ export { Calendar, type CalendarProps, DatePicker, type DatePickerProps };
@@ -0,0 +1,20 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+ import { DayPicker } from 'react-day-picker';
4
+
5
+ type CalendarProps = React.ComponentProps<typeof DayPicker>;
6
+ declare function Calendar({ className, classNames, showOutsideDays, ...props }: CalendarProps): react_jsx_runtime.JSX.Element;
7
+ declare namespace Calendar {
8
+ var displayName: string;
9
+ }
10
+
11
+ interface DatePickerProps {
12
+ date?: Date;
13
+ onDateChange?: (date: Date | undefined) => void;
14
+ placeholder?: string;
15
+ className?: string;
16
+ disabled?: boolean;
17
+ }
18
+ declare function DatePicker({ date, onDateChange, placeholder, className, disabled, }: DatePickerProps): react_jsx_runtime.JSX.Element;
19
+
20
+ export { Calendar, type CalendarProps, DatePicker, type DatePickerProps };
package/dist/dates.js ADDED
@@ -0,0 +1,230 @@
1
+ "use client";
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/dates.ts
32
+ var dates_exports = {};
33
+ __export(dates_exports, {
34
+ Calendar: () => Calendar,
35
+ DatePicker: () => DatePicker
36
+ });
37
+ module.exports = __toCommonJS(dates_exports);
38
+
39
+ // src/components/data-display/Calendar.tsx
40
+ var import_lucide_react = require("lucide-react");
41
+ var import_react_day_picker = require("react-day-picker");
42
+
43
+ // src/lib/utils.ts
44
+ var import_clsx = require("clsx");
45
+ var import_tailwind_merge = require("tailwind-merge");
46
+ function cn(...inputs) {
47
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
48
+ }
49
+
50
+ // src/components/actions/Button.tsx
51
+ var import_class_variance_authority = require("class-variance-authority");
52
+ var import_react_slot = require("@radix-ui/react-slot");
53
+ var import_jsx_runtime = require("react/jsx-runtime");
54
+ var buttonVariants = (0, import_class_variance_authority.cva)(
55
+ "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 sage-interactive [&_svg]:transition-transform [&_svg]:duration-300 hover:[&_svg]:translate-x-1",
56
+ {
57
+ variants: {
58
+ variant: {
59
+ default: "bg-primary text-primary-foreground shadow",
60
+ primary: "bg-primary text-primary-foreground shadow",
61
+ // Alias for default
62
+ destructive: "bg-destructive text-destructive-foreground shadow-sm",
63
+ outline: "border border-input bg-transparent shadow-sm hover:bg-primary hover:text-primary-foreground hover:border-primary",
64
+ secondary: "bg-black/5 dark:bg-white/10 backdrop-blur-md border border-black/5 dark:border-white/10 text-secondary-foreground shadow-sm hover:bg-primary hover:text-primary-foreground dark:hover:bg-primary dark:hover:text-primary-foreground",
65
+ ghost: "hover:text-accent-foreground",
66
+ link: "text-primary underline-offset-4 hover:underline"
67
+ },
68
+ size: {
69
+ default: "h-9 px-4 py-2",
70
+ sm: "h-8 rounded-md px-3 text-xs",
71
+ lg: "h-10 rounded-md px-8",
72
+ icon: "h-9 w-9"
73
+ }
74
+ },
75
+ defaultVariants: {
76
+ variant: "default",
77
+ size: "default"
78
+ }
79
+ }
80
+ );
81
+ var Button = ({
82
+ ref,
83
+ className,
84
+ variant,
85
+ size,
86
+ asChild = false,
87
+ children,
88
+ ...props
89
+ }) => {
90
+ const Comp = asChild ? import_react_slot.Slot : "button";
91
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
92
+ Comp,
93
+ {
94
+ className: cn(buttonVariants({ variant, size, className })),
95
+ ref,
96
+ ...props,
97
+ children: asChild ? children : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "relative z-20 flex items-center justify-center gap-2", children })
98
+ }
99
+ );
100
+ };
101
+
102
+ // src/components/data-display/Calendar.tsx
103
+ var import_jsx_runtime2 = require("react/jsx-runtime");
104
+ function Calendar({
105
+ className,
106
+ classNames,
107
+ showOutsideDays = true,
108
+ ...props
109
+ }) {
110
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
111
+ import_react_day_picker.DayPicker,
112
+ {
113
+ showOutsideDays,
114
+ className: cn("p-3", className),
115
+ classNames: {
116
+ months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
117
+ month: "space-y-4",
118
+ caption: "flex justify-center pt-1 relative items-center",
119
+ caption_label: "text-sm font-medium",
120
+ nav: "space-x-1 flex items-center",
121
+ nav_button: cn(
122
+ buttonVariants({ variant: "outline" }),
123
+ "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"
124
+ ),
125
+ nav_button_previous: "absolute left-1",
126
+ nav_button_next: "absolute right-1",
127
+ table: "w-full border-collapse space-y-1",
128
+ head_row: "flex",
129
+ head_cell: "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
130
+ row: "flex w-full mt-2",
131
+ cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
132
+ day: cn(
133
+ buttonVariants({ variant: "ghost" }),
134
+ "h-9 w-9 p-0 font-normal aria-selected:opacity-100"
135
+ ),
136
+ day_range_end: "day-range-end",
137
+ day_selected: "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
138
+ day_today: "bg-accent text-accent-foreground",
139
+ day_outside: "day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
140
+ day_disabled: "text-muted-foreground opacity-50",
141
+ day_range_middle: "aria-selected:bg-accent aria-selected:text-accent-foreground",
142
+ day_hidden: "invisible",
143
+ ...classNames
144
+ },
145
+ components: {
146
+ Chevron: ({ ...props2 }) => {
147
+ if (props2.orientation === "left") {
148
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.ChevronLeft, { className: "h-4 w-4" });
149
+ }
150
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.ChevronRight, { className: "h-4 w-4" });
151
+ }
152
+ },
153
+ ...props
154
+ }
155
+ );
156
+ }
157
+ Calendar.displayName = "Calendar";
158
+
159
+ // src/components/layout/DatePicker.tsx
160
+ var import_date_fns = require("date-fns");
161
+ var import_lucide_react2 = require("lucide-react");
162
+
163
+ // src/components/overlays/Popover.tsx
164
+ var PopoverPrimitive = __toESM(require("@radix-ui/react-popover"));
165
+ var import_jsx_runtime3 = require("react/jsx-runtime");
166
+ var Popover = PopoverPrimitive.Root;
167
+ var PopoverTrigger = PopoverPrimitive.Trigger;
168
+ var PopoverContent = ({
169
+ ref,
170
+ className,
171
+ align = "center",
172
+ sideOffset = 4,
173
+ ...props
174
+ }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PopoverPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
175
+ PopoverPrimitive.Content,
176
+ {
177
+ ref,
178
+ align,
179
+ sideOffset,
180
+ className: cn(
181
+ "z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none 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 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
182
+ className
183
+ ),
184
+ ...props
185
+ }
186
+ ) });
187
+
188
+ // src/components/layout/DatePicker.tsx
189
+ var import_jsx_runtime4 = require("react/jsx-runtime");
190
+ function DatePicker({
191
+ date,
192
+ onDateChange,
193
+ placeholder = "Pick a date",
194
+ className,
195
+ disabled = false
196
+ }) {
197
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Popover, { children: [
198
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
199
+ Button,
200
+ {
201
+ variant: "outline",
202
+ className: cn(
203
+ "w-[280px] justify-start text-left font-normal",
204
+ !date && "text-muted-foreground",
205
+ className
206
+ ),
207
+ disabled,
208
+ children: [
209
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Calendar, { className: "mr-2 h-4 w-4" }),
210
+ date ? (0, import_date_fns.format)(date, "PPP") : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: placeholder })
211
+ ]
212
+ }
213
+ ) }),
214
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PopoverContent, { className: "w-auto p-0", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
215
+ Calendar,
216
+ {
217
+ mode: "single",
218
+ selected: date,
219
+ onSelect: onDateChange,
220
+ initialFocus: true
221
+ }
222
+ ) })
223
+ ] });
224
+ }
225
+ // Annotate the CommonJS export names for ESM import in node:
226
+ 0 && (module.exports = {
227
+ Calendar,
228
+ DatePicker
229
+ });
230
+ //# sourceMappingURL=dates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/dates.ts","../src/components/data-display/Calendar.tsx","../src/lib/utils.ts","../src/components/actions/Button.tsx","../src/components/layout/DatePicker.tsx","../src/components/overlays/Popover.tsx"],"sourcesContent":["export * from './components/data-display/Calendar';\nexport * from './components/layout/DatePicker';\n","\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronLeft, ChevronRight } from \"lucide-react\"\nimport { DayPicker } from \"react-day-picker\"\n\nimport { cn } from \"../../lib/utils\"\nimport { buttonVariants } from \"../actions/Button\"\n\nexport type CalendarProps = React.ComponentProps<typeof DayPicker>\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n ...props\n}: CalendarProps) {\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n className={cn(\"p-3\", className)}\n classNames={{\n months: \"flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0\",\n month: \"space-y-4\",\n caption: \"flex justify-center pt-1 relative items-center\",\n caption_label: \"text-sm font-medium\",\n nav: \"space-x-1 flex items-center\",\n nav_button: cn(\n buttonVariants({ variant: \"outline\" }),\n \"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100\"\n ),\n nav_button_previous: \"absolute left-1\",\n nav_button_next: \"absolute right-1\",\n table: \"w-full border-collapse space-y-1\",\n head_row: \"flex\",\n head_cell:\n \"text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]\",\n row: \"flex w-full mt-2\",\n cell: \"h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20\",\n day: cn(\n buttonVariants({ variant: \"ghost\" }),\n \"h-9 w-9 p-0 font-normal aria-selected:opacity-100\"\n ),\n day_range_end: \"day-range-end\",\n day_selected:\n \"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground\",\n day_today: \"bg-accent text-accent-foreground\",\n day_outside:\n \"day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30\",\n day_disabled: \"text-muted-foreground opacity-50\",\n day_range_middle:\n \"aria-selected:bg-accent aria-selected:text-accent-foreground\",\n day_hidden: \"invisible\",\n ...classNames,\n }}\n components={{\n Chevron: ({ ...props }) => {\n if (props.orientation === \"left\") {\n return <ChevronLeft className=\"h-4 w-4\" />\n }\n return <ChevronRight className=\"h-4 w-4\" />\n },\n }}\n {...props}\n />\n )\n}\nCalendar.displayName = \"Calendar\"\n\nexport { Calendar }\n","import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../lib/utils';\nimport { Slot } from '@radix-ui/react-slot';\n\nconst buttonVariants = cva(\n 'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 sage-interactive [&_svg]:transition-transform [&_svg]:duration-300 hover:[&_svg]:translate-x-1',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground shadow',\n primary: 'bg-primary text-primary-foreground shadow', // Alias for default\n destructive: 'bg-destructive text-destructive-foreground shadow-sm',\n outline: 'border border-input bg-transparent shadow-sm hover:bg-primary hover:text-primary-foreground hover:border-primary',\n secondary: 'bg-black/5 dark:bg-white/10 backdrop-blur-md border border-black/5 dark:border-white/10 text-secondary-foreground shadow-sm hover:bg-primary hover:text-primary-foreground dark:hover:bg-primary dark:hover:text-primary-foreground',\n ghost: 'hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-10 rounded-md px-8',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nconst Button = (\n {\n ref,\n className,\n variant,\n size,\n asChild = false,\n children,\n ...props\n }: ButtonProps & {\n ref?: React.Ref<HTMLButtonElement>;\n }\n) => {\n const Comp = asChild ? Slot : \"button\"\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n >\n {asChild ? (\n children\n ) : (\n <span className=\"relative z-20 flex items-center justify-center gap-2\">\n {children}\n </span>\n )}\n </Comp>\n )\n}\n\nexport { Button, buttonVariants };\n","\"use client\"\n\nimport * as React from \"react\"\nimport { format } from \"date-fns\"\nimport { Calendar as CalendarIcon } from \"lucide-react\"\n\nimport { cn } from \"../../lib/utils\"\nimport { Button } from \"../actions/Button\"\nimport { Calendar } from \"../data-display/Calendar\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../overlays/Popover\"\n\nexport interface DatePickerProps {\n date?: Date\n onDateChange?: (date: Date | undefined) => void\n placeholder?: string\n className?: string\n disabled?: boolean\n}\n\nexport function DatePicker({\n date,\n onDateChange,\n placeholder = \"Pick a date\",\n className,\n disabled = false,\n}: DatePickerProps) {\n return (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n className={cn(\n \"w-[280px] justify-start text-left font-normal\",\n !date && \"text-muted-foreground\",\n className\n )}\n disabled={disabled}\n >\n <CalendarIcon className=\"mr-2 h-4 w-4\" />\n {date ? format(date, \"PPP\") : <span>{placeholder}</span>}\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto p-0\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={onDateChange}\n initialFocus\n />\n </PopoverContent>\n </Popover>\n )\n}\n","\"use client\";\nimport * as React from \"react\"\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst Popover = PopoverPrimitive.Root\n\nconst PopoverTrigger = PopoverPrimitive.Trigger\n\nconst PopoverAnchor = PopoverPrimitive.Anchor\n\nconst PopoverContent = (\n {\n ref,\n className,\n align = \"center\",\n sideOffset = 4,\n ...props\n }: React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content> & {\n ref?: React.Ref<React.ElementRef<typeof PopoverPrimitive.Content>>;\n }\n) => (<PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n ref={ref}\n align={align}\n sideOffset={sideOffset}\n className={cn(\n \"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none 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 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n className\n )}\n {...props}\n />\n</PopoverPrimitive.Portal>)\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }\n"],"mappings":"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","names":["import_jsx_runtime","props","import_lucide_react","import_jsx_runtime","import_jsx_runtime","CalendarIcon"]}