@janbox/storefront-builder 1.0.4 → 1.0.5

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.
Files changed (69) hide show
  1. package/README.md +477 -0
  2. package/dist/editor/ui/dialog/dialog/helpers.d.ts +1 -1
  3. package/dist/editor/ui/dialog/dialog-close/dialog-close.d.ts +1 -1
  4. package/dist/editor.js +2 -2
  5. package/dist/{index-CBDllFpx.js → index-DrJkOkbq.js} +13 -13
  6. package/dist/index.js +2 -2
  7. package/dist/lib/accordion/README.md +39 -0
  8. package/dist/lib/accordion-content/README.md +36 -0
  9. package/dist/lib/accordion-group/README.md +106 -0
  10. package/dist/lib/accordion-summary/README.md +37 -0
  11. package/dist/lib/box/README.md +107 -0
  12. package/dist/lib/button/README.md +94 -0
  13. package/dist/lib/cell/README.md +119 -0
  14. package/dist/lib/countdown-timer/README.md +157 -0
  15. package/dist/lib/flex-item/README.md +111 -0
  16. package/dist/lib/flexbox/README.md +120 -0
  17. package/dist/lib/grid/README.md +133 -0
  18. package/dist/lib/heading/README.md +53 -0
  19. package/dist/lib/icon/README.md +98 -0
  20. package/dist/lib/image/README.md +107 -0
  21. package/dist/lib/link/README.md +111 -0
  22. package/dist/lib/list-item/README.md +31 -0
  23. package/dist/lib/marquee/README.md +111 -0
  24. package/dist/lib/marquee-item/README.md +31 -0
  25. package/dist/lib/paragraph/README.md +82 -0
  26. package/dist/lib/root/README.md +33 -0
  27. package/dist/lib/swiper/README.md +108 -0
  28. package/dist/lib/swiper-slide/README.md +32 -0
  29. package/dist/lib/tab/README.md +35 -0
  30. package/dist/lib/tab-content/README.md +35 -0
  31. package/dist/lib/tab-list/README.md +35 -0
  32. package/dist/lib/tab-panel/README.md +35 -0
  33. package/dist/lib/tabs/README.md +90 -0
  34. package/dist/lib/text/README.md +90 -0
  35. package/dist/lib/unknown/README.md +48 -0
  36. package/dist/lib/unordered-list/README.md +82 -0
  37. package/dist/lib/video/README.md +91 -0
  38. package/lib/accordion/README.md +39 -0
  39. package/lib/accordion-content/README.md +36 -0
  40. package/lib/accordion-group/README.md +106 -0
  41. package/lib/accordion-summary/README.md +37 -0
  42. package/lib/box/README.md +107 -0
  43. package/lib/button/README.md +94 -0
  44. package/lib/cell/README.md +119 -0
  45. package/lib/countdown-timer/README.md +157 -0
  46. package/lib/flex-item/README.md +111 -0
  47. package/lib/flexbox/README.md +120 -0
  48. package/lib/grid/README.md +133 -0
  49. package/lib/heading/README.md +53 -0
  50. package/lib/icon/README.md +98 -0
  51. package/lib/image/README.md +107 -0
  52. package/lib/link/README.md +111 -0
  53. package/lib/list-item/README.md +31 -0
  54. package/lib/marquee/README.md +111 -0
  55. package/lib/marquee-item/README.md +31 -0
  56. package/lib/paragraph/README.md +82 -0
  57. package/lib/root/README.md +33 -0
  58. package/lib/swiper/README.md +108 -0
  59. package/lib/swiper-slide/README.md +32 -0
  60. package/lib/tab/README.md +35 -0
  61. package/lib/tab-content/README.md +35 -0
  62. package/lib/tab-list/README.md +35 -0
  63. package/lib/tab-panel/README.md +35 -0
  64. package/lib/tabs/README.md +90 -0
  65. package/lib/text/README.md +90 -0
  66. package/lib/unknown/README.md +48 -0
  67. package/lib/unordered-list/README.md +82 -0
  68. package/lib/video/README.md +91 -0
  69. package/package.json +5 -9
package/README.md ADDED
@@ -0,0 +1,477 @@
1
+ # @janbox/storefront-builder
2
+
3
+ A standalone visual page builder library built on [CraftJS](https://craft.js.org/). Provides drag-and-drop storefront creation with a full editor UI, 33 pre-built node components, and responsive design support.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @janbox/storefront-builder
9
+ # or
10
+ pnpm add @janbox/storefront-builder
11
+ ```
12
+
13
+ ### Peer dependencies
14
+
15
+ ```bash
16
+ npm install react@^19 react-dom@^19 @janbox/storefront-ui@>=2
17
+ ```
18
+
19
+ ## Package Exports
20
+
21
+ | Import path | Contents |
22
+ | --- | --- |
23
+ | `@janbox/storefront-builder` | Node components (all 33 nodes) |
24
+ | `@janbox/storefront-builder/editor` | Full editor UI (`Editor` component + toolbars) |
25
+ | `@janbox/storefront-builder/templates` | Pre-built element groups and section templates |
26
+ | `@janbox/storefront-builder/style.css` | Required CSS bundle |
27
+
28
+ ---
29
+
30
+ ## Quick Start — Full Editor
31
+
32
+ The `Editor` component from `/editor` renders the complete visual builder UI (header toolbar, sidebar with component library, drag-and-drop canvas).
33
+
34
+ ```tsx
35
+ import '@janbox/storefront-builder/style.css';
36
+ import { Editor } from '@janbox/storefront-builder/editor';
37
+ import {
38
+ LAYOUT_ELEMENT_GROUP,
39
+ TEXT_ELEMENT_GROUP,
40
+ MEDIA_ELEMENT_GROUP,
41
+ INTERACTIVE_ELEMENT_GROUP,
42
+ HERO_SECTION_GROUP,
43
+ } from '@janbox/storefront-builder/templates';
44
+ import type { Theme } from '@janbox/storefront-ui/theme';
45
+
46
+ const myTheme: Theme = {
47
+ palette: {
48
+ primary: {
49
+ 500: '#fa8c16',
50
+ 600: '#d46b08',
51
+ },
52
+ // ... full theme
53
+ },
54
+ typography: {
55
+ base: { fontSize: '1rem', lineHeight: '1.5rem' },
56
+ // ...
57
+ },
58
+ };
59
+
60
+ export default function BuilderPage() {
61
+ return (
62
+ <Editor
63
+ theme={myTheme}
64
+ insert={{
65
+ elements: [LAYOUT_ELEMENT_GROUP, TEXT_ELEMENT_GROUP, MEDIA_ELEMENT_GROUP, INTERACTIVE_ELEMENT_GROUP],
66
+ sections: [HERO_SECTION_GROUP],
67
+ }}
68
+ />
69
+ );
70
+ }
71
+ ```
72
+
73
+ `Editor` occupies the full viewport (`100vw × 100vh`). It should be the root of a dedicated page/route.
74
+
75
+ ---
76
+
77
+ ## Quick Start — Render Only (No Editor UI)
78
+
79
+ Use `Composer` + `Canvas` to render a saved page without the editor chrome. This is for the storefront-facing page.
80
+
81
+ ```tsx
82
+ import '@janbox/storefront-builder/style.css';
83
+ import { Composer, Canvas } from '@janbox/storefront-builder';
84
+ import { RootNode } from '@janbox/storefront-builder';
85
+ import type { SerializedNodes } from '@janbox/storefront-builder';
86
+
87
+ const savedData: SerializedNodes = { /* JSON from editor */ };
88
+
89
+ export default function StorefrontPage() {
90
+ return (
91
+ <Composer>
92
+ <Canvas data={savedData}>
93
+ <RootNode />
94
+ </Canvas>
95
+ </Composer>
96
+ );
97
+ }
98
+ ```
99
+
100
+ ---
101
+
102
+ ## Core Concepts
103
+
104
+ ### Nodes
105
+
106
+ Every element on the canvas is a **node** — a React component registered with CraftJS. The library ships 33 built-in nodes:
107
+
108
+ | Category | Nodes |
109
+ | --- | --- |
110
+ | Layout | `RootNode`, `Box`, `Flexbox`, `FlexItem`, `Grid`, `Cell` |
111
+ | Typography | `Text`, `Paragraph`, `Heading` |
112
+ | Media | `Image`, `Video`, `Icon` |
113
+ | Navigation | `Link`, `Button` |
114
+ | Lists | `UnorderedList`, `ListItem` |
115
+ | Tabs | `Tabs`, `TabList`, `Tab`, `TabContent`, `TabPanel` |
116
+ | Accordion | `Accordion`, `AccordionGroup`, `AccordionSummary`, `AccordionContent` |
117
+ | Carousel | `Swiper`, `SwiperSlide` |
118
+ | Marquee | `Marquee`, `MarqueeItem` |
119
+ | Utilities | `CountdownTimer` |
120
+ | Internal | `UnknownNode` (fallback for unresolved nodes) |
121
+
122
+ All nodes are exported from `@janbox/storefront-builder`.
123
+
124
+ ### Responsive Props
125
+
126
+ All style props accept either a plain value or a responsive object keyed by breakpoint:
127
+
128
+ ```ts
129
+ // Breakpoints: xs (390px), sm (768px), md (1280px), lg (1680px)
130
+
131
+ // Plain value (applies at all breakpoints)
132
+ { fontSize: '16px' }
133
+
134
+ // Responsive object (xs is the base; other keys override upward)
135
+ { fontSize: { xs: '14px', md: '18px' } }
136
+ ```
137
+
138
+ The current breakpoint is controlled via the `?screen=xs|sm|md|lg` query param.
139
+
140
+ ### Serialized State
141
+
142
+ The canvas state is plain JSON (`SerializedNodes` from `@craftjs/core`). Use `useComposer()` to read and serialize it:
143
+
144
+ ```tsx
145
+ import { useComposer } from '@janbox/storefront-builder';
146
+
147
+ function SaveButton() {
148
+ const { query } = useComposer();
149
+
150
+ const handleSave = () => {
151
+ const json = query.serialize(); // SerializedNodes as JSON string
152
+ // save to your backend
153
+ };
154
+
155
+ return <button onClick={handleSave}>Save</button>;
156
+ }
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Templates
162
+
163
+ Templates are pre-configured drag-and-drop groups shown in the editor sidebar.
164
+
165
+ ### Element Groups (sidebar "Elements" tab)
166
+
167
+ ```ts
168
+ import {
169
+ LAYOUT_ELEMENT_GROUP, // Box, Flexbox, Grid
170
+ TEXT_ELEMENT_GROUP, // Text, Heading, Paragraph
171
+ MEDIA_ELEMENT_GROUP, // Image, Video, Icon
172
+ INTERACTIVE_ELEMENT_GROUP, // Button, Link, Accordion, Tabs
173
+ CONTENT_LIST_ELEMENT_GROUP, // UnorderedList, Marquee, Swiper
174
+ UTILITIES_ELEMENT_GROUP, // CountdownTimer
175
+ } from '@janbox/storefront-builder/templates';
176
+ ```
177
+
178
+ ### Section Groups (sidebar "Sections" tab)
179
+
180
+ ```ts
181
+ import {
182
+ HERO_SECTION_GROUP,
183
+ FAQS_SECTION_GROUP,
184
+ GUARANTEE_SECTION_GROUP,
185
+ } from '@janbox/storefront-builder/templates';
186
+ ```
187
+
188
+ Pass them to `Editor` via the `insert` prop:
189
+
190
+ ```tsx
191
+ <Editor
192
+ theme={myTheme}
193
+ insert={{
194
+ elements: [LAYOUT_ELEMENT_GROUP, TEXT_ELEMENT_GROUP],
195
+ sections: [HERO_SECTION_GROUP],
196
+ }}
197
+ />
198
+ ```
199
+
200
+ ---
201
+
202
+ ## Custom Nodes
203
+
204
+ ### 1. Create a node component
205
+
206
+ ```tsx
207
+ // my-badge.node.tsx
208
+ import { defineNode } from '@janbox/storefront-builder';
209
+ import { useNode } from '@janbox/storefront-builder';
210
+
211
+ type MyBadgeProps = { label: string; color?: string };
212
+
213
+ export const MyBadge = ({ label, color = '#fa8c16' }: MyBadgeProps) => {
214
+ const { connectors } = useNode();
215
+
216
+ return (
217
+ <span
218
+ ref={(el) => el && connectors.connect(el)}
219
+ style={{ background: color, padding: '2px 8px', borderRadius: 4 }}
220
+ >
221
+ {label}
222
+ </span>
223
+ );
224
+ };
225
+
226
+ defineNode(MyBadge, {
227
+ resolved: 'MyBadge',
228
+ isCanvas: false,
229
+ info: { displayName: 'Badge' },
230
+ defaultProps: { label: 'Badge', color: '#fa8c16' },
231
+ });
232
+ ```
233
+
234
+ ### 2. Pass a resolver to the editor
235
+
236
+ ```tsx
237
+ import { MyBadge } from './my-badge.node';
238
+
239
+ <Editor
240
+ theme={myTheme}
241
+ resolver={{ MyBadge }}
242
+ insert={{ elements: [/* ... */], sections: [] }}
243
+ />
244
+ ```
245
+
246
+ ### 3. Add a toolbar (optional)
247
+
248
+ ```tsx
249
+ // my-badge.toolbar.tsx
250
+ import { useNodeProps } from '@janbox/storefront-builder';
251
+
252
+ export function MyBadgeToolbar() {
253
+ const { nodeProps, setNodeProps } = useNodeProps<MyBadgeProps>();
254
+
255
+ return (
256
+ <div>
257
+ <label>Label</label>
258
+ <input
259
+ value={nodeProps.label}
260
+ onChange={(e) => setNodeProps({ label: e.target.value })}
261
+ />
262
+ </div>
263
+ );
264
+ }
265
+ ```
266
+
267
+ Register the toolbar in `defineNode`:
268
+
269
+ ```ts
270
+ defineNode(MyBadge, {
271
+ resolved: 'MyBadge',
272
+ info: { displayName: 'Badge' },
273
+ related: { inspector: MyBadgeToolbar },
274
+ });
275
+ ```
276
+
277
+ ---
278
+
279
+ ## Hooks
280
+
281
+ All hooks must be called inside a `<Composer>` tree.
282
+
283
+ ### `useComposer(collector?)`
284
+
285
+ Enhanced wrapper around CraftJS `useEditor`. Adds `actions.duplicate()` and `actions.move()`.
286
+
287
+ ```ts
288
+ const { query, actions } = useComposer();
289
+
290
+ // Serialize current canvas state
291
+ const json = query.serialize();
292
+
293
+ // Duplicate a node
294
+ actions.duplicate(nodeId);
295
+
296
+ // Move a node
297
+ actions.move({ nodeId, sourceIndex: 0, destinationIndex: 2 });
298
+ ```
299
+
300
+ ### `useNodeProps<P>(options?)`
301
+
302
+ Read and write props for the current node (or a specific node via `options.nodeId`). Supports responsive updates.
303
+
304
+ ```ts
305
+ const { nodeProps, setNodeProps, setNodeResponsiveProps } = useNodeProps<MyProps>();
306
+
307
+ // Set a flat prop
308
+ setNodeProps({ color: '#ff0000' });
309
+
310
+ // Set a responsive prop for a specific breakpoint
311
+ setNodeResponsiveProps({ fontSize: '18px' }, 'md');
312
+ ```
313
+
314
+ ### `useNode()`
315
+
316
+ Direct access to the CraftJS node context (re-exported from `@craftjs/core`).
317
+
318
+ ```ts
319
+ const { id, connectors, actions } = useNode();
320
+ ```
321
+
322
+ ---
323
+
324
+ ## TailwindCSS Integration
325
+
326
+ The library uses TailwindCSS v4 internally with a `tw:` prefix. To extend it in your app:
327
+
328
+ ```ts
329
+ // tailwind.config.ts
330
+ import builderConfig from '@janbox/storefront-builder/tailwind.config';
331
+
332
+ export default {
333
+ presets: [builderConfig],
334
+ // your overrides
335
+ };
336
+ ```
337
+
338
+ Import the stylesheet once at your app entry:
339
+
340
+ ```ts
341
+ import '@janbox/storefront-builder/style.css';
342
+ ```
343
+
344
+ ---
345
+
346
+ ## Theme Shape
347
+
348
+ The `theme` prop on `Editor` follows the `@janbox/storefront-ui` `Theme` type:
349
+
350
+ ```ts
351
+ type Theme = {
352
+ palette: {
353
+ primary: Record<100 | 200 | 300 | 400 | 500 | 600 | 700 | 800, string>;
354
+ secondary: Record<...>;
355
+ red, orange, yellow, green, blue, violet, neutral: Record<...>;
356
+ black: string;
357
+ white: string;
358
+ background: { subtle, default, emphasis: string };
359
+ surface: { default: string };
360
+ border: { default: string };
361
+ inherit: string;
362
+ current: string;
363
+ transparent: string;
364
+ };
365
+ typography: Record<'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl', {
366
+ fontSize: string;
367
+ lineHeight: string;
368
+ }>;
369
+ };
370
+ ```
371
+
372
+ ---
373
+
374
+ ## TypeScript
375
+
376
+ The package ships full `.d.ts` declarations. Key types:
377
+
378
+ ```ts
379
+ import type {
380
+ SerializedNodes, // canvas JSON state
381
+ NodeId, // string node identifier
382
+ NodeTree, // tree of nodes
383
+ Resolver, // map of resolvedName → component
384
+ NodeConfig, // config passed to defineNode()
385
+ DisplayOnValue, // responsive visibility: Partial<Record<Screen, boolean>>
386
+ } from '@janbox/storefront-builder';
387
+ ```
388
+
389
+ ---
390
+
391
+ ## Node Reference
392
+
393
+ Chi tiết props, usage và rules cho từng node:
394
+
395
+ ### Layout
396
+
397
+ - [RootNode](lib/root/README.md) — top-level canvas container
398
+ - [BoxNode](lib/box/README.md) — block container
399
+ - [FlexboxNode](lib/flexbox/README.md) — flex container
400
+ - [FlexItemNode](lib/flex-item/README.md) — flex item
401
+ - [GridNode](lib/grid/README.md) — CSS grid container
402
+ - [CellNode](lib/cell/README.md) — grid cell
403
+
404
+ ### Typography
405
+
406
+ - [TextNode](lib/text/README.md) — inline/block text
407
+ - [HeadingNode](lib/heading/README.md) — h1–h6 heading
408
+ - [ParagraphNode](lib/paragraph/README.md) — paragraph
409
+
410
+ ### Media
411
+
412
+ - [ImageNode](lib/image/README.md) — image
413
+ - [VideoNode](lib/video/README.md) — video player
414
+ - [IconNode](lib/icon/README.md) — inline SVG icon
415
+
416
+ ### Navigation
417
+
418
+ - [LinkNode](lib/link/README.md) — anchor link
419
+ - [ButtonNode](lib/button/README.md) — CTA button
420
+
421
+ ### Lists
422
+
423
+ - [UnorderedListNode](lib/unordered-list/README.md) — list container
424
+ - [ListItemNode](lib/list-item/README.md) — list item
425
+
426
+ ### Accordion
427
+
428
+ - [AccordionGroupNode](lib/accordion-group/README.md) — accordion container
429
+ - [AccordionNode](lib/accordion/README.md) — accordion item
430
+ - [AccordionSummaryNode](lib/accordion-summary/README.md) — accordion header
431
+ - [AccordionContentNode](lib/accordion-content/README.md) — accordion content
432
+
433
+ ### Tabs
434
+
435
+ - [TabsNode](lib/tabs/README.md) — tabs container
436
+ - [TabListNode](lib/tab-list/README.md) — tab headers container
437
+ - [TabNode](lib/tab/README.md) — tab header button
438
+ - [TabContentNode](lib/tab-content/README.md) — tab panels container
439
+ - [TabPanelNode](lib/tab-panel/README.md) — tab panel content
440
+
441
+ ### Carousel
442
+
443
+ - [SwiperNode](lib/swiper/README.md) — carousel container
444
+ - [SwiperSlideNode](lib/swiper-slide/README.md) — carousel slide
445
+
446
+ ### Marquee
447
+
448
+ - [MarqueeNode](lib/marquee/README.md) — auto-scrolling ticker
449
+ - [MarqueeItemNode](lib/marquee-item/README.md) — ticker item
450
+
451
+ ### Utilities
452
+
453
+ - [CountdownTimerNode](lib/countdown-timer/README.md) — countdown timer
454
+
455
+ ### Internal
456
+
457
+ - [UnknownNode](lib/unknown/README.md) — fallback for unresolved nodes
458
+
459
+ ---
460
+
461
+ ## Monorepo Development
462
+
463
+ ```bash
464
+ # Install dependencies
465
+ pnpm install
466
+
467
+ # Start demo app (React Router 7)
468
+ pnpm dev
469
+
470
+ # Build the library
471
+ pnpm build
472
+
473
+ # Type check
474
+ pnpm typecheck
475
+ ```
476
+
477
+ Requires Node.js >= 20 and pnpm.
@@ -1 +1 @@
1
- export declare const useDialogContext: () => import('../../floating').WbFloatingContextValue;
1
+ export declare const useDialogContext: () => import('../..').WbFloatingContextValue;
@@ -1 +1 @@
1
- export declare const WbDialogClose: import('react').ForwardRefExoticComponent<Omit<import('../../floating').WbFloatingCloseProps, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
1
+ export declare const WbDialogClose: import('react').ForwardRefExoticComponent<Omit<import('../..').WbFloatingCloseProps, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
package/dist/editor.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx as n, Fragment as Ne, jsxs as g } from "@emotion/react/jsx-runtime";
2
- import { u as _e, a as ae, b as te, D as ze, c as qe, W as j, d as E, e as Ge, f as Ue, g as Le, h as Ee, i as Ze, j as Qe, k as we, l as Ye, m as ue, n as oe, A as Se, o as Ke, C as Me, p as Re, q as Xe, r as Je, T as et, s as fe, R as tt } from "./index-CBDllFpx.js";
3
- import { t as qr } from "./index-CBDllFpx.js";
2
+ import { u as _e, a as ae, b as te, D as ze, c as qe, W as j, d as E, e as Ge, f as Ue, g as Le, h as Ee, i as Ze, j as Qe, k as we, l as Ye, m as ue, n as oe, A as Se, o as Ke, C as Me, p as Re, q as Xe, r as Je, T as et, s as fe, R as tt } from "./index-DrJkOkbq.js";
3
+ import { t as qr } from "./index-DrJkOkbq.js";
4
4
  import rt from "mitt";
5
5
  import { c as I, N as pe, B as ge, g as nt, a as st, u as W, W as ot, b as $e, i as it, P as ct } from "./countdown-timer.node-CAsCNVin.js";
6
6
  import { useRef as je, useState as _, useEffect as z, createElement as Ae, Fragment as J, Suspense as at } from "react";
@@ -7,8 +7,8 @@ import { u as St, x as oi, J as ue, D as C, c as L, W as ur, i as Bn, b as In, t
7
7
  import { isFunction as Or, merge as ri, set as Ur, isNil as Wt, isString as Ne, isUndefined as Fe, get as ai } from "lodash-es";
8
8
  import { OverlayScrollbarsComponent as _r } from "overlayscrollbars-react";
9
9
  import { jsxs as Wr, jsx as li } from "react/jsx-runtime";
10
- import { useNode as tt, ROOT_NODE as $r, Frame as Kr, Editor as Hr, DefaultEventHandlers as zr } from "@craftjs/core";
11
- import { useMergeRefs as de, useFloating as ci, autoUpdate as ui, offset as di, flip as hi, size as Gr, useClick as qr, useHover as Xr, safePolygon as Yr, useDismiss as Zr, useRole as Jr, useInteractions as Qr, useFloatingParentNodeId as ta, FloatingTree as ea, FloatingPortal as fi } from "@floating-ui/react";
10
+ import { useMergeRefs as de, useFloating as ci, autoUpdate as ui, offset as di, flip as hi, size as $r, useClick as Kr, useHover as Hr, safePolygon as zr, useDismiss as Gr, useRole as qr, useInteractions as Xr, useFloatingParentNodeId as Yr, FloatingTree as Zr, FloatingPortal as fi } from "@floating-ui/react";
11
+ import { useNode as tt, ROOT_NODE as Jr, Frame as Qr, Editor as ta, DefaultEventHandlers as ea } from "@craftjs/core";
12
12
  import { useUpdateEffect as na } from "react-use";
13
13
  import { useFrame as sa } from "react-frame-component";
14
14
  import { Button as ia, UnorderedList as oa, ListItem as ra } from "@janbox/storefront-ui";
@@ -424,7 +424,7 @@ const bh = (t) => {
424
424
  middleware: [
425
425
  di(a),
426
426
  hi(),
427
- Gr({
427
+ $r({
428
428
  apply({ elements: S }) {
429
429
  const b = {
430
430
  zIndex: `${lr}`,
@@ -435,12 +435,12 @@ const bh = (t) => {
435
435
  })
436
436
  ],
437
437
  whileElementsMounted: ui
438
- }), { context: h, refs: f } = d, m = qr(h, {
438
+ }), { context: h, refs: f } = d, m = Kr(h, {
439
439
  enabled: o === "click"
440
- }), y = Xr(h, {
440
+ }), y = Hr(h, {
441
441
  enabled: o === "hover",
442
- handleClose: Yr()
443
- }), g = Zr(
442
+ handleClose: zr()
443
+ }), g = Gr(
444
444
  h,
445
445
  ri(
446
446
  {
@@ -448,7 +448,7 @@ const bh = (t) => {
448
448
  },
449
449
  s
450
450
  )
451
- ), p = Jr(h), v = Qr([m, g, p, y]), w = Y(
451
+ ), p = qr(h), v = Xr([m, g, p, y]), w = Y(
452
452
  () => ({
453
453
  ...d,
454
454
  ...v
@@ -458,7 +458,7 @@ const bh = (t) => {
458
458
  return na(() => {
459
459
  Fe(r) || (f.setReference?.(r), h.onOpenChange(!Wt(r)));
460
460
  }, [r]), /* @__PURE__ */ x(gi.Provider, { value: w, children: i });
461
- }, va = (t) => ta() ? /* @__PURE__ */ x(Un, { ...t }) : /* @__PURE__ */ x(ea, { children: /* @__PURE__ */ x(Un, { ...t }) }), wa = ft(({ children: t, ...e }, n) => {
461
+ }, va = (t) => Yr() ? /* @__PURE__ */ x(Un, { ...t }) : /* @__PURE__ */ x(Zr, { children: /* @__PURE__ */ x(Un, { ...t }) }), wa = ft(({ children: t, ...e }, n) => {
462
462
  const { getReferenceProps: s, context: i } = yi(), r = de([i.refs.setReference, ai(t, "ref"), n]);
463
463
  return _t(t) ? Je(
464
464
  t,
@@ -5339,7 +5339,7 @@ const Yd = (t, e) => ln(t) ? new Xd(e) : new qd(e, {
5339
5339
  } = tt((g) => {
5340
5340
  let p = g.data.parent ? n.node(g.data.parent).get() : null;
5341
5341
  for (; p && !Bn(p); )
5342
- p = p.data.parent && p.data.parent !== $r ? n.node(p.data.parent).get() : null;
5342
+ p = p.data.parent && p.data.parent !== Jr ? n.node(p.data.parent).get() : null;
5343
5343
  return {
5344
5344
  dom: g.dom,
5345
5345
  name: In(g),
@@ -5487,7 +5487,7 @@ const Bh = ({ children: t, data: e }) => {
5487
5487
  });
5488
5488
  }), i;
5489
5489
  }, [e, n]);
5490
- return /* @__PURE__ */ x(Kr, { data: s, children: t });
5490
+ return /* @__PURE__ */ x(Qr, { data: s, children: t });
5491
5491
  }, eh = {
5492
5492
  // Root
5493
5493
  [C.Root]: pi,
@@ -5532,7 +5532,7 @@ const Bh = ({ children: t, data: e }) => {
5532
5532
  // Timer
5533
5533
  [C.CountdownTimer]: dr
5534
5534
  }, Ih = ({ resolver: t, children: e, ...n }) => /* @__PURE__ */ x(
5535
- Hr,
5535
+ ta,
5536
5536
  {
5537
5537
  enabled: !1,
5538
5538
  onRender: nh,
@@ -5555,7 +5555,7 @@ const Bh = ({ children: t, data: e }) => {
5555
5555
  );
5556
5556
  }, [e, n]), t;
5557
5557
  };
5558
- class sh extends zr {
5558
+ class sh extends ea {
5559
5559
  handlers() {
5560
5560
  const e = super.handlers();
5561
5561
  return {
package/dist/index.js CHANGED
@@ -7,8 +7,8 @@ import { Draggable as vt, DragDropContext as bt, Droppable as Nt } from "@hello-
7
7
  import { getGridProps as so, getCellProps as ao, GRID_MINIMUM_COLS as Yt, GRID_MAXIMUM_COLS as io, getLinkProps as lo, getButtonProps as co, getFlexboxProps as uo, getFlexItemProps as ho, getTextProps as go, getImageProps as po, getMarqueeProps as wo, MarqueeDataAttributes as wt, getTabsProps as mo, getTabPanelProps as Co, getSwiperProps as xo, getUnorderedListProps as fo, getListItemProps as vo, getIconProps as bo, getAccordionProps as No, getAccordionGroupProps as ko, getAccordionDataAttributes as $e, AccordionDataAttributes as mt, getVideoProps as Ro, getBoxProps as Lo } from "@janbox/storefront-ui";
8
8
  import { isNumber as nt, isNil as z, isFunction as To, assign as So, isUndefined as kt, get as ze, parseInt as yo, trimStart as Rt, isString as me, set as Bo } from "lodash-es";
9
9
  import { useDebounceCallback as dn, useToggle as cn } from "usehooks-ts";
10
- import { v as W, h as Y, W as T, d as f, n as Po, q as Io, A as ve, L as Mo, b as Lt, w as Se, x as ye, f as Ct, y as Be, z as Pe, a as Tt, B as Ao, e as U, r as ee, g as Q, o as Re, i as j, j as F, k as S, l as Z, m as y, E as St, T as yt, F as Wo, t as I, D as un, c as hn, G as Vo } from "./index-CBDllFpx.js";
11
- import { p as pi, C as wi, R as mi, U as Ci, H as xi } from "./index-CBDllFpx.js";
10
+ import { v as W, h as Y, W as T, d as f, n as Po, q as Io, A as ve, L as Mo, b as Lt, w as Se, x as ye, f as Ct, y as Be, z as Pe, a as Tt, B as Ao, e as U, r as ee, g as Q, o as Re, i as j, j as F, k as S, l as Z, m as y, E as St, T as yt, F as Wo, t as I, D as un, c as hn, G as Vo } from "./index-DrJkOkbq.js";
11
+ import { p as pi, C as wi, R as mi, U as Ci, H as xi } from "./index-DrJkOkbq.js";
12
12
  import { useNode as re } from "@craftjs/core";
13
13
  import { useNode as vi } from "@craftjs/core";
14
14
  import { W as Ho } from "./tooltip-CqfT80iK.js";
@@ -0,0 +1,39 @@
1
+ # AccordionNode
2
+
3
+ Một accordion item. Chứa `AccordionSummaryNode` (header) và `AccordionContentNode` (nội dung). Không selectable — chỉnh sửa qua parent `AccordionGroupNode`.
4
+
5
+ ## Resolved name
6
+
7
+ `Accordion`
8
+
9
+ ## Configurable props
10
+
11
+ Không có props riêng. Tất cả styling được control qua `AccordionGroupNode`.
12
+
13
+ ## Usage
14
+
15
+ ```tsx
16
+ import { AccordionNode, AccordionSummaryNode, AccordionContentNode } from '@janbox/storefront-builder';
17
+
18
+ <AccordionNode>
19
+ <AccordionSummaryNode>
20
+ <TextNode>Question title</TextNode>
21
+ </AccordionSummaryNode>
22
+ <AccordionContentNode>
23
+ <TextNode>Answer content</TextNode>
24
+ </AccordionContentNode>
25
+ </AccordionNode>
26
+ ```
27
+
28
+ ## Rules
29
+
30
+ - **Canvas**: no.
31
+ - **Selectable**: no — user không thể select trực tiếp node này trong editor.
32
+ - **Parent**: phải là `AccordionGroupNode`.
33
+ - **Children**: phải có `AccordionSummaryNode` và `AccordionContentNode`.
34
+
35
+ ## Related nodes
36
+
37
+ - [`AccordionGroupNode`](../accordion-group/README.md) — parent container
38
+ - [`AccordionSummaryNode`](../accordion-summary/README.md) — header
39
+ - [`AccordionContentNode`](../accordion-content/README.md) — content area
@@ -0,0 +1,36 @@
1
+ # AccordionContentNode
2
+
3
+ Content area của accordion item — phần expand/collapse khi click vào header. Là canvas node — chứa bất kỳ node con nào.
4
+
5
+ ## Resolved name
6
+
7
+ `AccordionContent`
8
+
9
+ ## Configurable props
10
+
11
+ Không có props riêng. Padding được config qua `AccordionGroupNode.accordionContentProps.sx`.
12
+
13
+ ## Usage
14
+
15
+ ```tsx
16
+ import { AccordionContentNode, ParagraphNode } from '@janbox/storefront-builder';
17
+
18
+ <AccordionContentNode>
19
+ <ParagraphNode>
20
+ Answer content goes here. Can contain any nodes.
21
+ </ParagraphNode>
22
+ </AccordionContentNode>
23
+ ```
24
+
25
+ ## Rules
26
+
27
+ - **Canvas**: yes — chứa bất kỳ node con nào.
28
+ - **Selectable**: no.
29
+ - **canMoveOut**: no — không thể kéo ra khỏi `AccordionNode`.
30
+ - **Parent**: phải là `AccordionNode`.
31
+
32
+ ## Related nodes
33
+
34
+ - [`AccordionNode`](../accordion/README.md) — parent item
35
+ - [`AccordionGroupNode`](../accordion-group/README.md) — root container
36
+ - [`AccordionSummaryNode`](../accordion-summary/README.md) — header