@alexgorbatchev/shadcn 0.0.0-stage → 0.0.12
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 +349 -2
- package/THIRD_PARTY_NOTICES.md +105 -0
- package/dist/chunk-1j2hz3w9.js +16 -0
- package/dist/chunk-5wvvqege.js +259 -0
- package/dist/chunk-8a7dn9ps.js +93 -0
- package/dist/chunk-cp2m7y7v.js +26 -0
- package/dist/chunk-jpvw9xqy.js +4 -0
- package/dist/chunk-rajgnfbr.js +24 -0
- package/dist/chunk-rjjwytbx.js +12 -0
- package/dist/chunk-tnktkgvp.js +63 -0
- package/dist/chunk-z1fy613d.js +64 -0
- package/dist/components/Accordion.d.ts +12 -0
- package/dist/components/Alert.d.ts +15 -0
- package/dist/components/AlertDialog.d.ts +28 -0
- package/dist/components/AspectRatio.d.ts +5 -0
- package/dist/components/Attachment.d.ts +36 -0
- package/dist/components/Avatar.d.ts +19 -0
- package/dist/components/Badge.d.ts +15 -0
- package/dist/components/Breadcrumb.d.ts +18 -0
- package/dist/components/Bubble.d.ts +25 -0
- package/dist/components/Button.d.ts +13 -0
- package/dist/components/ButtonGroup.d.ts +14 -0
- package/dist/components/Card.d.ts +19 -0
- package/dist/components/Checkbox.d.ts +6 -0
- package/dist/components/Collapsible.d.ts +6 -0
- package/dist/components/Combobox.d.ts +39 -0
- package/dist/components/ConfirmationDialog.d.ts +11 -0
- package/dist/components/ContextMenu.d.ts +24 -0
- package/dist/components/DensityProvider.d.ts +7 -0
- package/dist/components/Dialog.d.ts +25 -0
- package/dist/components/DirectionProvider.d.ts +1 -0
- package/dist/components/DragDropPreview.d.ts +7 -0
- package/dist/components/DragDropProvider.d.ts +6 -0
- package/dist/components/DragSource.d.ts +10 -0
- package/dist/components/Drawer.d.ts +25 -0
- package/dist/components/DropTarget.d.ts +11 -0
- package/dist/components/DropdownMenu.d.ts +26 -0
- package/dist/components/Empty.d.ts +19 -0
- package/dist/components/EmptyState.d.ts +8 -0
- package/dist/components/Field.d.ts +36 -0
- package/dist/components/HoverCard.d.ts +8 -0
- package/dist/components/ImagePicker.d.ts +11 -0
- package/dist/components/InlineEdit.d.ts +14 -0
- package/dist/components/Input.d.ts +6 -0
- package/dist/components/InputGroup.d.ts +26 -0
- package/dist/components/Item.d.ts +32 -0
- package/dist/components/JsonViewer.d.ts +8 -0
- package/dist/components/Kbd.d.ts +7 -0
- package/dist/components/Label.d.ts +5 -0
- package/dist/components/Marker.d.ts +19 -0
- package/dist/components/Menubar.d.ts +29 -0
- package/dist/components/Message.d.ts +17 -0
- package/dist/components/NativeSelect.d.ts +11 -0
- package/dist/components/NavigationMenu.d.ts +21 -0
- package/dist/components/Pagination.d.ts +21 -0
- package/dist/components/Popover.d.ts +14 -0
- package/dist/components/Progress.d.ts +14 -0
- package/dist/components/RadioGroup.d.ts +9 -0
- package/dist/components/ScrollArea.d.ts +10 -0
- package/dist/components/Select.d.ts +25 -0
- package/dist/components/Separator.d.ts +8 -0
- package/dist/components/Sheet.d.ts +20 -0
- package/dist/components/Sidebar.d.ts +60 -0
- package/dist/components/Skeleton.d.ts +5 -0
- package/dist/components/Slider.d.ts +6 -0
- package/dist/components/Spinner.d.ts +5 -0
- package/dist/components/StarRating.d.ts +10 -0
- package/dist/components/Switch.d.ts +8 -0
- package/dist/components/Table.d.ts +28 -0
- package/dist/components/Tabs.d.ts +16 -0
- package/dist/components/Textarea.d.ts +5 -0
- package/dist/components/ThemeProvider.d.ts +9 -0
- package/dist/components/Toast.d.ts +18 -0
- package/dist/components/Toggle.d.ts +11 -0
- package/dist/components/ToggleGroup.d.ts +12 -0
- package/dist/components/Tooltip.d.ts +9 -0
- package/dist/components/calendar/Calendar.d.ts +6 -0
- package/dist/components/calendar/getCalendarClassNames.d.ts +3 -0
- package/dist/components/calendar/index.d.ts +1 -0
- package/dist/components/calendar/index.js +10 -0
- package/dist/components/calendar/types.d.ts +9 -0
- package/dist/components/carousel/Carousel.d.ts +9 -0
- package/dist/components/carousel/CarouselContext.d.ts +2 -0
- package/dist/components/carousel/hooks/useCarousel.d.ts +2 -0
- package/dist/components/carousel/index.d.ts +3 -0
- package/dist/components/carousel/index.js +207 -0
- package/dist/components/carousel/types.d.ts +23 -0
- package/dist/components/chart/Chart.d.ts +10 -0
- package/dist/components/chart/ChartContext.d.ts +2 -0
- package/dist/components/chart/ChartStyle.d.ts +3 -0
- package/dist/components/chart/getPayloadConfigFromPayload.d.ts +2 -0
- package/dist/components/chart/hooks/useChart.d.ts +2 -0
- package/dist/components/chart/index.d.ts +3 -0
- package/dist/components/chart/index.js +284 -0
- package/dist/components/chart/types.d.ts +50 -0
- package/dist/components/command/Command.d.ts +21 -0
- package/dist/components/command/index.d.ts +1 -0
- package/dist/components/command/index.js +142 -0
- package/dist/components/input-otp/InputOTP.d.ts +12 -0
- package/dist/components/input-otp/index.d.ts +1 -0
- package/dist/components/input-otp/index.js +303 -0
- package/dist/components/message-scroller/MessageScroller.d.ts +16 -0
- package/dist/components/message-scroller/hooks/useMessageScroller.d.ts +1 -0
- package/dist/components/message-scroller/hooks/useMessageScrollerScrollable.d.ts +1 -0
- package/dist/components/message-scroller/hooks/useMessageScrollerVisibility.d.ts +1 -0
- package/dist/components/message-scroller/index.d.ts +5 -0
- package/dist/components/message-scroller/index.js +600 -0
- package/dist/components/persian-calendar/PersianCalendar.d.ts +6 -0
- package/dist/components/persian-calendar/index.d.ts +1 -0
- package/dist/components/persian-calendar/index.js +36 -0
- package/dist/components/questionnaire/Questionnaire.d.ts +20 -0
- package/dist/components/questionnaire/index.d.ts +2 -0
- package/dist/components/questionnaire/index.js +747 -0
- package/dist/components/resizable/Resizable.d.ts +10 -0
- package/dist/components/resizable/SplitView.d.ts +12 -0
- package/dist/components/resizable/index.d.ts +2 -0
- package/dist/components/resizable/index.js +147 -0
- package/dist/components/sonner/Sonner.d.ts +7 -0
- package/dist/components/sonner/hooks/useSonner.d.ts +1 -0
- package/dist/components/sonner/index.d.ts +2 -0
- package/dist/components/sonner/index.js +1273 -0
- package/dist/density/DensityContext.d.ts +2 -0
- package/dist/density/types.d.ts +4 -0
- package/dist/drag-drop/DragDropContext.d.ts +2 -0
- package/dist/drag-drop/types.d.ts +45 -0
- package/dist/drawer/DrawerContext.d.ts +2 -0
- package/dist/drawer/types.d.ts +7 -0
- package/dist/fonts.css +1 -0
- package/dist/hooks/useComboboxAnchor.d.ts +2 -0
- package/dist/hooks/useDensity.d.ts +2 -0
- package/dist/hooks/useDragDrop.d.ts +2 -0
- package/dist/hooks/useDragSource.d.ts +2 -0
- package/dist/hooks/useDrawer.d.ts +2 -0
- package/dist/hooks/useDropTarget.d.ts +2 -0
- package/dist/hooks/useMediaQuery.d.ts +1 -0
- package/dist/hooks/useObjectURL.d.ts +1 -0
- package/dist/hooks/useSidebar.d.ts +2 -0
- package/dist/hooks/useTheme.d.ts +2 -0
- package/dist/hooks/useToastManager.d.ts +2 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.js +4908 -0
- package/dist/menu/types.d.ts +14 -0
- package/dist/message/MessageContext.d.ts +2 -0
- package/dist/message/types.d.ts +7 -0
- package/dist/sidebar/SidebarContext.d.ts +2 -0
- package/dist/sidebar/types.d.ts +32 -0
- package/dist/theme/ThemeContext.d.ts +2 -0
- package/dist/theme/types.d.ts +8 -0
- package/dist/theme.css +454 -0
- package/dist/toggle-group/ToggleGroupContext.d.ts +2 -0
- package/dist/toggle-group/types.d.ts +5 -0
- package/dist/typeset.css +444 -0
- package/dist/utils/cn.d.ts +2 -0
- package/package.json +193 -4
- package/patches/@shadcn%2Freact@0.3.1.patch +35 -0
- package/patches/input-otp@1.5.0.patch +20 -0
- package/patches/sonner@2.0.8.patch +87 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alex Gorbatchev
|
|
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,350 @@
|
|
|
1
|
-
|
|
1
|
+
`@alexgorbatchev/shadcn` is a standalone React component library for Bun applications that need the sharp, monospace devhost design language. Install it as an npm-compatible package and explore its components in the local interactive Storybook catalog. Consuming apps do not depend on the devhost project.
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# What It Does
|
|
4
|
+
|
|
5
|
+
- **Consistent controls**: Provides buttons, forms, selections, navigation, overlays, and loading states.
|
|
6
|
+
- **Two densities**: Offers compact 20px controls and comfortable 28px controls, with provider and component overrides.
|
|
7
|
+
- **Theme choices**: Supports light, dark, and system preference, with customizable accent colors and fonts.
|
|
8
|
+
- **Interactive reference**: Shows component variants and states in Storybook with editable controls and source examples.
|
|
9
|
+
|
|
10
|
+
# How It Works
|
|
11
|
+
|
|
12
|
+
1. Install the package in a Bun React project and import its theme into your Tailwind stylesheet.
|
|
13
|
+
2. Wrap the app in a theme provider and a density provider, then compose the exported components.
|
|
14
|
+
3. Open the local Storybook catalog to explore components, switch palettes and densities, and inspect examples.
|
|
15
|
+
|
|
16
|
+
# How it Really Works
|
|
17
|
+
|
|
18
|
+
1. The stylesheet supplies semantic tokens and base body styling. Your Tailwind build scans the installed package to generate component utilities. Font loading is optional; importing `fonts.css` serves JetBrains Mono through your app's asset pipeline.
|
|
19
|
+
2. Theme preference persists in browser local storage, and system mode follows the operating system color preference. The theme provider sets `data-theme` and `color-scheme` on the document root, so dialogs and menus share that palette. Use one provider per document. Density also follows components into their portals. A component's `density` prop overrides its own presentation; nest a `DensityProvider` to change a subtree and its popups together. `useTheme()` throws outside `ThemeProvider`.
|
|
20
|
+
3. Storybook's Theme and Density toolbars change the component examples. Docs backgrounds and example frames follow the selected palette; the preview starts in dark mode with comfortable density.
|
|
21
|
+
|
|
22
|
+
# Prerequisites
|
|
23
|
+
|
|
24
|
+
- [Bun](https://bun.com/docs), validated with 1.4.2.
|
|
25
|
+
- [React](https://react.dev) and React DOM 19.3, as specified by the package peer dependencies.
|
|
26
|
+
- [Tailwind CSS](https://tailwindcss.com/docs/installation) v4; the consumer build must process the imported theme.
|
|
27
|
+
|
|
28
|
+
The package targets client-rendered Bun React applications.
|
|
29
|
+
|
|
30
|
+
# Installation
|
|
31
|
+
|
|
32
|
+
Install the package in a consuming project:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
bun add @alexgorbatchev/shadcn
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Package preparation and contributor commands are documented in [AGENTS.md](./AGENTS.md#commands).
|
|
39
|
+
|
|
40
|
+
## Optional features
|
|
41
|
+
|
|
42
|
+
Import shared controls and providers from `@alexgorbatchev/shadcn`. Import the following features from their dedicated entry points and install only the peers you use. These features, their hooks, and their types are not exported from the package root.
|
|
43
|
+
|
|
44
|
+
| Import path suffix | Components | Install alongside the package |
|
|
45
|
+
| ------------------- | ------------------------------------------------------- | ------------------------------------------------------------- |
|
|
46
|
+
| `/chart` | Chart components, ChartStyle, useChart, and chart types | `bun add recharts@3.8.0 cssesc@3.0.0 es-toolkit@1.52.0` |
|
|
47
|
+
| `/calendar` | Calendar, CalendarDayButton | `bun add @daypicker/react@^10.0.2` |
|
|
48
|
+
| `/persian-calendar` | PersianCalendar | `bun add @daypicker/persian@^10.0.2 @daypicker/react@^10.0.2` |
|
|
49
|
+
| `/carousel` | Carousel components, useCarousel, and carousel types | `bun add embla-carousel-react@^8.6.0` |
|
|
50
|
+
| `/command` | Command components, including CommandDialog | `bun add cmdk@^1.1.1` |
|
|
51
|
+
| `/resizable` | Resizable components and SplitView | `bun add react-resizable-panels@^4.14.3` |
|
|
52
|
+
| `/fonts.css` | JetBrains Mono font stylesheet | `bun add @fontsource-variable/jetbrains-mono@^5.3.0` |
|
|
53
|
+
| `/sonner` | Sonner, SonnerToaster, Toaster, toast, useSonner | No additional install; patched implementation is bundled |
|
|
54
|
+
| `/input-otp` | InputOTP components | No additional install; patched implementation is bundled |
|
|
55
|
+
| `/message-scroller` | MessageScroller components, hooks, and types | No additional install; patched implementation is bundled |
|
|
56
|
+
| `/questionnaire` | Questionnaire components and types | No additional install; patched implementation is bundled |
|
|
57
|
+
|
|
58
|
+
For example:
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
import { Button, DensityProvider } from "@alexgorbatchev/shadcn";
|
|
62
|
+
import { ChartContainer, type ChartConfig } from "@alexgorbatchev/shadcn/chart";
|
|
63
|
+
import { Carousel, CarouselContent, CarouselItem } from "@alexgorbatchev/shadcn/carousel";
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The patched `sonner`, `input-otp`, and `@shadcn/react` packages remain regular dependencies pending upstream fixes. Other feature dependencies are optional peers, so a core-only installation does not request them. Shared providers work across entry points.
|
|
67
|
+
|
|
68
|
+
# Quick Start
|
|
69
|
+
|
|
70
|
+
For Bun's native HTML server, install its Tailwind plugin:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
bun add -d tailwindcss bun-plugin-tailwind
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The stylesheet example below also uses the optional font:
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
bun add @fontsource-variable/jetbrains-mono@^5.3.0
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Register the plugin in your app's `bunfig.toml`:
|
|
83
|
+
|
|
84
|
+
```toml
|
|
85
|
+
[serve.static]
|
|
86
|
+
plugins = ["bun-plugin-tailwind"]
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
In `src/styles.css`, import the theme after Tailwind and explicitly scan the installed package. The `@source` path is relative to this stylesheet; Tailwind excludes `node_modules` from automatic scanning. See [Tailwind source detection](https://tailwindcss.com/docs/detecting-classes-in-source-files#explicitly-registering-sources).
|
|
90
|
+
|
|
91
|
+
```css
|
|
92
|
+
@import "tailwindcss";
|
|
93
|
+
@import "@alexgorbatchev/shadcn/theme.css";
|
|
94
|
+
@import "@alexgorbatchev/shadcn/fonts.css";
|
|
95
|
+
@source "../node_modules/@alexgorbatchev/shadcn/dist";
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Omit the `fonts.css` import if your app supplies its own font. Bun's plugin registration is documented in [HTML and static sites](https://bun.com/docs/bundler/html-static#tailwind-css).
|
|
99
|
+
|
|
100
|
+
The theme sets `body { position: relative; }`. Preserve a positioned body when overriding global styles: Drawer's absolute Safari backdrop needs it to cover a scrolled page. See the [Base UI Safari setup](https://base-ui.com/react/overview/quick-start#ios-26-safari).
|
|
101
|
+
|
|
102
|
+
Give your application root `isolation: isolate` so page stacking levels stay below portaled menus and dialogs. For example, add `#root { isolation: isolate; }` to the stylesheet when mounting React into `#root`. SidebarProvider also isolates its own layout. See [Base UI portal setup](https://base-ui.com/react/overview/quick-start#portals).
|
|
103
|
+
|
|
104
|
+
Import that stylesheet from your app entry, then render:
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
import { useState, type ReactElement } from "react";
|
|
108
|
+
import { Button, DensityProvider, ThemeProvider } from "@alexgorbatchev/shadcn";
|
|
109
|
+
import "./styles.css";
|
|
110
|
+
|
|
111
|
+
export function App(): ReactElement {
|
|
112
|
+
const [count, setCount] = useState(0);
|
|
113
|
+
return (
|
|
114
|
+
<ThemeProvider defaultTheme="system">
|
|
115
|
+
<DensityProvider density="comfortable">
|
|
116
|
+
<Button onClick={() => setCount(count + 1)}>Clicked {count} times</Button>
|
|
117
|
+
<Button density="compact" variant="outline">
|
|
118
|
+
Compact action
|
|
119
|
+
</Button>
|
|
120
|
+
</DensityProvider>
|
|
121
|
+
</ThemeProvider>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
For a Vite consumer, install the maintained React and Tailwind plugins:
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
bun add -d vite @vitejs/plugin-react @tailwindcss/vite tailwindcss
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Use this `vite.config.ts`, with the same stylesheet imports and `@source` declaration above:
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
import { defineConfig } from "vite";
|
|
136
|
+
import react from "@vitejs/plugin-react";
|
|
137
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
138
|
+
|
|
139
|
+
export default defineConfig({
|
|
140
|
+
plugins: [react(), tailwindcss()],
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
An independent production Vite consumer installed from the archive verifies RTL grouped corners, tab markers, and portaled controls with `lang="en"`. Bun’s native CSS pipeline has the logical-property limitation described below. See the [Tailwind Vite integration](https://tailwindcss.com/docs/installation/using-vite).
|
|
145
|
+
|
|
146
|
+
# Configuration
|
|
147
|
+
|
|
148
|
+
| Option | Type | Default | Description |
|
|
149
|
+
| :--------------------------- | :------------------------------ | :------------------------------ | :--------------------------------------------------------------------- |
|
|
150
|
+
| `ThemeProvider.defaultTheme` | `"light" \| "dark" \| "system"` | `"system"` | Initial preference when storage has no saved value. |
|
|
151
|
+
| `ThemeProvider.storageKey` | `string` | `"shadcn-alexgorbatchev-theme"` | Local storage key for the preference. |
|
|
152
|
+
| `ThemeProvider.forcedTheme` | `"light" \| "dark"` | unset | Overrides the displayed palette without changing the saved preference. |
|
|
153
|
+
| `DensityProvider.density` | `"compact" \| "comfortable"` | `"comfortable"` | Density for descendants and their portals. |
|
|
154
|
+
| Component `density` | `"compact" \| "comfortable"` | inherited | Local override on styled components that expose the prop. |
|
|
155
|
+
|
|
156
|
+
`useTheme()` returns `theme`, `resolvedTheme`, and `setTheme`. Call `setTheme("light")`, `setTheme("dark")`, or `setTheme("system")` from a component inside the provider.
|
|
157
|
+
|
|
158
|
+
Override tokens after the theme imports. This example uses the existing success palette as the primary accent:
|
|
159
|
+
|
|
160
|
+
```css
|
|
161
|
+
:root,
|
|
162
|
+
[data-theme="light"],
|
|
163
|
+
[data-theme="dark"] {
|
|
164
|
+
--ag-font: ui-sans-serif, system-ui, sans-serif;
|
|
165
|
+
--primary: var(--success);
|
|
166
|
+
--primary-foreground: var(--success-foreground);
|
|
167
|
+
--ring: var(--success);
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
# Component Catalog
|
|
172
|
+
|
|
173
|
+
| Area | Components |
|
|
174
|
+
| :----------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
175
|
+
| Actions and status | Alert, Badge, Button, ButtonGroup, Sonner, Toast, Toggle, ToggleGroup |
|
|
176
|
+
| Forms and selections | Calendar, Checkbox, Combobox, Command, Field, Input, InputGroup, InputOTP, Label, NativeSelect, Questionnaire, RadioGroup, Select, Slider, Switch, Textarea |
|
|
177
|
+
| Structure and navigation | Accordion, AspectRatio, Avatar, Breadcrumb, Card, Carousel, Chart, Collapsible, Empty, Item, Kbd, Menubar, NavigationMenu, Pagination, Resizable, ScrollArea, Separator, Sidebar, Table, Tabs |
|
|
178
|
+
| Overlays | AlertDialog, ContextMenu, Dialog, Drawer, DropdownMenu, HoverCard, Popover, Sheet, Tooltip |
|
|
179
|
+
| Loading | Progress, Skeleton, Spinner |
|
|
180
|
+
| Conversations | Attachment, Bubble, Marker, Message, MessageScroller |
|
|
181
|
+
| App configuration | DensityProvider, DirectionProvider, ThemeProvider |
|
|
182
|
+
|
|
183
|
+
Use the composed parts exported from the package root, such as `DialogTrigger`, `DialogContent`, and `DialogTitle`. Storybook provides working compositions, variants, disabled states, and action callbacks. The local preview starts with `bun run storybook` and binds to `127.0.0.1:6006`.
|
|
184
|
+
|
|
185
|
+
`ScrollArea` supplies a native scroll viewport and one vertical `ScrollBar` by default. Set `scrollbars={<ScrollBar orientation="horizontal" />}` for a wide horizontal layout, or supply a fragment containing vertical and horizontal parts for both axes. The tracks stay outside the viewport and reserve their shared corner. `keepMounted` belongs to `ScrollBar`; root and track className callbacks receive native overflow/scroll state. Focus the viewport for native keyboard scrolling.
|
|
186
|
+
|
|
187
|
+
`Badge` renders a span by default. Use `render={<a href="https://base-ui.com/" />}` for navigation or a native button for actions; handlers and refs merge with the rendered element. Its render callback receives typed variant, density, and slot state. Mark icons with `data-icon="inline-start"` or `data-icon="inline-end"`; their spacing follows inline direction. Use the success and warning variants for those statuses.
|
|
188
|
+
|
|
189
|
+
Compose `CardHeader`, `CardTitle`, `CardDescription`, `CardAction`, `CardContent`, and `CardFooter` inside `Card`. Use a native heading inside `CardTitle` when the title belongs in the document outline. The `size="sm"` option reduces spacing; density controls the base inset. A leading image meets the frame without top padding, and cards without footers retain bottom padding. The `--card-spacing` CSS variable adjusts both section gaps and insets.
|
|
190
|
+
|
|
191
|
+
`Label` retains native explicit and implicit associations and refs. Connect it to an input with `htmlFor` and the input's `id`, or wrap the input. Prefer `FieldLabel` in Field compositions. For disabled styling, mark a wrapper with `className="group"` and `data-disabled="true"`, or mark a preceding disabled control with `className="peer"`. `Skeleton` supplies a visual placeholder and respects reduced-motion preference; your loading region owns status announcements and `aria-busy`, and replaces placeholders when content arrives.
|
|
192
|
+
|
|
193
|
+
Compose forms with `FieldGroup`, `Field`, labels, descriptions, and `FieldError`. The Field catalog demonstrates React Hook Form controllers with Zod validation, invalid-field focus, submission, and reset. To use that example, install `react-hook-form@7.89.0`, `@hookform/resolvers@5.9.1`, and `zod@4.6.5` in your app. These are optional example dependencies. The example uses `noValidate` to demonstrate schema errors; choose your app's browser-validation policy explicitly. `FieldError` deduplicates messages and omits alerts when the errors contain no nonempty messages. See the [official form guide](https://ui.shadcn.com/docs/forms/react-hook-form).
|
|
194
|
+
|
|
195
|
+
`Input` exposes Base UI's native props, including `onValueChange`, state-based className/style callbacks, `render`, and refs. `Textarea` uses native HTML textarea props and `onChange`; its content sizing grows and shrinks with text. Both support browser form submission, validation, disabled/read-only states, and uncontrolled reset. Restore controlled values through your form's reset handler. Input's field-state callbacks require Base UI's native Field context; the styled `Field` composition is an HTML layout.
|
|
196
|
+
|
|
197
|
+
Compose grouped controls with InputGroupInput or InputGroupTextarea, then place InputGroupAddon after the control in the DOM. Its align prop positions content at inline-start/end or block-start/end. Clicking addon text focuses the control; caller click handlers still run, and preventDefault cancels that focus. Links and buttons retain their own focus. InputGroupInput preserves Input’s native props and callbacks; InputGroupButton preserves Button’s native callbacks and defaults to type="button". Set type="submit" or type="reset" explicitly for form actions. Small text/icon actions fit the group frame in both densities. See the [official Input Group guide](https://ui.shadcn.com/docs/components/base/input-group).
|
|
198
|
+
|
|
199
|
+
`Checkbox` and `Switch` support controlled `checked`/`onCheckedChange`, initial `defaultChecked`, read-only and disabled states, cancellable changes, and state-based className callbacks. Named controls submit through their native hidden inputs; `uncheckedValue` supplies an explicit off value. For forms with reset actions, own the checked state and restore it in the form's `onReset` handler or through your form library. Base UI 1.9.0's uncontrolled Checkbox and Switch retain their rendered checked state on native form reset while their hidden inputs reset, so submitted values can disagree with the visible controls. The Switch thumb follows inline direction and stays inside its track in both sizes.
|
|
200
|
+
|
|
201
|
+
`RadioGroup` uses `value`/`onValueChange` for controlled selection and `defaultValue` for initial selection. Name the group and each option; use `FieldSet`/`FieldLegend` and `Field`/`FieldLabel` for visible labels. Arrow keys select options and skip disabled items; Space selects a focused option. Both the group and `RadioGroupItem` preserve native state-based className and style callbacks. Use `nativeButton` with `render={<button type="button" />}` for sibling labels on button-rendered items. `name`, `required`, and `form` connect selection to browser form submission and validation, including an external form. The required-form story restores controlled selection through `onReset`.
|
|
202
|
+
|
|
203
|
+
`Select` supports single, multiple, and object values through its native generic props. Pass `items` to display labels instead of raw values; provide object comparison and serialization through `isItemEqualToValue` and `itemToStringValue`. Disabled options remain focusable while rejecting selection. Read-only selection permits browsing and blocks value changes. The composed parts preserve state-based className callbacks, and portaled content follows density and DirectionProvider context. Named multiple selects submit repeated form entries. Restore controlled values in your form's reset handler. Bun-built RTL menus currently place the selection checkmark on the wrong side; verify that layout in consuming apps. See the [Base UI Select reference](https://base-ui.com/react/components/select).
|
|
204
|
+
|
|
205
|
+
`Combobox` retains native filtering, single/multiple selection, cancellation, controlled values, object identity comparison, and keyboard focus. Give its input an accessible name; an input inside the popup uses a named trigger. `ComboboxInput.className` belongs to the native input and accepts its state callback; use `frameClassName` for the surrounding InputGroup. Built-in controls use “Open popup” and “Clear selection”; customize them with `triggerLabel` and `clearLabel`. Chips use density metrics, and their removal button is named “Remove item”. Keep `ComboboxEmpty` mounted so its polite live region can announce results. In grouped lists, pass `items={group.items}` to each `ComboboxGroup`. Popup density and direction follow their providers, including through portals; reduced motion disables popup animations. See the [Base UI Combobox reference](https://base-ui.com/react/components/combobox).
|
|
206
|
+
|
|
207
|
+
`Slider` preserves scalar, mutable-array, and readonly-array value types and callbacks. Use `getAriaLabel` to name each thumb and `getAriaValueText` for custom spoken values. Vertical sliders accept an explicit height; `step`, `largeStep`, `minStepsBetweenValues`, and `format` retain native behavior. Named ranges submit a repeated entry for each thumb. Restore controlled values through your form's reset handler. See the [Base UI Slider reference](https://base-ui.com/react/components/slider).
|
|
208
|
+
|
|
209
|
+
`Dialog` traps keyboard focus by default, closes on Escape or an outside press, and restores focus when dismissed. Set `disablePointerDismissal` to block outside dismissal. `modal={false}` permits outside interaction and closes when focus leaves; `modal="trap-focus"` preserves Tab cycling while permitting outside pointer interaction. `AlertDialog` blocks outside dismissal; Escape and Cancel request closing. `AlertDialogAction` is a button: your app controls confirmation and closing. Use native `initialFocus` and `finalFocus` refs for custom focus targets. Both compositions preserve typed trigger payloads, state-based className callbacks, native render/ref behavior, density/direction in portals, and reduced-motion preference. Bun-built RTL Dialog close icons currently remain on the right; verify their placement in consuming apps. See the [Dialog](https://base-ui.com/react/components/dialog) and [Alert Dialog](https://base-ui.com/react/components/alert-dialog) references.
|
|
210
|
+
|
|
211
|
+
`Tabs` supports horizontal and vertical layouts. Its default keyboard behavior moves focus with arrow keys and activates with Enter or Space; `TabsList activateOnFocus` activates as focus moves. Disabled tabs remain focusable and reject activation. `TabsContent keepMounted` preserves panel inputs while hidden. Uncontrolled selection falls back when the active tab is removed or disabled. `Accordion` uses an array of expanded values, with `multiple` for independent panels. Its disabled native button triggers are skipped by Tab, as are disabled Collapsible triggers; enabled Accordion headings remain in the Tab order. Native className callbacks are preserved throughout both compositions, and AccordionContent applies its className to the native panel. Panel height follows dynamic content and reduced-motion preference. The current Bun consumer renders a vertical RTL line-tab marker on the wrong side; the same story passes under Storybook's Vite pipeline, so inspect RTL marker placement in Bun-built apps.
|
|
212
|
+
|
|
213
|
+
Compose a date picker from `Popover`, `Button`, and `Calendar`. The Calendar catalog demonstrates selection with popup dismissal and focus restoration, ranges, birth-date dropdowns, presets, a native time input, and editable date inputs. Input examples use `chrono-node` for strict dates or natural-language phrases such as “tomorrow”; install that dependency in apps using those examples. Invalid or cleared text clears the selected date. ArrowDown opens the calendar, and dismissal restores input focus. Keep the selected date in your app's state; there is no separate `DatePicker` export. See the [official date picker guide](https://ui.shadcn.com/docs/components/base/date-picker).
|
|
214
|
+
|
|
215
|
+
For rendered HTML or Markdown output, import `@alexgorbatchev/shadcn/typeset.css` after Tailwind and the package theme, then wrap the content in a native element with `className="typeset"`. Text follows its container's font size, document palette, and density leading. Set `--typeset-size`, `--typeset-leading`, and `--typeset-flow` in your own preset to tune reading rhythm. Your layout owns the content width. Add `not-typeset` or `data-not-typeset` to keep embedded UI and nested containers outside the prose styles. Wide tables can use a named, keyboard-focusable `typeset-scroll` wrapper; bare tables retain table semantics and wrap to fit. The Storybook Typeset composition page demonstrates these contracts. See the [official Typeset guide](https://ui.shadcn.com/docs/typeset).
|
|
216
|
+
|
|
217
|
+
Compose data tables with the exported Table parts and `@tanstack/react-table@9.2.8`, installed directly in your app. `Table dir="rtl"` sets both column direction and the overflow container's reading edge; headers align to the inline start. The Table catalog demonstrates TanStack v9's native `useTable` with sorting, filtering, pagination, column visibility, selection across pages, and row actions that copy invoice IDs or open invoice details. Pass the checkbox's original event to the row-selection handler to retain Shift range selection. There is no separate `DataTable` export. Both the [TanStack v9 quick start](https://tanstack.com/table/latest/docs/framework/react/quick-start) and [shadcn composition guide](https://ui.shadcn.com/docs/components/base/data-table) use the v9 API.
|
|
218
|
+
|
|
219
|
+
Compose `Sidebar` and `SidebarInset` inside `SidebarProvider`. Use Header, Content, Group, Menu, and Footer parts to organize navigation, and `SidebarTrigger` or `SidebarRail` to toggle it. `useSidebar` exposes desktop and mobile state. Desktop collapse supports `offcanvas`, `icon`, and `none`; the mobile panel uses a titled Sheet with Escape dismissal and focus restoration. Menu buttons accept native custom elements through `render`; use anchors for navigation and keep their accessible text when collapsed. Cmd/Ctrl+B toggles the sidebar. Set `open`/`onOpenChange` for controlled desktop state, or observe changes without supplying `open`. The provider writes the `sidebar_state` cookie for seven days; restore it through your own `defaultOpen`. Set widths through the typed `SidebarStyle` variables `--sidebar-width`, `--sidebar-width-mobile`, and `--sidebar-width-icon`.
|
|
220
|
+
|
|
221
|
+
`InputOTP` uses one real input for typing, selection, paste, and autofill. Compose its visual slots inside `InputOTPGroup`; supply `maxLength` and an accessible label. Use `defaultValue` to initialize an uncontrolled code, or `value` and `onChange` to control it. Changing `defaultValue` after mounting preserves the current input. Import the OTP parts together from `@alexgorbatchev/shadcn/input-otp`; its bundled implementation owns their context. `Calendar` supports single, multiple, and range selection. `ResizablePanelGroup` sizes use explicit percentage strings such as `defaultSize="50%"`; numeric sizes are pixels. `CommandDialog` supplies the modal title and description; set `Command`'s `label` to name its search input.
|
|
222
|
+
|
|
223
|
+
Use the Theme toolbar to select light, dark, or system palettes; Docs and example frames follow that selection. Local and routed previews can run on separate ports with independent dependency caches. Reload an open preview after restarting it on a different port.
|
|
224
|
+
|
|
225
|
+
`Carousel` supports horizontal, vertical, and right-to-left navigation. Focus its named region to use the arrow keys; arrow keys inside slide inputs retain their input behavior. Supply `opts` and `plugins` for carousel configuration, and `setApi` to receive its API. Reduced-motion preference disables programmatic slide animation.
|
|
226
|
+
|
|
227
|
+
Compose `ChartContainer`, `ChartTooltip`, and `ChartLegend` with Recharts components. Import the chart parts from `@alexgorbatchev/shadcn/chart` and install its peers listed above. Give the container a height or aspect ratio; `ChartConfig` supplies series labels, icons, and either one color or light/dark colors. Use semantic values such as `var(--primary)` and keep `accessibilityLayer` enabled for keyboard tooltips. Use `labelKey` and `nameKey` for custom tooltip data, and legend content's `nameKey` for custom legend labels. Keep series selection in application state; the tooltip's `defaultIndex` only sets its initial state.
|
|
228
|
+
|
|
229
|
+
Supply HTML attributes and refs to tooltip or legend content through `htmlProps`; Recharts injects its own chart props into those content components, so those props do not go to the DOM. An `onClick` legend callback renders keyboard-accessible buttons. Omit the tooltip's `portal` prop for native floating positioning; custom portal targets own their positioning through the native `wrapperStyle` API. Tooltip and legend content preserve chart density, direction and configured colors through portals. A container's `dir` overrides DirectionProvider context, and content's `htmlProps.dir` overrides the chart direction. Reverse Recharts' `XAxis` explicitly for RTL data ordering; native keyboard movement follows that axis. See the [Chart guide](https://ui.shadcn.com/docs/components/base/chart).
|
|
230
|
+
|
|
231
|
+
For notifications, mount `Sonner` (also exported as `Toaster` and `SonnerToaster`) inside `ThemeProvider` and call `toast.success("Saved")`. Use one host per document, or give hosts unique `id` values and target them with `toasterId`. `ToastToaster` provides the separate Base UI composition: call `useToastManager()` inside its provider, or create a manager with `createToastManager()` and pass it through `toastManager`. Both compositions provide actions, dismissal, promise feedback, and density overrides. The Base UI manager uses `{ title: "Uploading" }` for promise titles; a plain string sets the description.
|
|
232
|
+
|
|
233
|
+
Sonner inherits `DirectionProvider` and accepts an explicit `dir` override. Use `mobileOffset={{ left: 24, right: 40 }}` for independent mobile margins. To update a notification in place, retain the ID returned by `toast.loading()` and pass it as `id` to `toast.success()` or `toast.error()`. Sonner's `cancel` option accepts `{ label, onClick }` and dismisses the notification after the callback.
|
|
234
|
+
|
|
235
|
+
For Base UI notifications, retain the ID from `manager.add()` and call `manager.update(id, options)`; adding an existing ID updates that notification in place. `onClose` signals dismissal and `onRemove` signals removal after the exit transition. A provider's `limit` keeps older notifications mounted but inactive until space becomes available.
|
|
236
|
+
|
|
237
|
+
Set Sonner's `expand={false}` to show a collapsed stack that expands on hover. Older notification content stays hidden while collapsed; cards retain their width. Per-notification `onAutoClose` and `onDismiss` callbacks receive the notification, including its ID. Native timers pause while hovering the host. Use `toast.custom((id) => ...)` for custom content and `toast.dismiss(id)` from its action.
|
|
238
|
+
|
|
239
|
+
Import `Sonner`, `toast`, and `useSonner` together from `@alexgorbatchev/shadcn/sonner`. The package bundles a patched Sonner 2.0.8 implementation that remeasures open notifications after density changes, preserving their IDs and running timers. A separate direct import from `sonner` uses a different notification store.
|
|
240
|
+
|
|
241
|
+
`Bubble` provides seven visual variants, start/end alignment, grouped replies, and overlapping reactions. Compose interactive content with `BubbleContent render={<button type="button" />}` or a native anchor. Leave extra space between replies with reactions, such as `BubbleGroup className="gap-8"`; layout overrides replace the package's density spacing utilities. `Marker` presents conversation notes, statuses, bordered rows, and labeled dividers. Use `role="status"` for updates, and `render` for native links or buttons. Labeled dividers retain their text semantics; their lines are decorative. Icons in `MarkerIcon` are hidden from assistive technology. Separator labels wrap inside narrow columns; use `className="flex-col"` on Marker to stack its icon above the content.
|
|
242
|
+
|
|
243
|
+
For a Bubble tooltip or popover, keep `BubbleContent` outermost: `render={<TooltipTrigger render={<button type="button" />} />}` or the corresponding `PopoverTrigger`. This preserves the content slot used by Bubble variant styles. Base UI tooltips are visual only; give the trigger an accessible name containing the same information. Put essential error or delivery details in a popover or inline content. See the [native tooltip recommendations](https://base-ui.com/react/components/tooltip#recommendations). `MarkerContent shimmer` animates a pending status and restores static readable text under reduced motion.
|
|
244
|
+
|
|
245
|
+
Compose `MessageAvatar` and `MessageContent` inside `Message`; the content holds an optional `MessageHeader`, a Bubble or other surface, and an optional `MessageFooter`. Set `align="end"` for an outgoing reply. Headers stay at the content's start; surfaces and footers follow alignment. Avatar placement tracks the rendered footer height and spacing, including live density and content changes. `MessageGroup` stacks consecutive replies; an empty `MessageAvatar` reserves alignment space for earlier replies from the same sender.
|
|
246
|
+
|
|
247
|
+
`Attachment` displays file metadata and a caller-controlled state: `idle`, `uploading`, `processing`, `error`, or `done`. It provides three sizes, horizontal or vertical layout, and icon or image media. Uploading and processing titles shimmer; reduced-motion preference leaves static readable text. The exported theme includes the required shimmer and scroll-fade utilities. `AttachmentTrigger` fills the card with a native button or an element supplied through `render`, while `AttachmentAction` remains independently clickable. Give triggers and icon actions accessible labels and include the error reason in `AttachmentDescription`. `AttachmentGroup` provides a snapping scroll row; add `tabIndex={0}`, `role="group"`, and an accessible label when the items have no interactive controls.
|
|
248
|
+
|
|
249
|
+
Place `MessageScroller` inside `MessageScrollerProvider` and a container with a defined height. Wrap every regular transcript row in `MessageScrollerItem` with a stable `messageId`; set `scrollAnchor` for a new turn. The viewport is a named keyboard-scrollable region, and content is a live log for added rows. `defaultScrollPosition` opens at the start, end, or last anchor. Auto-scroll is opt-in; wheel scrolling, scroll keys and pointer interaction release following, and the reader can return with the scroll button. Older rows preserve the current reading position when prepended. The three exported hooks provide commands, available edges, and visible rows/current anchor. Scroll buttons become inert at their target edge and use instant scrolling under reduced-motion preference. Rows use normal layout because the registry's content-visibility optimization makes message jumps and history preservation unstable in the verified browser tests; this package does not claim the upstream optimization's long-transcript performance.
|
|
250
|
+
|
|
251
|
+
For virtualized history, use `MessageScrollerViewport` as the virtualizer's scroll element. Let the virtualizer own row measurement, positioning and indexed jumps; use block content with its total height instead of wrapping virtual rows in `MessageScrollerItem`. The Storybook `VirtualizedHistory` example uses TanStack Virtual with 1,000 rows and expandable content. The application supplies that optional dependency.
|
|
252
|
+
|
|
253
|
+
To animate a sent row, the `AnimatedNewTurn` example uses `motion.create(MessageScrollerItem)` from Motion, preserving its ref, stable `messageId` and `scrollAnchor`. Animate transform and opacity with a tween; keep the streamed reply in a regular row. Anchoring uses the row's layout position, so its entrance translation does not change the target. Disable the entrance when the reader prefers reduced motion. Motion is an optional application dependency; the component package does not import it.
|
|
254
|
+
|
|
255
|
+
Server-rendered transcripts opening at `end` or `last-anchor` remain hidden through `data-pending-scroll` until hydration applies their position; `start` remains visible. Keep the same transcript and opening position on the server and client. The [upstream guide](https://ui.shadcn.com/docs/components/base/message-scroller#avoiding-a-flash-on-reload) also describes an optional application-owned inline script for first-paint `end` positioning; that script is outside this package's verified hydration path.
|
|
256
|
+
|
|
257
|
+
Import the scroller parts and hooks together from `@alexgorbatchev/shadcn/message-scroller`. Its bundled native implementation preserves both caller root refs and the frame's scroll-state attributes; hooks imported directly from a separate `@shadcn/react/message-scroller` module use a different provider context. `scrollToMessage(id)` can queue a permalink before transcript rows mount; a true result means accepted or queued, rather than already visible. After rows mount, an unknown ID returns false. Anchors can mark system events as well as replies. The current-anchor hook retains the most recent anchor that has reached its tracking boundary, even after that row scrolls above the viewport.
|
|
258
|
+
|
|
259
|
+
Bun 1.4.0's CSS bundler lowers logical positioning to language-based selectors. A plain CSS reproduction confirms that `dir="rtl"` with inherited `lang="en"` positions a logical inline-end marker on the wrong side; production CSS contains the same lowering. This affects Bubble reactions and vertical line-tab markers. Direction changes independent of language remain a Bun consumer limitation. The Storybook/Vite build preserves native logical positioning. See [Bun's CSS lowering documentation](https://bun.com/docs/bundler/css#dir-selector).
|
|
260
|
+
|
|
261
|
+
Compose `QuestionnaireItem`, `QuestionnaireTitle`, and answer controls inside `Questionnaire`, which renders a native form. `QuestionnaireChoice` supplies native radios or, with `multiple`, checkboxes; label every `QuestionnaireInput`. Read answers with `FormData.get()` or `getAll()`. `QuestionnaireProgress` and the Previous, Skip, Next, and Submit parts follow the active item. Optional steps need an answer or an explicit skip; observe `onStatusChange` to distinguish skipped answers. Letter and number shortcuts select answers without advancing. Use `item`/`onItemChange` for controlled navigation and `invalid` for external validation. Draft defaults and native reset restore initial answers and navigation. These parts accept density overrides and native render/ref props where supported. See the [upstream composition guide](https://ui.shadcn.com/docs/components/base/questionnaire).
|
|
262
|
+
|
|
263
|
+
# Inline editing and ratings
|
|
264
|
+
|
|
265
|
+
`InlineEdit` mounts an edit session with a controlled `value`, `onValueChange`, `onCommit`, and `onCancel`. Mount it in place of the displayed label. Its input focuses and selects its text by default; `shouldSelectOnMount={false}` preserves the initial caret. Enter or blur commits once, Escape cancels without committing, and asynchronous saves disable the input until completion. Rejected saves display an error and allow retry.
|
|
266
|
+
|
|
267
|
+
`StarRating` takes a controlled numeric `value` from 0 to 5, `onValueChange`, and an accessible `label`. Its native radio buttons support keyboard selection and an Unrated option to clear the rating. Set `disabled` while saving. `Avatar shape="square"` displays square artwork with matching image, fallback, and border corners.
|
|
268
|
+
|
|
269
|
+
`DialogContent size="wide"` uses a desktop maximum width of 576px; `size="narrow"` uses 192px, and the default uses 384px. Dialogs remain bounded by the viewport. `FieldGroup columns={2}` arranges fields in two columns on desktop and one on mobile.
|
|
270
|
+
|
|
271
|
+
`ImagePicker` displays a 256px square preview with upload and unset buttons. Supply the existing `src`, a staged `file` (`undefined` for the existing image, `null` for removal), and `onFileChange`/`onClear` callbacks. It accepts PNG, JPEG, and GIF files and releases local preview URLs when they change or unmount. The consumer owns saving and removal confirmation.
|
|
272
|
+
|
|
273
|
+
`ConfirmationDialog` uses an alert dialog with Cancel and a destructive confirmation button. Supply `open`, `onOpenChange`, `title`, `description`, `confirmLabel`, and `onConfirm`. It waits for asynchronous work, keeps the dialog open on failure, and prevents cancellation while that work is pending.
|
|
274
|
+
|
|
275
|
+
# Split views
|
|
276
|
+
|
|
277
|
+
`SplitView` pairs a `sidebar` with its `children` in equally padded, borderless panels. Provide `sidebarLabel`, `contentLabel`, and `resizeLabel` for accessibility and a unique `storageKey` to remember the resized layout in localStorage. The desktop sidebar defaults to 325px (`defaultSidebarSize`), with a 200px minimum and a 50% maximum. Its 2px divider supports mouse, touch, and keyboard resizing. Below 1024px, the panels stack vertically while preserving the desktop preference. Storage failures leave the layout usable.
|
|
278
|
+
|
|
279
|
+
`ResizableHandle thickness="strong"` and `Separator thickness="strong"` use 2px dividers; their default thickness is 1px.
|
|
280
|
+
|
|
281
|
+
`TableHead` and `TableCell` accept `textAlign="start"`, `"center"`, or `"end"` to align labels and numeric columns consistently in either text direction.
|
|
282
|
+
|
|
283
|
+
# Drag and drop
|
|
284
|
+
|
|
285
|
+
Wrap draggable sources and drop targets in `DragDropProvider`. `DragSource` and `DropTarget` accept Base UI's `render` composition, so a button, table row, or sidebar item keeps its native element. For compositions that already manage rendering, use `useDragSource` and `useDropTarget` and spread their `props` onto the existing element.
|
|
286
|
+
|
|
287
|
+
```tsx
|
|
288
|
+
import { useState, type ReactElement } from "react";
|
|
289
|
+
import { Button, DragDropProvider, DragSource, DropTarget } from "@alexgorbatchev/shadcn";
|
|
290
|
+
|
|
291
|
+
export function MoveExample(): ReactElement {
|
|
292
|
+
const [result, setResult] = useState("Waiting");
|
|
293
|
+
return (
|
|
294
|
+
<DragDropProvider>
|
|
295
|
+
<DragSource
|
|
296
|
+
type="application/x-music"
|
|
297
|
+
data={{ title: "First light" }}
|
|
298
|
+
labels={["First light"]}
|
|
299
|
+
render={<Button />}
|
|
300
|
+
>
|
|
301
|
+
Drag track
|
|
302
|
+
</DragSource>
|
|
303
|
+
<DropTarget
|
|
304
|
+
accept={["application/x-music"]}
|
|
305
|
+
onDrop={(item) => setResult(JSON.stringify(item.data))}
|
|
306
|
+
render={<Button variant="outline" />}
|
|
307
|
+
>
|
|
308
|
+
Drop here
|
|
309
|
+
</DropTarget>
|
|
310
|
+
<Button onClick={() => setResult("Moved First light")}>Move without dragging</Button>
|
|
311
|
+
<output>{result}</output>
|
|
312
|
+
</DragDropProvider>
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Supply JSON-serializable `data` and display-only `labels`. Native drags preserve the custom MIME payload, plain-text labels, and keyboard modifiers. `canDrop` rejects unavailable destinations; `getDropEffect` chooses `move`, `copy`, or `link`. Drop callbacks receive the item and native drag event. Validate external payloads before applying application changes.
|
|
318
|
+
|
|
319
|
+
The preview shows compact individual badges, up to five labels followed by `+N more…`. Set `maxPreviewItems` on the provider to change the limit, or use `DragDropPreview` directly. `useDropTarget` exposes the hovered MIME `type`, `isOver`, `isAlt`, and `effect` for hints and highlighting. The provider clears drag state after drops and cancellation. Native drag gestures need an equivalent keyboard-accessible action, such as the move button above or a context-menu command.
|
|
320
|
+
|
|
321
|
+
`useDropTarget().feedback` retains the last accepted MIME type, Alt modifier, and drop effect after leaving or dropping. Use this snapshot for hint content that remains visible during an exit animation; use `isOver` to control visibility and active highlighting. New accepted drag events update feedback immediately, including modifier changes. The live `type`, `isAlt`, and `effect` fields still describe the current hover.
|
|
322
|
+
|
|
323
|
+
`EmptyState` composes a title, description, and optional child actions. `JsonViewer` displays a read-only formatted JSON value with configurable `label` and `rows`.
|
|
324
|
+
|
|
325
|
+
# Devhost Preview
|
|
326
|
+
|
|
327
|
+
The manifest uses `shadcn.example.com` as a documentation placeholder. Before using the routed preview, replace both `services.storybook.host` and `services.storybook.env.__VITE_ADDITIONAL_SERVER_ALLOWED_HOSTS` in `devhost.toml` with your locally configured hostname. Keep private hostnames out of commits.
|
|
328
|
+
|
|
329
|
+
From this repository, start the configured Storybook service:
|
|
330
|
+
|
|
331
|
+
```sh
|
|
332
|
+
devhost start
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Open your configured hostname over HTTPS. The manifest allocates a port automatically and serves Storybook through the shared devhost HTTPS proxy. The hostname must resolve to the machine running devhost, and the managed Caddy instance must be running (`devhost caddy start`).
|
|
336
|
+
|
|
337
|
+
Storybook binds to IPv4 loopback and allows the configured hostname in both Storybook and Vite. Caddy listens on all interfaces and serves HTTP as well as HTTPS, so the external devbox gateway can reach it. The direct `bun run storybook` preview remains available on `127.0.0.1:6006`.
|
|
338
|
+
|
|
339
|
+
# Troubleshooting
|
|
340
|
+
|
|
341
|
+
- **Components render without styling**: Check that your app imports the stylesheet, processes it with Tailwind v4, and registers the package's `dist` directory with `@source`. Adjust that path if your stylesheet lives somewhere other than `src/styles.css`.
|
|
342
|
+
- **A feature dependency cannot be resolved**: Install the peers listed for that feature under [Optional features](#optional-features). Importing a feature does not install its peers.
|
|
343
|
+
- **An export is missing from the package root**: Import feature components, hooks, and types from their dedicated entry point, such as `@alexgorbatchev/shadcn/chart` or `@alexgorbatchev/shadcn/resizable` for `SplitView`.
|
|
344
|
+
- **The custom font does not appear**: Install `@fontsource-variable/jetbrains-mono` and import `@alexgorbatchev/shadcn/fonts.css`, or override `--ag-font` with your app's font stack.
|
|
345
|
+
- **Theme controls throw a provider error**: Render components that call `useTheme()` inside the document's `ThemeProvider`.
|
|
346
|
+
- **Docs use an unexpected palette**: Select the desired Theme toolbar option. System uses the saved preview preference when one exists, otherwise the operating system preference. Reload an open preview after its server restarts on a different port.
|
|
347
|
+
|
|
348
|
+
# License
|
|
349
|
+
|
|
350
|
+
[MIT](./LICENSE). See [third-party notices](./THIRD_PARTY_NOTICES.md) for component and font attribution.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
Component sources are adapted from the official shadcn/ui `base-nova` registry (https://ui.shadcn.com/), retrieved on 2026-10-08. Local changes cover design tokens, density, module organization, scalar slider thumb handling, native aspect-ratio geometry, semantic prop types, preservation of Base UI state callbacks, native pagination links, drawer transitions without scale or bounce, the native Base UI navigation trigger icon, OTP placeholder presentation, cmdk selection styling, DayPicker's native root and day-button focus lifecycle, directional carousel keyboard navigation, reduced-motion behavior, framed notification surfaces without scale transitions, chart colors connected to the document theme, native chart payload formatting/sorting, and sharp conversation surfaces with native interactive rendering and logical reaction positioning.
|
|
4
|
+
|
|
5
|
+
The palette, radii, typography, and density metrics are derived from the devhost design references (Copyright (c) 2026 Alex Gorbatchev, MIT). They are copied into this package; there is no devhost runtime dependency.
|
|
6
|
+
|
|
7
|
+
Message and Attachment are adapted from the same official registry. Local changes preserve start-aligned message headers, measure footer geometry for avatar placement, preserve native attachment action callbacks, and keep vertical media full-width across sizes. MessageScroller uses the native `@shadcn/react` 0.3.1 provider, parts, and hooks; local presentation uses fade-only controls, reduced-motion scrolling, and normal row layout for stable message jumps/history preservation. The shimmer, horizontal and bottom scroll-fade, and scrollbar utilities in `src/theme.css` are adapted from the MIT-licensed `shadcn` 4.21.4 published `dist/tailwind.css`, retrieved on 2026-10-08 (https://unpkg.com/shadcn@4.21.4/dist/tailwind.css). They use semantic text colors and native direction selectors; the upstream legacy shimmer compatibility rule is excluded.
|
|
8
|
+
|
|
9
|
+
Marker separator content retains native flex shrinking so long labels wrap inside narrow conversation columns. Decorative icons and short separator labels retain their centered composition.
|
|
10
|
+
|
|
11
|
+
JetBrains Mono is supplied by `@fontsource-variable/jetbrains-mono` under OFL-1.1. The dependency includes its font license, and font files are served locally by the consuming app. Other runtime dependencies retain their own licenses in their installed packages.
|
|
12
|
+
|
|
13
|
+
Questionnaire adapts the official registry's fifteen styled parts around `@shadcn/react` 0.3.1 native form primitives. Local changes provide sharp controls, semantic colors, density-aware inputs/actions, distinct radio/checkbox indicators, and reduced-motion transitions. The native input reset implementation is patched to restore default text when an unselected freeform input is detached from its form. MessageScroller's native root composes caller refs with internal registration using the package's native ref helper. Its viewport routes pointer-down through the existing reader-interruption handler while preserving caller callbacks, allowing text selection to release live following. Its row position helpers use layout offsets, including offset-parent borders and intermediate scroll offsets, so transform entrances do not change anchoring or preservation coordinates. The package bundles these corrected implementations; React remains an external peer. The version-pinned patch is included under `patches/`, and the upstream MIT notice below covers the bundled source.
|
|
14
|
+
|
|
15
|
+
## shadcn/ui
|
|
16
|
+
|
|
17
|
+
Sidebar adapts the official provider and styled parts, preserving custom render/ref contracts, cookie writes, keyboard toggling, and native mobile Sheet behavior. Local changes support density, cancelled toggle events, observation without controlled state, inert offcanvas panels, configured mobile widths, and centered icons with accessible collapsed labels. Separator uses Base UI's current orientation attributes, and Tooltip preserves native state callbacks.
|
|
18
|
+
|
|
19
|
+
Field preserves the official form composition and filters empty error messages before rendering an alert. Popover preserves native className callbacks on its popup, title, and description. Storybook form, date picker, and data table examples follow the official composition guides; the data table uses TanStack Table v9's native API.
|
|
20
|
+
|
|
21
|
+
Calendar and PersianCalendar share the adapted shadcn presentation. PersianCalendar uses the maintained `@daypicker/persian` 10.0.2 native component, retaining its Solar Hijri arithmetic, locale labels, numerals and Gregorian Date selection values. Its native month formatter remains intact rather than applying the Gregorian Calendar formatter.
|
|
22
|
+
|
|
23
|
+
Carousel uses native Embla 8.6 behavior and events. Local presentation uses up/down icons for vertical controls in both text directions and preserves caller reduced-motion breakpoint options while disabling animation. The autoplay examples use `embla-carousel-autoplay` 8.6.0 with explicit start/stop controls; the plugin remains an optional consumer dependency.
|
|
24
|
+
|
|
25
|
+
Chart uses the MIT-licensed `cssesc` 3.0.0 runtime dependency for identifier escaping during both server and browser rendering. Its native Recharts composition permits shrinking inside grid tracks without replacing responsive measurement. Tooltip and legend portals retain the chart's direction and color-variable scope through context. Guide examples preserve native custom data keys, axis reversal, series selection, initial tooltip state and value-label rendering.
|
|
26
|
+
|
|
27
|
+
The optional `src/typeset.css` stylesheet adapts the official shadcn/typeset source at `apps/v4/app/(app)/(typeset)/typeset.css` in https://github.com/shadcn-ui/ui, retrieved on 2026-10-08. It retains native semantic HTML, container-relative sizing, low-specificity component-layer rules, logical spacing, responsive tables, and append-stable flow. Local changes use this package's font/density and semantic highlight tokens and guard Typeset root styles inside opted-out subtrees. The upstream MIT notice below covers this stylesheet.
|
|
28
|
+
|
|
29
|
+
Checkbox and Switch preserve native state-based className callbacks. Switch uses logical inline positioning for its thumb so both sizes stay within the track in RTL.
|
|
30
|
+
|
|
31
|
+
Table forwards explicit direction to its native table and overflow container, uses inline-start header alignment, and clears checkbox-cell padding at the inline end. Tabs uses logical leading/trailing icon padding, a one-pixel list inset and full-height triggers so compact icons remain inside their controls while preserving the native density height.
|
|
32
|
+
|
|
33
|
+
MIT License
|
|
34
|
+
|
|
35
|
+
Copyright (c) 2023 shadcn
|
|
36
|
+
|
|
37
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
38
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
39
|
+
in the Software without restriction, including without limitation the rights
|
|
40
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
41
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
42
|
+
furnished to do so, subject to the following conditions:
|
|
43
|
+
|
|
44
|
+
The above copyright notice and this permission notice shall be included in all
|
|
45
|
+
copies or substantial portions of the Software.
|
|
46
|
+
|
|
47
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
48
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
49
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
50
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
51
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
52
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
53
|
+
SOFTWARE.
|
|
54
|
+
|
|
55
|
+
## Sonner
|
|
56
|
+
|
|
57
|
+
The package bundles Sonner 2.0.8 from https://github.com/emilkowalski/sonner. The version-pinned patch in patches/sonner@2.0.8.patch measures notification height after each render, skips removed notifications, and preserves unchanged height state. This corrects density changes without remounting the native host or replacing its timers, callbacks, IDs or notification store. Both ESM and CommonJS implementations are patched.
|
|
58
|
+
|
|
59
|
+
MIT License
|
|
60
|
+
|
|
61
|
+
Copyright (c) 2023 Emil Kowalski
|
|
62
|
+
|
|
63
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
64
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
65
|
+
in the Software without restriction, including without limitation the rights
|
|
66
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
67
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
68
|
+
furnished to do so, subject to the following conditions:
|
|
69
|
+
|
|
70
|
+
The above copyright notice and this permission notice shall be included in all
|
|
71
|
+
copies or substantial portions of the Software.
|
|
72
|
+
|
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
74
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
75
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
76
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
77
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
78
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
79
|
+
SOFTWARE.
|
|
80
|
+
|
|
81
|
+
## Input OTP
|
|
82
|
+
|
|
83
|
+
The package bundles input-otp 1.5.0 from https://github.com/guilhermerodz/input-otp. The version-pinned patch in patches/input-otp@1.5.0.patch consumes defaultValue when initializing native internal state and excludes it from forwarded input props. Both ESM and CommonJS implementations preserve controlled value precedence and native input editing. React remains an external peer.
|
|
84
|
+
|
|
85
|
+
MIT License
|
|
86
|
+
|
|
87
|
+
Copyright (c) 2024 Guilherme Rodz
|
|
88
|
+
|
|
89
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
90
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
91
|
+
in the Software without restriction, including without limitation the rights
|
|
92
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
93
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
94
|
+
furnished to do so, subject to the following conditions:
|
|
95
|
+
|
|
96
|
+
The above copyright notice and this permission notice shall be included in all
|
|
97
|
+
copies or substantial portions of the Software.
|
|
98
|
+
|
|
99
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
100
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
101
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
102
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
103
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
104
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
105
|
+
SOFTWARE.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// src/hooks/useTheme.ts
|
|
2
|
+
import { useContext } from "react";
|
|
3
|
+
|
|
4
|
+
// src/theme/ThemeContext.ts
|
|
5
|
+
import { createContext } from "react";
|
|
6
|
+
var ThemeContext = createContext(null);
|
|
7
|
+
|
|
8
|
+
// src/hooks/useTheme.ts
|
|
9
|
+
function useTheme2() {
|
|
10
|
+
const context = useContext(ThemeContext);
|
|
11
|
+
if (!context)
|
|
12
|
+
throw new Error("useTheme must be used within ThemeProvider.");
|
|
13
|
+
return context;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { ThemeContext, useTheme2 };
|