@nphuonha/ui-kit 0.0.0-stage → 0.2.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/CONVENTIONS.md +38 -0
- package/LICENSE +21 -0
- package/README.md +136 -2
- package/dist/components/ui/_shared/icon-provider.d.ts +18 -0
- package/dist/components/ui/_shared/icon-provider.js +26 -0
- package/dist/components/ui/alert/alert-variants.d.ts +5 -0
- package/dist/components/ui/alert/alert-variants.js +13 -0
- package/dist/components/ui/alert/alert.d.ts +9 -0
- package/dist/components/ui/alert/alert.js +13 -0
- package/dist/components/ui/alert/index.d.ts +2 -0
- package/dist/components/ui/alert/index.js +2 -0
- package/dist/components/ui/badge/badge-variants.d.ts +5 -0
- package/dist/components/ui/badge/badge-variants.js +16 -0
- package/dist/components/ui/badge/badge.d.ts +6 -0
- package/dist/components/ui/badge/badge.js +6 -0
- package/dist/components/ui/badge/index.d.ts +2 -0
- package/dist/components/ui/badge/index.js +2 -0
- package/dist/components/ui/button/button-variants.d.ts +7 -0
- package/dist/components/ui/button/button-variants.js +29 -0
- package/dist/components/ui/button/button.d.ts +10 -0
- package/dist/components/ui/button/button.js +12 -0
- package/dist/components/ui/button/index.d.ts +2 -0
- package/dist/components/ui/button/index.js +2 -0
- package/dist/components/ui/card/card.d.ts +7 -0
- package/dist/components/ui/card/card.js +20 -0
- package/dist/components/ui/card/index.d.ts +1 -0
- package/dist/components/ui/card/index.js +1 -0
- package/dist/components/ui/checkbox/checkbox.d.ts +8 -0
- package/dist/components/ui/checkbox/checkbox.js +18 -0
- package/dist/components/ui/checkbox/index.d.ts +1 -0
- package/dist/components/ui/checkbox/index.js +1 -0
- package/dist/components/ui/dialog/dialog.d.ts +15 -0
- package/dist/components/ui/dialog/dialog.js +10 -0
- package/dist/components/ui/dialog/index.d.ts +1 -0
- package/dist/components/ui/dialog/index.js +1 -0
- package/dist/components/ui/field/field.d.ts +11 -0
- package/dist/components/ui/field/field.js +22 -0
- package/dist/components/ui/field/index.d.ts +1 -0
- package/dist/components/ui/field/index.js +1 -0
- package/dist/components/ui/icon-button/icon-button.d.ts +7 -0
- package/dist/components/ui/icon-button/icon-button.js +7 -0
- package/dist/components/ui/icon-button/index.d.ts +1 -0
- package/dist/components/ui/icon-button/index.js +1 -0
- package/dist/components/ui/input/index.d.ts +1 -0
- package/dist/components/ui/input/index.js +1 -0
- package/dist/components/ui/input/input.d.ts +5 -0
- package/dist/components/ui/input/input.js +6 -0
- package/dist/components/ui/label/index.d.ts +1 -0
- package/dist/components/ui/label/index.js +1 -0
- package/dist/components/ui/label/label.d.ts +5 -0
- package/dist/components/ui/label/label.js +6 -0
- package/dist/components/ui/popover/index.d.ts +1 -0
- package/dist/components/ui/popover/index.js +1 -0
- package/dist/components/ui/popover/popover.d.ts +14 -0
- package/dist/components/ui/popover/popover.js +7 -0
- package/dist/components/ui/radio-group/index.d.ts +1 -0
- package/dist/components/ui/radio-group/index.js +1 -0
- package/dist/components/ui/radio-group/radio-group.d.ts +17 -0
- package/dist/components/ui/radio-group/radio-group.js +17 -0
- package/dist/components/ui/select/index.d.ts +1 -0
- package/dist/components/ui/select/index.js +1 -0
- package/dist/components/ui/select/select.d.ts +21 -0
- package/dist/components/ui/select/select.js +10 -0
- package/dist/components/ui/separator/index.d.ts +1 -0
- package/dist/components/ui/separator/index.js +1 -0
- package/dist/components/ui/separator/separator.d.ts +6 -0
- package/dist/components/ui/separator/separator.js +5 -0
- package/dist/components/ui/sheet/index.d.ts +1 -0
- package/dist/components/ui/sheet/index.js +1 -0
- package/dist/components/ui/sheet/sheet.d.ts +15 -0
- package/dist/components/ui/sheet/sheet.js +15 -0
- package/dist/components/ui/spinner/index.d.ts +1 -0
- package/dist/components/ui/spinner/index.js +1 -0
- package/dist/components/ui/spinner/spinner.d.ts +5 -0
- package/dist/components/ui/spinner/spinner.js +8 -0
- package/dist/components/ui/switch/index.d.ts +1 -0
- package/dist/components/ui/switch/index.js +1 -0
- package/dist/components/ui/switch/switch.d.ts +7 -0
- package/dist/components/ui/switch/switch.js +15 -0
- package/dist/components/ui/tabs/index.d.ts +1 -0
- package/dist/components/ui/tabs/index.js +1 -0
- package/dist/components/ui/tabs/tabs.d.ts +14 -0
- package/dist/components/ui/tabs/tabs.js +7 -0
- package/dist/components/ui/textarea/index.d.ts +1 -0
- package/dist/components/ui/textarea/index.js +1 -0
- package/dist/components/ui/textarea/textarea.d.ts +5 -0
- package/dist/components/ui/textarea/textarea.js +6 -0
- package/dist/components/ui/toast/index.d.ts +1 -0
- package/dist/components/ui/toast/index.js +1 -0
- package/dist/components/ui/toast/toast.d.ts +19 -0
- package/dist/components/ui/toast/toast.js +20 -0
- package/dist/components/ui/tooltip/index.d.ts +1 -0
- package/dist/components/ui/tooltip/index.js +1 -0
- package/dist/components/ui/tooltip/tooltip.d.ts +12 -0
- package/dist/components/ui/tooltip/tooltip.js +9 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +29 -0
- package/dist/lib/color.d.ts +16 -0
- package/dist/lib/color.js +118 -0
- package/dist/lib/utils.d.ts +7 -0
- package/dist/lib/utils.js +5 -0
- package/dist/styles/base.css +212 -0
- package/dist/styles/theme.css +121 -0
- package/dist/styles.css +5 -0
- package/package.json +184 -4
package/CONVENTIONS.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# UI Kit Conventions (Solid / Clean / Flat / Modern)
|
|
2
|
+
|
|
3
|
+
Single-suite, not-shadcn component kit: **Base UI** for behavior/a11y + owned tokens, styles, and a consistent **prop-driven** API. Visual direction: solid surfaces, clean hierarchy, flat-first depth, modern rounded shapes, vibrant-but-customizable accent (inspired by M3 Expressive, not M3 Expressive).
|
|
4
|
+
|
|
5
|
+
## Foundations
|
|
6
|
+
- **Semantic tokens only** in components (no app-specific variables, no hardcoded brand paints). Core contract lives in `src/styles/theme.css` and is mapped in `src/styles/base.css`.
|
|
7
|
+
- **Accent is customizable** via CSS vars (`--primary`, `--primary-foreground`, `--primary-hover/active`, `--primary-soft*`, `--ring`). Use `generateAccentVars`/`accentStyle` from `@nphuonha/ui-kit` to derive a palette from one color (light/dark).
|
|
8
|
+
- **Scope**: wrap with `data-ui="kit"` (put on `<html>`/portal root so overlay portals inherit tokens). Dark mode via `.dark`.
|
|
9
|
+
|
|
10
|
+
## Visual
|
|
11
|
+
- **Flat-first, softly curved**: separate surfaces with tonal solid fills; use a **top-lit rim + micro vertical gradient** for convexity instead of full outlines.
|
|
12
|
+
- `surface-curved` — cards, dialogs, popovers, primary/danger buttons.
|
|
13
|
+
- `surface-curved-soft` — secondary buttons, tabs, alerts, badges, switch tracks.
|
|
14
|
+
- `surface-curved-pill` — switch thumbs and pill controls.
|
|
15
|
+
- `surface-inset` — native fields (input/textarea/select), where `::before` is unavailable.
|
|
16
|
+
- Lighting tokens: `--light-top`, `--light-sheen`, `--light-bottom`, `--light-rim` (defined per light/dark theme).
|
|
17
|
+
- **Shadows only lift, never outline**: keep subtle outer shadows for overlays (`--shadow-overlay`) and raised cards/buttons (`--shadow-soft`/`--shadow-raised`); the curved utilities only add inset edge light.
|
|
18
|
+
- **Shape** via tokens: `--radius-control` (~12px), `--radius-card` (~20px), `--radius-overlay`, `--radius-field`; pill (`rounded-pill`) for actions and switch thumbs.
|
|
19
|
+
- **Typography**: tokenized (`--font-body`), clear hierarchy.
|
|
20
|
+
- **Motion**: restrained 150–220ms, `--ease-out-ui`, CSS transitions for feedback/enter-exit; **no bouncy springs** by default. Honor `prefers-reduced-motion` (global guard in `base.css`).
|
|
21
|
+
|
|
22
|
+
## Component API
|
|
23
|
+
- **Prop-driven & consistent**: prefer clear props over compound anatomy for core controls.
|
|
24
|
+
- **Controls**: comfortable `h-10` default; shared focus/disabled/error states.
|
|
25
|
+
- **Forms**: `label`, `description`, `error` (with `aria-invalid`/`aria-describedby`/`role="alert"` where relevant), `required` mark.
|
|
26
|
+
- **Icons**: default internal affordances use **Phosphor**. `startIcon`/`endIcon`, `Alert.icon` and `IconButton` children accept any icon component (`IconComponent { size?, className? }`), so user-facing icons are pack-agnostic. The internal set (`check`, `minus`, `chevron`, `close`, `spinner`) is replaceable via `IconProvider`; `Toaster` exposes its own `icons` prop.
|
|
27
|
+
- **Loading**: preserve layout (spinner + label), set `disabled`/`aria-busy`.
|
|
28
|
+
|
|
29
|
+
## Structure & exports
|
|
30
|
+
- One folder per component: `src/components/ui/<name>/<name>.tsx`, `<name>-variants.ts`, `<name>.test.tsx`, `index.ts`.
|
|
31
|
+
- Extract `cva` into `<name>-variants.ts` **without** `"use client"`, so variants can be used in server components.
|
|
32
|
+
- The folder `index.ts` exports the component and its variants explicitly. The main `src/index.ts` barrel re-exports folders, and `package.json` exposes subpaths (`@nphuonha/ui-kit/<name>`) for smaller client bundles.
|
|
33
|
+
- Keep tests colocated with the component. Prefer a11y smoke tests plus token/scale regressions for components with meaningful state.
|
|
34
|
+
|
|
35
|
+
## Stack notes
|
|
36
|
+
- Overlays/behavior: `@base-ui/react`. Toast: `sonner` (restyled via tokens).
|
|
37
|
+
- Prefer CSS transitions; avoid adding animation libraries for core MVP unless necessary.
|
|
38
|
+
- When adding components, follow the token contract + these conventions and add/extend colocated tests.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 nphuonha
|
|
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,137 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @nphuonha/ui-kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Solid, clean, flat, modern React UI kit. **Base UI** for behavior/a11y + owned tokens/styles + a consistent prop-driven API. Accent is vibrant by default and **customizable by color generation** (M3 Expressive-inspired, not M3 Expressive).
|
|
4
|
+
|
|
5
|
+
> Status: MVP rewrite (single suite). Breaking changes from previous `warm-editorial`/`celebration` suites.
|
|
6
|
+
|
|
7
|
+
## Install / use (workspace or package)
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import "@nphuonha/ui-kit/styles.css";
|
|
11
|
+
import { Button, Card, CardContent, Input, Toaster, accentStyle } from "@nphuonha/ui-kit";
|
|
12
|
+
|
|
13
|
+
export function App() {
|
|
14
|
+
return (
|
|
15
|
+
<div data-ui="kit">
|
|
16
|
+
<Toaster />
|
|
17
|
+
<Card>
|
|
18
|
+
<CardContent className="flex gap-2 pt-5">
|
|
19
|
+
<Input placeholder="Email" />
|
|
20
|
+
<Button>Continue</Button>
|
|
21
|
+
</CardContent>
|
|
22
|
+
</Card>
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- Scope tokens/overlays with `data-ui="kit"` (add to `<html>` for portalled overlays).
|
|
29
|
+
- Dark mode: add `class="dark"` (and/or `data-ui="kit"` dark variant as supported by your setup).
|
|
30
|
+
- Change accent at runtime: `style={accentStyle("#0d9488", "light")}` or `generateAccentVars(color, mode)` to override `--primary*`/`--ring`.
|
|
31
|
+
|
|
32
|
+
### Framework setup
|
|
33
|
+
|
|
34
|
+
The published package ships compiled ESM + `.d.ts`, so it works with Next.js, Vite, Remix and other bundlers. **No `transpilePackages` is required for the published package.**
|
|
35
|
+
|
|
36
|
+
If you are consuming the TypeScript source from this monorepo instead, add:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
// next.config.ts
|
|
40
|
+
const nextConfig = {
|
|
41
|
+
transpilePackages: ["@nphuonha/ui-kit"],
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default nextConfig;
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The published stylesheet scans its own components with `@source "./components"` inside `dist`. If your Tailwind setup ignores `@source` directives from dependencies, add this to your app CSS as a fallback:
|
|
48
|
+
|
|
49
|
+
```css
|
|
50
|
+
@source "../node_modules/@nphuonha/ui-kit/dist/components";
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Granular imports
|
|
54
|
+
|
|
55
|
+
The main barrel is convenient. For smaller client bundles, import from a component subpath:
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { Button, buttonVariants } from "@nphuonha/ui-kit/button";
|
|
59
|
+
import { Field } from "@nphuonha/ui-kit/field";
|
|
60
|
+
import { Input } from "@nphuonha/ui-kit/input";
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Variants live in server-safe `*-variants.ts` files and can be used from server components.
|
|
64
|
+
|
|
65
|
+
## Structure
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
src/components/ui/button/
|
|
69
|
+
button.tsx # "use client" behavior/render
|
|
70
|
+
button-variants.ts # cva, server-safe
|
|
71
|
+
button.test.tsx # colocated test
|
|
72
|
+
index.ts # explicit exports
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Icons
|
|
76
|
+
|
|
77
|
+
The kit uses **Phosphor** as its default internal icon set (check, minus, chevron, close, spinner). User-facing icons stay icon-agnostic — pass any icon component that accepts `size` and `className`:
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
<Button startIcon={Plus}>New item</Button>
|
|
81
|
+
<IconButton aria-label="Search"><Search /></IconButton>
|
|
82
|
+
<Alert icon={Info} title="Heads up">...</Alert>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Swap the internal set at any time with `IconProvider`:
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import { IconProvider } from "@nphuonha/ui-kit";
|
|
89
|
+
import { Check, ChevronUpDown, Loader, Minus, X } from "your-icon-pack";
|
|
90
|
+
|
|
91
|
+
<IconProvider
|
|
92
|
+
icons={{ check: Check, minus: Minus, chevron: ChevronUpDown, close: X, spinner: Loader }}
|
|
93
|
+
>
|
|
94
|
+
<App />
|
|
95
|
+
</IconProvider>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`Toaster` also accepts an `icons` prop for `success`, `info`, `warning`, `error`, `loading` and `close`.
|
|
99
|
+
|
|
100
|
+
The docs site uses Phosphor too. Swapping to another pack only affects the kit's internal affordances; icons you pass to `Button`, `IconButton` and `Alert` are always yours.
|
|
101
|
+
|
|
102
|
+
## MVP components
|
|
103
|
+
|
|
104
|
+
`Button`, `IconButton`, `Input`, `Textarea`, `Field`/`Label`, `Checkbox`, `RadioGroup`, `Switch`, `Select`, `Dialog`, `Sheet`, `Popover`, `Tooltip`, `Tabs`, `Card` (+Header/Title/Description/Content/Footer), `Badge`, `Alert`, `Separator`, `Spinner`, `Toaster`/`toast`.
|
|
105
|
+
|
|
106
|
+
## Scripts
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npm run build -w @nphuonha/ui-kit # emit dist (ESM + .d.ts + CSS)
|
|
110
|
+
npm run typecheck -w @nphuonha/ui-kit
|
|
111
|
+
npm run test -w @nphuonha/ui-kit
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Publishing
|
|
115
|
+
|
|
116
|
+
The package builds to `dist` as ESM + `.d.ts` with `npm run build`. `prepack` builds automatically before `npm pack`/`npm publish`; `prepublishOnly` runs typecheck + tests.
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npm login
|
|
120
|
+
npm publish -w @nphuonha/ui-kit
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Or from the repo root:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
npm run publish:kit
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Bump the version with:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npm version patch -w @nphuonha/ui-kit
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The published package is compiled and works with Vite, Remix, Next.js and plain bundler-based JS apps. The repository's docs app consumes the TypeScript source via a local path alias for fast iteration.
|
|
136
|
+
|
|
137
|
+
See `CONVENTIONS.md` for design/API rules.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export type KitIconName = "check" | "minus" | "chevron" | "close" | "spinner";
|
|
3
|
+
export type KitIcon = React.ComponentType<{
|
|
4
|
+
size?: number;
|
|
5
|
+
} & React.SVGProps<SVGSVGElement>>;
|
|
6
|
+
export interface IconProviderProps {
|
|
7
|
+
icons?: Partial<Record<KitIconName, KitIcon>>;
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Default internal icons come from Phosphor. Swap any of them for another pack:
|
|
12
|
+
*
|
|
13
|
+
* <IconProvider icons={{ check: LucideCheck, close: LucideX }}>
|
|
14
|
+
* <App />
|
|
15
|
+
* </IconProvider>
|
|
16
|
+
*/
|
|
17
|
+
export declare function IconProvider({ icons, children }: IconProviderProps): React.JSX.Element;
|
|
18
|
+
export declare function useKitIcon(name: KitIconName): KitIcon;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { CaretUpDownIcon, CheckIcon, MinusIcon, SpinnerIcon, XIcon, } from "@phosphor-icons/react";
|
|
5
|
+
const defaultIcons = {
|
|
6
|
+
check: (props) => _jsx(CheckIcon, { ...props, weight: "bold" }),
|
|
7
|
+
minus: (props) => _jsx(MinusIcon, { ...props, weight: "bold" }),
|
|
8
|
+
chevron: (props) => _jsx(CaretUpDownIcon, { ...props, weight: "bold" }),
|
|
9
|
+
close: (props) => _jsx(XIcon, { ...props, weight: "bold" }),
|
|
10
|
+
spinner: SpinnerIcon,
|
|
11
|
+
};
|
|
12
|
+
const IconContext = React.createContext({});
|
|
13
|
+
/**
|
|
14
|
+
* Default internal icons come from Phosphor. Swap any of them for another pack:
|
|
15
|
+
*
|
|
16
|
+
* <IconProvider icons={{ check: LucideCheck, close: LucideX }}>
|
|
17
|
+
* <App />
|
|
18
|
+
* </IconProvider>
|
|
19
|
+
*/
|
|
20
|
+
export function IconProvider({ icons, children }) {
|
|
21
|
+
return _jsx(IconContext.Provider, { value: icons ?? {}, children: children });
|
|
22
|
+
}
|
|
23
|
+
export function useKitIcon(name) {
|
|
24
|
+
const icons = React.useContext(IconContext);
|
|
25
|
+
return icons[name] ?? defaultIcons[name];
|
|
26
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type VariantProps } from "class-variance-authority";
|
|
2
|
+
export declare const alertVariants: (props?: ({
|
|
3
|
+
variant?: "neutral" | "info" | "success" | "warning" | "danger" | null | undefined;
|
|
4
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
5
|
+
export type AlertVariants = VariantProps<typeof alertVariants>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { cva } from "class-variance-authority";
|
|
2
|
+
export const alertVariants = cva("surface-curved-soft relative flex w-full items-start gap-3 rounded-card px-4 py-3.5 text-sm", {
|
|
3
|
+
variants: {
|
|
4
|
+
variant: {
|
|
5
|
+
neutral: "bg-surface text-foreground",
|
|
6
|
+
info: "bg-info/10 text-foreground",
|
|
7
|
+
success: "bg-success/10 text-foreground",
|
|
8
|
+
warning: "bg-warning/12 text-foreground",
|
|
9
|
+
danger: "bg-destructive/10 text-foreground",
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
defaultVariants: { variant: "neutral" },
|
|
13
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { VariantProps } from "class-variance-authority";
|
|
3
|
+
import { type IconComponent } from "../../../lib/utils.js";
|
|
4
|
+
import { alertVariants } from "./alert-variants.js";
|
|
5
|
+
export interface AlertProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof alertVariants> {
|
|
6
|
+
title?: string;
|
|
7
|
+
icon?: IconComponent;
|
|
8
|
+
}
|
|
9
|
+
export declare function Alert({ className, variant, title, icon: Icon, children, ...props }: AlertProps): React.JSX.Element;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../../lib/utils.js";
|
|
3
|
+
import { alertVariants } from "./alert-variants.js";
|
|
4
|
+
const iconTone = {
|
|
5
|
+
neutral: "text-muted-foreground",
|
|
6
|
+
info: "text-info",
|
|
7
|
+
success: "text-success",
|
|
8
|
+
warning: "text-warning",
|
|
9
|
+
danger: "text-destructive",
|
|
10
|
+
};
|
|
11
|
+
export function Alert({ className, variant = "neutral", title, icon: Icon, children, ...props }) {
|
|
12
|
+
return (_jsxs("div", { role: "status", className: cn(alertVariants({ variant }), className), ...props, children: [Icon ? _jsx(Icon, { size: 18, className: cn("mt-0.5 shrink-0", iconTone[variant ?? "neutral"]) }) : null, _jsxs("div", { className: "min-w-0 flex-1", children: [title ? _jsx("div", { className: "font-semibold leading-5 tracking-[-0.01em]", children: title }) : null, children ? _jsx("div", { className: cn("text-muted-foreground", title && "mt-0.5"), children: children }) : null] })] }));
|
|
13
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type VariantProps } from "class-variance-authority";
|
|
2
|
+
export declare const badgeVariants: (props?: ({
|
|
3
|
+
variant?: "neutral" | "info" | "success" | "warning" | "danger" | "primary" | "solid" | "outline" | null | undefined;
|
|
4
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
5
|
+
export type BadgeVariants = VariantProps<typeof badgeVariants>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { cva } from "class-variance-authority";
|
|
2
|
+
export const badgeVariants = cva("surface-curved-soft relative inline-flex items-center gap-1 whitespace-nowrap rounded-pill px-2.5 py-0.5 text-xs font-semibold tracking-[-0.01em] transition-colors", {
|
|
3
|
+
variants: {
|
|
4
|
+
variant: {
|
|
5
|
+
neutral: "bg-surface text-foreground",
|
|
6
|
+
primary: "bg-primary-soft text-primary-soft-foreground",
|
|
7
|
+
success: "bg-success/12 text-success",
|
|
8
|
+
warning: "bg-warning/14 text-warning",
|
|
9
|
+
danger: "bg-destructive/12 text-destructive",
|
|
10
|
+
info: "bg-info/12 text-info",
|
|
11
|
+
solid: "bg-primary text-primary-foreground",
|
|
12
|
+
outline: "bg-transparent text-foreground shadow-[inset_0_0_0_1px_var(--border)]",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
defaultVariants: { variant: "neutral" },
|
|
16
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { VariantProps } from "class-variance-authority";
|
|
3
|
+
import { badgeVariants } from "./badge-variants.js";
|
|
4
|
+
export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement>, VariantProps<typeof badgeVariants> {
|
|
5
|
+
}
|
|
6
|
+
export declare function Badge({ className, variant, ...props }: BadgeProps): React.JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../../lib/utils.js";
|
|
3
|
+
import { badgeVariants } from "./badge-variants.js";
|
|
4
|
+
export function Badge({ className, variant, ...props }) {
|
|
5
|
+
return _jsx("span", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
6
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type VariantProps } from "class-variance-authority";
|
|
2
|
+
export declare const buttonVariants: (props?: ({
|
|
3
|
+
variant?: "danger" | "primary" | "outline" | "secondary" | "ghost" | "soft" | null | undefined;
|
|
4
|
+
size?: "icon" | "sm" | "default" | "lg" | "icon-sm" | null | undefined;
|
|
5
|
+
shape?: "rounded" | "pill" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
export type ButtonVariants = VariantProps<typeof buttonVariants>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { cva } from "class-variance-authority";
|
|
2
|
+
export const buttonVariants = cva("relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap text-sm font-semibold tracking-[-0.01em] transition-[background-color,color,box-shadow,transform] duration-[var(--duration-ui)] ease-[var(--ease-out-ui)] outline-none select-none focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-45 data-[loading]:opacity-80 motion-safe:active:scale-[0.97]", {
|
|
3
|
+
variants: {
|
|
4
|
+
variant: {
|
|
5
|
+
primary: "surface-curved bg-primary text-primary-foreground shadow-[var(--shadow-raised)] hover:bg-primary-hover active:bg-primary-active",
|
|
6
|
+
secondary: "surface-curved-soft bg-field text-field-foreground hover:bg-field-hover",
|
|
7
|
+
outline: "bg-transparent text-foreground shadow-[inset_0_0_0_1.5px_var(--border)] hover:bg-surface",
|
|
8
|
+
ghost: "bg-transparent text-foreground hover:bg-surface active:bg-surface-hover",
|
|
9
|
+
danger: "surface-curved bg-destructive text-destructive-foreground shadow-[var(--shadow-raised)] hover:bg-destructive/90",
|
|
10
|
+
soft: "surface-curved-soft bg-primary-soft text-primary-soft-foreground hover:bg-primary-soft/75",
|
|
11
|
+
},
|
|
12
|
+
size: {
|
|
13
|
+
sm: "h-9 px-3.5 text-[13px]",
|
|
14
|
+
default: "h-10 px-4",
|
|
15
|
+
lg: "h-11 px-5 text-[15px]",
|
|
16
|
+
icon: "size-10 p-0",
|
|
17
|
+
"icon-sm": "size-9 p-0",
|
|
18
|
+
},
|
|
19
|
+
shape: {
|
|
20
|
+
rounded: "rounded-control",
|
|
21
|
+
pill: "rounded-pill",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
defaultVariants: {
|
|
25
|
+
variant: "primary",
|
|
26
|
+
size: "default",
|
|
27
|
+
shape: "rounded",
|
|
28
|
+
},
|
|
29
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Button as ButtonPrimitive } from "@base-ui/react/button";
|
|
3
|
+
import { type ButtonVariants } from "./button-variants.js";
|
|
4
|
+
import { type IconComponent } from "../../../lib/utils.js";
|
|
5
|
+
export interface ButtonProps extends ButtonPrimitive.Props, ButtonVariants {
|
|
6
|
+
loading?: boolean;
|
|
7
|
+
startIcon?: IconComponent;
|
|
8
|
+
endIcon?: IconComponent;
|
|
9
|
+
}
|
|
10
|
+
export declare const Button: React.ForwardRefExoticComponent<Omit<ButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Button as ButtonPrimitive } from "@base-ui/react/button";
|
|
5
|
+
import { Spinner } from "../spinner/index.js";
|
|
6
|
+
import { buttonVariants } from "./button-variants.js";
|
|
7
|
+
import { cn } from "../../../lib/utils.js";
|
|
8
|
+
export const Button = React.forwardRef(({ className, variant, size, shape, loading, startIcon: StartIcon, endIcon: EndIcon, children, disabled, ...props }, ref) => {
|
|
9
|
+
const iconOnly = size === "icon" || size === "icon-sm";
|
|
10
|
+
return (_jsxs(ButtonPrimitive, { ref: ref, disabled: loading || disabled, "aria-busy": loading || undefined, "data-loading": loading || undefined, className: cn(buttonVariants({ variant, size, shape }), className), ...props, children: [loading ? _jsx(Spinner, { size: 16, className: "shrink-0" }) : null, !loading && StartIcon ? _jsx(StartIcon, { size: 16, className: "shrink-0" }) : null, children != null && children !== "" && !(loading && iconOnly) ? (iconOnly ? (_jsx("span", { "aria-hidden": "true", className: "inline-flex items-center justify-center", children: children })) : (_jsx("span", { className: "truncate", children: children }))) : null, !loading && EndIcon ? _jsx(EndIcon, { size: 16, className: "shrink-0" }) : null] }));
|
|
11
|
+
});
|
|
12
|
+
Button.displayName = "Button";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export declare function Card({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
|
|
3
|
+
export declare function CardHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
|
|
4
|
+
export declare function CardTitle({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>): React.JSX.Element;
|
|
5
|
+
export declare function CardDescription({ className, ...props }: React.HTMLAttributes<HTMLParagraphElement>): React.JSX.Element;
|
|
6
|
+
export declare function CardContent({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
|
|
7
|
+
export declare function CardFooter({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../../lib/utils.js";
|
|
3
|
+
export function Card({ className, ...props }) {
|
|
4
|
+
return (_jsx("div", { className: cn("surface-curved relative rounded-card bg-card text-card-foreground shadow-[var(--shadow-soft)]", className), ...props }));
|
|
5
|
+
}
|
|
6
|
+
export function CardHeader({ className, ...props }) {
|
|
7
|
+
return _jsx("div", { className: cn("flex flex-col gap-1.5 p-6 pb-0", className), ...props });
|
|
8
|
+
}
|
|
9
|
+
export function CardTitle({ className, ...props }) {
|
|
10
|
+
return _jsx("h3", { className: cn("text-base font-semibold tracking-[-0.015em] leading-tight", className), ...props });
|
|
11
|
+
}
|
|
12
|
+
export function CardDescription({ className, ...props }) {
|
|
13
|
+
return _jsx("p", { className: cn("text-sm leading-relaxed text-muted-foreground", className), ...props });
|
|
14
|
+
}
|
|
15
|
+
export function CardContent({ className, ...props }) {
|
|
16
|
+
return _jsx("div", { className: cn("p-6", className), ...props });
|
|
17
|
+
}
|
|
18
|
+
export function CardFooter({ className, ...props }) {
|
|
19
|
+
return _jsx("div", { className: cn("flex items-center gap-2 p-6 pt-0", className), ...props });
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from "./card.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from "./card.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Checkbox as CheckboxPrimitive } from "@base-ui/react/checkbox";
|
|
3
|
+
export interface CheckboxProps extends Omit<React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>, "children"> {
|
|
4
|
+
label?: React.ReactNode;
|
|
5
|
+
description?: React.ReactNode;
|
|
6
|
+
error?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare const Checkbox: React.ForwardRefExoticComponent<CheckboxProps & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Checkbox as CheckboxPrimitive } from "@base-ui/react/checkbox";
|
|
5
|
+
import { cn } from "../../../lib/utils.js";
|
|
6
|
+
import { useKitIcon } from "../_shared/icon-provider.js";
|
|
7
|
+
export const Checkbox = React.forwardRef(({ className, label, description, error, id, ...props }, ref) => {
|
|
8
|
+
const CheckIcon = useKitIcon("check");
|
|
9
|
+
const MinusIcon = useKitIcon("minus");
|
|
10
|
+
const autoId = React.useId();
|
|
11
|
+
const controlId = id ?? autoId;
|
|
12
|
+
const descriptionId = description ? `${controlId}-description` : undefined;
|
|
13
|
+
const control = (_jsx(CheckboxPrimitive.Root, { ref: ref, id: controlId, "aria-invalid": error || undefined, "aria-describedby": descriptionId, className: cn("surface-inset peer inline-flex size-5 shrink-0 items-center justify-center rounded-[7px] bg-field text-primary-foreground transition-[background-color,box-shadow] duration-[var(--duration-ui)] ease-[var(--ease-out-ui)] outline-none focus-visible:ring-2 focus-visible:ring-ring/40 focus-visible:ring-offset-2 focus-visible:ring-offset-background data-[checked]:bg-primary data-[indeterminate]:bg-primary disabled:cursor-not-allowed disabled:opacity-45", error && "bg-destructive/15 data-[checked]:bg-destructive", className), ...props, children: _jsxs(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center text-current data-[unchecked]:hidden", children: [_jsx(CheckIcon, { size: 13, className: "in-data-[indeterminate]:hidden" }), _jsx(MinusIcon, { size: 13, className: "hidden in-data-[indeterminate]:block" })] }) }));
|
|
14
|
+
if (!label && !description)
|
|
15
|
+
return control;
|
|
16
|
+
return (_jsxs("div", { className: "flex items-start gap-2.5", children: [control, _jsxs("div", { className: "grid gap-0.5 pt-0.5", children: [label ? (_jsx("label", { htmlFor: controlId, className: "cursor-pointer text-sm font-medium leading-none text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-45", children: label })) : null, description ? _jsx("p", { id: descriptionId, className: "text-xs text-muted-foreground", children: description }) : null] })] }));
|
|
17
|
+
});
|
|
18
|
+
Checkbox.displayName = "Checkbox";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Checkbox, type CheckboxProps } from "./checkbox.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Checkbox } from "./checkbox.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export interface DialogProps {
|
|
3
|
+
open?: boolean;
|
|
4
|
+
defaultOpen?: boolean;
|
|
5
|
+
onOpenChange?: (open: boolean) => void;
|
|
6
|
+
trigger?: React.ReactElement;
|
|
7
|
+
title?: React.ReactNode;
|
|
8
|
+
description?: React.ReactNode;
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
footer?: React.ReactNode;
|
|
11
|
+
className?: string;
|
|
12
|
+
showClose?: boolean;
|
|
13
|
+
"aria-label"?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function Dialog({ open, defaultOpen, onOpenChange, trigger, title, description, children, footer, className, showClose, "aria-label": ariaLabel, }: DialogProps): React.JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Dialog as DialogPrimitive } from "@base-ui/react/dialog";
|
|
4
|
+
import { cn } from "../../../lib/utils.js";
|
|
5
|
+
import { IconButton } from "../icon-button/index.js";
|
|
6
|
+
import { useKitIcon } from "../_shared/icon-provider.js";
|
|
7
|
+
export function Dialog({ open, defaultOpen, onOpenChange, trigger, title, description, children, footer, className, showClose = true, "aria-label": ariaLabel, }) {
|
|
8
|
+
const CloseIcon = useKitIcon("close");
|
|
9
|
+
return (_jsxs(DialogPrimitive.Root, { open: open, defaultOpen: defaultOpen, onOpenChange: onOpenChange, children: [trigger ? _jsx(DialogPrimitive.Trigger, { render: trigger }) : null, _jsxs(DialogPrimitive.Portal, { children: [_jsx(DialogPrimitive.Backdrop, { className: "fixed inset-0 z-50 bg-overlay backdrop-blur-[2px] transition-opacity duration-[var(--duration-ui-slow)] data-[starting-style]:opacity-0 data-[ending-style]:opacity-0" }), _jsxs(DialogPrimitive.Popup, { "aria-label": ariaLabel, className: cn("surface-curved fixed left-1/2 top-1/2 z-50 grid w-[calc(100%-2rem)] max-w-lg -translate-x-1/2 -translate-y-1/2 grid-cols-1 gap-5 rounded-overlay bg-popover p-6 text-popover-foreground shadow-[var(--shadow-overlay)] outline-none", "transition-[opacity,transform] duration-[var(--duration-ui-slow)] ease-[var(--ease-out-ui)]", "data-[starting-style]:opacity-0 data-[starting-style]:-translate-x-1/2 data-[starting-style]:-translate-y-[47%] data-[starting-style]:scale-[0.97]", "data-[ending-style]:opacity-0 data-[ending-style]:-translate-x-1/2 data-[ending-style]:-translate-y-[47%] data-[ending-style]:scale-[0.97]", className), children: [(title || description || showClose) && (_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { className: "grid gap-1", children: [title ? _jsx(DialogPrimitive.Title, { className: "text-lg font-semibold tracking-[-0.02em] leading-tight", children: title }) : null, description ? _jsx(DialogPrimitive.Description, { className: "text-sm leading-relaxed text-muted-foreground", children: description }) : null] }), showClose ? (_jsx(DialogPrimitive.Close, { render: _jsx(IconButton, { "aria-label": "Close", variant: "ghost", size: "icon-sm", className: "-mr-2 -mt-2 shrink-0", children: _jsx(CloseIcon, { size: 16 }) }) })) : null] })), _jsx("div", { className: "min-w-0", children: children }), footer ? _jsx("div", { className: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", children: footer }) : null] })] })] }));
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Dialog, type DialogProps } from "./dialog.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Dialog } from "./dialog.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
export interface FieldProps {
|
|
3
|
+
id?: string;
|
|
4
|
+
label?: React.ReactNode;
|
|
5
|
+
description?: React.ReactNode;
|
|
6
|
+
error?: React.ReactNode;
|
|
7
|
+
required?: boolean;
|
|
8
|
+
className?: string;
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
export declare function Field({ id, label, description, error, required, className, children }: FieldProps): React.JSX.Element;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { cn } from "../../../lib/utils.js";
|
|
5
|
+
import { Label } from "../label/index.js";
|
|
6
|
+
export function Field({ id, label, description, error, required, className, children }) {
|
|
7
|
+
const autoId = React.useId();
|
|
8
|
+
const controlId = id ?? autoId;
|
|
9
|
+
const descriptionId = description ? `${controlId}-description` : undefined;
|
|
10
|
+
const errorId = error ? `${controlId}-error` : undefined;
|
|
11
|
+
const describedBy = [descriptionId, errorId].filter(Boolean).join(" ") || undefined;
|
|
12
|
+
const child = React.isValidElement(children)
|
|
13
|
+
? React.cloneElement(children, {
|
|
14
|
+
id: children.props.id ?? controlId,
|
|
15
|
+
"aria-describedby": [children.props["aria-describedby"], describedBy]
|
|
16
|
+
.filter(Boolean)
|
|
17
|
+
.join(" ") || undefined,
|
|
18
|
+
"aria-invalid": error ? true : children.props["aria-invalid"],
|
|
19
|
+
})
|
|
20
|
+
: children;
|
|
21
|
+
return (_jsxs("div", { className: cn("flex flex-col gap-1.5", className), children: [label ? (_jsx(Label, { htmlFor: controlId, requiredMark: required, children: label })) : null, child, description ? (_jsx("p", { id: descriptionId, className: "text-xs text-muted-foreground", children: description })) : null, error ? (_jsx("p", { id: errorId, role: "alert", className: "text-xs font-medium text-destructive", children: error })) : null] }));
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Field, type FieldProps } from "./field.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Field } from "./field.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type ButtonProps } from "../button/index.js";
|
|
3
|
+
export interface IconButtonProps extends Omit<ButtonProps, "startIcon" | "endIcon" | "children"> {
|
|
4
|
+
"aria-label": string;
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export declare const IconButton: React.ForwardRefExoticComponent<Omit<IconButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Button } from "../button/index.js";
|
|
5
|
+
import { cn } from "../../../lib/utils.js";
|
|
6
|
+
export const IconButton = React.forwardRef(({ className, size = "icon", shape = "rounded", children, ...props }, ref) => (_jsx(Button, { ref: ref, size: size, shape: shape, className: cn(className), ...props, children: children })));
|
|
7
|
+
IconButton.displayName = "IconButton";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { IconButton, type IconButtonProps } from "./icon-button.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { IconButton } from "./icon-button.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Input, type InputProps } from "./input.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Input } from "./input.js";
|