@anvilkit/puck-studio 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +195 -176
- package/dist/index.cjs +945 -803
- package/dist/index.d.cts +110 -46
- package/dist/index.d.ts +110 -46
- package/dist/index.js +928 -789
- package/dist/legacy.cjs +54 -0
- package/dist/legacy.js +52 -0
- package/dist/overrides.cjs +2090 -0
- package/dist/overrides.d.cts +212 -0
- package/dist/overrides.d.ts +212 -0
- package/dist/overrides.js +2057 -0
- package/dist/styles.css +88 -0
- package/package.json +109 -65
package/README.md
CHANGED
|
@@ -1,267 +1,286 @@
|
|
|
1
1
|
# @anvilkit/puck-studio
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@anvilkit/puck-studio)
|
|
4
|
-
[](
|
|
4
|
+
[](https://www.npmjs.com/package/@anvilkit/puck-studio)
|
|
5
5
|
[](https://react.dev)
|
|
6
6
|
[](https://puckeditor.com)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Opinionated Puck editor chrome and override pack built with React 19, `@base-ui/react`, and Tailwind v4.
|
|
9
9
|
|
|
10
|
-
>
|
|
10
|
+
> Chinese reference: [docs/README.zh.md](./docs/README.zh.md). This README is the canonical, up-to-date guide for the current implementation.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
## What This Package Gives You
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
- `Studio`: a desktop editor shell around `<Puck />` with a custom header, left sidebar, preview area, and fields panel
|
|
15
|
+
- `puckOverrides`: a packaged set of Puck overrides for drawer, outline, preview, canvas, and fields surfaces
|
|
16
|
+
- Image and copy libraries with ghost-drag into the canvas
|
|
17
|
+
- Per-instance persisted UI state via `storeId`
|
|
18
|
+
- Persisted locale state plus message overrides
|
|
19
|
+
- Light/dark theme sync between the host document and the Puck iframe
|
|
20
|
+
- Optional AI copilot panel when `aiHost` is provided
|
|
21
|
+
- Exported CSS tokens in `@anvilkit/puck-studio/styles.css`
|
|
15
22
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
`@anvilkit/puck-studio` solves this with a single drop-in `overrides` object built on Shadcn UI, @base-ui/react primitives, and Tailwind v4. All 15 override surfaces are covered. Components are **bundled** into the package — you do not run a Shadcn CLI to copy them.
|
|
19
|
-
|
|
20
|
-
**Key value props:**
|
|
21
|
-
|
|
22
|
-
- All 15 Puck override surfaces implemented
|
|
23
|
-
- TypeScript-first with full type inference
|
|
24
|
-
- Ships ESM + CJS + `.d.ts`
|
|
25
|
-
- No Next.js at runtime — `next` is demo-only
|
|
26
|
-
- @base-ui/react and lucide-react are bundled, not peer deps
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
## Architecture
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
┌─────────────────────────────────────────────────────────────────────┐
|
|
34
|
-
│ <Studio /> │
|
|
35
|
-
│ props: config, data, onPublish, images?, copywritings?, aiHost? │
|
|
36
|
-
│ │
|
|
37
|
-
│ ┌──────────────────────────────────────────────────────────────┐ │
|
|
38
|
-
│ │ <Puck overrides={mergedOverrides} plugins={[aiPlugin]}> │ │
|
|
39
|
-
│ │ │ │
|
|
40
|
-
│ │ ┌────────────────────────────────────────────────────────┐ │ │
|
|
41
|
-
│ │ │ <EditorLayout /> │ │ │
|
|
42
|
-
│ │ │ │ │ │
|
|
43
|
-
│ │ │ ┌──────────────────────────────────────────────────┐ │ │ │
|
|
44
|
-
│ │ │ │ <Header /> │ │ │ │
|
|
45
|
-
│ │ │ │ back · title · undo/redo · collab · publish │ │ │ │
|
|
46
|
-
│ │ │ └──────────────────────────────────────────────────┘ │ │ │
|
|
47
|
-
│ │ │ │ │ │
|
|
48
|
-
│ │ │ ┌──────┐ ┌────────────────┐ ┌────────┐ ┌───────┐ │ │ │
|
|
49
|
-
│ │ │ │Aside │ │ Dynamic Panel │ │ Canvas │ │Fields │ │ │ │
|
|
50
|
-
│ │ │ │ │ │ │ │ │ │ │ │ │ │
|
|
51
|
-
│ │ │ │insert│ │ insert → │ │ Puck. │ │ Puck. │ │ │ │
|
|
52
|
-
│ │ │ │layer │ │ Puck.Comps │ │Preview │ │Fields │ │ │ │
|
|
53
|
-
│ │ │ │image │ │ layer → │ │ │ │ │ │ │ │
|
|
54
|
-
│ │ │ │text │ │ Puck.Outline │ │ │ │ │ │ │ │
|
|
55
|
-
│ │ │ │copil.│ │ image → │ │ │ │ │ │ │ │
|
|
56
|
-
│ │ │ │ │ │ ImageLibrary │ │ │ │ │ │ │ │
|
|
57
|
-
│ │ │ │ │ │ text → │ │ │ │ │ │ │ │
|
|
58
|
-
│ │ │ │ │ │ CopyLibrary │ │ │ │ │ │ │ │
|
|
59
|
-
│ │ │ │ │ │ copilot→ │ │ │ │ │ │ │ │
|
|
60
|
-
│ │ │ │ │ │ aiPanel │ │ │ │ │ │ │ │
|
|
61
|
-
│ │ │ └──────┘ └────────────────┘ └────────┘ └───────┘ │ │ │
|
|
62
|
-
│ │ └────────────────────────────────────────────────────────┘ │ │
|
|
63
|
-
│ └──────────────────────────────────────────────────────────────┘ │
|
|
64
|
-
└─────────────────────────────────────────────────────────────────────┘
|
|
65
|
-
|
|
66
|
-
Puck Override Surfaces (15 total)
|
|
67
|
-
──────────────────────────────────
|
|
68
|
-
Layout: header · headerActions · drawer · components · outline
|
|
69
|
-
Canvas: iframe · preview · componentOverlay · actionBar · drawerItem · componentItem
|
|
70
|
-
Fields: fields · fieldLabel · fieldTypes (11 renderers) · puck
|
|
71
|
-
|
|
72
|
-
Custom drag-drop events (window):
|
|
73
|
-
anvilkit:librarydragstart → fired on pointer-down in either library
|
|
74
|
-
anvilkit:imagedrop → fired on pointer-up with { src, clientX, clientY }
|
|
75
|
-
anvilkit:textdrop → fired on pointer-up with { text, clientX, clientY }
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## Installation
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
pnpm add @anvilkit/puck-studio
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
> `next` is a devDependency used only for the local demo app. It is not included in the published bundle.
|
|
87
|
-
|
|
88
|
-
The package ships both ESM and CJS builds. No additional bundler configuration is required.
|
|
89
|
-
|
|
90
|
-
---
|
|
91
|
-
|
|
92
|
-
## Peer Dependencies
|
|
23
|
+
## Requirements
|
|
93
24
|
|
|
94
25
|
| Package | Version |
|
|
95
26
|
|---|---|
|
|
96
|
-
| `react` |
|
|
97
|
-
| `react-dom` |
|
|
27
|
+
| `react` | `^19.2.4` |
|
|
28
|
+
| `react-dom` | `^19.2.4` |
|
|
98
29
|
| `@puckeditor/core` | `^0.21.1` |
|
|
99
30
|
| `@base-ui/react` | `^1.2.0` |
|
|
100
|
-
| `tailwindcss` | `^4` |
|
|
101
|
-
|
|
102
|
-
> `lucide-react`, `@dnd-kit/*`, `motion`, and `zustand` are **bundled** — do not install them separately.
|
|
31
|
+
| `tailwindcss` | `^4.2.1` |
|
|
103
32
|
|
|
104
|
-
|
|
33
|
+
`next` is used only by the local demo app in [`app/`](./app) and is not imported from the publishable library code in [`src/`](./src).
|
|
105
34
|
|
|
106
|
-
|
|
35
|
+
Tailwind note:
|
|
36
|
+
This package exports design tokens and class names, not a standalone compiled utility bundle. Your app still needs Tailwind v4 configured. If your Tailwind setup does not scan dependency code automatically, include this package in the sources Tailwind reads.
|
|
107
37
|
|
|
108
|
-
|
|
38
|
+
## Installation
|
|
109
39
|
|
|
110
|
-
```
|
|
111
|
-
|
|
40
|
+
```bash
|
|
41
|
+
pnpm add @anvilkit/puck-studio
|
|
112
42
|
```
|
|
113
43
|
|
|
114
|
-
|
|
44
|
+
The package publishes:
|
|
115
45
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
46
|
+
- root exports from `@anvilkit/puck-studio`
|
|
47
|
+
- overrides-only exports from `@anvilkit/puck-studio/overrides`
|
|
48
|
+
- deprecated compatibility exports from `@anvilkit/puck-studio/legacy`
|
|
49
|
+
- design tokens from `@anvilkit/puck-studio/styles.css`
|
|
119
50
|
|
|
120
|
-
|
|
121
|
-
return (
|
|
122
|
-
<Puck
|
|
123
|
-
config={config}
|
|
124
|
-
data={data}
|
|
125
|
-
onPublish={onPublish}
|
|
126
|
-
overrides={puckOverrides}
|
|
127
|
-
/>
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
```
|
|
51
|
+
## Recommended Usage: `Studio`
|
|
131
52
|
|
|
132
|
-
|
|
53
|
+
`Studio` is the higher-level entry point. It mounts `Puck`, injects Puck base CSS, creates the UI and i18n stores, merges the default overrides, and renders the custom shell.
|
|
133
54
|
|
|
134
55
|
```tsx
|
|
56
|
+
import "@anvilkit/puck-studio/styles.css";
|
|
135
57
|
import { Studio } from "@anvilkit/puck-studio";
|
|
136
58
|
|
|
137
|
-
export
|
|
59
|
+
export function Editor({ config, data, setData, save }) {
|
|
138
60
|
return (
|
|
139
61
|
<Studio
|
|
140
62
|
config={config}
|
|
141
63
|
data={data}
|
|
142
|
-
|
|
64
|
+
onChange={setData}
|
|
65
|
+
onPublish={save}
|
|
66
|
+
className="h-screen"
|
|
67
|
+
storeId="marketing-home"
|
|
143
68
|
/>
|
|
144
69
|
);
|
|
145
70
|
}
|
|
146
71
|
```
|
|
147
72
|
|
|
148
|
-
`Studio`
|
|
73
|
+
### `Studio` Props That Matter Most
|
|
149
74
|
|
|
150
|
-
|
|
75
|
+
| Prop | What it does |
|
|
76
|
+
|---|---|
|
|
77
|
+
| `config`, `data`, `onPublish` | Standard Puck inputs |
|
|
78
|
+
| `onChange` | Optional Puck `onChange` passthrough |
|
|
79
|
+
| `overrideExtensions` | Merged last, so your overrides win over the packaged defaults |
|
|
80
|
+
| `images` | Seeds or fixed items for the image library |
|
|
81
|
+
| `copywritings` | Fixed snippets for the copy library |
|
|
82
|
+
| `aiHost` | Lazily loads `@puckeditor/plugin-ai` and renders its panel in the copilot tab |
|
|
83
|
+
| `storeId` | Namespaces persisted UI state under `anvilkit-ui-${storeId}` |
|
|
84
|
+
| `locale` | Current locale string; defaults to `"zh"` |
|
|
85
|
+
| `messages` | Plain key/value message map used by the shell |
|
|
86
|
+
| `className` | Applied to the outer wrapper around `Puck` |
|
|
87
|
+
|
|
88
|
+
Merge order for overrides is:
|
|
151
89
|
|
|
152
|
-
|
|
90
|
+
```ts
|
|
91
|
+
{ ...(aiPlugin?.overrides ?? {}), ...puckOverrides, ...overrideExtensions }
|
|
92
|
+
```
|
|
153
93
|
|
|
154
|
-
|
|
94
|
+
That means consumer overrides take precedence.
|
|
95
|
+
|
|
96
|
+
## Library Customization
|
|
155
97
|
|
|
156
98
|
### Image Library
|
|
157
99
|
|
|
158
100
|
```tsx
|
|
159
|
-
import type {
|
|
101
|
+
import type { ImageItem } from "@anvilkit/puck-studio";
|
|
102
|
+
|
|
103
|
+
const brandImages: ImageItem[] = [
|
|
104
|
+
{ id: "hero-1", src: "https://cdn.example.com/hero.jpg", alt: "Hero" },
|
|
105
|
+
{ id: "logo-1", src: "https://cdn.example.com/logo.png", alt: "Logo" },
|
|
106
|
+
];
|
|
160
107
|
|
|
161
|
-
// Option A — replace the default picsum seed list
|
|
162
108
|
<Studio
|
|
163
109
|
config={config}
|
|
164
110
|
data={data}
|
|
165
111
|
onPublish={save}
|
|
166
|
-
images={{
|
|
112
|
+
images={{ items: brandImages }}
|
|
167
113
|
/>
|
|
114
|
+
```
|
|
168
115
|
|
|
169
|
-
|
|
170
|
-
const myImages: ImageItem[] = [
|
|
171
|
-
{ id: "hero-1", src: "https://cdn.example.com/hero.jpg", alt: "Hero" },
|
|
172
|
-
{ id: "logo-1", src: "https://cdn.example.com/logo.png", alt: "Logo" },
|
|
173
|
-
];
|
|
116
|
+
If you only want placeholder images, provide `seeds` instead of `items`:
|
|
174
117
|
|
|
118
|
+
```tsx
|
|
175
119
|
<Studio
|
|
176
120
|
config={config}
|
|
177
121
|
data={data}
|
|
178
122
|
onPublish={save}
|
|
179
|
-
images={{
|
|
123
|
+
images={{ seeds: ["brand", "product", "team", "office"] }}
|
|
180
124
|
/>
|
|
181
125
|
```
|
|
182
126
|
|
|
183
|
-
When `items` is provided the search input is hidden (external data is static). When only `seeds` is provided, search still generates picsum results from the query string.
|
|
184
|
-
|
|
185
127
|
### Copy Library
|
|
186
128
|
|
|
187
129
|
```tsx
|
|
188
|
-
import type {
|
|
130
|
+
import type { CopywritingItem } from "@anvilkit/puck-studio";
|
|
189
131
|
|
|
190
|
-
const
|
|
191
|
-
{ category: "Headlines", label: "
|
|
192
|
-
{ category: "CTAs",
|
|
132
|
+
const snippets: CopywritingItem[] = [
|
|
133
|
+
{ category: "Headlines", label: "Promise", text: "Built for builders." },
|
|
134
|
+
{ category: "CTAs", label: "Primary", text: "Start for free" },
|
|
193
135
|
];
|
|
194
136
|
|
|
195
137
|
<Studio
|
|
196
138
|
config={config}
|
|
197
139
|
data={data}
|
|
198
140
|
onPublish={save}
|
|
199
|
-
copywritings={{ items:
|
|
141
|
+
copywritings={{ items: snippets }}
|
|
142
|
+
/>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
If you omit `copywritings`, the built-in snippet library is used.
|
|
146
|
+
|
|
147
|
+
## Localization
|
|
148
|
+
|
|
149
|
+
`Studio` defaults to Chinese UI messages because [`defaultMessages`](./src/store/i18n-defaults.ts) re-exports the Chinese catalog.
|
|
150
|
+
|
|
151
|
+
You can switch locale and provide your own message map:
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
<Studio
|
|
155
|
+
config={config}
|
|
156
|
+
data={data}
|
|
157
|
+
onPublish={save}
|
|
158
|
+
locale="en"
|
|
159
|
+
messages={{
|
|
160
|
+
"header.publish": "Publish",
|
|
161
|
+
"header.undo": "Undo",
|
|
162
|
+
"header.redo": "Redo",
|
|
163
|
+
}}
|
|
200
164
|
/>
|
|
201
165
|
```
|
|
202
166
|
|
|
203
|
-
|
|
167
|
+
Any missing message falls back to its key string at runtime.
|
|
204
168
|
|
|
205
|
-
|
|
169
|
+
## Using the Raw Overrides
|
|
206
170
|
|
|
207
|
-
|
|
171
|
+
Use `puckOverrides` when you want the styled Puck surfaces without the full `Studio` shell.
|
|
208
172
|
|
|
209
|
-
|
|
173
|
+
```tsx
|
|
174
|
+
import "@puckeditor/core/puck.css";
|
|
175
|
+
import "@anvilkit/puck-studio/styles.css";
|
|
210
176
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
| `header` | `EditorHeader` | Top toolbar shell |
|
|
214
|
-
| `headerActions` | `EditorHeader` | Action buttons injected into header; **must render `children`** |
|
|
215
|
-
| `drawer` | `EditorDrawer` | Left panel component list container |
|
|
216
|
-
| `components` | `EditorDrawer` | Component group list inside drawer |
|
|
217
|
-
| `outline` | `EditorOutline` | Layer tree / page outline panel |
|
|
177
|
+
import { Puck } from "@puckeditor/core";
|
|
178
|
+
import { puckOverrides } from "@anvilkit/puck-studio";
|
|
218
179
|
|
|
219
|
-
|
|
180
|
+
export function Editor({ config, data, onPublish }) {
|
|
181
|
+
return (
|
|
182
|
+
<Puck
|
|
183
|
+
config={config}
|
|
184
|
+
data={data}
|
|
185
|
+
onPublish={onPublish}
|
|
186
|
+
overrides={puckOverrides}
|
|
187
|
+
/>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
```
|
|
220
191
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
192
|
+
The packaged override object currently wires these Puck keys:
|
|
193
|
+
|
|
194
|
+
- `drawer`
|
|
195
|
+
- `components`
|
|
196
|
+
- `drawerItem`
|
|
197
|
+
- `componentItem`
|
|
198
|
+
- `outline`
|
|
199
|
+
- `iframe`
|
|
200
|
+
- `preview`
|
|
201
|
+
- `componentOverlay`
|
|
202
|
+
- `actionBar`
|
|
203
|
+
- `fields`
|
|
204
|
+
- `fieldTypes`
|
|
205
|
+
- `puck`
|
|
206
|
+
|
|
207
|
+
`Studio` adds the surrounding header, sidebar, image library, copy library, and fields layout on top of that.
|
|
208
|
+
|
|
209
|
+
## Architecture At A Glance
|
|
210
|
+
|
|
211
|
+
```text
|
|
212
|
+
Studio
|
|
213
|
+
-> EditorUiStoreProvider
|
|
214
|
+
-> EditorI18nStoreProvider
|
|
215
|
+
-> Puck
|
|
216
|
+
-> merged overrides
|
|
217
|
+
-> optional AI plugin
|
|
218
|
+
-> EditorLayout
|
|
219
|
+
-> Header
|
|
220
|
+
-> Aside
|
|
221
|
+
-> Puck.Components / Puck.Outline / ImageLibrary / CopyLibrary / aiPanel
|
|
222
|
+
-> Puck.Preview
|
|
223
|
+
-> Puck.Fields
|
|
224
|
+
```
|
|
229
225
|
|
|
230
|
-
|
|
226
|
+
The drag-drop libraries communicate with the canvas through typed `window` events defined in [`src/features/library-dnd/drop-contract.ts`](./src/features/library-dnd/drop-contract.ts). The iframe bridge listens for those events, hit-tests the hovered component, and dispatches Puck `replace` actions with updated props.
|
|
231
227
|
|
|
232
|
-
|
|
233
|
-
|---|---|---|
|
|
234
|
-
| `fields` | `FieldWrapper` | Props panel field list wrapper |
|
|
235
|
-
| `fieldLabel` | `FieldWrapper` | Individual field label + tooltip |
|
|
236
|
-
| `fieldTypes` | `FieldTypesRegistry` | Map of all 11 field type renderers |
|
|
237
|
-
| `puck` | `EditorHeader` | Puck logo / menu slot in header |
|
|
228
|
+
## Public API Summary
|
|
238
229
|
|
|
239
|
-
|
|
230
|
+
### Runtime exports
|
|
240
231
|
|
|
241
|
-
|
|
232
|
+
- `Studio`
|
|
233
|
+
- `puckOverrides`
|
|
234
|
+
- `createEditorUiStore`
|
|
235
|
+
- `createEditorI18nStore`
|
|
236
|
+
- `EditorUiStoreProvider`
|
|
237
|
+
- `EditorI18nStoreProvider`
|
|
238
|
+
- `useEditorUiStoreApi`
|
|
239
|
+
- `useEditorI18nStoreApi`
|
|
240
|
+
- `defaultMessages`
|
|
242
241
|
|
|
243
|
-
|
|
242
|
+
### Public types
|
|
244
243
|
|
|
245
|
-
|
|
244
|
+
- `StudioProps`
|
|
245
|
+
- `ImagesProps`
|
|
246
|
+
- `ImageItem`
|
|
247
|
+
- `CopywritingProps`
|
|
248
|
+
- `CopywritingItem`
|
|
249
|
+
- `EditorUiStore`
|
|
250
|
+
- `EditorUiStoreApi`
|
|
251
|
+
- `ActiveTab`
|
|
252
|
+
- `EditorI18nStoreApi`
|
|
253
|
+
- `Locale`
|
|
254
|
+
- `Messages`
|
|
246
255
|
|
|
247
|
-
|
|
248
|
-
pnpm install # install all dependencies
|
|
249
|
-
pnpm dev # start Next.js demo app
|
|
250
|
-
pnpm build # run tsup → dist/
|
|
251
|
-
```
|
|
256
|
+
### Deprecated compatibility exports
|
|
252
257
|
|
|
253
|
-
|
|
258
|
+
`@anvilkit/puck-studio/legacy` exists only for the deprecated singleton `uiStore` and `UIStore` type alias.
|
|
254
259
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
+
## Current Scope
|
|
261
|
+
|
|
262
|
+
- `Studio` is desktop-first today; [`EditorLayout`](./src/core/studio/layout/Layout.tsx) is hidden on very small screens
|
|
263
|
+
- The image and copy libraries are local editor tooling, not asset management backends
|
|
264
|
+
- The share and collaborators popovers in the header are presentational shell UI, not real-time collaboration features
|
|
265
|
+
- If you need fully custom publish, share, or shell-level workflows, build on `puckOverrides` directly or fork `Studio`
|
|
266
|
+
|
|
267
|
+
## Development
|
|
260
268
|
|
|
261
|
-
|
|
269
|
+
```bash
|
|
270
|
+
pnpm install
|
|
271
|
+
pnpm dev
|
|
272
|
+
pnpm lint
|
|
273
|
+
pnpm test
|
|
274
|
+
pnpm test:types
|
|
275
|
+
pnpm build
|
|
276
|
+
```
|
|
262
277
|
|
|
263
|
-
|
|
278
|
+
Useful directories:
|
|
264
279
|
|
|
265
|
-
|
|
280
|
+
- [`src/core/studio`](./src/core/studio): `Studio` and the shell layout
|
|
281
|
+
- [`src/core/overrides`](./src/core/overrides): packaged Puck overrides
|
|
282
|
+
- [`src/features/library-dnd`](./src/features/library-dnd): drag/drop protocol and prop replacement helpers
|
|
283
|
+
- [`src/store`](./src/store): UI and i18n stores, providers, hooks
|
|
284
|
+
- [`app`](./app): local Next.js demo only
|
|
266
285
|
|
|
267
|
-
|
|
286
|
+
Build output is generated in [`dist/`](./dist) as ESM `.js`, CJS `.cjs`, CSS, and type declaration files.
|