@delightui/components 0.1.104 → 0.1.106
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 +104 -1
- package/dist/cjs/components/molecules/Modal/DemoModal.d.ts +8 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/index.d.ts +3 -0
- package/dist/cjs/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
- package/dist/cjs/components/molecules/Modal/index.d.ts +2 -0
- package/dist/cjs/components/molecules/Popover/Popover.presenter.d.ts +26 -0
- package/dist/cjs/components/molecules/Select/Option/Option.types.d.ts +6 -0
- package/dist/cjs/components/molecules/Select/Select.Context.d.ts +1 -1
- package/dist/cjs/components/molecules/Select/Select.d.ts +5 -5
- package/dist/cjs/components/molecules/Select/Select.presenter.d.ts +1 -0
- package/dist/cjs/components/molecules/Select/Select.types.d.ts +5 -0
- package/dist/cjs/components/molecules/Select/index.d.ts +2 -9
- package/dist/cjs/components/molecules/index.d.ts +2 -0
- package/dist/cjs/components/utils/accessibilityUtils.d.ts +41 -0
- package/dist/cjs/components/utils/index.d.ts +2 -0
- package/dist/cjs/library.css +13 -0
- package/dist/cjs/library.js +2 -2
- package/dist/cjs/library.js.map +1 -1
- package/dist/esm/components/molecules/Modal/DemoModal.d.ts +8 -0
- package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.d.ts +41 -0
- package/dist/esm/components/molecules/Modal/ModalContext/ModalContext.types.d.ts +87 -0
- package/dist/esm/components/molecules/Modal/ModalContext/index.d.ts +3 -0
- package/dist/esm/components/molecules/Modal/ModalContext/useModal.d.ts +34 -0
- package/dist/esm/components/molecules/Modal/index.d.ts +2 -0
- package/dist/esm/components/molecules/Popover/Popover.presenter.d.ts +26 -0
- package/dist/esm/components/molecules/Select/Option/Option.types.d.ts +6 -0
- package/dist/esm/components/molecules/Select/Select.Context.d.ts +1 -1
- package/dist/esm/components/molecules/Select/Select.d.ts +5 -5
- package/dist/esm/components/molecules/Select/Select.presenter.d.ts +1 -0
- package/dist/esm/components/molecules/Select/Select.types.d.ts +5 -0
- package/dist/esm/components/molecules/Select/index.d.ts +2 -9
- package/dist/esm/components/molecules/index.d.ts +2 -0
- package/dist/esm/components/utils/accessibilityUtils.d.ts +41 -0
- package/dist/esm/components/utils/index.d.ts +2 -0
- package/dist/esm/library.css +13 -0
- package/dist/esm/library.js +3 -3
- package/dist/esm/library.js.map +1 -1
- package/dist/index.d.ts +156 -12
- package/docs/README.md +264 -0
- package/docs/components/atoms/ActionImage.md +119 -0
- package/docs/components/atoms/Button.md +197 -0
- package/docs/components/atoms/Checkbox.md +299 -0
- package/docs/components/atoms/CheckboxItem.md +314 -0
- package/docs/components/atoms/Chip.md +380 -0
- package/docs/components/atoms/CustomToggle.md +270 -0
- package/docs/components/atoms/Icon.md +365 -0
- package/docs/components/atoms/IconButton.md +407 -0
- package/docs/components/atoms/Image.md +448 -0
- package/docs/components/atoms/Input.md +430 -0
- package/docs/components/atoms/ListItem.md +502 -0
- package/docs/components/atoms/Password.md +472 -0
- package/docs/components/atoms/RadioButton.md +614 -0
- package/docs/components/atoms/RadioButtonItem.md +588 -0
- package/docs/components/atoms/ResponsiveComponent.md +612 -0
- package/docs/components/atoms/SelectListItem.md +609 -0
- package/docs/components/atoms/Slider.md +605 -0
- package/docs/components/atoms/Spinner.md +605 -0
- package/docs/components/atoms/Text.md +463 -0
- package/docs/components/atoms/TextArea.md +670 -0
- package/docs/components/atoms/ToastNotification.md +668 -0
- package/docs/components/atoms/Toggle.md +737 -0
- package/docs/components/atoms/ToggleButton.md +751 -0
- package/docs/components/atoms/Tooltip.md +391 -0
- package/docs/components/molecules/Accordion.md +440 -0
- package/docs/components/molecules/AccordionGroup.md +547 -0
- package/docs/components/molecules/ActionCard.md +546 -0
- package/docs/components/molecules/Breadcrumb.md +403 -0
- package/docs/components/molecules/Breadcrumbs.md +485 -0
- package/docs/components/molecules/ButtonGroup.md +383 -0
- package/docs/components/molecules/Card.md +298 -0
- package/docs/components/molecules/ChipInput.md +646 -0
- package/docs/components/molecules/ContextMenu.md +768 -0
- package/docs/components/molecules/CustomTimeSelector.md +116 -0
- package/docs/components/molecules/DatePicker.md +516 -0
- package/docs/components/molecules/DateTimeSelector.md +166 -0
- package/docs/components/molecules/FormField.md +312 -0
- package/docs/components/molecules/Grid.md +577 -0
- package/docs/components/molecules/GridItem.md +834 -0
- package/docs/components/molecules/GridList.md +244 -0
- package/docs/components/molecules/List.md +485 -0
- package/docs/components/molecules/Modal.md +470 -0
- package/docs/components/molecules/ModalFooter.md +702 -0
- package/docs/components/molecules/ModalHeader.md +756 -0
- package/docs/components/molecules/ModalProvider.md +205 -0
- package/docs/components/molecules/Nav.md +530 -0
- package/docs/components/molecules/NavItem.md +572 -0
- package/docs/components/molecules/NavLink.md +499 -0
- package/docs/components/molecules/Option.md +521 -0
- package/docs/components/molecules/Pagination.md +592 -0
- package/docs/components/molecules/PaginationNumberField.md +722 -0
- package/docs/components/molecules/Popover.md +516 -0
- package/docs/components/molecules/ProgressBar.md +624 -0
- package/docs/components/molecules/RadioGroup.md +831 -0
- package/docs/components/molecules/RepeaterList.md +185 -0
- package/docs/components/molecules/Select.md +402 -0
- package/docs/components/molecules/SortableTrigger.md +82 -0
- package/docs/components/molecules/useModal.md +379 -0
- package/docs/components/organisms/Dropzone.md +346 -0
- package/docs/components/organisms/DropzoneClear.md +135 -0
- package/docs/components/organisms/DropzoneContent.md +216 -0
- package/docs/components/organisms/DropzoneFilename.md +191 -0
- package/docs/components/organisms/DropzoneSupportedFormats.md +184 -0
- package/docs/components/organisms/DropzoneTrigger.md +209 -0
- package/docs/components/organisms/Form.md +533 -0
- package/docs/components/organisms/SlideOutPanel.md +662 -0
- package/docs/components/organisms/TabContent.md +902 -0
- package/docs/components/organisms/TabItem.md +1091 -0
- package/docs/components/organisms/Table.md +611 -0
- package/docs/components/organisms/TableBody.md +679 -0
- package/docs/components/organisms/TableCell.md +482 -0
- package/docs/components/organisms/TableHeader.md +513 -0
- package/docs/components/organisms/TableHeaderCell.md +661 -0
- package/docs/components/organisms/TableRow.md +715 -0
- package/docs/components/organisms/Tabs.md +1330 -0
- package/docs/components/utils/ConditionalView.md +568 -0
- package/docs/components/utils/RenderStateView.md +726 -0
- package/docs/components/utils/WrapTextNodes.md +614 -0
- package/package.json +3 -2
|
@@ -0,0 +1,834 @@
|
|
|
1
|
+
# GridItem
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
An individual grid item component designed to work within the Grid component. Provides flexible control over item positioning and spanning with columnSpan and rowSpan properties, enabling complex grid layouts with items that can occupy multiple cells.
|
|
6
|
+
|
|
7
|
+
## Aliases
|
|
8
|
+
|
|
9
|
+
- GridItem
|
|
10
|
+
- GridCell
|
|
11
|
+
- GridChild
|
|
12
|
+
- GridElement
|
|
13
|
+
- LayoutItem
|
|
14
|
+
|
|
15
|
+
## Props Breakdown
|
|
16
|
+
|
|
17
|
+
**Extends:** HTMLAttributes<HTMLDivElement> (inherits all div element properties)
|
|
18
|
+
|
|
19
|
+
| Prop | Type | Default | Required | Description |
|
|
20
|
+
|------|------|---------|----------|-------------|
|
|
21
|
+
| `columnSpan` | `number` | `1` | No | Number of columns the item should span |
|
|
22
|
+
| `rowSpan` | `number` | `1` | No | Number of rows the item should span |
|
|
23
|
+
| `children` | `ReactNode` | - | Yes | Content to be displayed within the grid item |
|
|
24
|
+
| `className` | `string` | - | No | Additional CSS class names |
|
|
25
|
+
| `style` | `CSSProperties` | - | No | Inline styles for the grid item |
|
|
26
|
+
|
|
27
|
+
## Examples
|
|
28
|
+
|
|
29
|
+
### Basic Grid Items
|
|
30
|
+
```tsx
|
|
31
|
+
import { Grid, GridItem, Card, Text } from '@delightui/components';
|
|
32
|
+
|
|
33
|
+
function BasicGridItemExample() {
|
|
34
|
+
return (
|
|
35
|
+
<Grid columns={3} className="basic-grid">
|
|
36
|
+
<GridItem>
|
|
37
|
+
<Card>
|
|
38
|
+
<Text type="Heading6">Regular Item</Text>
|
|
39
|
+
<Text>This item spans 1 column and 1 row</Text>
|
|
40
|
+
</Card>
|
|
41
|
+
</GridItem>
|
|
42
|
+
|
|
43
|
+
<GridItem columnSpan={2}>
|
|
44
|
+
<Card>
|
|
45
|
+
<Text type="Heading6">Wide Item</Text>
|
|
46
|
+
<Text>This item spans 2 columns and 1 row</Text>
|
|
47
|
+
</Card>
|
|
48
|
+
</GridItem>
|
|
49
|
+
|
|
50
|
+
<GridItem rowSpan={2}>
|
|
51
|
+
<Card>
|
|
52
|
+
<Text type="Heading6">Tall Item</Text>
|
|
53
|
+
<Text>This item spans 1 column and 2 rows</Text>
|
|
54
|
+
</Card>
|
|
55
|
+
</GridItem>
|
|
56
|
+
|
|
57
|
+
<GridItem>
|
|
58
|
+
<Card>
|
|
59
|
+
<Text type="Heading6">Regular Item</Text>
|
|
60
|
+
<Text>Another regular item</Text>
|
|
61
|
+
</Card>
|
|
62
|
+
</GridItem>
|
|
63
|
+
|
|
64
|
+
<GridItem columnSpan={2} rowSpan={2}>
|
|
65
|
+
<Card>
|
|
66
|
+
<Text type="Heading6">Large Item</Text>
|
|
67
|
+
<Text>This item spans 2 columns and 2 rows</Text>
|
|
68
|
+
</Card>
|
|
69
|
+
</GridItem>
|
|
70
|
+
</Grid>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### News Layout Grid
|
|
76
|
+
```tsx
|
|
77
|
+
function NewsLayoutExample() {
|
|
78
|
+
const articles = [
|
|
79
|
+
{
|
|
80
|
+
id: 1,
|
|
81
|
+
title: 'Breaking: Major Tech Announcement',
|
|
82
|
+
excerpt: 'Industry leaders gather to discuss the future of technology...',
|
|
83
|
+
category: 'Technology',
|
|
84
|
+
image: '/news1.jpg',
|
|
85
|
+
featured: true
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: 2,
|
|
89
|
+
title: 'Market Update: Stocks Rise',
|
|
90
|
+
excerpt: 'Financial markets show positive trends...',
|
|
91
|
+
category: 'Finance',
|
|
92
|
+
image: '/news2.jpg'
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: 3,
|
|
96
|
+
title: 'Sports: Championship Finals',
|
|
97
|
+
excerpt: 'Teams prepare for the ultimate showdown...',
|
|
98
|
+
category: 'Sports',
|
|
99
|
+
image: '/news3.jpg'
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: 4,
|
|
103
|
+
title: 'Weather Alert: Storm Approaching',
|
|
104
|
+
excerpt: 'Meteorologists warn of severe weather conditions...',
|
|
105
|
+
category: 'Weather',
|
|
106
|
+
image: '/news4.jpg'
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: 5,
|
|
110
|
+
title: 'Health: New Research Findings',
|
|
111
|
+
excerpt: 'Scientists discover breakthrough in medical research...',
|
|
112
|
+
category: 'Health',
|
|
113
|
+
image: '/news5.jpg'
|
|
114
|
+
}
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<div className="news-layout">
|
|
119
|
+
<Text type="Heading3">Latest News</Text>
|
|
120
|
+
|
|
121
|
+
<Grid columns={4} className="news-grid">
|
|
122
|
+
{articles.map((article, index) => (
|
|
123
|
+
<GridItem
|
|
124
|
+
key={article.id}
|
|
125
|
+
columnSpan={article.featured ? 2 : 1}
|
|
126
|
+
rowSpan={article.featured ? 2 : 1}
|
|
127
|
+
>
|
|
128
|
+
<Card className={`news-card ${article.featured ? 'featured' : ''}`}>
|
|
129
|
+
<Image
|
|
130
|
+
src={article.image}
|
|
131
|
+
alt={article.title}
|
|
132
|
+
className="news-image"
|
|
133
|
+
fit="Cover"
|
|
134
|
+
/>
|
|
135
|
+
|
|
136
|
+
<div className="news-content">
|
|
137
|
+
<Chip size="Small" className="category-chip">
|
|
138
|
+
{article.category}
|
|
139
|
+
</Chip>
|
|
140
|
+
|
|
141
|
+
<Text
|
|
142
|
+
type={article.featured ? 'Heading4' : 'Heading6'}
|
|
143
|
+
className="news-title"
|
|
144
|
+
>
|
|
145
|
+
{article.title}
|
|
146
|
+
</Text>
|
|
147
|
+
|
|
148
|
+
<Text
|
|
149
|
+
type={article.featured ? 'Body' : 'BodySmall'}
|
|
150
|
+
className="news-excerpt"
|
|
151
|
+
>
|
|
152
|
+
{article.excerpt}
|
|
153
|
+
</Text>
|
|
154
|
+
|
|
155
|
+
<Button type="Text" size="Small">
|
|
156
|
+
Read More →
|
|
157
|
+
</Button>
|
|
158
|
+
</div>
|
|
159
|
+
</Card>
|
|
160
|
+
</GridItem>
|
|
161
|
+
))}
|
|
162
|
+
</Grid>
|
|
163
|
+
</div>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Dashboard Widgets
|
|
169
|
+
```tsx
|
|
170
|
+
function DashboardWidgetsExample() {
|
|
171
|
+
const widgets = [
|
|
172
|
+
{
|
|
173
|
+
id: 'sales',
|
|
174
|
+
title: 'Sales Overview',
|
|
175
|
+
type: 'chart',
|
|
176
|
+
columnSpan: 2,
|
|
177
|
+
rowSpan: 2,
|
|
178
|
+
data: { revenue: '$45,230', growth: '+12%' }
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
id: 'users',
|
|
182
|
+
title: 'Active Users',
|
|
183
|
+
type: 'metric',
|
|
184
|
+
columnSpan: 1,
|
|
185
|
+
rowSpan: 1,
|
|
186
|
+
data: { count: '1,234', change: '+8%' }
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
id: 'orders',
|
|
190
|
+
title: 'Recent Orders',
|
|
191
|
+
type: 'metric',
|
|
192
|
+
columnSpan: 1,
|
|
193
|
+
rowSpan: 1,
|
|
194
|
+
data: { count: '89', change: '-3%' }
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
id: 'activity',
|
|
198
|
+
title: 'Activity Feed',
|
|
199
|
+
type: 'list',
|
|
200
|
+
columnSpan: 2,
|
|
201
|
+
rowSpan: 3,
|
|
202
|
+
data: [
|
|
203
|
+
'User John signed up',
|
|
204
|
+
'Order #1234 completed',
|
|
205
|
+
'Payment processed',
|
|
206
|
+
'New review posted'
|
|
207
|
+
]
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
id: 'performance',
|
|
211
|
+
title: 'Performance Metrics',
|
|
212
|
+
type: 'chart',
|
|
213
|
+
columnSpan: 2,
|
|
214
|
+
rowSpan: 1,
|
|
215
|
+
data: { score: '94%', trend: 'up' }
|
|
216
|
+
}
|
|
217
|
+
];
|
|
218
|
+
|
|
219
|
+
const renderWidget = (widget) => {
|
|
220
|
+
switch (widget.type) {
|
|
221
|
+
case 'chart':
|
|
222
|
+
return (
|
|
223
|
+
<Card className="dashboard-widget chart-widget">
|
|
224
|
+
<Text type="Heading5">{widget.title}</Text>
|
|
225
|
+
<div className="chart-content">
|
|
226
|
+
<Text type="Heading3">{widget.data.revenue || widget.data.score}</Text>
|
|
227
|
+
<Text type="BodySmall" className="metric-change">
|
|
228
|
+
{widget.data.growth || `Trending ${widget.data.trend}`}
|
|
229
|
+
</Text>
|
|
230
|
+
</div>
|
|
231
|
+
</Card>
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
case 'metric':
|
|
235
|
+
return (
|
|
236
|
+
<Card className="dashboard-widget metric-widget">
|
|
237
|
+
<Text type="Heading6">{widget.title}</Text>
|
|
238
|
+
<Text type="Heading3">{widget.data.count}</Text>
|
|
239
|
+
<Text type="BodySmall" className="metric-change">
|
|
240
|
+
{widget.data.change}
|
|
241
|
+
</Text>
|
|
242
|
+
</Card>
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
case 'list':
|
|
246
|
+
return (
|
|
247
|
+
<Card className="dashboard-widget list-widget">
|
|
248
|
+
<Text type="Heading5">{widget.title}</Text>
|
|
249
|
+
<List className="activity-list">
|
|
250
|
+
{widget.data.map((item, index) => (
|
|
251
|
+
<ListItem key={index}>{item}</ListItem>
|
|
252
|
+
))}
|
|
253
|
+
</List>
|
|
254
|
+
</Card>
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
default:
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
return (
|
|
263
|
+
<div className="dashboard-widgets">
|
|
264
|
+
<Text type="Heading3">Dashboard</Text>
|
|
265
|
+
|
|
266
|
+
<Grid columns={4} className="widgets-grid">
|
|
267
|
+
{widgets.map(widget => (
|
|
268
|
+
<GridItem
|
|
269
|
+
key={widget.id}
|
|
270
|
+
columnSpan={widget.columnSpan}
|
|
271
|
+
rowSpan={widget.rowSpan}
|
|
272
|
+
>
|
|
273
|
+
{renderWidget(widget)}
|
|
274
|
+
</GridItem>
|
|
275
|
+
))}
|
|
276
|
+
</Grid>
|
|
277
|
+
</div>
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Product Showcase
|
|
283
|
+
```tsx
|
|
284
|
+
function ProductShowcaseExample() {
|
|
285
|
+
const products = [
|
|
286
|
+
{
|
|
287
|
+
id: 1,
|
|
288
|
+
name: 'Premium Headphones',
|
|
289
|
+
price: '$299',
|
|
290
|
+
image: '/headphones.jpg',
|
|
291
|
+
featured: true,
|
|
292
|
+
badge: 'Best Seller'
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
id: 2,
|
|
296
|
+
name: 'Smart Watch',
|
|
297
|
+
price: '$199',
|
|
298
|
+
image: '/watch.jpg',
|
|
299
|
+
badge: 'New'
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
id: 3,
|
|
303
|
+
name: 'Wireless Earbuds',
|
|
304
|
+
price: '$129',
|
|
305
|
+
image: '/earbuds.jpg'
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
id: 4,
|
|
309
|
+
name: 'Laptop Stand',
|
|
310
|
+
price: '$79',
|
|
311
|
+
image: '/stand.jpg'
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
id: 5,
|
|
315
|
+
name: 'USB-C Hub',
|
|
316
|
+
price: '$49',
|
|
317
|
+
image: '/hub.jpg'
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
id: 6,
|
|
321
|
+
name: 'Wireless Mouse',
|
|
322
|
+
price: '$39',
|
|
323
|
+
image: '/mouse.jpg'
|
|
324
|
+
}
|
|
325
|
+
];
|
|
326
|
+
|
|
327
|
+
return (
|
|
328
|
+
<div className="product-showcase">
|
|
329
|
+
<Text type="Heading3">Featured Products</Text>
|
|
330
|
+
|
|
331
|
+
<Grid columns={4} className="showcase-grid">
|
|
332
|
+
{products.map((product, index) => (
|
|
333
|
+
<GridItem
|
|
334
|
+
key={product.id}
|
|
335
|
+
columnSpan={product.featured ? 2 : 1}
|
|
336
|
+
rowSpan={product.featured ? 2 : 1}
|
|
337
|
+
>
|
|
338
|
+
<Card className={`product-card ${product.featured ? 'featured' : ''}`}>
|
|
339
|
+
{product.badge && (
|
|
340
|
+
<Chip className="product-badge" size="Small">
|
|
341
|
+
{product.badge}
|
|
342
|
+
</Chip>
|
|
343
|
+
)}
|
|
344
|
+
|
|
345
|
+
<Image
|
|
346
|
+
src={product.image}
|
|
347
|
+
alt={product.name}
|
|
348
|
+
className="product-image"
|
|
349
|
+
fit="Cover"
|
|
350
|
+
/>
|
|
351
|
+
|
|
352
|
+
<div className="product-info">
|
|
353
|
+
<Text
|
|
354
|
+
type={product.featured ? 'Heading4' : 'Heading6'}
|
|
355
|
+
className="product-name"
|
|
356
|
+
>
|
|
357
|
+
{product.name}
|
|
358
|
+
</Text>
|
|
359
|
+
|
|
360
|
+
<Text
|
|
361
|
+
type={product.featured ? 'Heading5' : 'Heading6'}
|
|
362
|
+
className="product-price"
|
|
363
|
+
>
|
|
364
|
+
{product.price}
|
|
365
|
+
</Text>
|
|
366
|
+
|
|
367
|
+
<Button
|
|
368
|
+
size={product.featured ? 'Medium' : 'Small'}
|
|
369
|
+
className="add-to-cart"
|
|
370
|
+
>
|
|
371
|
+
Add to Cart
|
|
372
|
+
</Button>
|
|
373
|
+
</div>
|
|
374
|
+
</Card>
|
|
375
|
+
</GridItem>
|
|
376
|
+
))}
|
|
377
|
+
</Grid>
|
|
378
|
+
</div>
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### Social Media Feed
|
|
384
|
+
```tsx
|
|
385
|
+
function SocialMediaFeedExample() {
|
|
386
|
+
const posts = [
|
|
387
|
+
{
|
|
388
|
+
id: 1,
|
|
389
|
+
type: 'image',
|
|
390
|
+
user: 'john_doe',
|
|
391
|
+
content: 'Beautiful sunset at the beach! 🌅',
|
|
392
|
+
image: '/sunset.jpg',
|
|
393
|
+
likes: 245,
|
|
394
|
+
comments: 18,
|
|
395
|
+
size: 'large'
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
id: 2,
|
|
399
|
+
type: 'text',
|
|
400
|
+
user: 'jane_smith',
|
|
401
|
+
content: 'Just finished reading an amazing book. Highly recommend "The Art of Coding" to all developers out there!',
|
|
402
|
+
likes: 89,
|
|
403
|
+
comments: 12,
|
|
404
|
+
size: 'regular'
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
id: 3,
|
|
408
|
+
type: 'video',
|
|
409
|
+
user: 'tech_guru',
|
|
410
|
+
content: 'Quick tutorial on React hooks',
|
|
411
|
+
thumbnail: '/video-thumb.jpg',
|
|
412
|
+
likes: 156,
|
|
413
|
+
comments: 23,
|
|
414
|
+
size: 'regular'
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
id: 4,
|
|
418
|
+
type: 'image',
|
|
419
|
+
user: 'foodie_life',
|
|
420
|
+
content: 'Homemade pasta night! 🍝',
|
|
421
|
+
image: '/pasta.jpg',
|
|
422
|
+
likes: 92,
|
|
423
|
+
comments: 8,
|
|
424
|
+
size: 'regular'
|
|
425
|
+
}
|
|
426
|
+
];
|
|
427
|
+
|
|
428
|
+
return (
|
|
429
|
+
<div className="social-feed">
|
|
430
|
+
<Text type="Heading3">Social Feed</Text>
|
|
431
|
+
|
|
432
|
+
<Grid columns={3} className="feed-grid">
|
|
433
|
+
{posts.map(post => (
|
|
434
|
+
<GridItem
|
|
435
|
+
key={post.id}
|
|
436
|
+
columnSpan={post.size === 'large' ? 2 : 1}
|
|
437
|
+
rowSpan={post.size === 'large' ? 2 : 1}
|
|
438
|
+
>
|
|
439
|
+
<Card className={`feed-post ${post.size === 'large' ? 'large-post' : ''}`}>
|
|
440
|
+
<div className="post-header">
|
|
441
|
+
<div className="user-info">
|
|
442
|
+
<div className="user-avatar">
|
|
443
|
+
<Image
|
|
444
|
+
src={`/avatars/${post.user}.jpg`}
|
|
445
|
+
alt={post.user}
|
|
446
|
+
className="avatar"
|
|
447
|
+
/>
|
|
448
|
+
</div>
|
|
449
|
+
<Text type="Heading6">@{post.user}</Text>
|
|
450
|
+
</div>
|
|
451
|
+
|
|
452
|
+
<IconButton size="Small">
|
|
453
|
+
<Icon icon="More" />
|
|
454
|
+
</IconButton>
|
|
455
|
+
</div>
|
|
456
|
+
|
|
457
|
+
<div className="post-content">
|
|
458
|
+
<Text type="Body">{post.content}</Text>
|
|
459
|
+
|
|
460
|
+
{post.image && (
|
|
461
|
+
<Image
|
|
462
|
+
src={post.image}
|
|
463
|
+
alt="Post image"
|
|
464
|
+
className="post-image"
|
|
465
|
+
fit="Cover"
|
|
466
|
+
/>
|
|
467
|
+
)}
|
|
468
|
+
|
|
469
|
+
{post.thumbnail && (
|
|
470
|
+
<div className="video-thumbnail">
|
|
471
|
+
<Image
|
|
472
|
+
src={post.thumbnail}
|
|
473
|
+
alt="Video thumbnail"
|
|
474
|
+
fit="Cover"
|
|
475
|
+
/>
|
|
476
|
+
<Icon icon="PlayCircle" className="play-button" />
|
|
477
|
+
</div>
|
|
478
|
+
)}
|
|
479
|
+
</div>
|
|
480
|
+
|
|
481
|
+
<div className="post-actions">
|
|
482
|
+
<Button type="Text" size="Small">
|
|
483
|
+
<Icon icon="Heart" /> {post.likes}
|
|
484
|
+
</Button>
|
|
485
|
+
<Button type="Text" size="Small">
|
|
486
|
+
<Icon icon="Comment" /> {post.comments}
|
|
487
|
+
</Button>
|
|
488
|
+
<Button type="Text" size="Small">
|
|
489
|
+
<Icon icon="Share" />
|
|
490
|
+
</Button>
|
|
491
|
+
</div>
|
|
492
|
+
</Card>
|
|
493
|
+
</GridItem>
|
|
494
|
+
))}
|
|
495
|
+
</Grid>
|
|
496
|
+
</div>
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### Portfolio Gallery
|
|
502
|
+
```tsx
|
|
503
|
+
function PortfolioGalleryExample() {
|
|
504
|
+
const portfolioItems = [
|
|
505
|
+
{
|
|
506
|
+
id: 1,
|
|
507
|
+
title: 'E-commerce Website',
|
|
508
|
+
category: 'Web Design',
|
|
509
|
+
image: '/portfolio1.jpg',
|
|
510
|
+
size: 'large',
|
|
511
|
+
tech: ['React', 'Node.js', 'MongoDB']
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
id: 2,
|
|
515
|
+
title: 'Mobile Banking App',
|
|
516
|
+
category: 'UI/UX Design',
|
|
517
|
+
image: '/portfolio2.jpg',
|
|
518
|
+
size: 'regular',
|
|
519
|
+
tech: ['React Native', 'Firebase']
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
id: 3,
|
|
523
|
+
title: 'Brand Identity',
|
|
524
|
+
category: 'Branding',
|
|
525
|
+
image: '/portfolio3.jpg',
|
|
526
|
+
size: 'regular',
|
|
527
|
+
tech: ['Illustrator', 'Photoshop']
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
id: 4,
|
|
531
|
+
title: 'Dashboard Analytics',
|
|
532
|
+
category: 'Data Visualization',
|
|
533
|
+
image: '/portfolio4.jpg',
|
|
534
|
+
size: 'wide',
|
|
535
|
+
tech: ['D3.js', 'React', 'Python']
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
id: 5,
|
|
539
|
+
title: 'Landing Page',
|
|
540
|
+
category: 'Web Design',
|
|
541
|
+
image: '/portfolio5.jpg',
|
|
542
|
+
size: 'regular',
|
|
543
|
+
tech: ['HTML', 'CSS', 'JavaScript']
|
|
544
|
+
}
|
|
545
|
+
];
|
|
546
|
+
|
|
547
|
+
const getGridSpan = (size) => {
|
|
548
|
+
switch (size) {
|
|
549
|
+
case 'large':
|
|
550
|
+
return { columnSpan: 2, rowSpan: 2 };
|
|
551
|
+
case 'wide':
|
|
552
|
+
return { columnSpan: 2, rowSpan: 1 };
|
|
553
|
+
case 'tall':
|
|
554
|
+
return { columnSpan: 1, rowSpan: 2 };
|
|
555
|
+
default:
|
|
556
|
+
return { columnSpan: 1, rowSpan: 1 };
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
return (
|
|
561
|
+
<div className="portfolio-gallery">
|
|
562
|
+
<div className="portfolio-header">
|
|
563
|
+
<Text type="Heading3">My Portfolio</Text>
|
|
564
|
+
<Text>A collection of my recent work and projects</Text>
|
|
565
|
+
</div>
|
|
566
|
+
|
|
567
|
+
<Grid columns={3} className="portfolio-grid">
|
|
568
|
+
{portfolioItems.map(item => {
|
|
569
|
+
const { columnSpan, rowSpan } = getGridSpan(item.size);
|
|
570
|
+
|
|
571
|
+
return (
|
|
572
|
+
<GridItem
|
|
573
|
+
key={item.id}
|
|
574
|
+
columnSpan={columnSpan}
|
|
575
|
+
rowSpan={rowSpan}
|
|
576
|
+
>
|
|
577
|
+
<Card className={`portfolio-item ${item.size}`}>
|
|
578
|
+
<Image
|
|
579
|
+
src={item.image}
|
|
580
|
+
alt={item.title}
|
|
581
|
+
className="portfolio-image"
|
|
582
|
+
fit="Cover"
|
|
583
|
+
/>
|
|
584
|
+
|
|
585
|
+
<div className="portfolio-overlay">
|
|
586
|
+
<div className="portfolio-info">
|
|
587
|
+
<Text type="Heading6" className="portfolio-title">
|
|
588
|
+
{item.title}
|
|
589
|
+
</Text>
|
|
590
|
+
|
|
591
|
+
<Text type="BodySmall" className="portfolio-category">
|
|
592
|
+
{item.category}
|
|
593
|
+
</Text>
|
|
594
|
+
|
|
595
|
+
<div className="portfolio-tech">
|
|
596
|
+
{item.tech.map(tech => (
|
|
597
|
+
<Chip key={tech} size="Small" className="tech-chip">
|
|
598
|
+
{tech}
|
|
599
|
+
</Chip>
|
|
600
|
+
))}
|
|
601
|
+
</div>
|
|
602
|
+
</div>
|
|
603
|
+
|
|
604
|
+
<div className="portfolio-actions">
|
|
605
|
+
<IconButton size="Small" className="view-button">
|
|
606
|
+
<Icon icon="Eye" />
|
|
607
|
+
</IconButton>
|
|
608
|
+
<IconButton size="Small" className="link-button">
|
|
609
|
+
<Icon icon="ExternalLink" />
|
|
610
|
+
</IconButton>
|
|
611
|
+
</div>
|
|
612
|
+
</div>
|
|
613
|
+
</Card>
|
|
614
|
+
</GridItem>
|
|
615
|
+
);
|
|
616
|
+
})}
|
|
617
|
+
</Grid>
|
|
618
|
+
</div>
|
|
619
|
+
);
|
|
620
|
+
}
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
### Event Calendar Grid
|
|
624
|
+
```tsx
|
|
625
|
+
function EventCalendarExample() {
|
|
626
|
+
const events = [
|
|
627
|
+
{
|
|
628
|
+
id: 1,
|
|
629
|
+
title: 'Team Meeting',
|
|
630
|
+
time: '9:00 AM',
|
|
631
|
+
duration: 1, // hours
|
|
632
|
+
color: 'blue'
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
id: 2,
|
|
636
|
+
title: 'Project Review',
|
|
637
|
+
time: '2:00 PM',
|
|
638
|
+
duration: 2,
|
|
639
|
+
color: 'green'
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
id: 3,
|
|
643
|
+
title: 'Client Call',
|
|
644
|
+
time: '4:00 PM',
|
|
645
|
+
duration: 1,
|
|
646
|
+
color: 'orange'
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
id: 4,
|
|
650
|
+
title: 'Workshop',
|
|
651
|
+
time: '10:00 AM',
|
|
652
|
+
duration: 3,
|
|
653
|
+
color: 'purple'
|
|
654
|
+
}
|
|
655
|
+
];
|
|
656
|
+
|
|
657
|
+
const timeSlots = Array.from({ length: 9 }, (_, i) => `${i + 9}:00`);
|
|
658
|
+
|
|
659
|
+
return (
|
|
660
|
+
<div className="event-calendar">
|
|
661
|
+
<Text type="Heading3">Today's Schedule</Text>
|
|
662
|
+
|
|
663
|
+
<Grid columns={4} className="calendar-grid">
|
|
664
|
+
{timeSlots.map((time, index) => (
|
|
665
|
+
<GridItem key={time} className="time-slot">
|
|
666
|
+
<Text type="BodySmall" className="time-label">
|
|
667
|
+
{time}
|
|
668
|
+
</Text>
|
|
669
|
+
</GridItem>
|
|
670
|
+
))}
|
|
671
|
+
|
|
672
|
+
{events.map(event => (
|
|
673
|
+
<GridItem
|
|
674
|
+
key={event.id}
|
|
675
|
+
columnSpan={1}
|
|
676
|
+
rowSpan={event.duration}
|
|
677
|
+
className={`event-item ${event.color}`}
|
|
678
|
+
>
|
|
679
|
+
<Card className="event-card">
|
|
680
|
+
<Text type="Heading6" className="event-title">
|
|
681
|
+
{event.title}
|
|
682
|
+
</Text>
|
|
683
|
+
<Text type="BodySmall" className="event-time">
|
|
684
|
+
{event.time}
|
|
685
|
+
</Text>
|
|
686
|
+
<Text type="BodySmall" className="event-duration">
|
|
687
|
+
{event.duration}h
|
|
688
|
+
</Text>
|
|
689
|
+
</Card>
|
|
690
|
+
</GridItem>
|
|
691
|
+
))}
|
|
692
|
+
</Grid>
|
|
693
|
+
</div>
|
|
694
|
+
);
|
|
695
|
+
}
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
### Masonry-Style Layout
|
|
699
|
+
```tsx
|
|
700
|
+
function MasonryLayoutExample() {
|
|
701
|
+
const items = [
|
|
702
|
+
{ id: 1, title: 'Short Content', content: 'Brief description here.', height: 1 },
|
|
703
|
+
{ id: 2, title: 'Medium Content', content: 'This is a medium-length content item with more text to display.', height: 2 },
|
|
704
|
+
{ id: 3, title: 'Long Content', content: 'This is a much longer content item that spans multiple lines and contains detailed information about the topic being discussed.', height: 3 },
|
|
705
|
+
{ id: 4, title: 'Short Content', content: 'Another brief item.', height: 1 },
|
|
706
|
+
{ id: 5, title: 'Medium Content', content: 'Another medium-length content item with descriptive text.', height: 2 },
|
|
707
|
+
{ id: 6, title: 'Short Content', content: 'Brief content here.', height: 1 }
|
|
708
|
+
];
|
|
709
|
+
|
|
710
|
+
return (
|
|
711
|
+
<div className="masonry-layout">
|
|
712
|
+
<Text type="Heading3">Masonry-Style Grid</Text>
|
|
713
|
+
|
|
714
|
+
<Grid columns={3} className="masonry-grid">
|
|
715
|
+
{items.map(item => (
|
|
716
|
+
<GridItem
|
|
717
|
+
key={item.id}
|
|
718
|
+
rowSpan={item.height}
|
|
719
|
+
>
|
|
720
|
+
<Card className={`masonry-item height-${item.height}`}>
|
|
721
|
+
<Text type="Heading6">{item.title}</Text>
|
|
722
|
+
<Text type="Body">{item.content}</Text>
|
|
723
|
+
|
|
724
|
+
<div className="item-meta">
|
|
725
|
+
<Text type="BodySmall">
|
|
726
|
+
Height: {item.height} unit{item.height > 1 ? 's' : ''}
|
|
727
|
+
</Text>
|
|
728
|
+
</div>
|
|
729
|
+
</Card>
|
|
730
|
+
</GridItem>
|
|
731
|
+
))}
|
|
732
|
+
</Grid>
|
|
733
|
+
</div>
|
|
734
|
+
);
|
|
735
|
+
}
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
### Responsive Grid Items
|
|
739
|
+
```tsx
|
|
740
|
+
function ResponsiveGridItemsExample() {
|
|
741
|
+
const [screenSize, setScreenSize] = useState('desktop');
|
|
742
|
+
|
|
743
|
+
const items = [
|
|
744
|
+
{ id: 1, title: 'Header', priority: 'high' },
|
|
745
|
+
{ id: 2, title: 'Sidebar', priority: 'medium' },
|
|
746
|
+
{ id: 3, title: 'Main Content', priority: 'high' },
|
|
747
|
+
{ id: 4, title: 'Widget 1', priority: 'low' },
|
|
748
|
+
{ id: 5, title: 'Widget 2', priority: 'low' },
|
|
749
|
+
{ id: 6, title: 'Footer', priority: 'medium' }
|
|
750
|
+
];
|
|
751
|
+
|
|
752
|
+
const getItemSpan = (item, screen) => {
|
|
753
|
+
if (screen === 'mobile') {
|
|
754
|
+
return { columnSpan: 4, rowSpan: 1 }; // Full width on mobile
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
if (screen === 'tablet') {
|
|
758
|
+
switch (item.id) {
|
|
759
|
+
case 1: return { columnSpan: 4, rowSpan: 1 }; // Header full width
|
|
760
|
+
case 2: return { columnSpan: 1, rowSpan: 2 }; // Sidebar
|
|
761
|
+
case 3: return { columnSpan: 3, rowSpan: 2 }; // Main content
|
|
762
|
+
case 4:
|
|
763
|
+
case 5: return { columnSpan: 2, rowSpan: 1 }; // Widgets half width
|
|
764
|
+
case 6: return { columnSpan: 4, rowSpan: 1 }; // Footer full width
|
|
765
|
+
default: return { columnSpan: 1, rowSpan: 1 };
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
// Desktop layout
|
|
770
|
+
switch (item.id) {
|
|
771
|
+
case 1: return { columnSpan: 4, rowSpan: 1 }; // Header
|
|
772
|
+
case 2: return { columnSpan: 1, rowSpan: 3 }; // Sidebar
|
|
773
|
+
case 3: return { columnSpan: 2, rowSpan: 2 }; // Main content
|
|
774
|
+
case 4:
|
|
775
|
+
case 5: return { columnSpan: 1, rowSpan: 1 }; // Widgets
|
|
776
|
+
case 6: return { columnSpan: 4, rowSpan: 1 }; // Footer
|
|
777
|
+
default: return { columnSpan: 1, rowSpan: 1 };
|
|
778
|
+
}
|
|
779
|
+
};
|
|
780
|
+
|
|
781
|
+
return (
|
|
782
|
+
<div className="responsive-grid-items">
|
|
783
|
+
<div className="layout-controls">
|
|
784
|
+
<Text type="Heading4">Responsive Layout Demo</Text>
|
|
785
|
+
|
|
786
|
+
<ButtonGroup>
|
|
787
|
+
<Button
|
|
788
|
+
type={screenSize === 'mobile' ? 'Primary' : 'Outlined'}
|
|
789
|
+
onClick={() => setScreenSize('mobile')}
|
|
790
|
+
>
|
|
791
|
+
Mobile
|
|
792
|
+
</Button>
|
|
793
|
+
<Button
|
|
794
|
+
type={screenSize === 'tablet' ? 'Primary' : 'Outlined'}
|
|
795
|
+
onClick={() => setScreenSize('tablet')}
|
|
796
|
+
>
|
|
797
|
+
Tablet
|
|
798
|
+
</Button>
|
|
799
|
+
<Button
|
|
800
|
+
type={screenSize === 'desktop' ? 'Primary' : 'Outlined'}
|
|
801
|
+
onClick={() => setScreenSize('desktop')}
|
|
802
|
+
>
|
|
803
|
+
Desktop
|
|
804
|
+
</Button>
|
|
805
|
+
</ButtonGroup>
|
|
806
|
+
</div>
|
|
807
|
+
|
|
808
|
+
<Grid columns={4} className={`responsive-grid ${screenSize}`}>
|
|
809
|
+
{items.map(item => {
|
|
810
|
+
const { columnSpan, rowSpan } = getItemSpan(item, screenSize);
|
|
811
|
+
|
|
812
|
+
return (
|
|
813
|
+
<GridItem
|
|
814
|
+
key={item.id}
|
|
815
|
+
columnSpan={columnSpan}
|
|
816
|
+
rowSpan={rowSpan}
|
|
817
|
+
>
|
|
818
|
+
<Card className={`layout-item ${item.title.toLowerCase().replace(' ', '-')}`}>
|
|
819
|
+
<Text type="Heading6">{item.title}</Text>
|
|
820
|
+
<Text type="BodySmall">
|
|
821
|
+
Span: {columnSpan}×{rowSpan}
|
|
822
|
+
</Text>
|
|
823
|
+
<Text type="BodySmall">
|
|
824
|
+
Priority: {item.priority}
|
|
825
|
+
</Text>
|
|
826
|
+
</Card>
|
|
827
|
+
</GridItem>
|
|
828
|
+
);
|
|
829
|
+
})}
|
|
830
|
+
</Grid>
|
|
831
|
+
</div>
|
|
832
|
+
);
|
|
833
|
+
}
|
|
834
|
+
```
|