@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
@@ -0,0 +1,133 @@
1
+ # GridNode
2
+
3
+ A CSS Grid container node. Accepts only `CellNode` children — the editor enforces this via `canMoveIn`.
4
+
5
+ ## Resolved name
6
+
7
+ `Grid`
8
+
9
+ ## Configurable props
10
+
11
+ Props mà user có thể chỉnh trong editor inspector. Tất cả đều hỗ trợ responsive trừ `container`.
12
+
13
+ ### Top-level props
14
+
15
+ | Prop | Type | Description |
16
+ | --- | --- | --- |
17
+ | `cols` | `number` | Số cột — generates `grid-template-columns: repeat(cols, minmax(0, 1fr))` |
18
+ | `container` | `boolean` | Bật max-width container constraint |
19
+
20
+ ### `sx` props
21
+
22
+ `sx` nhận `StyledCSS` với responsive keys `sm`, `md`, `lg` bên trong:
23
+
24
+ ```ts
25
+ sx?: {
26
+ // layout
27
+ columnGap?: number
28
+ rowGap?: number
29
+ alignItems?: 'start' | 'center' | 'end' | 'stretch'
30
+ justifyItems?: 'start' | 'center' | 'end' | 'stretch'
31
+ width?: number | string
32
+ height?: number | string
33
+
34
+ // spacing
35
+ paddingTop?: number
36
+ paddingRight?: number
37
+ paddingBottom?: number
38
+ paddingLeft?: number
39
+ marginTop?: number
40
+ marginRight?: number
41
+ marginBottom?: number
42
+ marginLeft?: number
43
+
44
+ // border
45
+ borderStyle?: string
46
+ borderColor?: string
47
+ borderTopWidth?: number
48
+ borderRightWidth?: number
49
+ borderBottomWidth?: number
50
+ borderLeftWidth?: number
51
+ borderTopLeftRadius?: number | string
52
+ borderTopRightRadius?: number | string
53
+ borderBottomRightRadius?: number | string
54
+ borderBottomLeftRadius?: number | string
55
+
56
+ // background
57
+ backgroundColor?: string
58
+ backgroundImage?: string
59
+ backgroundPosition?: string
60
+ backgroundRepeat?: string
61
+ backgroundSize?: string
62
+ backgroundAttachment?: string
63
+ background?: string
64
+
65
+ // responsive overrides
66
+ sm?: { /* same keys above */ }
67
+ md?: { /* same keys above */ }
68
+ lg?: { /* same keys above */ }
69
+ }
70
+ ```
71
+
72
+ ## Usage
73
+
74
+ ```tsx
75
+ import { GridNode, CellNode } from '@janbox/storefront-builder';
76
+
77
+ // 2 cột cố định
78
+ <GridNode cols={2}>
79
+ <CellNode>...</CellNode>
80
+ <CellNode>...</CellNode>
81
+ </GridNode>
82
+
83
+ // Responsive: 1 cột mobile, 3 cột desktop
84
+ <GridNode cols={1} md={{ cols: 3 }}>
85
+ <CellNode>...</CellNode>
86
+ <CellNode>...</CellNode>
87
+ <CellNode>...</CellNode>
88
+ </GridNode>
89
+
90
+ // sx responsive: gap nhỏ trên mobile, lớn hơn trên desktop
91
+ <GridNode
92
+ cols={1}
93
+ md={{ cols: 2 }}
94
+ sx={{
95
+ columnGap: 8,
96
+ rowGap: 8,
97
+ paddingTop: 16,
98
+ paddingBottom: 16,
99
+ md: {
100
+ columnGap: 24,
101
+ rowGap: 24,
102
+ paddingTop: 32,
103
+ paddingBottom: 32,
104
+ },
105
+ }}
106
+ >
107
+ <CellNode>...</CellNode>
108
+ <CellNode>...</CellNode>
109
+ </GridNode>
110
+
111
+ // Container với background
112
+ <GridNode
113
+ container
114
+ cols={2}
115
+ sx={{
116
+ backgroundColor: '#f5f5f5',
117
+ paddingTop: 32,
118
+ paddingBottom: 32,
119
+ }}
120
+ >
121
+ <CellNode>...</CellNode>
122
+ <CellNode>...</CellNode>
123
+ </GridNode>
124
+ ```
125
+
126
+ ## Rules
127
+
128
+ - **Canvas**: yes — accepts dropped children.
129
+ - **canMoveIn**: only `CellNode` children are allowed.
130
+
131
+ ## Related nodes
132
+
133
+ - [`CellNode`](../cell/README.md) — the only valid direct child of `GridNode`
@@ -0,0 +1,53 @@
1
+ # HeadingNode
2
+
3
+ Text node dành cho tiêu đề. Dùng chung `TextInspector` với `TextNode` nhưng giới hạn tag trong `h1`–`h6` và `div`.
4
+
5
+ ## Resolved name
6
+
7
+ `Heading`
8
+
9
+ ## Configurable props
10
+
11
+ Giống hệt `TextNode`. Xem chi tiết tại [TextNode](../text/README.md#configurable-props).
12
+
13
+ ### Điểm khác biệt
14
+
15
+ | Prop | Giá trị cho phép | Default |
16
+ | --- | --- | --- |
17
+ | `as` | `'h1' \| 'h2' \| 'h3' \| 'h4' \| 'h5' \| 'h6' \| 'div'` | `'p'` (từ Text) |
18
+
19
+ ## Usage
20
+
21
+ ```tsx
22
+ import { HeadingNode } from '@janbox/storefront-builder';
23
+
24
+ // H1 mặc định
25
+ <HeadingNode as="h1" sizeVariant="4xl">
26
+ Page Title
27
+ </HeadingNode>
28
+
29
+ // Responsive size
30
+ <HeadingNode
31
+ as="h2"
32
+ sizeVariant="2xl"
33
+ md={{ sizeVariant: '4xl' }}
34
+ sx={{ color: '#111111', textAlign: 'center' }}
35
+ >
36
+ Section Title
37
+ </HeadingNode>
38
+
39
+ // Dùng div khi không cần semantic heading nhưng muốn style heading
40
+ <HeadingNode as="div" sizeVariant="xl" sx={{ fontWeight: 700 }}>
41
+ Display text
42
+ </HeadingNode>
43
+ ```
44
+
45
+ ## Rules
46
+
47
+ - **Canvas**: no — không chứa node con.
48
+ - **Inline editing**: có thể double-click để chỉnh nội dung trong canvas.
49
+
50
+ ## Related nodes
51
+
52
+ - [`TextNode`](../text/README.md) — base component dùng chung inspector
53
+ - [`ParagraphNode`](../paragraph/README.md) — dành cho nội dung dạng đoạn văn
@@ -0,0 +1,98 @@
1
+ # IconNode
2
+
3
+ SVG icon node. Render inline SVG từ raw string hoặc URL.
4
+
5
+ ## Resolved name
6
+
7
+ `Icon`
8
+
9
+ ## Configurable props
10
+
11
+ ### Top-level props
12
+
13
+ | Prop | Type | Description |
14
+ | --- | --- | --- |
15
+ | `source` | `string` | Raw SVG string hoặc URL tới file SVG |
16
+ | `size` | `number` | Kích thước icon (px) — set cả `width` và `height` |
17
+
18
+ `size` hỗ trợ responsive: `size={24}` xs, `md={{ size: 32 }}` desktop.
19
+
20
+ ### `sx` props
21
+
22
+ ```ts
23
+ sx?: {
24
+ // color (áp dụng toàn breakpoint — không responsive)
25
+ color?: string
26
+
27
+ // spacing
28
+ paddingTop?: number
29
+ paddingRight?: number
30
+ paddingBottom?: number
31
+ paddingLeft?: number
32
+ marginTop?: number
33
+ marginRight?: number
34
+ marginBottom?: number
35
+ marginLeft?: number
36
+
37
+ // border
38
+ borderStyle?: string
39
+ borderColor?: string
40
+ borderTopWidth?: number
41
+ borderRightWidth?: number
42
+ borderBottomWidth?: number
43
+ borderLeftWidth?: number
44
+ borderTopLeftRadius?: number | string
45
+ borderTopRightRadius?: number | string
46
+ borderBottomRightRadius?: number | string
47
+ borderBottomLeftRadius?: number | string
48
+
49
+ // responsive overrides
50
+ sm?: { /* same keys above */ }
51
+ md?: { /* same keys above */ }
52
+ lg?: { /* same keys above */ }
53
+ }
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ ```tsx
59
+ import { IconNode } from '@janbox/storefront-builder';
60
+
61
+ // Icon từ raw SVG
62
+ <IconNode
63
+ source='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="..."/></svg>'
64
+ size={24}
65
+ sx={{ color: '#333333' }}
66
+ />
67
+
68
+ // Responsive size
69
+ <IconNode
70
+ source="https://example.com/icon.svg"
71
+ size={20}
72
+ md={{ size: 28 }}
73
+ sx={{ color: '#fa8c16' }}
74
+ />
75
+
76
+ // Icon với background tròn
77
+ <IconNode
78
+ source='<svg>...</svg>'
79
+ size={16}
80
+ sx={{
81
+ color: '#ffffff',
82
+ paddingTop: 8,
83
+ paddingBottom: 8,
84
+ paddingLeft: 8,
85
+ paddingRight: 8,
86
+ backgroundColor: '#fa8c16',
87
+ borderTopLeftRadius: '50%',
88
+ borderTopRightRadius: '50%',
89
+ borderBottomLeftRadius: '50%',
90
+ borderBottomRightRadius: '50%',
91
+ }}
92
+ />
93
+ ```
94
+
95
+ ## Rules
96
+
97
+ - **Canvas**: no — không chứa node con.
98
+ - `source` bắt buộc phải có — nếu không có, icon sẽ không hiển thị.
@@ -0,0 +1,107 @@
1
+ # ImageNode
2
+
3
+ Image node render ra `<img>`. Không chứa node con.
4
+
5
+ ## Resolved name
6
+
7
+ `Image`
8
+
9
+ ## Configurable props
10
+
11
+ ### Top-level props
12
+
13
+ | Prop | Type | Description |
14
+ | --- | --- | --- |
15
+ | `src` | `string` | URL ảnh |
16
+ | `alt` | `string` | Alt text cho SEO và accessibility |
17
+ | `loading` | `'eager' \| 'lazy'` | Preload: `'eager'` = tải ngay, `'lazy'` = lazy load (default) |
18
+
19
+ ### `sx` props
20
+
21
+ ```ts
22
+ sx?: {
23
+ // size
24
+ width?: number | string
25
+ height?: number | string // chỉ hiển thị khi aspectRatio là 'auto'
26
+
27
+ // aspect ratio
28
+ aspectRatio?: 'auto' | '1 / 1' | '16 / 9' | '9 / 16' | string // ví dụ custom: '4 / 3'
29
+
30
+ // object fit (áp dụng toàn breakpoint — không responsive)
31
+ objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'
32
+
33
+ // spacing
34
+ paddingTop?: number
35
+ paddingRight?: number
36
+ paddingBottom?: number
37
+ paddingLeft?: number
38
+ marginTop?: number
39
+ marginRight?: number
40
+ marginBottom?: number
41
+ marginLeft?: number
42
+
43
+ // border
44
+ borderStyle?: string
45
+ borderColor?: string
46
+ borderTopWidth?: number
47
+ borderRightWidth?: number
48
+ borderBottomWidth?: number
49
+ borderLeftWidth?: number
50
+ borderTopLeftRadius?: number | string
51
+ borderTopRightRadius?: number | string
52
+ borderBottomRightRadius?: number | string
53
+ borderBottomLeftRadius?: number | string
54
+
55
+ // responsive overrides
56
+ sm?: { /* same keys above */ }
57
+ md?: { /* same keys above */ }
58
+ lg?: { /* same keys above */ }
59
+ }
60
+ ```
61
+
62
+ > Khi `aspectRatio` được set (khác `auto`), prop `height` bị ẩn trong inspector vì chiều cao tự tính từ ratio.
63
+
64
+ ## Usage
65
+
66
+ ```tsx
67
+ import { ImageNode } from '@janbox/storefront-builder';
68
+
69
+ // Ảnh cơ bản
70
+ <ImageNode
71
+ src="https://example.com/photo.jpg"
72
+ alt="Product photo"
73
+ loading="lazy"
74
+ sx={{ width: '100%', objectFit: 'cover' }}
75
+ />
76
+
77
+ // Tỉ lệ 16:9, full width
78
+ <ImageNode
79
+ src="https://example.com/banner.jpg"
80
+ alt="Banner"
81
+ sx={{
82
+ width: '100%',
83
+ aspectRatio: '16 / 9',
84
+ objectFit: 'cover',
85
+ }}
86
+ />
87
+
88
+ // Thumbnail vuông, responsive width
89
+ <ImageNode
90
+ src="https://example.com/thumb.jpg"
91
+ alt="Thumbnail"
92
+ sx={{
93
+ width: 80,
94
+ aspectRatio: '1 / 1',
95
+ objectFit: 'cover',
96
+ borderTopLeftRadius: 8,
97
+ borderTopRightRadius: 8,
98
+ borderBottomLeftRadius: 8,
99
+ borderBottomRightRadius: 8,
100
+ md: { width: 120 },
101
+ }}
102
+ />
103
+ ```
104
+
105
+ ## Rules
106
+
107
+ - **Canvas**: no — không chứa node con.
@@ -0,0 +1,111 @@
1
+ # LinkNode
2
+
3
+ Anchor node render ra `<a>` qua React Router `Link`. Là canvas node — có thể chứa text hoặc các node con khác làm nội dung link.
4
+
5
+ ## Resolved name
6
+
7
+ `Link`
8
+
9
+ ## Configurable props
10
+
11
+ ### Top-level props
12
+
13
+ | Prop | Type | Description |
14
+ | --- | --- | --- |
15
+ | `to` | `string \| { pathname: string }` | Đường dẫn điều hướng |
16
+ | `target` | `'_self' \| '_blank' \| '_parent' \| '_top'` | Cách mở link |
17
+ | `rel` | `string` | SEO attribute, ví dụ `'nofollow noreferrer'` |
18
+ | `textVariant` | `TypographySizeVariant` | Preset typography size từ theme |
19
+
20
+ `textVariant` hỗ trợ responsive: `textVariant="sm"` xs, `md={{ textVariant: 'base' }}` desktop.
21
+
22
+ **`TypographySizeVariant`:** `'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl'`
23
+
24
+ ### `sx` props
25
+
26
+ ```ts
27
+ sx?: {
28
+ // typography (áp dụng toàn breakpoint — không responsive)
29
+ color?: string
30
+ fontStyle?: 'normal' | 'italic'
31
+ fontWeight?: number | string
32
+ textDecorationLine?: 'none' | 'underline' | 'line-through'
33
+ textAlign?: 'left' | 'center' | 'right' | 'justify'
34
+ textTransform?: 'none' | 'uppercase' | 'lowercase' | 'capitalize'
35
+
36
+ // spacing
37
+ paddingTop?: number
38
+ paddingRight?: number
39
+ paddingBottom?: number
40
+ paddingLeft?: number
41
+ marginTop?: number
42
+ marginRight?: number
43
+ marginBottom?: number
44
+ marginLeft?: number
45
+
46
+ // border
47
+ borderStyle?: string
48
+ borderColor?: string
49
+ borderTopWidth?: number
50
+ borderRightWidth?: number
51
+ borderBottomWidth?: number
52
+ borderLeftWidth?: number
53
+ borderTopLeftRadius?: number | string
54
+ borderTopRightRadius?: number | string
55
+ borderBottomRightRadius?: number | string
56
+ borderBottomLeftRadius?: number | string
57
+
58
+ // responsive overrides
59
+ sm?: { /* same keys above */ }
60
+ md?: { /* same keys above */ }
61
+ lg?: { /* same keys above */ }
62
+ }
63
+ ```
64
+
65
+ ## Usage
66
+
67
+ ```tsx
68
+ import { LinkNode } from '@janbox/storefront-builder';
69
+
70
+ // Link đơn giản
71
+ <LinkNode to="/products">View all products</LinkNode>
72
+
73
+ // Mở tab mới, no-follow
74
+ <LinkNode to="https://example.com" target="_blank" rel="nofollow noreferrer">
75
+ External link
76
+ </LinkNode>
77
+
78
+ // Link dạng button (có border, padding)
79
+ <LinkNode
80
+ to="/checkout"
81
+ sx={{
82
+ paddingTop: 12,
83
+ paddingBottom: 12,
84
+ paddingLeft: 24,
85
+ paddingRight: 24,
86
+ borderTopLeftRadius: 6,
87
+ borderTopRightRadius: 6,
88
+ borderBottomLeftRadius: 6,
89
+ borderBottomRightRadius: 6,
90
+ backgroundColor: '#fa8c16',
91
+ color: '#ffffff',
92
+ }}
93
+ >
94
+ Checkout
95
+ </LinkNode>
96
+
97
+ // textVariant responsive
98
+ <LinkNode to="/sale" textVariant="sm" md={{ textVariant: 'base' }}>
99
+ Sale items
100
+ </LinkNode>
101
+ ```
102
+
103
+ ## Rules
104
+
105
+ - **Canvas**: yes — chứa node con.
106
+ - **canMoveIn**: bị block khi prop `dangerouslySetInnerHTML` đang được dùng.
107
+ - Editor preview: click bị `preventDefault` khi editor đang bật để tránh navigate.
108
+
109
+ ## Related nodes
110
+
111
+ - [`ButtonNode`](../button/README.md) — dùng khi cần CTA có style button từ theme
@@ -0,0 +1,31 @@
1
+ # ListItemNode
2
+
3
+ Một item trong `UnorderedListNode` (`li`). Là canvas node — chứa bất kỳ node con nào.
4
+
5
+ ## Resolved name
6
+
7
+ `ListItem`
8
+
9
+ ## Configurable props
10
+
11
+ Không có props riêng. Styling được control qua parent `UnorderedListNode`.
12
+
13
+ ## Usage
14
+
15
+ ```tsx
16
+ import { ListItemNode, TextNode } from '@janbox/storefront-builder';
17
+
18
+ <ListItemNode>
19
+ <TextNode>Item content</TextNode>
20
+ </ListItemNode>
21
+ ```
22
+
23
+ ## Rules
24
+
25
+ - **Canvas**: yes — chứa bất kỳ node con nào.
26
+ - **Selectable**: no — chỉnh sửa qua parent `UnorderedListNode` inspector.
27
+ - **Parent**: phải là `UnorderedListNode`.
28
+
29
+ ## Related nodes
30
+
31
+ - [`UnorderedListNode`](../unordered-list/README.md) — parent list container
@@ -0,0 +1,111 @@
1
+ # MarqueeNode
2
+
3
+ Auto-scrolling ticker/marquee container dùng Embla Carousel Auto Scroll. Chỉ chấp nhận `MarqueeItemNode` children.
4
+
5
+ ## Resolved name
6
+
7
+ `Marquee`
8
+
9
+ ## Configurable props
10
+
11
+ ### Top-level props
12
+
13
+ | Prop | Type | Description |
14
+ | --- | --- | --- |
15
+ | `spaceBetween` | `number` | Khoảng cách giữa các items (px) |
16
+ | `autoScrollOptions` | `AutoScrollOptionsType` | Options từ embla-carousel-auto-scroll |
17
+ | `separatorIcon.source` | `string` | Raw SVG string cho icon phân cách giữa các items |
18
+ | `separatorIcon.size` | `number` | Kích thước separator icon (px) |
19
+ | `separatorIcon.sx.color` | `string` | Màu separator icon |
20
+
21
+ `spaceBetween` hỗ trợ responsive.
22
+
23
+ > Editor tự động set `autoScrollOptions.playOnInit = false` khi đang trong edit mode để tránh scroll khi đang drag/drop.
24
+
25
+ ### `sx` props
26
+
27
+ ```ts
28
+ sx?: {
29
+ // spacing
30
+ paddingTop?: number
31
+ paddingRight?: number
32
+ paddingBottom?: number
33
+ paddingLeft?: number
34
+ marginTop?: number
35
+ marginRight?: number
36
+ marginBottom?: number
37
+ marginLeft?: number
38
+
39
+ // border
40
+ borderStyle?: string
41
+ borderColor?: string
42
+ borderTopWidth?: number
43
+ borderRightWidth?: number
44
+ borderBottomWidth?: number
45
+ borderLeftWidth?: number
46
+ borderTopLeftRadius?: number | string
47
+ borderTopRightRadius?: number | string
48
+ borderBottomRightRadius?: number | string
49
+ borderBottomLeftRadius?: number | string
50
+
51
+ // background
52
+ backgroundColor?: string
53
+ backgroundImage?: string
54
+ backgroundPosition?: string
55
+ backgroundRepeat?: string
56
+ backgroundSize?: string
57
+ backgroundAttachment?: string
58
+ background?: string
59
+
60
+ // responsive overrides
61
+ sm?: { /* same keys above */ }
62
+ md?: { /* same keys above */ }
63
+ lg?: { /* same keys above */ }
64
+ }
65
+ ```
66
+
67
+ ## Usage
68
+
69
+ ```tsx
70
+ import { MarqueeNode, MarqueeItemNode, ImageNode } from '@janbox/storefront-builder';
71
+
72
+ // Marquee cơ bản, auto-scroll từ đầu
73
+ <MarqueeNode
74
+ spaceBetween={32}
75
+ autoScrollOptions={{ speed: 1 }}
76
+ >
77
+ <MarqueeItemNode><ImageNode src="..." alt="Logo 1" sx={{ width: 100 }} /></MarqueeItemNode>
78
+ <MarqueeItemNode><ImageNode src="..." alt="Logo 2" sx={{ width: 100 }} /></MarqueeItemNode>
79
+ <MarqueeItemNode><ImageNode src="..." alt="Logo 3" sx={{ width: 100 }} /></MarqueeItemNode>
80
+ </MarqueeNode>
81
+
82
+ // Với separator icon giữa các item
83
+ <MarqueeNode
84
+ spaceBetween={24}
85
+ separatorIcon={{
86
+ source: '<svg>...</svg>',
87
+ size: 16,
88
+ sx: { color: '#fa8c16' },
89
+ }}
90
+ >
91
+ <MarqueeItemNode>Item 1</MarqueeItemNode>
92
+ <MarqueeItemNode>Item 2</MarqueeItemNode>
93
+ </MarqueeNode>
94
+
95
+ // Responsive spacing
96
+ <MarqueeNode
97
+ spaceBetween={16}
98
+ md={{ spaceBetween: 32 }}
99
+ >
100
+ <MarqueeItemNode>...</MarqueeItemNode>
101
+ </MarqueeNode>
102
+ ```
103
+
104
+ ## Rules
105
+
106
+ - **Canvas**: yes — chứa `MarqueeItemNode` children.
107
+ - **canMoveIn**: chỉ chấp nhận `MarqueeItemNode`.
108
+
109
+ ## Related nodes
110
+
111
+ - [`MarqueeItemNode`](../marquee-item/README.md) — mỗi item trong marquee
@@ -0,0 +1,31 @@
1
+ # MarqueeItemNode
2
+
3
+ Một item trong `MarqueeNode`. Là canvas node — chứa bất kỳ node con nào.
4
+
5
+ ## Resolved name
6
+
7
+ `MarqueeItem`
8
+
9
+ ## Configurable props
10
+
11
+ Không có props riêng. Styling được control qua parent `MarqueeNode`.
12
+
13
+ ## Usage
14
+
15
+ ```tsx
16
+ import { MarqueeItemNode, ImageNode, TextNode } from '@janbox/storefront-builder';
17
+
18
+ <MarqueeItemNode>
19
+ <ImageNode src="..." alt="Brand logo" sx={{ width: 80, height: 40, objectFit: 'contain' }} />
20
+ </MarqueeItemNode>
21
+ ```
22
+
23
+ ## Rules
24
+
25
+ - **Canvas**: yes — chứa bất kỳ node con nào.
26
+ - **Selectable**: no — chỉnh sửa qua parent `MarqueeNode` inspector.
27
+ - **Parent**: phải là `MarqueeNode`.
28
+
29
+ ## Related nodes
30
+
31
+ - [`MarqueeNode`](../marquee/README.md) — parent scrolling container