@janbox/storefront-builder 1.0.3 → 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.
- package/README.md +477 -0
- package/dist/editor/lib/index.d.ts +3 -3
- package/dist/editor/lib/sidebar/index.d.ts +1 -1
- package/dist/editor/lib/sidebar/insert-action.d.ts +2 -2
- package/dist/editor/ui/dialog/dialog/helpers.d.ts +1 -1
- package/dist/editor/ui/dialog/dialog-close/dialog-close.d.ts +1 -1
- package/dist/editor.js +326 -313
- package/dist/lib/accordion/README.md +39 -0
- package/dist/lib/accordion-content/README.md +36 -0
- package/dist/lib/accordion-group/README.md +106 -0
- package/dist/lib/accordion-summary/README.md +37 -0
- package/dist/lib/box/README.md +107 -0
- package/dist/lib/button/README.md +94 -0
- package/dist/lib/cell/README.md +119 -0
- package/dist/lib/countdown-timer/README.md +157 -0
- package/dist/lib/flex-item/README.md +111 -0
- package/dist/lib/flexbox/README.md +120 -0
- package/dist/lib/grid/README.md +133 -0
- package/dist/lib/heading/README.md +53 -0
- package/dist/lib/icon/README.md +98 -0
- package/dist/lib/image/README.md +107 -0
- package/dist/lib/link/README.md +111 -0
- package/dist/lib/list-item/README.md +31 -0
- package/dist/lib/marquee/README.md +111 -0
- package/dist/lib/marquee-item/README.md +31 -0
- package/dist/lib/paragraph/README.md +82 -0
- package/dist/lib/root/README.md +33 -0
- package/dist/lib/swiper/README.md +108 -0
- package/dist/lib/swiper-slide/README.md +32 -0
- package/dist/lib/tab/README.md +35 -0
- package/dist/lib/tab-content/README.md +35 -0
- package/dist/lib/tab-list/README.md +35 -0
- package/dist/lib/tab-panel/README.md +35 -0
- package/dist/lib/tabs/README.md +90 -0
- package/dist/lib/text/README.md +90 -0
- package/dist/lib/unknown/README.md +48 -0
- package/dist/lib/unordered-list/README.md +82 -0
- package/dist/lib/video/README.md +91 -0
- package/lib/accordion/README.md +39 -0
- package/lib/accordion-content/README.md +36 -0
- package/lib/accordion-group/README.md +106 -0
- package/lib/accordion-summary/README.md +37 -0
- package/lib/box/README.md +107 -0
- package/lib/button/README.md +94 -0
- package/lib/cell/README.md +119 -0
- package/lib/countdown-timer/README.md +157 -0
- package/lib/flex-item/README.md +111 -0
- package/lib/flexbox/README.md +120 -0
- package/lib/grid/README.md +133 -0
- package/lib/heading/README.md +53 -0
- package/lib/icon/README.md +98 -0
- package/lib/image/README.md +107 -0
- package/lib/link/README.md +111 -0
- package/lib/list-item/README.md +31 -0
- package/lib/marquee/README.md +111 -0
- package/lib/marquee-item/README.md +31 -0
- package/lib/paragraph/README.md +82 -0
- package/lib/root/README.md +33 -0
- package/lib/swiper/README.md +108 -0
- package/lib/swiper-slide/README.md +32 -0
- package/lib/tab/README.md +35 -0
- package/lib/tab-content/README.md +35 -0
- package/lib/tab-list/README.md +35 -0
- package/lib/tab-panel/README.md +35 -0
- package/lib/tabs/README.md +90 -0
- package/lib/text/README.md +90 -0
- package/lib/unknown/README.md +48 -0
- package/lib/unordered-list/README.md +82 -0
- package/lib/video/README.md +91 -0
- package/package.json +5 -9
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# TabsNode
|
|
2
|
+
|
|
3
|
+
Root container cho tabs component. Quản lý active state và chứa `TabListNode` (headers) + `TabContentNode` (panels).
|
|
4
|
+
|
|
5
|
+
## Resolved name
|
|
6
|
+
|
|
7
|
+
`Tabs`
|
|
8
|
+
|
|
9
|
+
## Configurable props
|
|
10
|
+
|
|
11
|
+
### Top-level props
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Description |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| `defaultActiveIndex` | `number` | Index của tab active mặc định (0-based) |
|
|
16
|
+
|
|
17
|
+
### `sx` props
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
sx?: {
|
|
21
|
+
// size
|
|
22
|
+
width?: number | string
|
|
23
|
+
|
|
24
|
+
// spacing
|
|
25
|
+
paddingTop?: number
|
|
26
|
+
paddingRight?: number
|
|
27
|
+
paddingBottom?: number
|
|
28
|
+
paddingLeft?: number
|
|
29
|
+
marginTop?: number
|
|
30
|
+
marginRight?: number
|
|
31
|
+
marginBottom?: number
|
|
32
|
+
marginLeft?: number
|
|
33
|
+
|
|
34
|
+
// border
|
|
35
|
+
borderStyle?: string
|
|
36
|
+
borderColor?: string
|
|
37
|
+
borderTopWidth?: number
|
|
38
|
+
borderRightWidth?: number
|
|
39
|
+
borderBottomWidth?: number
|
|
40
|
+
borderLeftWidth?: number
|
|
41
|
+
borderTopLeftRadius?: number | string
|
|
42
|
+
borderTopRightRadius?: number | string
|
|
43
|
+
borderBottomRightRadius?: number | string
|
|
44
|
+
borderBottomLeftRadius?: number | string
|
|
45
|
+
|
|
46
|
+
// background
|
|
47
|
+
backgroundColor?: string
|
|
48
|
+
backgroundImage?: string
|
|
49
|
+
backgroundPosition?: string
|
|
50
|
+
backgroundRepeat?: string
|
|
51
|
+
backgroundSize?: string
|
|
52
|
+
backgroundAttachment?: string
|
|
53
|
+
background?: string
|
|
54
|
+
|
|
55
|
+
// responsive overrides
|
|
56
|
+
sm?: { /* same keys above */ }
|
|
57
|
+
md?: { /* same keys above */ }
|
|
58
|
+
lg?: { /* same keys above */ }
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Usage
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
import { TabsNode } from '@janbox/storefront-builder';
|
|
66
|
+
|
|
67
|
+
<TabsNode
|
|
68
|
+
defaultActiveIndex={0}
|
|
69
|
+
sx={{
|
|
70
|
+
width: '100%',
|
|
71
|
+
paddingTop: 16,
|
|
72
|
+
paddingBottom: 16,
|
|
73
|
+
}}
|
|
74
|
+
>
|
|
75
|
+
{/* TabListNode và TabContentNode tự động được thêm bởi editor */}
|
|
76
|
+
</TabsNode>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Rules
|
|
80
|
+
|
|
81
|
+
- **Canvas**: no.
|
|
82
|
+
- **Children**: phải có `TabListNode` và `TabContentNode`.
|
|
83
|
+
- Inspector có "Items management" để add/remove/reorder tabs — sync giữa `TabNode` và `TabPanelNode`.
|
|
84
|
+
|
|
85
|
+
## Related nodes
|
|
86
|
+
|
|
87
|
+
- [`TabListNode`](../tab-list/README.md) — container cho tab headers
|
|
88
|
+
- [`TabNode`](../tab/README.md) — mỗi tab header button
|
|
89
|
+
- [`TabContentNode`](../tab-content/README.md) — container cho tab panels
|
|
90
|
+
- [`TabPanelNode`](../tab-panel/README.md) — nội dung của mỗi tab
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# TextNode
|
|
2
|
+
|
|
3
|
+
Inline/block text node có thể chỉnh typography. Render ra bất kỳ HTML tag nào qua prop `as`. Hỗ trợ inline editing trong canvas.
|
|
4
|
+
|
|
5
|
+
## Resolved name
|
|
6
|
+
|
|
7
|
+
`Text`
|
|
8
|
+
|
|
9
|
+
## Configurable props
|
|
10
|
+
|
|
11
|
+
### Top-level props
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Description |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| `as` | `HTMLElementType` | HTML tag render ra (mặc định `p`) |
|
|
16
|
+
| `sizeVariant` | `TypographySizeVariant` | Preset typography size từ theme |
|
|
17
|
+
|
|
18
|
+
`sizeVariant` hỗ trợ responsive: `sizeVariant="base"` xs, `md={{ sizeVariant: 'lg' }}` desktop.
|
|
19
|
+
|
|
20
|
+
**`TypographySizeVariant`:** `'xs' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl'`
|
|
21
|
+
|
|
22
|
+
### `sx` props
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
sx?: {
|
|
26
|
+
// typography (áp dụng toàn breakpoint — không responsive)
|
|
27
|
+
color?: string
|
|
28
|
+
fontStyle?: 'normal' | 'italic'
|
|
29
|
+
fontWeight?: number | string
|
|
30
|
+
textDecorationLine?: 'none' | 'underline' | 'line-through'
|
|
31
|
+
textAlign?: 'left' | 'center' | 'right' | 'justify'
|
|
32
|
+
textTransform?: 'none' | 'uppercase' | 'lowercase' | 'capitalize'
|
|
33
|
+
|
|
34
|
+
// size
|
|
35
|
+
width?: number | string
|
|
36
|
+
|
|
37
|
+
// spacing
|
|
38
|
+
paddingTop?: number
|
|
39
|
+
paddingRight?: number
|
|
40
|
+
paddingBottom?: number
|
|
41
|
+
paddingLeft?: number
|
|
42
|
+
marginTop?: number
|
|
43
|
+
marginRight?: number
|
|
44
|
+
marginBottom?: number
|
|
45
|
+
marginLeft?: number
|
|
46
|
+
|
|
47
|
+
// responsive overrides
|
|
48
|
+
sm?: { /* same keys above */ }
|
|
49
|
+
md?: { /* same keys above */ }
|
|
50
|
+
lg?: { /* same keys above */ }
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
> `color`, `fontStyle`, `textDecorationLine`, `textAlign`, `textTransform` được editor set ở breakpoint `xs` (áp dụng toàn bộ). `fontWeight` và `sizeVariant` hỗ trợ responsive.
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
import { TextNode } from '@janbox/storefront-builder';
|
|
60
|
+
|
|
61
|
+
// Text đơn giản
|
|
62
|
+
<TextNode>Hello world</TextNode>
|
|
63
|
+
|
|
64
|
+
// Đổi tag, size variant
|
|
65
|
+
<TextNode as="span" sizeVariant="sm">
|
|
66
|
+
Small label
|
|
67
|
+
</TextNode>
|
|
68
|
+
|
|
69
|
+
// sizeVariant responsive
|
|
70
|
+
<TextNode sizeVariant="base" md={{ sizeVariant: 'lg' }}>
|
|
71
|
+
Body text
|
|
72
|
+
</TextNode>
|
|
73
|
+
|
|
74
|
+
// Màu, căn giữa, font weight responsive
|
|
75
|
+
<TextNode
|
|
76
|
+
sx={{
|
|
77
|
+
color: '#333333',
|
|
78
|
+
textAlign: 'center',
|
|
79
|
+
fontWeight: 400,
|
|
80
|
+
md: { fontWeight: 600 },
|
|
81
|
+
}}
|
|
82
|
+
>
|
|
83
|
+
Styled text
|
|
84
|
+
</TextNode>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Rules
|
|
88
|
+
|
|
89
|
+
- **Canvas**: no — không chứa node con.
|
|
90
|
+
- **Inline editing**: có thể double-click để chỉnh nội dung trực tiếp trong canvas.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# UnknownNode
|
|
2
|
+
|
|
3
|
+
Fallback node hiển thị khi một node trong serialized data có `resolvedName` không tồn tại trong resolver.
|
|
4
|
+
|
|
5
|
+
## Resolved name
|
|
6
|
+
|
|
7
|
+
`Unknown`
|
|
8
|
+
|
|
9
|
+
## Configurable props
|
|
10
|
+
|
|
11
|
+
Không có props.
|
|
12
|
+
|
|
13
|
+
## Behavior
|
|
14
|
+
|
|
15
|
+
- **Render mode** (`enabled: false`): render nothing — hoàn toàn invisible.
|
|
16
|
+
- **Editor mode** (`enabled: true`): hiển thị placeholder "Section is not available" kèm nút **Remove** để xóa node.
|
|
17
|
+
|
|
18
|
+
## Khi nào xảy ra
|
|
19
|
+
|
|
20
|
+
`Canvas` tự động thay thế node bằng `UnknownNode` khi load `SerializedNodes` mà `resolvedName` không có trong resolver:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
// Trong Canvas component
|
|
24
|
+
const resolvedNode = resolver[resolvedName];
|
|
25
|
+
if (!resolvedNode) {
|
|
26
|
+
value.type = { resolvedName: CoreNodeResolvedEnum.Unknown };
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Thường xảy ra khi:
|
|
31
|
+
- Custom node bị xóa khỏi codebase nhưng data cũ vẫn còn lưu
|
|
32
|
+
- Resolver không được pass đầy đủ node types
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
Không cần dùng trực tiếp. Được xử lý tự động bởi `Canvas`.
|
|
37
|
+
|
|
38
|
+
Nếu muốn tránh `UnknownNode` xuất hiện, đảm bảo truyền đầy đủ resolver khi mount `Composer`:
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
import { MyCustomNode } from './my-custom-node';
|
|
42
|
+
|
|
43
|
+
<Composer resolver={{ MyCustomNode }}>
|
|
44
|
+
<Canvas data={savedNodes}>
|
|
45
|
+
<RootNode />
|
|
46
|
+
</Canvas>
|
|
47
|
+
</Composer>
|
|
48
|
+
```
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# UnorderedListNode
|
|
2
|
+
|
|
3
|
+
Danh sách dọc (`ul`) — container cho các `ListItemNode`. Không render bullet mặc định, layout dùng flexbox column.
|
|
4
|
+
|
|
5
|
+
## Resolved name
|
|
6
|
+
|
|
7
|
+
`UnorderedList`
|
|
8
|
+
|
|
9
|
+
## Configurable props
|
|
10
|
+
|
|
11
|
+
### `sx` props
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
sx?: {
|
|
15
|
+
// layout
|
|
16
|
+
width?: number | string
|
|
17
|
+
rowGap?: number // khoảng cách giữa các items
|
|
18
|
+
alignItems?: 'flex-start' | 'flex-end' | 'center' // căn ngang các items
|
|
19
|
+
|
|
20
|
+
// spacing
|
|
21
|
+
paddingTop?: number
|
|
22
|
+
paddingRight?: number
|
|
23
|
+
paddingBottom?: number
|
|
24
|
+
paddingLeft?: number
|
|
25
|
+
marginTop?: number
|
|
26
|
+
marginRight?: number
|
|
27
|
+
marginBottom?: number
|
|
28
|
+
marginLeft?: number
|
|
29
|
+
|
|
30
|
+
// border
|
|
31
|
+
borderStyle?: string
|
|
32
|
+
borderColor?: string
|
|
33
|
+
borderTopWidth?: number
|
|
34
|
+
borderRightWidth?: number
|
|
35
|
+
borderBottomWidth?: number
|
|
36
|
+
borderLeftWidth?: number
|
|
37
|
+
borderTopLeftRadius?: number | string
|
|
38
|
+
borderTopRightRadius?: number | string
|
|
39
|
+
borderBottomRightRadius?: number | string
|
|
40
|
+
borderBottomLeftRadius?: number | string
|
|
41
|
+
|
|
42
|
+
// responsive overrides
|
|
43
|
+
sm?: { /* same keys above */ }
|
|
44
|
+
md?: { /* same keys above */ }
|
|
45
|
+
lg?: { /* same keys above */ }
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
import { UnorderedListNode, ListItemNode, TextNode, IconNode } from '@janbox/storefront-builder';
|
|
53
|
+
|
|
54
|
+
// Danh sách các text items
|
|
55
|
+
<UnorderedListNode sx={{ rowGap: 8 }}>
|
|
56
|
+
<ListItemNode>
|
|
57
|
+
<TextNode>Item 1</TextNode>
|
|
58
|
+
</ListItemNode>
|
|
59
|
+
<ListItemNode>
|
|
60
|
+
<TextNode>Item 2</TextNode>
|
|
61
|
+
</ListItemNode>
|
|
62
|
+
</UnorderedListNode>
|
|
63
|
+
|
|
64
|
+
// Icon + text, căn giữa dọc
|
|
65
|
+
<UnorderedListNode sx={{ rowGap: 12, width: '100%' }}>
|
|
66
|
+
<ListItemNode>
|
|
67
|
+
<FlexboxNode sx={{ flexDirection: 'row', alignItems: 'center', columnGap: 8 }}>
|
|
68
|
+
<FlexItemNode><IconNode source="..." size={16} /></FlexItemNode>
|
|
69
|
+
<FlexItemNode sx={{ flexGrow: 1 }}><TextNode>Feature description</TextNode></FlexItemNode>
|
|
70
|
+
</FlexboxNode>
|
|
71
|
+
</ListItemNode>
|
|
72
|
+
</UnorderedListNode>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Rules
|
|
76
|
+
|
|
77
|
+
- **Canvas**: no — không trực tiếp nhận drop.
|
|
78
|
+
- **Children**: `ListItemNode` — thêm qua inspector.
|
|
79
|
+
|
|
80
|
+
## Related nodes
|
|
81
|
+
|
|
82
|
+
- [`ListItemNode`](../list-item/README.md) — mỗi item trong list
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# VideoNode
|
|
2
|
+
|
|
3
|
+
Video player node dùng `react-player`. Hỗ trợ nhiều nguồn video: YouTube, Vimeo, file MP4, v.v.
|
|
4
|
+
|
|
5
|
+
## Resolved name
|
|
6
|
+
|
|
7
|
+
`Video`
|
|
8
|
+
|
|
9
|
+
## Configurable props
|
|
10
|
+
|
|
11
|
+
### Top-level props
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Description |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| `src` | `string` | URL video (YouTube, Vimeo, MP4, v.v.) |
|
|
16
|
+
| `light` | `string \| boolean` | URL thumbnail hiển thị trước khi play |
|
|
17
|
+
|
|
18
|
+
### `sx` props
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
sx?: {
|
|
22
|
+
// size
|
|
23
|
+
width?: number | string
|
|
24
|
+
aspectRatio?: string // ví dụ: '16 / 9', '1 / 1'
|
|
25
|
+
|
|
26
|
+
// spacing
|
|
27
|
+
paddingTop?: number
|
|
28
|
+
paddingRight?: number
|
|
29
|
+
paddingBottom?: number
|
|
30
|
+
paddingLeft?: number
|
|
31
|
+
marginTop?: number
|
|
32
|
+
marginRight?: number
|
|
33
|
+
marginBottom?: number
|
|
34
|
+
marginLeft?: number
|
|
35
|
+
|
|
36
|
+
// border
|
|
37
|
+
borderStyle?: string
|
|
38
|
+
borderColor?: string
|
|
39
|
+
borderTopWidth?: number
|
|
40
|
+
borderRightWidth?: number
|
|
41
|
+
borderBottomWidth?: number
|
|
42
|
+
borderLeftWidth?: number
|
|
43
|
+
borderTopLeftRadius?: number | string
|
|
44
|
+
borderTopRightRadius?: number | string
|
|
45
|
+
borderBottomRightRadius?: number | string
|
|
46
|
+
borderBottomLeftRadius?: number | string
|
|
47
|
+
|
|
48
|
+
// responsive overrides
|
|
49
|
+
sm?: { /* same keys above */ }
|
|
50
|
+
md?: { /* same keys above */ }
|
|
51
|
+
lg?: { /* same keys above */ }
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Usage
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { VideoNode } from '@janbox/storefront-builder';
|
|
59
|
+
|
|
60
|
+
// YouTube video
|
|
61
|
+
<VideoNode
|
|
62
|
+
src="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
|
|
63
|
+
sx={{ width: '100%', aspectRatio: '16 / 9' }}
|
|
64
|
+
/>
|
|
65
|
+
|
|
66
|
+
// MP4 video với thumbnail
|
|
67
|
+
<VideoNode
|
|
68
|
+
src="https://example.com/video.mp4"
|
|
69
|
+
light="https://example.com/thumbnail.jpg"
|
|
70
|
+
sx={{ width: '100%', aspectRatio: '16 / 9' }}
|
|
71
|
+
/>
|
|
72
|
+
|
|
73
|
+
// Responsive width, aspect ratio cố định
|
|
74
|
+
<VideoNode
|
|
75
|
+
src="https://vimeo.com/123456789"
|
|
76
|
+
sx={{
|
|
77
|
+
width: '100%',
|
|
78
|
+
aspectRatio: '16 / 9',
|
|
79
|
+
borderTopLeftRadius: 8,
|
|
80
|
+
borderTopRightRadius: 8,
|
|
81
|
+
borderBottomLeftRadius: 8,
|
|
82
|
+
borderBottomRightRadius: 8,
|
|
83
|
+
md: { width: '80%' },
|
|
84
|
+
}}
|
|
85
|
+
/>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Rules
|
|
89
|
+
|
|
90
|
+
- **Canvas**: no — không chứa node con.
|
|
91
|
+
- Dùng `react-player` bên dưới — hỗ trợ YouTube, Vimeo, Twitch, SoundCloud, Streamable, Wistia, Facebook, file video, v.v.
|
|
@@ -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
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# AccordionGroupNode
|
|
2
|
+
|
|
3
|
+
Container cho danh sách accordion items. Quản lý open mode (single/multiple) và styling chung cho tất cả items.
|
|
4
|
+
|
|
5
|
+
## Resolved name
|
|
6
|
+
|
|
7
|
+
`AccordionGroup` (displayName: `Accordion`)
|
|
8
|
+
|
|
9
|
+
## Configurable props
|
|
10
|
+
|
|
11
|
+
### Top-level props
|
|
12
|
+
|
|
13
|
+
| Prop | Type | Description |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| `openMode` | `'single' \| 'multiple'` | Single: chỉ 1 item mở cùng lúc. Multiple: nhiều items mở cùng lúc |
|
|
16
|
+
| `accordionSummaryProps.sx` | `StyledCSS` | Styling áp dụng cho tất cả accordion headers |
|
|
17
|
+
| `accordionContentProps.sx` | `StyledCSS` | Styling áp dụng cho tất cả accordion content areas |
|
|
18
|
+
|
|
19
|
+
### `sx` props
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
sx?: {
|
|
23
|
+
// layout
|
|
24
|
+
width?: number | string
|
|
25
|
+
rowGap?: number // khoảng cách giữa các items
|
|
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
|
+
// responsive overrides
|
|
38
|
+
sm?: { /* same keys above */ }
|
|
39
|
+
md?: { /* same keys above */ }
|
|
40
|
+
lg?: { /* same keys above */ }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Styling cho headers (accordionSummaryProps.sx)
|
|
44
|
+
accordionSummaryProps?: {
|
|
45
|
+
sx?: {
|
|
46
|
+
paddingTop?: number
|
|
47
|
+
paddingRight?: number
|
|
48
|
+
paddingBottom?: number
|
|
49
|
+
paddingLeft?: number
|
|
50
|
+
// ... responsive
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Styling cho content (accordionContentProps.sx)
|
|
55
|
+
accordionContentProps?: {
|
|
56
|
+
sx?: {
|
|
57
|
+
paddingTop?: number
|
|
58
|
+
paddingRight?: number
|
|
59
|
+
paddingBottom?: number
|
|
60
|
+
paddingLeft?: number
|
|
61
|
+
// ... responsive
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Usage
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import { AccordionGroupNode, AccordionNode } from '@janbox/storefront-builder';
|
|
70
|
+
|
|
71
|
+
// Single open mode
|
|
72
|
+
<AccordionGroupNode
|
|
73
|
+
openMode="single"
|
|
74
|
+
sx={{ rowGap: 8 }}
|
|
75
|
+
accordionSummaryProps={{ sx: { paddingTop: 12, paddingBottom: 12 } }}
|
|
76
|
+
accordionContentProps={{ sx: { paddingTop: 16, paddingBottom: 16 } }}
|
|
77
|
+
>
|
|
78
|
+
<AccordionNode>...</AccordionNode>
|
|
79
|
+
<AccordionNode>...</AccordionNode>
|
|
80
|
+
</AccordionGroupNode>
|
|
81
|
+
|
|
82
|
+
// Multiple items có thể mở cùng lúc
|
|
83
|
+
<AccordionGroupNode
|
|
84
|
+
openMode="multiple"
|
|
85
|
+
sx={{
|
|
86
|
+
width: '100%',
|
|
87
|
+
rowGap: 4,
|
|
88
|
+
md: { rowGap: 8 },
|
|
89
|
+
}}
|
|
90
|
+
>
|
|
91
|
+
<AccordionNode>...</AccordionNode>
|
|
92
|
+
<AccordionNode>...</AccordionNode>
|
|
93
|
+
<AccordionNode>...</AccordionNode>
|
|
94
|
+
</AccordionGroupNode>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Rules
|
|
98
|
+
|
|
99
|
+
- **Canvas**: yes — chứa `AccordionNode` children.
|
|
100
|
+
- **canMoveIn**: chỉ chấp nhận `AccordionNode`.
|
|
101
|
+
|
|
102
|
+
## Related nodes
|
|
103
|
+
|
|
104
|
+
- [`AccordionNode`](../accordion/README.md) — item bên trong group
|
|
105
|
+
- [`AccordionSummaryNode`](../accordion-summary/README.md) — header của mỗi item
|
|
106
|
+
- [`AccordionContentNode`](../accordion-content/README.md) — content area của mỗi item
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# AccordionSummaryNode
|
|
2
|
+
|
|
3
|
+
Header của accordion item — phần luôn hiển thị, click để toggle open/close. Là canvas node — chứa text/icon/node con.
|
|
4
|
+
|
|
5
|
+
## Resolved name
|
|
6
|
+
|
|
7
|
+
`AccordionSummary`
|
|
8
|
+
|
|
9
|
+
## Configurable props
|
|
10
|
+
|
|
11
|
+
Không có props riêng. Padding được config qua `AccordionGroupNode.accordionSummaryProps.sx`.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { AccordionSummaryNode, TextNode, IconNode } from '@janbox/storefront-builder';
|
|
17
|
+
|
|
18
|
+
<AccordionSummaryNode>
|
|
19
|
+
<FlexboxNode sx={{ justifyContent: 'space-between', alignItems: 'center' }}>
|
|
20
|
+
<TextNode>Question title</TextNode>
|
|
21
|
+
<IconNode source="..." size={16} />
|
|
22
|
+
</FlexboxNode>
|
|
23
|
+
</AccordionSummaryNode>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Rules
|
|
27
|
+
|
|
28
|
+
- **Canvas**: yes — chứa bất kỳ node con nào.
|
|
29
|
+
- **Selectable**: no.
|
|
30
|
+
- **canMoveOut**: no — không thể kéo ra khỏi `AccordionNode`.
|
|
31
|
+
- **Parent**: phải là `AccordionNode`.
|
|
32
|
+
|
|
33
|
+
## Related nodes
|
|
34
|
+
|
|
35
|
+
- [`AccordionNode`](../accordion/README.md) — parent item
|
|
36
|
+
- [`AccordionGroupNode`](../accordion-group/README.md) — root container
|
|
37
|
+
- [`AccordionContentNode`](../accordion-content/README.md) — content area
|