@mikenotthepope/substrateui 0.1.1 → 0.1.3
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.
- package/CHANGELOG.md +23 -0
- package/LICENSE +1 -1
- package/README.md +98 -165
- package/dist/chunk-IQWAGBDM.js +42 -0
- package/dist/chunk-IQWAGBDM.js.map +1 -0
- package/dist/chunk-IRBORST3.js +258 -0
- package/dist/chunk-IRBORST3.js.map +1 -0
- package/dist/index.d.ts +1485 -1098
- package/dist/index.js +4692 -5339
- package/dist/index.js.map +1 -1
- package/dist/organisms.d.ts +112 -0
- package/dist/organisms.js +403 -0
- package/dist/organisms.js.map +1 -0
- package/dist/styles.css +583 -0
- package/dist/tabs-d_9ZRlWe.d.ts +18 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +4 -0
- package/dist/utils.js.map +1 -0
- package/package.json +84 -70
- package/base/substrate.css +0 -489
- package/dist/index.d.mts +0 -1222
- package/dist/index.mjs +0 -6399
- package/dist/index.mjs.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to SubstrateUI will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-04-04
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release
|
|
12
|
+
- 75 UI components built on Radix UI primitives
|
|
13
|
+
- 3-layer OKLCH color token system (raw palette → semantic → Tailwind utilities)
|
|
14
|
+
- Dark mode via semantic token swap (`.dark` class)
|
|
15
|
+
- Layout primitives: Stack, Cluster, Grid, Center, Divider, Spacer
|
|
16
|
+
- Form patterns: Field (with context), FormSection, FormActions, Fieldset
|
|
17
|
+
- App shell organisms: AppShell, PageHeader, PageBody, PageTabs, StatCard
|
|
18
|
+
- Typography system: H1-H4, P, Lead, Large, Small, Muted, Code, Mono
|
|
19
|
+
- Data display: DataTable with sorting, filtering, pagination, row selection
|
|
20
|
+
- Custom components: Combobox (single/multi), SearchField, InputGroup, ButtonGroup, DatePicker, Kbd, Spinner, Empty, NativeSelect, Item
|
|
21
|
+
- Tailwind CSS v4 native (`@theme inline`, CSS-first configuration)
|
|
22
|
+
- Full TypeScript support with exported types
|
|
23
|
+
- Tree-shakeable ESM exports via three entry points
|
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,226 +1,159 @@
|
|
|
1
|
-
#
|
|
1
|
+
# SubstrateUI
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A chunky, opinionated design system for Next.js — OKLCH tokens, Tailwind CSS v4, Radix UI primitives.
|
|
4
4
|
|
|
5
|
-
[](https://react.dev/)
|
|
5
|
+
[](https://www.npmjs.com/package/substrateui)
|
|
6
|
+
[](https://github.com/substrateui/substrateui/blob/main/LICENSE)
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
<!-- Replace <OWNER>/<REPO> with the GitHub owner/repo once the repo is pushed,
|
|
9
|
+
and <VERCEL-PRODUCTION-URL> with the production URL after Vercel deploys. -->
|
|
10
|
+
## Status
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
[](https://github.com/<OWNER>/<REPO>/actions/workflows/ci.yml)
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
- **Docs:** <VERCEL-PRODUCTION-URL>
|
|
15
|
+
- **Storybook:** https://substrateui.dev/storybook/ — run locally with `bun run storybook`
|
|
16
|
+
- **npm:** `@substrateui/core` (not yet published)
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
## Features
|
|
16
19
|
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
20
|
+
- 75 components from atomic Button to organism App Shell
|
|
21
|
+
- 3-layer OKLCH color system: raw palette → semantic tokens → Tailwind utilities
|
|
22
|
+
- Dark mode as a token swap — zero component changes
|
|
23
|
+
- Chunky 2px borders and press-down animations
|
|
24
|
+
- CVD-safe plum + amber color pairing
|
|
25
|
+
- WCAG AA contrast verified on every token pairing — see [contrast report](./audit-contrast-report.md)
|
|
26
|
+
- Built for Tailwind CSS v4 (`@theme inline`, CSS-first config)
|
|
27
|
+
- Full TypeScript support with exported types
|
|
28
|
+
- Tree-shakeable ESM exports
|
|
23
29
|
|
|
24
30
|
## Quick Start
|
|
25
31
|
|
|
26
|
-
### Install
|
|
27
|
-
|
|
28
32
|
```bash
|
|
29
|
-
npm install
|
|
33
|
+
npm install substrateui
|
|
30
34
|
```
|
|
31
35
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
### Import the stylesheet
|
|
35
|
-
|
|
36
|
-
Add the base stylesheet once in your app root. This provides all design tokens and component styles.
|
|
37
|
-
|
|
38
|
-
```tsx
|
|
39
|
-
// app/layout.tsx (Next.js) or src/main.tsx (Vite)
|
|
40
|
-
import "@mikenotthepope/substrateui/styles";
|
|
41
|
-
```
|
|
36
|
+
### CSS Setup
|
|
42
37
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
import
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return (
|
|
50
|
-
<Card>
|
|
51
|
-
<Card.Header>
|
|
52
|
-
<Text variant="h3">Hello</Text>
|
|
53
|
-
</Card.Header>
|
|
54
|
-
<Card.Body>
|
|
55
|
-
<Text>Neobrutalist components, ready to go.</Text>
|
|
56
|
-
<Button>Get Started</Button>
|
|
57
|
-
</Card.Body>
|
|
58
|
-
</Card>
|
|
59
|
-
);
|
|
60
|
-
}
|
|
38
|
+
```css
|
|
39
|
+
/* globals.css */
|
|
40
|
+
@import "tailwindcss";
|
|
41
|
+
@import "tw-animate-css";
|
|
42
|
+
@import "substrateui/styles.css";
|
|
43
|
+
@source "../node_modules/substrateui";
|
|
61
44
|
```
|
|
62
45
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
Substrate UI uses three font families via CSS custom properties:
|
|
66
|
-
|
|
67
|
-
| Token | Default Font | Purpose |
|
|
68
|
-
| -------------- | --------------- | ---------- |
|
|
69
|
-
| `--font-head` | Bricolage Grotesque | Headings |
|
|
70
|
-
| `--font-sans` | Space Grotesk | Body text |
|
|
71
|
-
| `--font-mono` | Space Mono | Code |
|
|
72
|
-
|
|
73
|
-
**Next.js:**
|
|
46
|
+
### Font Setup (recommended)
|
|
74
47
|
|
|
75
48
|
```tsx
|
|
76
|
-
|
|
49
|
+
// layout.tsx
|
|
50
|
+
import { DM_Sans, DM_Mono } from "next/font/google"
|
|
77
51
|
|
|
78
|
-
const sans =
|
|
79
|
-
const
|
|
80
|
-
const mono = Space_Mono({ variable: "--font-mono", subsets: ["latin"], weight: "400" });
|
|
52
|
+
const sans = DM_Sans({ subsets: ["latin"], variable: "--font-sans" })
|
|
53
|
+
const mono = DM_Mono({ weight: ["400", "500"], subsets: ["latin"], variable: "--font-mono" })
|
|
81
54
|
|
|
82
|
-
export default function
|
|
55
|
+
export default function Layout({ children }: { children: React.ReactNode }) {
|
|
83
56
|
return (
|
|
84
|
-
<html className={`${sans.variable} ${
|
|
57
|
+
<html className={`${sans.variable} ${mono.variable}`}>
|
|
85
58
|
<body>{children}</body>
|
|
86
59
|
</html>
|
|
87
|
-
)
|
|
60
|
+
)
|
|
88
61
|
}
|
|
89
62
|
```
|
|
90
63
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
```html
|
|
94
|
-
<link href="https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:wght@400;700;800&family=Space+Grotesk:wght@400;500;700&family=Space+Mono&display=swap" rel="stylesheet">
|
|
95
|
-
<style>
|
|
96
|
-
:root {
|
|
97
|
-
--font-head: 'Bricolage Grotesque', sans-serif;
|
|
98
|
-
--font-sans: 'Space Grotesk', sans-serif;
|
|
99
|
-
--font-mono: 'Space Mono', monospace;
|
|
100
|
-
}
|
|
101
|
-
</style>
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
If fonts aren't loaded, the library falls back to `Space Grotesk -> system-ui -> sans-serif`.
|
|
105
|
-
|
|
106
|
-
## Theming
|
|
107
|
-
|
|
108
|
-
### Light / Dark Mode
|
|
109
|
-
|
|
110
|
-
Use the built-in `ThemeProvider` to manage theme switching:
|
|
64
|
+
### Dark Mode
|
|
111
65
|
|
|
112
66
|
```tsx
|
|
113
|
-
import { ThemeProvider } from "
|
|
67
|
+
import { ThemeProvider } from "next-themes"
|
|
114
68
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
</ThemeProvider>
|
|
120
|
-
);
|
|
121
|
-
}
|
|
69
|
+
// Wrap your app:
|
|
70
|
+
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
|
71
|
+
{children}
|
|
72
|
+
</ThemeProvider>
|
|
122
73
|
```
|
|
123
74
|
|
|
124
|
-
|
|
75
|
+
### Use Components
|
|
125
76
|
|
|
126
77
|
```tsx
|
|
127
|
-
import {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const { theme, setTheme } = useTheme();
|
|
131
|
-
return (
|
|
132
|
-
<button onClick={() => setTheme(theme === "dark" ? "light" : "dark")}>
|
|
133
|
-
Toggle theme
|
|
134
|
-
</button>
|
|
135
|
-
);
|
|
136
|
-
}
|
|
78
|
+
import { Button, Stack, Card, CardHeader, CardTitle, CardContent } from "substrateui"
|
|
79
|
+
import { AppShell, AppShellSidebar, AppShellMain } from "substrateui/organisms"
|
|
80
|
+
import { cn } from "substrateui/utils"
|
|
137
81
|
```
|
|
138
82
|
|
|
139
|
-
|
|
83
|
+
## Exports
|
|
140
84
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
```
|
|
85
|
+
| Import path | Contents |
|
|
86
|
+
|---|---|
|
|
87
|
+
| `substrateui` | All 75 UI primitives (Button, Card, Input, Table, etc.) |
|
|
88
|
+
| `substrateui/organisms` | App-level patterns (AppShell, PageHeader, PageBody, PageTabs, StatCard) |
|
|
89
|
+
| `substrateui/utils` | `cn()` utility (clsx + tailwind-merge) |
|
|
90
|
+
| `substrateui/styles.css` | OKLCH token system + Tailwind theme + base styles |
|
|
148
91
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
Override any CSS custom property to customize the theme:
|
|
152
|
-
|
|
153
|
-
```css
|
|
154
|
-
:root {
|
|
155
|
-
--primary: #6366f1;
|
|
156
|
-
--primary-foreground: #fff;
|
|
157
|
-
--primary-hover: #4f46e5;
|
|
158
|
-
}
|
|
159
|
-
```
|
|
92
|
+
## Requirements
|
|
160
93
|
|
|
161
|
-
|
|
94
|
+
- React 18+
|
|
95
|
+
- Tailwind CSS 4+
|
|
96
|
+
- `tw-animate-css` (for animations)
|
|
97
|
+
- `next-themes` (optional, for dark mode toggle)
|
|
98
|
+
- `next` 15+ (optional, only for `substrateui/organisms` which use `next/link`)
|
|
162
99
|
|
|
163
|
-
##
|
|
100
|
+
## Token Architecture
|
|
164
101
|
|
|
165
|
-
|
|
102
|
+
SubstrateUI uses a 3-layer OKLCH color system:
|
|
166
103
|
|
|
167
|
-
|
|
104
|
+
1. **Raw palette** — OKLCH values (`--raw-plum-600`, `--raw-amber-500`, etc.)
|
|
105
|
+
2. **Semantic tokens** — Purpose-based mappings (`--primary`, `--surface-raised`, `--status-error`, etc.) with automatic dark mode via `.dark` class
|
|
106
|
+
3. **Tailwind utilities** — `@theme inline` maps tokens to `bg-primary`, `text-foreground`, `border-border`, etc.
|
|
168
107
|
|
|
169
|
-
|
|
108
|
+
## Component Categories
|
|
170
109
|
|
|
171
|
-
|
|
110
|
+
- **General** — Button, ButtonGroup, Badge, Kbd, Spinner, Empty
|
|
111
|
+
- **Typography** — H1-H4, P, Lead, Large, Small, Muted, Code, Mono
|
|
112
|
+
- **Layout** — Stack, Cluster, Grid, Center, Divider, Spacer, Separator, AspectRatio, ResizablePanels
|
|
113
|
+
- **Forms** — Input, Textarea, Select, NativeSelect, Checkbox, RadioGroup, Switch, Slider, DatePicker, Combobox, InputGroup, InputOTP, SearchField, Field, Fieldset, FormSection, FormActions
|
|
114
|
+
- **Data Display** — Card, Table, DataTable, Avatar, Calendar, Carousel, Chart, HoverCard, Item
|
|
115
|
+
- **Feedback** — Alert, AlertDialog, Dialog, Progress, Skeleton, Sonner (toast)
|
|
116
|
+
- **Overlays** — Sheet, Drawer, Popover, Tooltip, ContextMenu, DropdownMenu, Command
|
|
117
|
+
- **Navigation** — Tabs, Breadcrumb, NavigationMenu, Menubar, Pagination, ScrollArea, Sidebar, Collapsible, Accordion
|
|
118
|
+
- **Patterns** — AppShell, PageHeader, PageBody, PageTabs, StatCard
|
|
172
119
|
|
|
173
|
-
|
|
120
|
+
## Customization
|
|
174
121
|
|
|
175
|
-
|
|
122
|
+
Override tokens after importing the stylesheet:
|
|
176
123
|
|
|
177
|
-
|
|
124
|
+
```css
|
|
125
|
+
/* After importing substrateui/styles.css */
|
|
126
|
+
:root {
|
|
127
|
+
--primary: oklch(0.55 0.15 250); /* Change primary to blue */
|
|
128
|
+
}
|
|
129
|
+
```
|
|
178
130
|
|
|
179
|
-
|
|
131
|
+
## Accessibility
|
|
180
132
|
|
|
181
|
-
|
|
133
|
+
SubstrateUI meets WCAG AA contrast requirements (verified by automated audit) and is built on Radix UI primitives for robust keyboard and screen reader support.
|
|
182
134
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
import { NavBar } from "@mikenotthepope/substrateui";
|
|
135
|
+
- [Accessibility documentation](https://substrateui.dev/docs/accessibility)
|
|
136
|
+
- [Contrast audit report](./audit-contrast-report.md)
|
|
186
137
|
|
|
187
|
-
|
|
188
|
-
```
|
|
138
|
+
Every component ships with accessible defaults. For guidance on specific components, see the "Accessibility" section on each component's documentation page.
|
|
189
139
|
|
|
190
|
-
|
|
140
|
+
## Storybook
|
|
191
141
|
|
|
192
|
-
|
|
142
|
+
Contributors can browse components in isolation, flip between light/dark themes, swap `ltr`/`rtl` direction, and switch the semantic palette (Plum / Forest) from the toolbar.
|
|
193
143
|
|
|
194
144
|
```bash
|
|
195
|
-
bun
|
|
196
|
-
bun
|
|
197
|
-
bun storybook # Start Storybook
|
|
198
|
-
bun test # Run tests
|
|
199
|
-
bun run build # Build the library (tsup)
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### Project Structure
|
|
203
|
-
|
|
204
|
-
```
|
|
205
|
-
substrateui/
|
|
206
|
-
├── src/index.ts # Barrel export for the published package
|
|
207
|
-
├── components/ui/ # 57 primitive components
|
|
208
|
-
├── components/landing/ # 12 landing page components
|
|
209
|
-
├── components/ # Composite components + ThemeProvider
|
|
210
|
-
├── base/substrate.css # Design tokens & base styles
|
|
211
|
-
├── app/ # Next.js demo/docs site
|
|
212
|
-
├── AGENTS.md # Shared AI agent instructions
|
|
213
|
-
├── CLAUDE.md # Claude Code config (imports AGENTS.md)
|
|
214
|
-
└── tsup.config.ts # Library build config
|
|
145
|
+
bun run storybook # dev server on http://localhost:6006
|
|
146
|
+
bun run build-storybook # static bundle in ./storybook-static
|
|
215
147
|
```
|
|
216
148
|
|
|
217
|
-
|
|
149
|
+
Hosted build: https://substrateui.dev/storybook/
|
|
218
150
|
|
|
219
|
-
|
|
151
|
+
## Links
|
|
220
152
|
|
|
221
|
-
- [
|
|
222
|
-
- [
|
|
153
|
+
- [GitHub](https://github.com/substrateui/substrateui)
|
|
154
|
+
- [npm](https://www.npmjs.com/package/substrateui)
|
|
155
|
+
- [Storybook](https://substrateui.dev/storybook/)
|
|
223
156
|
|
|
224
157
|
## License
|
|
225
158
|
|
|
226
|
-
|
|
159
|
+
MIT
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __defProps = Object.defineProperties;
|
|
7
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
8
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
11
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
12
|
+
var __spreadValues = (a, b) => {
|
|
13
|
+
for (var prop in b || (b = {}))
|
|
14
|
+
if (__hasOwnProp.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
if (__getOwnPropSymbols)
|
|
17
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
18
|
+
if (__propIsEnum.call(b, prop))
|
|
19
|
+
__defNormalProp(a, prop, b[prop]);
|
|
20
|
+
}
|
|
21
|
+
return a;
|
|
22
|
+
};
|
|
23
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
24
|
+
var __objRest = (source, exclude) => {
|
|
25
|
+
var target = {};
|
|
26
|
+
for (var prop in source)
|
|
27
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
28
|
+
target[prop] = source[prop];
|
|
29
|
+
if (source != null && __getOwnPropSymbols)
|
|
30
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
31
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
32
|
+
target[prop] = source[prop];
|
|
33
|
+
}
|
|
34
|
+
return target;
|
|
35
|
+
};
|
|
36
|
+
function cn(...inputs) {
|
|
37
|
+
return twMerge(clsx(inputs));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { __objRest, __spreadProps, __spreadValues, cn };
|
|
41
|
+
//# sourceMappingURL=chunk-IQWAGBDM.js.map
|
|
42
|
+
//# sourceMappingURL=chunk-IQWAGBDM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B","file":"chunk-IQWAGBDM.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n"]}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { __objRest, __spreadValues, cn } from './chunk-IQWAGBDM.js';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
5
|
+
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
6
|
+
|
|
7
|
+
function Card(_a) {
|
|
8
|
+
var _b = _a, {
|
|
9
|
+
className,
|
|
10
|
+
interactive = false,
|
|
11
|
+
ref
|
|
12
|
+
} = _b, props = __objRest(_b, [
|
|
13
|
+
"className",
|
|
14
|
+
"interactive",
|
|
15
|
+
"ref"
|
|
16
|
+
]);
|
|
17
|
+
return /* @__PURE__ */ jsx(
|
|
18
|
+
"div",
|
|
19
|
+
__spreadValues({
|
|
20
|
+
ref,
|
|
21
|
+
"data-slot": "card",
|
|
22
|
+
className: cn(
|
|
23
|
+
"rounded-lg border-2 bg-card text-card-foreground shadow-sm",
|
|
24
|
+
interactive && "cursor-pointer hover:border-ring hover:shadow-md transition-all active:translate-y-[1.5px]",
|
|
25
|
+
className
|
|
26
|
+
)
|
|
27
|
+
}, props)
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
function CardHeader(_a) {
|
|
31
|
+
var _b = _a, {
|
|
32
|
+
className,
|
|
33
|
+
ref
|
|
34
|
+
} = _b, props = __objRest(_b, [
|
|
35
|
+
"className",
|
|
36
|
+
"ref"
|
|
37
|
+
]);
|
|
38
|
+
return /* @__PURE__ */ jsx(
|
|
39
|
+
"div",
|
|
40
|
+
__spreadValues({
|
|
41
|
+
ref,
|
|
42
|
+
"data-slot": "card-header",
|
|
43
|
+
className: cn("flex flex-col space-y-1.5 p-6", className)
|
|
44
|
+
}, props)
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
function CardTitle(_a) {
|
|
48
|
+
var _b = _a, {
|
|
49
|
+
className,
|
|
50
|
+
ref
|
|
51
|
+
} = _b, props = __objRest(_b, [
|
|
52
|
+
"className",
|
|
53
|
+
"ref"
|
|
54
|
+
]);
|
|
55
|
+
return /* @__PURE__ */ jsx(
|
|
56
|
+
"div",
|
|
57
|
+
__spreadValues({
|
|
58
|
+
ref,
|
|
59
|
+
"data-slot": "card-title",
|
|
60
|
+
className: cn(
|
|
61
|
+
"text-2xl font-semibold leading-none tracking-tight",
|
|
62
|
+
className
|
|
63
|
+
)
|
|
64
|
+
}, props)
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
function CardDescription(_a) {
|
|
68
|
+
var _b = _a, {
|
|
69
|
+
className,
|
|
70
|
+
ref
|
|
71
|
+
} = _b, props = __objRest(_b, [
|
|
72
|
+
"className",
|
|
73
|
+
"ref"
|
|
74
|
+
]);
|
|
75
|
+
return /* @__PURE__ */ jsx(
|
|
76
|
+
"div",
|
|
77
|
+
__spreadValues({
|
|
78
|
+
ref,
|
|
79
|
+
"data-slot": "card-description",
|
|
80
|
+
className: cn("text-sm text-muted-foreground", className)
|
|
81
|
+
}, props)
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
function CardContent(_a) {
|
|
85
|
+
var _b = _a, {
|
|
86
|
+
className,
|
|
87
|
+
ref
|
|
88
|
+
} = _b, props = __objRest(_b, [
|
|
89
|
+
"className",
|
|
90
|
+
"ref"
|
|
91
|
+
]);
|
|
92
|
+
return /* @__PURE__ */ jsx(
|
|
93
|
+
"div",
|
|
94
|
+
__spreadValues({
|
|
95
|
+
ref,
|
|
96
|
+
"data-slot": "card-content",
|
|
97
|
+
className: cn("p-6 pt-0", className)
|
|
98
|
+
}, props)
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
function CardFooter(_a) {
|
|
102
|
+
var _b = _a, {
|
|
103
|
+
className,
|
|
104
|
+
ref
|
|
105
|
+
} = _b, props = __objRest(_b, [
|
|
106
|
+
"className",
|
|
107
|
+
"ref"
|
|
108
|
+
]);
|
|
109
|
+
return /* @__PURE__ */ jsx(
|
|
110
|
+
"div",
|
|
111
|
+
__spreadValues({
|
|
112
|
+
ref,
|
|
113
|
+
"data-slot": "card-footer",
|
|
114
|
+
className: cn("flex items-center p-6 pt-0", className)
|
|
115
|
+
}, props)
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
var maxMap = {
|
|
119
|
+
sm: "max-w-screen-sm",
|
|
120
|
+
md: "max-w-screen-md",
|
|
121
|
+
lg: "max-w-screen-lg",
|
|
122
|
+
xl: "max-w-screen-xl",
|
|
123
|
+
"2xl": "max-w-screen-2xl",
|
|
124
|
+
full: "max-w-full"
|
|
125
|
+
};
|
|
126
|
+
function Center(_a) {
|
|
127
|
+
var _b = _a, {
|
|
128
|
+
max = "2xl",
|
|
129
|
+
padding = true,
|
|
130
|
+
asChild = false,
|
|
131
|
+
className,
|
|
132
|
+
ref
|
|
133
|
+
} = _b, props = __objRest(_b, [
|
|
134
|
+
"max",
|
|
135
|
+
"padding",
|
|
136
|
+
"asChild",
|
|
137
|
+
"className",
|
|
138
|
+
"ref"
|
|
139
|
+
]);
|
|
140
|
+
const Comp = asChild ? Slot : "div";
|
|
141
|
+
return /* @__PURE__ */ jsx(
|
|
142
|
+
Comp,
|
|
143
|
+
__spreadValues({
|
|
144
|
+
"data-slot": "center",
|
|
145
|
+
className: cn(
|
|
146
|
+
"mx-auto w-full",
|
|
147
|
+
maxMap[max],
|
|
148
|
+
padding && "px-4 sm:px-6 lg:px-8",
|
|
149
|
+
className
|
|
150
|
+
),
|
|
151
|
+
ref
|
|
152
|
+
}, props)
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
var gapMap = {
|
|
156
|
+
none: "gap-0",
|
|
157
|
+
xs: "gap-1",
|
|
158
|
+
sm: "gap-2",
|
|
159
|
+
md: "gap-4",
|
|
160
|
+
lg: "gap-6",
|
|
161
|
+
xl: "gap-8",
|
|
162
|
+
"2xl": "gap-12"
|
|
163
|
+
};
|
|
164
|
+
var alignMap = {
|
|
165
|
+
start: "items-start",
|
|
166
|
+
center: "items-center",
|
|
167
|
+
end: "items-end",
|
|
168
|
+
stretch: "items-stretch"
|
|
169
|
+
};
|
|
170
|
+
function Stack(_a) {
|
|
171
|
+
var _b = _a, {
|
|
172
|
+
gap = "md",
|
|
173
|
+
align = "stretch",
|
|
174
|
+
asChild = false,
|
|
175
|
+
className,
|
|
176
|
+
ref
|
|
177
|
+
} = _b, props = __objRest(_b, [
|
|
178
|
+
"gap",
|
|
179
|
+
"align",
|
|
180
|
+
"asChild",
|
|
181
|
+
"className",
|
|
182
|
+
"ref"
|
|
183
|
+
]);
|
|
184
|
+
const Comp = asChild ? Slot : "div";
|
|
185
|
+
return /* @__PURE__ */ jsx(
|
|
186
|
+
Comp,
|
|
187
|
+
__spreadValues({
|
|
188
|
+
"data-slot": "stack",
|
|
189
|
+
className: cn("flex flex-col", gapMap[gap], alignMap[align], className),
|
|
190
|
+
ref
|
|
191
|
+
}, props)
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
var Tabs = TabsPrimitive.Root;
|
|
195
|
+
function TabsList(_a) {
|
|
196
|
+
var _b = _a, {
|
|
197
|
+
className,
|
|
198
|
+
ref
|
|
199
|
+
} = _b, props = __objRest(_b, [
|
|
200
|
+
"className",
|
|
201
|
+
"ref"
|
|
202
|
+
]);
|
|
203
|
+
return /* @__PURE__ */ jsx(
|
|
204
|
+
TabsPrimitive.List,
|
|
205
|
+
__spreadValues({
|
|
206
|
+
ref,
|
|
207
|
+
"data-slot": "tabs-list",
|
|
208
|
+
className: cn(
|
|
209
|
+
"inline-flex h-10 items-center justify-center rounded-lg bg-surface-sunken border-2 p-1 text-muted-foreground",
|
|
210
|
+
className
|
|
211
|
+
)
|
|
212
|
+
}, props)
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
function TabsTrigger(_a) {
|
|
216
|
+
var _b = _a, {
|
|
217
|
+
className,
|
|
218
|
+
ref
|
|
219
|
+
} = _b, props = __objRest(_b, [
|
|
220
|
+
"className",
|
|
221
|
+
"ref"
|
|
222
|
+
]);
|
|
223
|
+
return /* @__PURE__ */ jsx(
|
|
224
|
+
TabsPrimitive.Trigger,
|
|
225
|
+
__spreadValues({
|
|
226
|
+
ref,
|
|
227
|
+
"data-slot": "tabs-trigger",
|
|
228
|
+
className: cn(
|
|
229
|
+
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1.5 text-sm font-medium ring-offset-background transition-all active:translate-y-[1.5px] transition-transform focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
|
230
|
+
className
|
|
231
|
+
)
|
|
232
|
+
}, props)
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
function TabsContent(_a) {
|
|
236
|
+
var _b = _a, {
|
|
237
|
+
className,
|
|
238
|
+
ref
|
|
239
|
+
} = _b, props = __objRest(_b, [
|
|
240
|
+
"className",
|
|
241
|
+
"ref"
|
|
242
|
+
]);
|
|
243
|
+
return /* @__PURE__ */ jsx(
|
|
244
|
+
TabsPrimitive.Content,
|
|
245
|
+
__spreadValues({
|
|
246
|
+
ref,
|
|
247
|
+
"data-slot": "tabs-content",
|
|
248
|
+
className: cn(
|
|
249
|
+
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
250
|
+
className
|
|
251
|
+
)
|
|
252
|
+
}, props)
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Center, Stack, Tabs, TabsContent, TabsList, TabsTrigger };
|
|
257
|
+
//# sourceMappingURL=chunk-IRBORST3.js.map
|
|
258
|
+
//# sourceMappingURL=chunk-IRBORST3.js.map
|