@refine-studio/ui 0.0.0 → 0.1.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.
- package/LICENSE +21 -0
- package/README.md +102 -2
- package/dist/components/accordion/accordion.d.ts +15 -0
- package/dist/components/accordion/accordion.js +58 -0
- package/dist/components/accordion/accordion.js.map +1 -0
- package/dist/components/alert/alert.d.ts +24 -0
- package/dist/components/alert/alert.js +98 -0
- package/dist/components/alert/alert.js.map +1 -0
- package/dist/components/alert-dialog/alert-dialog.d.ts +36 -0
- package/dist/components/alert-dialog/alert-dialog.js +112 -0
- package/dist/components/alert-dialog/alert-dialog.js.map +1 -0
- package/dist/components/app-shell/app-shell.d.ts +77 -0
- package/dist/components/app-shell/app-shell.js +224 -0
- package/dist/components/app-shell/app-shell.js.map +1 -0
- package/dist/components/avatar/avatar.d.ts +32 -0
- package/dist/components/avatar/avatar.js +83 -0
- package/dist/components/avatar/avatar.js.map +1 -0
- package/dist/components/badge/badge.d.ts +15 -0
- package/dist/components/badge/badge.js +50 -0
- package/dist/components/badge/badge.js.map +1 -0
- package/dist/components/breadcrumb/breadcrumb.d.ts +24 -0
- package/dist/components/breadcrumb/breadcrumb.js +82 -0
- package/dist/components/breadcrumb/breadcrumb.js.map +1 -0
- package/dist/components/button/button.d.ts +15 -0
- package/dist/components/button/button.js +75 -0
- package/dist/components/button/button.js.map +1 -0
- package/dist/components/card/card.d.ts +46 -0
- package/dist/components/card/card.js +124 -0
- package/dist/components/card/card.js.map +1 -0
- package/dist/components/checkbox/checkbox.d.ts +6 -0
- package/dist/components/checkbox/checkbox.js +31 -0
- package/dist/components/checkbox/checkbox.js.map +1 -0
- package/dist/components/chip/chip.d.ts +25 -0
- package/dist/components/chip/chip.js +54 -0
- package/dist/components/chip/chip.js.map +1 -0
- package/dist/components/code/code.d.ts +15 -0
- package/dist/components/code/code.js +63 -0
- package/dist/components/code/code.js.map +1 -0
- package/dist/components/collapsible/collapsible.d.ts +14 -0
- package/dist/components/collapsible/collapsible.js +55 -0
- package/dist/components/collapsible/collapsible.js.map +1 -0
- package/dist/components/combobox/combobox.d.ts +33 -0
- package/dist/components/combobox/combobox.js +244 -0
- package/dist/components/combobox/combobox.js.map +1 -0
- package/dist/components/command-menu/command-menu.d.ts +35 -0
- package/dist/components/command-menu/command-menu.js +116 -0
- package/dist/components/command-menu/command-menu.js.map +1 -0
- package/dist/components/context-menu/context-menu.d.ts +45 -0
- package/dist/components/context-menu/context-menu.js +136 -0
- package/dist/components/context-menu/context-menu.js.map +1 -0
- package/dist/components/data-table/data-table.d.ts +49 -0
- package/dist/components/data-table/data-table.js +171 -0
- package/dist/components/data-table/data-table.js.map +1 -0
- package/dist/components/data-table/sort-rows.d.ts +6 -0
- package/dist/components/data-table/sort-rows.js +33 -0
- package/dist/components/data-table/sort-rows.js.map +1 -0
- package/dist/components/dialog/dialog.d.ts +42 -0
- package/dist/components/dialog/dialog.js +118 -0
- package/dist/components/dialog/dialog.js.map +1 -0
- package/dist/components/dropdown-menu/dropdown-menu.d.ts +45 -0
- package/dist/components/dropdown-menu/dropdown-menu.js +137 -0
- package/dist/components/dropdown-menu/dropdown-menu.js.map +1 -0
- package/dist/components/dropdown-menu/menu-styles.d.ts +10 -0
- package/dist/components/dropdown-menu/menu-styles.js +34 -0
- package/dist/components/dropdown-menu/menu-styles.js.map +1 -0
- package/dist/components/empty-state/empty-state.d.ts +12 -0
- package/dist/components/empty-state/empty-state.js +46 -0
- package/dist/components/empty-state/empty-state.js.map +1 -0
- package/dist/components/eyebrow/eyebrow.d.ts +9 -0
- package/dist/components/eyebrow/eyebrow.js +25 -0
- package/dist/components/eyebrow/eyebrow.js.map +1 -0
- package/dist/components/field/field.d.ts +56 -0
- package/dist/components/field/field.js +135 -0
- package/dist/components/field/field.js.map +1 -0
- package/dist/components/glow-border/glow-border.d.ts +9 -0
- package/dist/components/glow-border/glow-border.js +39 -0
- package/dist/components/glow-border/glow-border.js.map +1 -0
- package/dist/components/hex-field/hex-field.d.ts +12 -0
- package/dist/components/hex-field/hex-field.js +86 -0
- package/dist/components/hex-field/hex-field.js.map +1 -0
- package/dist/components/input/input.d.ts +14 -0
- package/dist/components/input/input.js +52 -0
- package/dist/components/input/input.js.map +1 -0
- package/dist/components/kbd/kbd.d.ts +9 -0
- package/dist/components/kbd/kbd.js +26 -0
- package/dist/components/kbd/kbd.js.map +1 -0
- package/dist/components/label/label.d.ts +6 -0
- package/dist/components/label/label.js +17 -0
- package/dist/components/label/label.js.map +1 -0
- package/dist/components/logo/logo-paths.d.ts +5 -0
- package/dist/components/logo/logo-paths.js +20 -0
- package/dist/components/logo/logo-paths.js.map +1 -0
- package/dist/components/logo/logo.d.ts +18 -0
- package/dist/components/logo/logo.js +94 -0
- package/dist/components/logo/logo.js.map +1 -0
- package/dist/components/marquee/marquee.d.ts +15 -0
- package/dist/components/marquee/marquee.js +54 -0
- package/dist/components/marquee/marquee.js.map +1 -0
- package/dist/components/page-header/page-header.d.ts +15 -0
- package/dist/components/page-header/page-header.js +50 -0
- package/dist/components/page-header/page-header.js.map +1 -0
- package/dist/components/pagination/pagination.d.ts +28 -0
- package/dist/components/pagination/pagination.js +95 -0
- package/dist/components/pagination/pagination.js.map +1 -0
- package/dist/components/popover/popover.d.ts +14 -0
- package/dist/components/popover/popover.js +48 -0
- package/dist/components/popover/popover.js.map +1 -0
- package/dist/components/progress/progress.d.ts +14 -0
- package/dist/components/progress/progress.js +41 -0
- package/dist/components/progress/progress.js.map +1 -0
- package/dist/components/radio-group/radio-group.d.ts +10 -0
- package/dist/components/radio-group/radio-group.js +33 -0
- package/dist/components/radio-group/radio-group.js.map +1 -0
- package/dist/components/section-heading/section-heading.d.ts +18 -0
- package/dist/components/section-heading/section-heading.js +57 -0
- package/dist/components/section-heading/section-heading.js.map +1 -0
- package/dist/components/select/select.d.ts +32 -0
- package/dist/components/select/select.js +100 -0
- package/dist/components/select/select.js.map +1 -0
- package/dist/components/separator/separator.d.ts +10 -0
- package/dist/components/separator/separator.js +37 -0
- package/dist/components/separator/separator.js.map +1 -0
- package/dist/components/sheet/sheet.d.ts +29 -0
- package/dist/components/sheet/sheet.js +130 -0
- package/dist/components/sheet/sheet.js.map +1 -0
- package/dist/components/skeleton/skeleton.d.ts +5 -0
- package/dist/components/skeleton/skeleton.js +18 -0
- package/dist/components/skeleton/skeleton.js.map +1 -0
- package/dist/components/slider/slider.d.ts +10 -0
- package/dist/components/slider/slider.js +36 -0
- package/dist/components/slider/slider.js.map +1 -0
- package/dist/components/spinner/spinner.d.ts +9 -0
- package/dist/components/spinner/spinner.js +40 -0
- package/dist/components/spinner/spinner.js.map +1 -0
- package/dist/components/spotlight/spotlight.d.ts +9 -0
- package/dist/components/spotlight/spotlight.js +32 -0
- package/dist/components/spotlight/spotlight.js.map +1 -0
- package/dist/components/starfield/starfield.d.ts +11 -0
- package/dist/components/starfield/starfield.js +76 -0
- package/dist/components/starfield/starfield.js.map +1 -0
- package/dist/components/stat/stat.d.ts +28 -0
- package/dist/components/stat/stat.js +100 -0
- package/dist/components/stat/stat.js.map +1 -0
- package/dist/components/switch/switch.d.ts +13 -0
- package/dist/components/switch/switch.js +44 -0
- package/dist/components/switch/switch.js.map +1 -0
- package/dist/components/table/table.d.ts +52 -0
- package/dist/components/table/table.js +96 -0
- package/dist/components/table/table.js.map +1 -0
- package/dist/components/tabs/tabs.d.ts +24 -0
- package/dist/components/tabs/tabs.js +89 -0
- package/dist/components/tabs/tabs.js.map +1 -0
- package/dist/components/textarea/textarea.d.ts +5 -0
- package/dist/components/textarea/textarea.js +20 -0
- package/dist/components/textarea/textarea.js.map +1 -0
- package/dist/components/theme-switcher/theme-switcher.d.ts +7 -0
- package/dist/components/theme-switcher/theme-switcher.js +57 -0
- package/dist/components/theme-switcher/theme-switcher.js.map +1 -0
- package/dist/components/toaster/toaster.d.ts +7 -0
- package/dist/components/toaster/toaster.js +43 -0
- package/dist/components/toaster/toaster.js.map +1 -0
- package/dist/components/toggle-group/toggle-group.d.ts +24 -0
- package/dist/components/toggle-group/toggle-group.js +84 -0
- package/dist/components/toggle-group/toggle-group.js.map +1 -0
- package/dist/components/tooltip/tooltip.d.ts +19 -0
- package/dist/components/tooltip/tooltip.js +49 -0
- package/dist/components/tooltip/tooltip.js.map +1 -0
- package/dist/fonts/geist-cyrillic-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-cyrillic-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-latin-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-mono-cyrillic-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-mono-cyrillic-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-mono-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-mono-latin-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-mono-symbols2-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-mono-vietnamese-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-mono.LICENSE +93 -0
- package/dist/fonts/geist-vietnamese-wght-normal.woff2 +0 -0
- package/dist/fonts/geist.LICENSE +93 -0
- package/dist/icons/create-refine-icon.d.ts +13 -0
- package/dist/icons/create-refine-icon.js +37 -0
- package/dist/icons/create-refine-icon.js.map +1 -0
- package/dist/icons/icon.d.ts +10 -0
- package/dist/icons/icon.js +13 -0
- package/dist/icons/icon.js.map +1 -0
- package/dist/icons/refine-icon-names.d.ts +1857 -0
- package/dist/icons/refine-icon-names.js +471 -0
- package/dist/icons/refine-icon-names.js.map +1 -0
- package/dist/icons/refine-icons.d.ts +1852 -0
- package/dist/icons/refine-icons.js +604 -0
- package/dist/icons/refine-icons.js.map +1 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.js +61 -0
- package/dist/lib/cn.d.ts +5 -0
- package/dist/lib/cn.js +49 -0
- package/dist/lib/cn.js.map +1 -0
- package/dist/lib/use-breakpoint.d.ts +16 -0
- package/dist/lib/use-breakpoint.js +52 -0
- package/dist/lib/use-breakpoint.js.map +1 -0
- package/dist/styles.css +697 -0
- package/dist/theme/theme-provider.d.ts +31 -0
- package/dist/theme/theme-provider.js +115 -0
- package/dist/theme/theme-provider.js.map +1 -0
- package/dist/theme/theme-scope.d.ts +12 -0
- package/dist/theme/theme-scope.js +22 -0
- package/dist/theme/theme-scope.js.map +1 -0
- package/dist/theme/theme.d.ts +20 -0
- package/dist/theme/theme.js +37 -0
- package/dist/theme/theme.js.map +1 -0
- package/package.json +91 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Refine Studio
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,103 @@
|
|
|
1
|
-
|
|
1
|
+
<picture>
|
|
2
|
+
<source media="(prefers-color-scheme: dark)" srcset=".github/assets/banner-dark.png" />
|
|
3
|
+
<img alt="Refine UI: Where Diamonds craft Diamonds. The design system for everything we build for ourselves." src=".github/assets/banner-light.png" />
|
|
4
|
+
</picture>
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
# 💎 Refine UI
|
|
7
|
+
|
|
8
|
+
Refine UI is the design system the Diamonds use to build internal tools: time trackers, voting bots, dashboards, admin panels, and the experiment you start on a Friday. It takes its look from [refine.studio](https://refine.studio), so every tool we build looks like it came from us.
|
|
9
|
+
|
|
10
|
+
**📖 Storybook:** [ui.refine.studio](https://ui.refine.studio). Sign in with a GitHub account in the `refine-studio` organisation to open it.
|
|
11
|
+
|
|
12
|
+
## 🎯 Why it exists
|
|
13
|
+
|
|
14
|
+
Refine UI is built for us first, so it is free to experiment. It has one brand and its own voice: the refine teal, heavy display type, gradients, glass, soft shadows, the hex field and the diamond mark. You get a solid set of everyday parts, so you can spend your time on the idea and not on another button.
|
|
15
|
+
|
|
16
|
+
## 📦 What is inside
|
|
17
|
+
|
|
18
|
+
| Area | Holds |
|
|
19
|
+
| ----------- | ------------------------------------------------------------------------------------------------ |
|
|
20
|
+
| Foundations | Principles, logo, colour, type, shape and spacing, elevation, motion, light and dark mode, icons |
|
|
21
|
+
| Components | About 45 building blocks: buttons, forms, dialogs, menus, tables, tabs, toasts and more |
|
|
22
|
+
| Widgets | Composed pieces such as App Shell, Command Menu and Page Header, plus full example screens |
|
|
23
|
+
| Icons | All of lucide, plus 463 extra icons drawn at lucide's line weight |
|
|
24
|
+
|
|
25
|
+
**Stack:** React 19 · Tailwind CSS 4 · Radix UI · class-variance-authority · lucide-react · Geist Sans and Geist Mono
|
|
26
|
+
|
|
27
|
+
## 🚀 Install it in another repo
|
|
28
|
+
|
|
29
|
+
Refine UI is published to the public npm registry as [`@refine-studio/ui`](https://www.npmjs.com/package/@refine-studio/ui). The install needs no token and no `.npmrc`, and the version arrives already built.
|
|
30
|
+
|
|
31
|
+
### 1. Install the package
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
pnpm add @refine-studio/ui
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Your app needs React 19 and Tailwind CSS 4.
|
|
38
|
+
|
|
39
|
+
### 2. Import the styles
|
|
40
|
+
|
|
41
|
+
Import the stylesheet after Tailwind in your global stylesheet. It brings the tokens, the Geist fonts and the animations. It also registers the library's components as a Tailwind source, so you need no extra `@source` line.
|
|
42
|
+
|
|
43
|
+
```css
|
|
44
|
+
@import 'tailwindcss';
|
|
45
|
+
@import '@refine-studio/ui/styles.css';
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 3. Wrap the app and build
|
|
49
|
+
|
|
50
|
+
`ThemeProvider` sets light or dark mode on `<html>` and remembers the choice.
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
import { Button, ThemeProvider } from '@refine-studio/ui';
|
|
54
|
+
|
|
55
|
+
export const App = () => {
|
|
56
|
+
return (
|
|
57
|
+
<ThemeProvider mode="system">
|
|
58
|
+
<Button variant="gem">Ship it</Button>
|
|
59
|
+
</ThemeProvider>
|
|
60
|
+
);
|
|
61
|
+
};
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 🔤 Fonts in a build of your own
|
|
65
|
+
|
|
66
|
+
The stylesheet loads Geist and Geist Mono from `./fonts/`, next to itself. A bundler such as Vite resolves them for you. When your build writes the CSS out by hand, copy one folder next to it:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
cp -R node_modules/@refine-studio/ui/dist/fonts <your-css-folder>/fonts
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The folder holds the `.woff2` files and their licences (SIL Open Font License).
|
|
73
|
+
|
|
74
|
+
## Theming in one breath
|
|
75
|
+
|
|
76
|
+
There is one brand: refine.studio's teal, zinc neutrals and the website's radii. Two knobs remain, and you can set each on `<html>` or on any subtree.
|
|
77
|
+
|
|
78
|
+
| Knob | Values |
|
|
79
|
+
| ------- | --------------------------------------------------- |
|
|
80
|
+
| Mode | `.light`, `.dark`, `.on-gem` |
|
|
81
|
+
| Density | `data-density="compact \| comfortable \| spacious"` |
|
|
82
|
+
|
|
83
|
+
`ThemeProvider` and `useTheme` manage the document theme, `ThemeSwitcher` gives people a light/dark/system toggle, and `ThemeScope` re-themes a single subtree.
|
|
84
|
+
|
|
85
|
+
## Develop
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
pnpm install
|
|
89
|
+
pnpm dev # Storybook on http://localhost:6006
|
|
90
|
+
pnpm test # Vitest
|
|
91
|
+
pnpm typecheck && pnpm lint
|
|
92
|
+
pnpm build # library → dist/
|
|
93
|
+
pnpm build-storybook # static Storybook → storybook-static/
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Every component lives in `src/components/<name>/` next to its stories. The tokens live in `src/styles/refine-ui.css`. When you add a custom utility or token, also register it in `src/lib/cn.ts` so `tailwind-merge` resolves conflicts with it.
|
|
97
|
+
|
|
98
|
+
## Release
|
|
99
|
+
|
|
100
|
+
1. Bump `version` in `package.json`.
|
|
101
|
+
2. Tag the commit with `vX.Y.Z` and push the tag.
|
|
102
|
+
|
|
103
|
+
The `Release` workflow publishes that version to npm with provenance and creates a GitHub release. It publishes through npm's trusted publishing, so no npm token exists anywhere. The tag must match `version`, or the workflow stops. Pushing to `main` redeploys Storybook to [ui.refine.studio](https://ui.refine.studio) through GitHub Pages.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Accordion as AccordionPrimitive } from 'radix-ui';
|
|
2
|
+
import type { ComponentProps } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Stacks collapsible sections; `type="single"` keeps one open, `type="multiple"` lets several open.
|
|
5
|
+
*/
|
|
6
|
+
export declare const Accordion: ({ className, ...props }: ComponentProps<typeof AccordionPrimitive.Root>) => import("react").JSX.Element;
|
|
7
|
+
export declare const AccordionItem: ({ className, ...props }: ComponentProps<typeof AccordionPrimitive.Item>) => import("react").JSX.Element;
|
|
8
|
+
/**
|
|
9
|
+
* Toggles its section and turns the chevron to show the state.
|
|
10
|
+
*/
|
|
11
|
+
export declare const AccordionTrigger: ({ children, className, ...props }: ComponentProps<typeof AccordionPrimitive.Trigger>) => import("react").JSX.Element;
|
|
12
|
+
/**
|
|
13
|
+
* Reveals its section with a height animation.
|
|
14
|
+
*/
|
|
15
|
+
export declare const AccordionContent: ({ children, className, ...props }: ComponentProps<typeof AccordionPrimitive.Content>) => import("react").JSX.Element;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/cn.js";
|
|
3
|
+
import { ChevronDown } from "lucide-react";
|
|
4
|
+
import { Accordion } from "radix-ui";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
// src/components/accordion/accordion.tsx
|
|
7
|
+
/**
|
|
8
|
+
* Stacks collapsible sections; `type="single"` keeps one open, `type="multiple"` lets several open.
|
|
9
|
+
*/
|
|
10
|
+
var Accordion$1 = ({ className, ...props }) => {
|
|
11
|
+
return /* @__PURE__ */ jsx(Accordion.Root, {
|
|
12
|
+
className: cn("w-full", className),
|
|
13
|
+
"data-slot": "accordion",
|
|
14
|
+
...props
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
var AccordionItem = ({ className, ...props }) => {
|
|
18
|
+
return /* @__PURE__ */ jsx(Accordion.Item, {
|
|
19
|
+
className: cn("border-b last:border-b-0", className),
|
|
20
|
+
"data-slot": "accordion-item",
|
|
21
|
+
...props
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Toggles its section and turns the chevron to show the state.
|
|
26
|
+
*/
|
|
27
|
+
var AccordionTrigger = ({ children, className, ...props }) => {
|
|
28
|
+
return /* @__PURE__ */ jsx(Accordion.Header, {
|
|
29
|
+
className: "flex",
|
|
30
|
+
children: /* @__PURE__ */ jsxs(Accordion.Trigger, {
|
|
31
|
+
className: cn("group/accordion flex flex-1 items-center justify-between gap-4 rounded-control py-4 text-left text-body font-medium transition-colors focus-ring", "hover:text-gem-ink", "disabled:pointer-events-none disabled:opacity-45", className),
|
|
32
|
+
"data-slot": "accordion-trigger",
|
|
33
|
+
...props,
|
|
34
|
+
children: [children, /* @__PURE__ */ jsx(ChevronDown, {
|
|
35
|
+
"aria-hidden": true,
|
|
36
|
+
className: "size-4 shrink-0 text-muted-foreground transition-transform duration-200 ease-out-expo group-data-[state=open]/accordion:rotate-180",
|
|
37
|
+
role: "presentation"
|
|
38
|
+
})]
|
|
39
|
+
})
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Reveals its section with a height animation.
|
|
44
|
+
*/
|
|
45
|
+
var AccordionContent = ({ children, className, ...props }) => {
|
|
46
|
+
return /* @__PURE__ */ jsx(Accordion.Content, {
|
|
47
|
+
className: "overflow-hidden text-body-sm text-muted-foreground data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",
|
|
48
|
+
"data-slot": "accordion-content",
|
|
49
|
+
...props,
|
|
50
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
51
|
+
className: cn("pb-4", className),
|
|
52
|
+
children
|
|
53
|
+
})
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
export { Accordion$1 as Accordion, AccordionContent, AccordionItem, AccordionTrigger };
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=accordion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accordion.js","names":["Accordion","AccordionPrimitive"],"sources":["../../../src/components/accordion/accordion.tsx"],"sourcesContent":["'use client';\n\nimport { ChevronDown } from 'lucide-react';\nimport { Accordion as AccordionPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../../lib/cn';\n\n/**\n * Stacks collapsible sections; `type=\"single\"` keeps one open, `type=\"multiple\"` lets several open.\n */\nexport const Accordion = ({ className, ...props }: ComponentProps<typeof AccordionPrimitive.Root>) => {\n return <AccordionPrimitive.Root className={cn('w-full', className)} data-slot=\"accordion\" {...props} />;\n};\n\nexport const AccordionItem = ({ className, ...props }: ComponentProps<typeof AccordionPrimitive.Item>) => {\n return (\n <AccordionPrimitive.Item\n className={cn('border-b last:border-b-0', className)}\n data-slot=\"accordion-item\"\n {...props}\n />\n );\n};\n\n/**\n * Toggles its section and turns the chevron to show the state.\n */\nexport const AccordionTrigger = ({ children, className, ...props }: ComponentProps<typeof AccordionPrimitive.Trigger>) => {\n return (\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n className={cn(\n // base\n 'group/accordion flex flex-1 items-center justify-between gap-4 rounded-control py-4 text-left text-body font-medium transition-colors focus-ring',\n // hover\n 'hover:text-gem-ink',\n // disabled\n 'disabled:pointer-events-none disabled:opacity-45',\n className,\n )}\n data-slot=\"accordion-trigger\"\n {...props}\n >\n {children}\n <ChevronDown\n aria-hidden\n className=\"size-4 shrink-0 text-muted-foreground transition-transform duration-200 ease-out-expo group-data-[state=open]/accordion:rotate-180\"\n role=\"presentation\"\n />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n};\n\n/**\n * Reveals its section with a height animation.\n */\nexport const AccordionContent = ({ children, className, ...props }: ComponentProps<typeof AccordionPrimitive.Content>) => {\n return (\n <AccordionPrimitive.Content\n className=\"overflow-hidden text-body-sm text-muted-foreground data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down\"\n data-slot=\"accordion-content\"\n {...props}\n >\n <div className={cn('pb-4', className)}>{children}</div>\n </AccordionPrimitive.Content>\n );\n};\n"],"mappings":";;;;;;;;;AAWA,IAAaA,eAAa,EAAE,WAAW,GAAG,YAA4D;CACpG,OAAO,oBAACC,UAAmB,MAApB;EAAyB,WAAW,GAAG,UAAU,SAAS;EAAG,aAAU;EAAY,GAAI;CAAQ,CAAA;AACxG;AAEA,IAAa,iBAAiB,EAAE,WAAW,GAAG,YAA4D;CACxG,OACE,oBAACA,UAAmB,MAApB;EACE,WAAW,GAAG,4BAA4B,SAAS;EACnD,aAAU;EACV,GAAI;CACL,CAAA;AAEL;;;;AAKA,IAAa,oBAAoB,EAAE,UAAU,WAAW,GAAG,YAA+D;CACxH,OACE,oBAACA,UAAmB,QAApB;EAA2B,WAAU;EACnC,UAAA,qBAACA,UAAmB,SAApB;GACE,WAAW,GAET,oJAEA,sBAEA,oDACA,SACF;GACA,aAAU;GACV,GAAI;GAXN,UAAA,CAaG,UACD,oBAAC,aAAD;IACE,eAAA;IACA,WAAU;IACV,MAAK;GACN,CAAA,CACyB;;CACH,CAAA;AAE/B;;;;AAKA,IAAa,oBAAoB,EAAE,UAAU,WAAW,GAAG,YAA+D;CACxH,OACE,oBAACA,UAAmB,SAApB;EACE,WAAU;EACV,aAAU;EACV,GAAI;EAEJ,UAAA,oBAAC,OAAD;GAAK,WAAW,GAAG,QAAQ,SAAS;GAAI;EAAc,CAAA;CAC5B,CAAA;AAEhC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
2
|
+
import { type ComponentProps, type ReactNode } from 'react';
|
|
3
|
+
export declare const alertVariants: (props?: ({
|
|
4
|
+
variant?: "gem" | "danger" | "warning" | "neutral" | "info" | "success" | null | undefined;
|
|
5
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
|
+
interface AlertProps extends ComponentProps<'div'>, VariantProps<typeof alertVariants> {
|
|
7
|
+
action?: ReactNode;
|
|
8
|
+
dismissible?: boolean;
|
|
9
|
+
icon?: ReactNode | false;
|
|
10
|
+
onDismiss?: () => void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A callout for status the reader should notice; danger and warning announce themselves as alerts, the rest as status.
|
|
14
|
+
*/
|
|
15
|
+
export declare const Alert: ({ action, children, className, dismissible, icon, onDismiss, variant, ...props }: AlertProps) => import("react").JSX.Element | null;
|
|
16
|
+
/**
|
|
17
|
+
* The alert's heading line.
|
|
18
|
+
*/
|
|
19
|
+
export declare const AlertTitle: ({ className, ...props }: ComponentProps<"p">) => import("react").JSX.Element;
|
|
20
|
+
/**
|
|
21
|
+
* The alert's explanatory copy, a step quieter than the title.
|
|
22
|
+
*/
|
|
23
|
+
export declare const AlertDescription: ({ className, ...props }: ComponentProps<"div">) => import("react").JSX.Element;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/cn.js";
|
|
3
|
+
import { Button } from "../button/button.js";
|
|
4
|
+
import { CircleAlert, CircleCheck, Info, Sparkles, TriangleAlert, X } from "lucide-react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { cva } from "class-variance-authority";
|
|
7
|
+
import { useState } from "react";
|
|
8
|
+
// src/components/alert/alert.tsx
|
|
9
|
+
var alertVariants = cva(["relative flex w-full items-start gap-3 rounded-card border p-4 text-body-sm", "[&>svg]:mt-0.5 [&>svg]:shrink-0 [&>svg:not([class*='size-'])]:size-[1.15em]"], {
|
|
10
|
+
variants: { variant: {
|
|
11
|
+
neutral: "border-border bg-muted text-foreground [&>svg]:text-muted-foreground",
|
|
12
|
+
gem: "border-gem/30 bg-gem-soft text-gem-ink",
|
|
13
|
+
info: "border-info/25 bg-info-soft text-info-ink",
|
|
14
|
+
success: "border-success/25 bg-success-soft text-success-ink",
|
|
15
|
+
warning: "border-warning/35 bg-warning-soft text-warning-ink",
|
|
16
|
+
danger: "border-danger/25 bg-danger-soft text-danger-ink"
|
|
17
|
+
} },
|
|
18
|
+
defaultVariants: { variant: "neutral" }
|
|
19
|
+
});
|
|
20
|
+
var ICON_BY_VARIANT = {
|
|
21
|
+
danger: CircleAlert,
|
|
22
|
+
gem: Sparkles,
|
|
23
|
+
info: Info,
|
|
24
|
+
neutral: Info,
|
|
25
|
+
success: CircleCheck,
|
|
26
|
+
warning: TriangleAlert
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* A callout for status the reader should notice; danger and warning announce themselves as alerts, the rest as status.
|
|
30
|
+
*/
|
|
31
|
+
var Alert = ({ action, children, className, dismissible = false, icon, onDismiss, variant = "neutral", ...props }) => {
|
|
32
|
+
const [isDismissed, setIsDismissed] = useState(false);
|
|
33
|
+
if (isDismissed) return null;
|
|
34
|
+
const resolvedVariant = variant ?? "neutral";
|
|
35
|
+
const DefaultIcon = ICON_BY_VARIANT[resolvedVariant];
|
|
36
|
+
const isUrgent = resolvedVariant === "danger" || resolvedVariant === "warning";
|
|
37
|
+
/**
|
|
38
|
+
* Hides the alert and tells the owner.
|
|
39
|
+
*/
|
|
40
|
+
const handleDismiss = () => {
|
|
41
|
+
setIsDismissed(true);
|
|
42
|
+
onDismiss?.();
|
|
43
|
+
};
|
|
44
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
45
|
+
className: cn(alertVariants({ variant }), className),
|
|
46
|
+
"data-slot": "alert",
|
|
47
|
+
role: isUrgent ? "alert" : "status",
|
|
48
|
+
...props,
|
|
49
|
+
children: [
|
|
50
|
+
icon === void 0 ? /* @__PURE__ */ jsx(DefaultIcon, {
|
|
51
|
+
"aria-hidden": true,
|
|
52
|
+
role: "presentation"
|
|
53
|
+
}) : icon,
|
|
54
|
+
/* @__PURE__ */ jsx("div", {
|
|
55
|
+
className: "flex min-w-0 flex-1 flex-col gap-1",
|
|
56
|
+
children
|
|
57
|
+
}),
|
|
58
|
+
action && /* @__PURE__ */ jsx("div", {
|
|
59
|
+
className: "flex shrink-0 items-center gap-2 self-center",
|
|
60
|
+
children: action
|
|
61
|
+
}),
|
|
62
|
+
dismissible && /* @__PURE__ */ jsxs(Button, {
|
|
63
|
+
className: "-mt-1 -mr-1 text-current",
|
|
64
|
+
size: "icon-sm",
|
|
65
|
+
title: "Dismiss",
|
|
66
|
+
variant: "ghost",
|
|
67
|
+
onClick: handleDismiss,
|
|
68
|
+
children: [/* @__PURE__ */ jsx(X, {}), /* @__PURE__ */ jsx("span", {
|
|
69
|
+
className: "sr-only",
|
|
70
|
+
children: "Dismiss"
|
|
71
|
+
})]
|
|
72
|
+
})
|
|
73
|
+
]
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* The alert's heading line.
|
|
78
|
+
*/
|
|
79
|
+
var AlertTitle = ({ className, ...props }) => {
|
|
80
|
+
return /* @__PURE__ */ jsx("p", {
|
|
81
|
+
className: cn("font-semibold", className),
|
|
82
|
+
"data-slot": "alert-title",
|
|
83
|
+
...props
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* The alert's explanatory copy, a step quieter than the title.
|
|
88
|
+
*/
|
|
89
|
+
var AlertDescription = ({ className, ...props }) => {
|
|
90
|
+
return /* @__PURE__ */ jsx("div", {
|
|
91
|
+
className: cn("text-pretty opacity-85 [&_p]:leading-relaxed", className),
|
|
92
|
+
"data-slot": "alert-description",
|
|
93
|
+
...props
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
export { Alert, AlertDescription, AlertTitle, alertVariants };
|
|
97
|
+
|
|
98
|
+
//# sourceMappingURL=alert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alert.js","names":[],"sources":["../../../src/components/alert/alert.tsx"],"sourcesContent":["'use client';\n\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { CircleAlert, CircleCheck, Info, Sparkles, TriangleAlert, X } from 'lucide-react';\nimport { type ComponentProps, type ReactNode, useState } from 'react';\n\nimport { cn } from '../../lib/cn';\nimport { Button } from '../button/button';\n\nexport const alertVariants = cva(\n [\n // base\n 'relative flex w-full items-start gap-3 rounded-card border p-4 text-body-sm',\n \"[&>svg]:mt-0.5 [&>svg]:shrink-0 [&>svg:not([class*='size-'])]:size-[1.15em]\",\n ],\n {\n variants: {\n variant: {\n neutral: 'border-border bg-muted text-foreground [&>svg]:text-muted-foreground',\n gem: 'border-gem/30 bg-gem-soft text-gem-ink',\n info: 'border-info/25 bg-info-soft text-info-ink',\n success: 'border-success/25 bg-success-soft text-success-ink',\n warning: 'border-warning/35 bg-warning-soft text-warning-ink',\n danger: 'border-danger/25 bg-danger-soft text-danger-ink',\n },\n },\n defaultVariants: {\n variant: 'neutral',\n },\n },\n);\n\ntype AlertVariant = NonNullable<VariantProps<typeof alertVariants>['variant']>;\n\nconst ICON_BY_VARIANT = {\n danger: CircleAlert,\n gem: Sparkles,\n info: Info,\n neutral: Info,\n success: CircleCheck,\n warning: TriangleAlert,\n} satisfies Record<AlertVariant, typeof Info>;\n\ninterface AlertProps extends ComponentProps<'div'>, VariantProps<typeof alertVariants> {\n action?: ReactNode;\n dismissible?: boolean;\n icon?: ReactNode | false;\n onDismiss?: () => void;\n}\n\n/**\n * A callout for status the reader should notice; danger and warning announce themselves as alerts, the rest as status.\n */\nexport const Alert = ({\n action,\n children,\n className,\n dismissible = false,\n icon,\n onDismiss,\n variant = 'neutral',\n ...props\n}: AlertProps) => {\n const [isDismissed, setIsDismissed] = useState(false);\n if (isDismissed) return null;\n\n const resolvedVariant = variant ?? 'neutral';\n const DefaultIcon = ICON_BY_VARIANT[resolvedVariant];\n const isUrgent = resolvedVariant === 'danger' || resolvedVariant === 'warning';\n\n /**\n * Hides the alert and tells the owner.\n */\n const handleDismiss = () => {\n setIsDismissed(true);\n onDismiss?.();\n };\n\n return (\n <div\n className={cn(alertVariants({ variant }), className)}\n data-slot=\"alert\"\n role={isUrgent ? 'alert' : 'status'}\n {...props}\n >\n {icon === undefined ? <DefaultIcon aria-hidden role=\"presentation\" /> : icon}\n <div className=\"flex min-w-0 flex-1 flex-col gap-1\">{children}</div>\n {action && <div className=\"flex shrink-0 items-center gap-2 self-center\">{action}</div>}\n {dismissible && (\n <Button\n className=\"-mt-1 -mr-1 text-current\"\n size=\"icon-sm\"\n title=\"Dismiss\"\n variant=\"ghost\"\n onClick={handleDismiss}\n >\n <X />\n <span className=\"sr-only\">Dismiss</span>\n </Button>\n )}\n </div>\n );\n};\n\n/**\n * The alert's heading line.\n */\nexport const AlertTitle = ({ className, ...props }: ComponentProps<'p'>) => {\n return <p className={cn('font-semibold', className)} data-slot=\"alert-title\" {...props} />;\n};\n\n/**\n * The alert's explanatory copy, a step quieter than the title.\n */\nexport const AlertDescription = ({ className, ...props }: ComponentProps<'div'>) => {\n return (\n <div className={cn('text-pretty opacity-85 [&_p]:leading-relaxed', className)} data-slot=\"alert-description\" {...props} />\n );\n};\n"],"mappings":";;;;;;;;AASA,IAAa,gBAAgB,IAC3B,CAEE,+EACA,6EACF,GACA;CACE,UAAU,EACR,SAAS;EACP,SAAS;EACT,KAAK;EACL,MAAM;EACN,SAAS;EACT,SAAS;EACT,QAAQ;CACV,EACF;CACA,iBAAiB,EACf,SAAS,UACX;AACF,CACF;AAIA,IAAM,kBAAkB;CACtB,QAAQ;CACR,KAAK;CACL,MAAM;CACN,SAAS;CACT,SAAS;CACT,SAAS;AACX;;;;AAYA,IAAa,SAAS,EACpB,QACA,UACA,WACA,cAAc,OACd,MACA,WACA,UAAU,WACV,GAAG,YACa;CAChB,MAAM,CAAC,aAAa,kBAAkB,SAAS,KAAK;CACpD,IAAI,aAAa,OAAO;CAExB,MAAM,kBAAkB,WAAW;CACnC,MAAM,cAAc,gBAAgB;CACpC,MAAM,WAAW,oBAAoB,YAAY,oBAAoB;;;;CAKrE,MAAM,sBAAsB;EAC1B,eAAe,IAAI;EACnB,YAAY;CACd;CAEA,OACE,qBAAC,OAAD;EACE,WAAW,GAAG,cAAc,EAAE,QAAQ,CAAC,GAAG,SAAS;EACnD,aAAU;EACV,MAAM,WAAW,UAAU;EAC3B,GAAI;EAJN,UAAA;GAMG,SAAS,KAAA,IAAY,oBAAC,aAAD;IAAa,eAAA;IAAY,MAAK;GAAgB,CAAA,IAAI;GACxE,oBAAC,OAAD;IAAK,WAAU;IAAsC;GAAc,CAAA;GAClE,UAAU,oBAAC,OAAD;IAAK,WAAU;IAAgD,UAAA;GAAY,CAAA;GACrF,eACC,qBAAC,QAAD;IACE,WAAU;IACV,MAAK;IACL,OAAM;IACN,SAAQ;IACR,SAAS;IALX,UAAA,CAOE,oBAAC,GAAD,CAAI,CAAA,GACJ,oBAAC,QAAD;KAAM,WAAU;KAAU,UAAA;IAAa,CAAA,CACjC;;EAEP;;AAET;;;;AAKA,IAAa,cAAc,EAAE,WAAW,GAAG,YAAiC;CAC1E,OAAO,oBAAC,KAAD;EAAG,WAAW,GAAG,iBAAiB,SAAS;EAAG,aAAU;EAAc,GAAI;CAAQ,CAAA;AAC3F;;;;AAKA,IAAa,oBAAoB,EAAE,WAAW,GAAG,YAAmC;CAClF,OACE,oBAAC,OAAD;EAAK,WAAW,GAAG,gDAAgD,SAAS;EAAG,aAAU;EAAoB,GAAI;CAAQ,CAAA;AAE7H"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { AlertDialog as AlertDialogPrimitive } from 'radix-ui';
|
|
2
|
+
import type { ComponentProps } from 'react';
|
|
3
|
+
import { Button } from '../button/button';
|
|
4
|
+
/**
|
|
5
|
+
* Holds the open state of a confirmation that must be answered before the user continues.
|
|
6
|
+
*/
|
|
7
|
+
export declare const AlertDialog: (props: ComponentProps<typeof AlertDialogPrimitive.Root>) => import("react").JSX.Element;
|
|
8
|
+
export declare const AlertDialogTrigger: (props: ComponentProps<typeof AlertDialogPrimitive.Trigger>) => import("react").JSX.Element;
|
|
9
|
+
/**
|
|
10
|
+
* Portals the confirmation panel above a blurred scrim; it cannot be dismissed by clicking outside.
|
|
11
|
+
*/
|
|
12
|
+
export declare const AlertDialogContent: ({ className, ...props }: ComponentProps<typeof AlertDialogPrimitive.Content>) => import("react").JSX.Element;
|
|
13
|
+
/**
|
|
14
|
+
* Lays an optional icon beside the title and description.
|
|
15
|
+
*/
|
|
16
|
+
export declare const AlertDialogHeader: ({ className, ...props }: ComponentProps<"div">) => import("react").JSX.Element;
|
|
17
|
+
interface AlertDialogIconProps extends ComponentProps<'div'> {
|
|
18
|
+
tone?: 'danger' | 'gem' | 'warning';
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Frames an icon in a tinted tile that spans the title and description rows.
|
|
22
|
+
*/
|
|
23
|
+
export declare const AlertDialogIcon: ({ className, tone, ...props }: AlertDialogIconProps) => import("react").JSX.Element;
|
|
24
|
+
export declare const AlertDialogFooter: ({ className, ...props }: ComponentProps<"div">) => import("react").JSX.Element;
|
|
25
|
+
export declare const AlertDialogTitle: ({ className, ...props }: ComponentProps<typeof AlertDialogPrimitive.Title>) => import("react").JSX.Element;
|
|
26
|
+
export declare const AlertDialogDescription: ({ className, ...props }: ComponentProps<typeof AlertDialogPrimitive.Description>) => import("react").JSX.Element;
|
|
27
|
+
type AlertDialogButtonProps = ComponentProps<typeof Button>;
|
|
28
|
+
/**
|
|
29
|
+
* Confirms the action; defaults to the danger button.
|
|
30
|
+
*/
|
|
31
|
+
export declare const AlertDialogAction: ({ variant, ...props }: AlertDialogButtonProps) => import("react").JSX.Element;
|
|
32
|
+
/**
|
|
33
|
+
* Dismisses the confirmation; receives focus first so a stray Enter never confirms.
|
|
34
|
+
*/
|
|
35
|
+
export declare const AlertDialogCancel: ({ variant, ...props }: AlertDialogButtonProps) => import("react").JSX.Element;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../../lib/cn.js";
|
|
3
|
+
import { Button } from "../button/button.js";
|
|
4
|
+
import { DIALOG_OVERLAY_CLASS_NAME } from "../dialog/dialog.js";
|
|
5
|
+
import { AlertDialog } from "radix-ui";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
// src/components/alert-dialog/alert-dialog.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Holds the open state of a confirmation that must be answered before the user continues.
|
|
10
|
+
*/
|
|
11
|
+
var AlertDialog$1 = (props) => {
|
|
12
|
+
return /* @__PURE__ */ jsx(AlertDialog.Root, {
|
|
13
|
+
"data-slot": "alert-dialog",
|
|
14
|
+
...props
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
var AlertDialogTrigger = (props) => {
|
|
18
|
+
return /* @__PURE__ */ jsx(AlertDialog.Trigger, {
|
|
19
|
+
"data-slot": "alert-dialog-trigger",
|
|
20
|
+
...props
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Portals the confirmation panel above a blurred scrim; it cannot be dismissed by clicking outside.
|
|
25
|
+
*/
|
|
26
|
+
var AlertDialogContent = ({ className, ...props }) => {
|
|
27
|
+
return /* @__PURE__ */ jsxs(AlertDialog.Portal, { children: [/* @__PURE__ */ jsx(AlertDialog.Overlay, {
|
|
28
|
+
className: DIALOG_OVERLAY_CLASS_NAME,
|
|
29
|
+
"data-slot": "alert-dialog-overlay"
|
|
30
|
+
}), /* @__PURE__ */ jsx(AlertDialog.Content, {
|
|
31
|
+
className: cn("fixed top-1/2 left-1/2 z-50 flex w-[calc(100vw-2rem)] max-w-md -translate-x-1/2 -translate-y-1/2 flex-col gap-6 rounded-panel border bg-popover p-6 text-popover-foreground shadow-float outline-none", "duration-200 ease-out-expo data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", className),
|
|
32
|
+
"data-slot": "alert-dialog-content",
|
|
33
|
+
...props
|
|
34
|
+
})] });
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Lays an optional icon beside the title and description.
|
|
38
|
+
*/
|
|
39
|
+
var AlertDialogHeader = ({ className, ...props }) => {
|
|
40
|
+
return /* @__PURE__ */ jsx("div", {
|
|
41
|
+
className: cn("grid gap-1.5 has-data-[slot=alert-dialog-icon]:grid-cols-[auto_1fr] has-data-[slot=alert-dialog-icon]:gap-x-4", className),
|
|
42
|
+
"data-slot": "alert-dialog-header",
|
|
43
|
+
...props
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
var ICON_TONE_CLASS_NAME_BY_TONE = {
|
|
47
|
+
danger: "bg-danger-soft text-danger-ink",
|
|
48
|
+
gem: "bg-gem-soft text-gem-ink",
|
|
49
|
+
warning: "bg-warning-soft text-warning-ink"
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Frames an icon in a tinted tile that spans the title and description rows.
|
|
53
|
+
*/
|
|
54
|
+
var AlertDialogIcon = ({ className, tone = "danger", ...props }) => {
|
|
55
|
+
return /* @__PURE__ */ jsx("div", {
|
|
56
|
+
"aria-hidden": true,
|
|
57
|
+
className: cn("row-span-2 flex size-10 items-center justify-center rounded-control [&_svg]:size-5", ICON_TONE_CLASS_NAME_BY_TONE[tone], className),
|
|
58
|
+
"data-slot": "alert-dialog-icon",
|
|
59
|
+
role: "presentation",
|
|
60
|
+
...props
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
var AlertDialogFooter = ({ className, ...props }) => {
|
|
64
|
+
return /* @__PURE__ */ jsx("div", {
|
|
65
|
+
className: cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className),
|
|
66
|
+
"data-slot": "alert-dialog-footer",
|
|
67
|
+
...props
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
var AlertDialogTitle = ({ className, ...props }) => {
|
|
71
|
+
return /* @__PURE__ */ jsx(AlertDialog.Title, {
|
|
72
|
+
className: cn("text-headline-sm text-foreground", className),
|
|
73
|
+
"data-slot": "alert-dialog-title",
|
|
74
|
+
...props
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
var AlertDialogDescription = ({ className, ...props }) => {
|
|
78
|
+
return /* @__PURE__ */ jsx(AlertDialog.Description, {
|
|
79
|
+
className: cn("text-body-sm text-muted-foreground", className),
|
|
80
|
+
"data-slot": "alert-dialog-description",
|
|
81
|
+
...props
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Confirms the action; defaults to the danger button.
|
|
86
|
+
*/
|
|
87
|
+
var AlertDialogAction = ({ variant = "danger", ...props }) => {
|
|
88
|
+
return /* @__PURE__ */ jsx(AlertDialog.Action, {
|
|
89
|
+
asChild: true,
|
|
90
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
91
|
+
"data-slot": "alert-dialog-action",
|
|
92
|
+
variant,
|
|
93
|
+
...props
|
|
94
|
+
})
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Dismisses the confirmation; receives focus first so a stray Enter never confirms.
|
|
99
|
+
*/
|
|
100
|
+
var AlertDialogCancel = ({ variant = "outline", ...props }) => {
|
|
101
|
+
return /* @__PURE__ */ jsx(AlertDialog.Cancel, {
|
|
102
|
+
asChild: true,
|
|
103
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
104
|
+
"data-slot": "alert-dialog-cancel",
|
|
105
|
+
variant,
|
|
106
|
+
...props
|
|
107
|
+
})
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
export { AlertDialog$1 as AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogIcon, AlertDialogTitle, AlertDialogTrigger };
|
|
111
|
+
|
|
112
|
+
//# sourceMappingURL=alert-dialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alert-dialog.js","names":["AlertDialog","AlertDialogPrimitive"],"sources":["../../../src/components/alert-dialog/alert-dialog.tsx"],"sourcesContent":["'use client';\n\nimport { AlertDialog as AlertDialogPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../../lib/cn';\nimport { Button } from '../button/button';\nimport { DIALOG_OVERLAY_CLASS_NAME } from '../dialog/dialog';\n\n/**\n * Holds the open state of a confirmation that must be answered before the user continues.\n */\nexport const AlertDialog = (props: ComponentProps<typeof AlertDialogPrimitive.Root>) => {\n return <AlertDialogPrimitive.Root data-slot=\"alert-dialog\" {...props} />;\n};\n\nexport const AlertDialogTrigger = (props: ComponentProps<typeof AlertDialogPrimitive.Trigger>) => {\n return <AlertDialogPrimitive.Trigger data-slot=\"alert-dialog-trigger\" {...props} />;\n};\n\n/**\n * Portals the confirmation panel above a blurred scrim; it cannot be dismissed by clicking outside.\n */\nexport const AlertDialogContent = ({ className, ...props }: ComponentProps<typeof AlertDialogPrimitive.Content>) => {\n return (\n <AlertDialogPrimitive.Portal>\n <AlertDialogPrimitive.Overlay className={DIALOG_OVERLAY_CLASS_NAME} data-slot=\"alert-dialog-overlay\" />\n <AlertDialogPrimitive.Content\n className={cn(\n // base\n 'fixed top-1/2 left-1/2 z-50 flex w-[calc(100vw-2rem)] max-w-md -translate-x-1/2 -translate-y-1/2 flex-col gap-6 rounded-panel border bg-popover p-6 text-popover-foreground shadow-float outline-none',\n // animation\n 'duration-200 ease-out-expo data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',\n className,\n )}\n data-slot=\"alert-dialog-content\"\n {...props}\n />\n </AlertDialogPrimitive.Portal>\n );\n};\n\n/**\n * Lays an optional icon beside the title and description.\n */\nexport const AlertDialogHeader = ({ className, ...props }: ComponentProps<'div'>) => {\n return (\n <div\n className={cn(\n 'grid gap-1.5 has-data-[slot=alert-dialog-icon]:grid-cols-[auto_1fr] has-data-[slot=alert-dialog-icon]:gap-x-4',\n className,\n )}\n data-slot=\"alert-dialog-header\"\n {...props}\n />\n );\n};\n\ninterface AlertDialogIconProps extends ComponentProps<'div'> {\n tone?: 'danger' | 'gem' | 'warning';\n}\n\nconst ICON_TONE_CLASS_NAME_BY_TONE = {\n danger: 'bg-danger-soft text-danger-ink',\n gem: 'bg-gem-soft text-gem-ink',\n warning: 'bg-warning-soft text-warning-ink',\n} satisfies Record<NonNullable<AlertDialogIconProps['tone']>, string>;\n\n/**\n * Frames an icon in a tinted tile that spans the title and description rows.\n */\nexport const AlertDialogIcon = ({ className, tone = 'danger', ...props }: AlertDialogIconProps) => {\n return (\n <div\n aria-hidden\n className={cn(\n 'row-span-2 flex size-10 items-center justify-center rounded-control [&_svg]:size-5',\n ICON_TONE_CLASS_NAME_BY_TONE[tone],\n className,\n )}\n data-slot=\"alert-dialog-icon\"\n role=\"presentation\"\n {...props}\n />\n );\n};\n\nexport const AlertDialogFooter = ({ className, ...props }: ComponentProps<'div'>) => {\n return (\n <div\n className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}\n data-slot=\"alert-dialog-footer\"\n {...props}\n />\n );\n};\n\nexport const AlertDialogTitle = ({ className, ...props }: ComponentProps<typeof AlertDialogPrimitive.Title>) => {\n return (\n <AlertDialogPrimitive.Title\n className={cn('text-headline-sm text-foreground', className)}\n data-slot=\"alert-dialog-title\"\n {...props}\n />\n );\n};\n\nexport const AlertDialogDescription = ({\n className,\n ...props\n}: ComponentProps<typeof AlertDialogPrimitive.Description>) => {\n return (\n <AlertDialogPrimitive.Description\n className={cn('text-body-sm text-muted-foreground', className)}\n data-slot=\"alert-dialog-description\"\n {...props}\n />\n );\n};\n\ntype AlertDialogButtonProps = ComponentProps<typeof Button>;\n\n/**\n * Confirms the action; defaults to the danger button.\n */\nexport const AlertDialogAction = ({ variant = 'danger', ...props }: AlertDialogButtonProps) => {\n return (\n <AlertDialogPrimitive.Action asChild>\n <Button data-slot=\"alert-dialog-action\" variant={variant} {...props} />\n </AlertDialogPrimitive.Action>\n );\n};\n\n/**\n * Dismisses the confirmation; receives focus first so a stray Enter never confirms.\n */\nexport const AlertDialogCancel = ({ variant = 'outline', ...props }: AlertDialogButtonProps) => {\n return (\n <AlertDialogPrimitive.Cancel asChild>\n <Button data-slot=\"alert-dialog-cancel\" variant={variant} {...props} />\n </AlertDialogPrimitive.Cancel>\n );\n};\n"],"mappings":";;;;;;;;;;AAYA,IAAaA,iBAAe,UAA4D;CACtF,OAAO,oBAACC,YAAqB,MAAtB;EAA2B,aAAU;EAAe,GAAI;CAAQ,CAAA;AACzE;AAEA,IAAa,sBAAsB,UAA+D;CAChG,OAAO,oBAACA,YAAqB,SAAtB;EAA8B,aAAU;EAAuB,GAAI;CAAQ,CAAA;AACpF;;;;AAKA,IAAa,sBAAsB,EAAE,WAAW,GAAG,YAAiE;CAClH,OACE,qBAACA,YAAqB,QAAtB,EAAA,UAAA,CACE,oBAACA,YAAqB,SAAtB;EAA8B,WAAW;EAA2B,aAAU;CAAwB,CAAA,GACtG,oBAACA,YAAqB,SAAtB;EACE,WAAW,GAET,yMAEA,mNACA,SACF;EACA,aAAU;EACV,GAAI;CACL,CAAA,CAC0B,EAAA,CAAA;AAEjC;;;;AAKA,IAAa,qBAAqB,EAAE,WAAW,GAAG,YAAmC;CACnF,OACE,oBAAC,OAAD;EACE,WAAW,GACT,iHACA,SACF;EACA,aAAU;EACV,GAAI;CACL,CAAA;AAEL;AAMA,IAAM,+BAA+B;CACnC,QAAQ;CACR,KAAK;CACL,SAAS;AACX;;;;AAKA,IAAa,mBAAmB,EAAE,WAAW,OAAO,UAAU,GAAG,YAAkC;CACjG,OACE,oBAAC,OAAD;EACE,eAAA;EACA,WAAW,GACT,sFACA,6BAA6B,OAC7B,SACF;EACA,aAAU;EACV,MAAK;EACL,GAAI;CACL,CAAA;AAEL;AAEA,IAAa,qBAAqB,EAAE,WAAW,GAAG,YAAmC;CACnF,OACE,oBAAC,OAAD;EACE,WAAW,GAAG,0DAA0D,SAAS;EACjF,aAAU;EACV,GAAI;CACL,CAAA;AAEL;AAEA,IAAa,oBAAoB,EAAE,WAAW,GAAG,YAA+D;CAC9G,OACE,oBAACA,YAAqB,OAAtB;EACE,WAAW,GAAG,oCAAoC,SAAS;EAC3D,aAAU;EACV,GAAI;CACL,CAAA;AAEL;AAEA,IAAa,0BAA0B,EACrC,WACA,GAAG,YAC0D;CAC7D,OACE,oBAACA,YAAqB,aAAtB;EACE,WAAW,GAAG,sCAAsC,SAAS;EAC7D,aAAU;EACV,GAAI;CACL,CAAA;AAEL;;;;AAOA,IAAa,qBAAqB,EAAE,UAAU,UAAU,GAAG,YAAoC;CAC7F,OACE,oBAACA,YAAqB,QAAtB;EAA6B,SAAA;EAC3B,UAAA,oBAAC,QAAD;GAAQ,aAAU;GAA+B;GAAS,GAAI;EAAQ,CAAA;CAC3C,CAAA;AAEjC;;;;AAKA,IAAa,qBAAqB,EAAE,UAAU,WAAW,GAAG,YAAoC;CAC9F,OACE,oBAACA,YAAqB,QAAtB;EAA6B,SAAA;EAC3B,UAAA,oBAAC,QAAD;GAAQ,aAAU;GAA+B;GAAS,GAAI;EAAQ,CAAA;CAC3C,CAAA;AAEjC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { type ComponentProps, type ReactNode } from 'react';
|
|
2
|
+
interface AppShellContextValue {
|
|
3
|
+
collapsed: boolean;
|
|
4
|
+
/** Whether the shell shows its phone layout: the sidebar as a drawer, below `md`. `true` on the server. */
|
|
5
|
+
isMobile: boolean;
|
|
6
|
+
mobileOpen: boolean;
|
|
7
|
+
setCollapsed: (collapsed: boolean) => void;
|
|
8
|
+
setMobileOpen: (mobileOpen: boolean) => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Returns the shell's sidebar state and whether it shows the phone layout; throws outside an `AppShell`.
|
|
12
|
+
*/
|
|
13
|
+
export declare const useAppShell: () => AppShellContextValue;
|
|
14
|
+
interface AppShellProps extends ComponentProps<'div'> {
|
|
15
|
+
collapsed?: boolean;
|
|
16
|
+
defaultCollapsed?: boolean;
|
|
17
|
+
onCollapsedChange?: (collapsed: boolean) => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Lays out an internal tool as sidebar plus content, and owns whether the sidebar is collapsed to a rail or open as a mobile drawer.
|
|
21
|
+
*/
|
|
22
|
+
export declare const AppShell: ({ className, collapsed: controlledCollapsed, defaultCollapsed, onCollapsedChange, ...props }: AppShellProps) => import("react").JSX.Element;
|
|
23
|
+
interface AppShellSidebarProps extends ComponentProps<'aside'> {
|
|
24
|
+
label?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Renders the navigation column: a sticky panel that collapses to an icon rail from `md` up, and an off-canvas drawer below it.
|
|
28
|
+
*/
|
|
29
|
+
export declare const AppShellSidebar: ({ children, className, label, ...props }: AppShellSidebarProps) => import("react").JSX.Element;
|
|
30
|
+
/**
|
|
31
|
+
* Holds the brand row at the top of the sidebar; hides everything but the first child when collapsed.
|
|
32
|
+
*/
|
|
33
|
+
export declare const SidebarHeader: ({ className, ...props }: ComponentProps<"div">) => import("react").JSX.Element;
|
|
34
|
+
/**
|
|
35
|
+
* Scrolls the sidebar's sections when they outgrow the viewport.
|
|
36
|
+
*/
|
|
37
|
+
export declare const SidebarContent: ({ className, ...props }: ComponentProps<"div">) => import("react").JSX.Element;
|
|
38
|
+
interface SidebarSectionProps extends Omit<ComponentProps<'div'>, 'title'> {
|
|
39
|
+
title?: ReactNode;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Groups related items under a mono caption, which turns into a hairline when the sidebar is a rail.
|
|
43
|
+
*/
|
|
44
|
+
export declare const SidebarSection: ({ children, className, title, ...props }: SidebarSectionProps) => import("react").JSX.Element;
|
|
45
|
+
interface SidebarItemProps extends ComponentProps<'button'> {
|
|
46
|
+
active?: boolean;
|
|
47
|
+
asChild?: boolean;
|
|
48
|
+
badge?: ReactNode;
|
|
49
|
+
icon?: ReactNode;
|
|
50
|
+
label: string;
|
|
51
|
+
number?: number | string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Renders one navigation entry with icon, optional website-style number and badge; pass a router link as the child with `asChild`.
|
|
55
|
+
*/
|
|
56
|
+
export declare const SidebarItem: ({ active, asChild, badge, children, className, icon, label, number, onClick, ...props }: SidebarItemProps) => import("react").JSX.Element;
|
|
57
|
+
/**
|
|
58
|
+
* Pins account and settings controls to the bottom of the sidebar.
|
|
59
|
+
*/
|
|
60
|
+
export declare const SidebarFooter: ({ className, ...props }: ComponentProps<"div">) => import("react").JSX.Element;
|
|
61
|
+
/**
|
|
62
|
+
* Toggles the sidebar: collapses it to a rail from `md` up and opens the drawer below it.
|
|
63
|
+
*/
|
|
64
|
+
export declare const AppShellSidebarTrigger: ({ className, onClick, ...props }: ComponentProps<"button">) => import("react").JSX.Element;
|
|
65
|
+
/**
|
|
66
|
+
* Stacks the header and page content to the right of the sidebar.
|
|
67
|
+
*/
|
|
68
|
+
export declare const AppShellMain: ({ className, ...props }: ComponentProps<"div">) => import("react").JSX.Element;
|
|
69
|
+
/**
|
|
70
|
+
* Renders the sticky, frosted top bar of the content column, like the refine.studio header.
|
|
71
|
+
*/
|
|
72
|
+
export declare const AppShellHeader: ({ className, ...props }: ComponentProps<"header">) => import("react").JSX.Element;
|
|
73
|
+
/**
|
|
74
|
+
* Holds the page itself, padded and capped for readable line lengths on very wide screens.
|
|
75
|
+
*/
|
|
76
|
+
export declare const AppShellContent: ({ className, ...props }: ComponentProps<"main">) => import("react").JSX.Element;
|
|
77
|
+
export {};
|