@ttoss/components 2.3.0 → 2.4.1
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 +230 -317
- package/dist/FileUploader/index.d.ts +48 -0
- package/dist/JsonEditor/index.d.ts +1 -0
- package/dist/esm/Accordion/index.js +11 -15
- package/dist/esm/Drawer/index.js +14 -18
- package/dist/esm/FileUploader/index.js +346 -0
- package/dist/esm/InstallPwa/index.js +27 -32
- package/dist/esm/JsonEditor/index.js +1 -0
- package/dist/esm/JsonView/index.js +1 -0
- package/dist/esm/List/index.js +9 -12
- package/dist/esm/Markdown/index.js +10 -12
- package/dist/esm/Menu/index.js +76 -2168
- package/dist/esm/Modal/index.js +8 -10
- package/dist/esm/NotificationCard/index.js +3 -1
- package/dist/esm/NotificationsMenu/index.js +137 -148
- package/dist/esm/Search/index.js +6 -6
- package/dist/esm/Table/index.js +25 -25
- package/dist/esm/Tabs/index.js +10 -14
- package/dist/esm/Toast/index.js +10 -11
- package/dist/esm/{chunk-Q4MJKM2X.js → chunk-AZTAV4VC.js} +133 -207
- package/dist/esm/chunk-GOISZ4AR.js +156 -0
- package/dist/esm/chunk-V4MHYKRI.js +7 -0
- package/package.json +13 -5
package/README.md
CHANGED
|
@@ -1,366 +1,279 @@
|
|
|
1
1
|
# @ttoss/components
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
React components for the ttoss ecosystem. **ESM only** package.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Quick Start
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```shell
|
|
8
|
+
pnpm add @ttoss/components @ttoss/ui @emotion/react @ttoss/react-hooks
|
|
9
|
+
```
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
**📖 [View all components in Storybook](https://storybook.ttoss.dev/?path=/docs/components-accordion--docs)**
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
## Components Overview
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
All components are theme-aware and integrate seamlessly with `@ttoss/ui`.
|
|
16
|
+
|
|
17
|
+
### Accordion
|
|
18
|
+
|
|
19
|
+
Collapsible content sections. [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-accordion--docs)
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import {
|
|
23
|
+
Accordion,
|
|
24
|
+
AccordionItem,
|
|
25
|
+
AccordionItemButton,
|
|
26
|
+
AccordionItemHeading,
|
|
27
|
+
AccordionItemPanel,
|
|
28
|
+
} from '@ttoss/components/Accordion';
|
|
29
|
+
|
|
30
|
+
<Accordion allowMultipleExpanded>
|
|
31
|
+
<AccordionItem>
|
|
32
|
+
<AccordionItemHeading>
|
|
33
|
+
<AccordionItemButton>Section Title</AccordionItemButton>
|
|
34
|
+
</AccordionItemHeading>
|
|
35
|
+
<AccordionItemPanel>Section content</AccordionItemPanel>
|
|
36
|
+
</AccordionItem>
|
|
37
|
+
</Accordion>;
|
|
15
38
|
```
|
|
16
39
|
|
|
17
|
-
|
|
40
|
+
### Drawer
|
|
18
41
|
|
|
19
|
-
|
|
42
|
+
Slide-out panels from screen edges. [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-drawer--docs)
|
|
20
43
|
|
|
21
|
-
|
|
44
|
+
```tsx
|
|
45
|
+
import { Drawer } from '@ttoss/components/Drawer';
|
|
46
|
+
|
|
47
|
+
<Drawer open={isOpen} direction="right" size="300px">
|
|
48
|
+
<div>Drawer content</div>
|
|
49
|
+
</Drawer>;
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### FileUploader
|
|
53
|
+
|
|
54
|
+
Drag-and-drop file upload with progress tracking. [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-fileuploader--docs)
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
import { FileUploader } from '@ttoss/components/FileUploader';
|
|
58
|
+
|
|
59
|
+
<FileUploader
|
|
60
|
+
onUpload={async (file) => ({ url: 'file-url', id: 'file-id' })}
|
|
61
|
+
onUploadComplete={(file, result) => console.log('Uploaded:', result)}
|
|
62
|
+
/>;
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### InstallPwa
|
|
66
|
+
|
|
67
|
+
PWA installation prompt component. [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-installpwa--docs)
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import { InstallPwa } from '@ttoss/components/InstallPwa';
|
|
22
71
|
|
|
23
|
-
|
|
24
|
-
|
|
72
|
+
<InstallPwa />;
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### JsonEditor
|
|
76
|
+
|
|
77
|
+
JSON editor component. Re-exports from [json-edit-react](https://carlosdevpereira.github.io/json-edit-react/). [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-jsoneditor--docs)
|
|
25
78
|
|
|
26
79
|
```tsx
|
|
27
|
-
import
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const MyComponent = () => (
|
|
31
|
-
<List>
|
|
32
|
-
<ListItem>Item 1</ListItem>
|
|
33
|
-
<ListItem>Item 2</ListItem>
|
|
34
|
-
<ListItem>Item 3</ListItem>
|
|
35
|
-
<ListItem>
|
|
36
|
-
<CustomComponent />
|
|
37
|
-
</ListItem>
|
|
38
|
-
</List>
|
|
39
|
-
);
|
|
80
|
+
import { JsonEditor } from '@ttoss/components/JsonEditor';
|
|
81
|
+
|
|
82
|
+
<JsonEditor data={jsonData} setData={setJsonData} />;
|
|
40
83
|
```
|
|
41
84
|
|
|
42
|
-
|
|
85
|
+
### JsonView
|
|
86
|
+
|
|
87
|
+
JSON viewer component. Re-exports from [react-json-view-lite](https://github.com/AnyRoad/react-json-view-lite). [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-jsonview--docs)
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import { JsonView } from '@ttoss/components/JsonView';
|
|
91
|
+
|
|
92
|
+
<JsonView data={jsonData} />;
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### List
|
|
96
|
+
|
|
97
|
+
Unordered lists with customizable items. [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-list--docs)
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
import { List, ListItem } from '@ttoss/components/List';
|
|
43
101
|
|
|
44
|
-
|
|
102
|
+
<List>
|
|
103
|
+
<ListItem>First item</ListItem>
|
|
104
|
+
<ListItem>Second item</ListItem>
|
|
105
|
+
</List>;
|
|
106
|
+
```
|
|
45
107
|
|
|
46
108
|
### Markdown
|
|
47
109
|
|
|
48
|
-
|
|
110
|
+
Render markdown content with theme integration. [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-markdown--docs)
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
import { Markdown } from '@ttoss/components/Markdown';
|
|
114
|
+
|
|
115
|
+
<Markdown
|
|
116
|
+
components={{
|
|
117
|
+
a: ({ children, ...props }) => <Link {...props}>{children}</Link>,
|
|
118
|
+
}}
|
|
119
|
+
>
|
|
120
|
+
# Heading Some **bold** text
|
|
121
|
+
</Markdown>;
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Menu
|
|
125
|
+
|
|
126
|
+
Dropdown menus with customizable triggers. [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-menu--docs)
|
|
49
127
|
|
|
50
128
|
```tsx
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Odit quasi dolorum aperiam fugiat earum expedita non eligendi similique id minus explicabo, eum facere nihil aspernatur libero! Sapiente aliquid tenetur dolor.
|
|
59
|
-
|
|
60
|
-
- Item 1
|
|
61
|
-
- Item 2
|
|
62
|
-
- Item 3
|
|
63
|
-
|
|
64
|
-

|
|
65
|
-
|
|
66
|
-
[Google](https://google.com)
|
|
67
|
-
`;
|
|
68
|
-
|
|
69
|
-
const Component = () => {
|
|
70
|
-
return (
|
|
71
|
-
<Markdown
|
|
72
|
-
components={{
|
|
73
|
-
a: ({ children, ...props }) => (
|
|
74
|
-
<Link {...props} quiet>
|
|
75
|
-
{children}
|
|
76
|
-
</Link>
|
|
77
|
-
),
|
|
78
|
-
}}
|
|
79
|
-
>
|
|
80
|
-
{MARKDOWN_CONTENT}
|
|
81
|
-
</Markdown>
|
|
82
|
-
);
|
|
83
|
-
};
|
|
129
|
+
import { Menu } from '@ttoss/components/Menu';
|
|
130
|
+
|
|
131
|
+
<Menu trigger={<Button>Open Menu</Button>}>
|
|
132
|
+
<Menu.Item onClick={() => {}}>Action 1</Menu.Item>
|
|
133
|
+
<Menu.Item onClick={() => {}}>Action 2</Menu.Item>
|
|
134
|
+
</Menu>;
|
|
84
135
|
```
|
|
85
136
|
|
|
86
137
|
### Modal
|
|
87
138
|
|
|
88
|
-
|
|
139
|
+
Theme-aware modals with accessibility features. [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-modal--docs)
|
|
89
140
|
|
|
90
141
|
```tsx
|
|
91
|
-
import { Modal } from '@ttoss/components';
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
Modal
|
|
100
|
-
|
|
101
|
-
const Component = () => {
|
|
102
|
-
const [isOpen, setIsOpen] = React.useState(false);
|
|
103
|
-
|
|
104
|
-
return (
|
|
105
|
-
<Box id="modal-root">
|
|
106
|
-
<Modal
|
|
107
|
-
isOpen={isOpen}
|
|
108
|
-
onAfterOpen={action('onAfterOpen')}
|
|
109
|
-
onAfterClose={action('onAfterClose')}
|
|
110
|
-
onRequestClose={() => {
|
|
111
|
-
action('onRequestClose')();
|
|
112
|
-
setIsOpen(false);
|
|
113
|
-
}}
|
|
114
|
-
style={{
|
|
115
|
-
overlay: {
|
|
116
|
-
backgroundColor: 'primary',
|
|
117
|
-
},
|
|
118
|
-
content: {
|
|
119
|
-
backgroundColor: 'secondary',
|
|
120
|
-
padding: ['lg', 'xl'], // Array as value don't work.
|
|
121
|
-
},
|
|
122
|
-
}}
|
|
123
|
-
>
|
|
124
|
-
<Flex>
|
|
125
|
-
<Text>This is a modal.</Text>
|
|
126
|
-
<Text>Here is the content.</Text>
|
|
127
|
-
<Button
|
|
128
|
-
onClick={() => {
|
|
129
|
-
setIsOpen(false);
|
|
130
|
-
}}
|
|
131
|
-
>
|
|
132
|
-
Close Modal
|
|
133
|
-
</Button>
|
|
134
|
-
</Flex>
|
|
135
|
-
</Modal>
|
|
136
|
-
<Button
|
|
137
|
-
onClick={() => {
|
|
138
|
-
setIsOpen(true);
|
|
139
|
-
}}
|
|
140
|
-
>
|
|
141
|
-
Open Modal
|
|
142
|
-
</Button>
|
|
143
|
-
</Box>
|
|
144
|
-
);
|
|
145
|
-
};
|
|
142
|
+
import { Modal } from '@ttoss/components/Modal';
|
|
143
|
+
|
|
144
|
+
<Modal
|
|
145
|
+
isOpen={isOpen}
|
|
146
|
+
onRequestClose={() => setIsOpen(false)}
|
|
147
|
+
style={{ content: { backgroundColor: 'secondary' } }}
|
|
148
|
+
>
|
|
149
|
+
Modal content
|
|
150
|
+
</Modal>;
|
|
146
151
|
```
|
|
147
152
|
|
|
148
|
-
###
|
|
153
|
+
### NotificationCard
|
|
149
154
|
|
|
150
|
-
|
|
155
|
+
Display notification messages with actions. [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-notificationcard--docs)
|
|
151
156
|
|
|
152
|
-
|
|
157
|
+
```tsx
|
|
158
|
+
import { NotificationCard } from '@ttoss/components/NotificationCard';
|
|
159
|
+
|
|
160
|
+
<NotificationCard
|
|
161
|
+
title="Notification Title"
|
|
162
|
+
message="Notification message"
|
|
163
|
+
onClose={() => {}}
|
|
164
|
+
/>;
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### NotificationsMenu
|
|
168
|
+
|
|
169
|
+
Menu component for displaying notifications. [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-notificationsmenu--docs)
|
|
153
170
|
|
|
154
171
|
```tsx
|
|
155
|
-
import
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const handleSearchChange = (newValue) => {
|
|
163
|
-
setSearchText(newValue);
|
|
164
|
-
// Perform search or update logic here
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
return (
|
|
168
|
-
<Box>
|
|
169
|
-
<Search
|
|
170
|
-
value={searchText}
|
|
171
|
-
onChange={handleSearchChange}
|
|
172
|
-
loading={/* loading state here */}
|
|
173
|
-
debounce={500} // Adjust the debounce time as needed
|
|
174
|
-
/>
|
|
175
|
-
</Box>
|
|
176
|
-
);
|
|
177
|
-
};
|
|
172
|
+
import { NotificationsMenu } from '@ttoss/components/NotificationsMenu';
|
|
173
|
+
|
|
174
|
+
<NotificationsMenu
|
|
175
|
+
notifications={[{ id: '1', title: 'New message', read: false }]}
|
|
176
|
+
onNotificationClick={(notification) => {}}
|
|
177
|
+
/>;
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
-
|
|
180
|
+
### Search
|
|
181
181
|
|
|
182
|
-
|
|
182
|
+
Debounced search input with loading states. [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-search--docs)
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
import { Search } from '@ttoss/components/Search';
|
|
186
|
+
|
|
187
|
+
<Search
|
|
188
|
+
value={searchText}
|
|
189
|
+
onChange={setSearchText}
|
|
190
|
+
loading={isLoading}
|
|
191
|
+
debounce={300}
|
|
192
|
+
/>;
|
|
193
|
+
```
|
|
183
194
|
|
|
184
|
-
|
|
195
|
+
### Table
|
|
185
196
|
|
|
186
|
-
|
|
197
|
+
Flexible tables with sorting and pagination. Uses [TanStack Table](https://tanstack.com/table/latest). [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-table--docs)
|
|
187
198
|
|
|
188
199
|
```tsx
|
|
189
|
-
import * as React from 'react';
|
|
190
200
|
import {
|
|
191
201
|
Table,
|
|
192
|
-
createColumnHelper,
|
|
193
|
-
flexRender,
|
|
194
|
-
getCoreRowModel,
|
|
195
202
|
useReactTable,
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
type Person = {
|
|
199
|
-
firstName: string;
|
|
200
|
-
lastName: string;
|
|
201
|
-
age: number;
|
|
202
|
-
visits: number;
|
|
203
|
-
status: string;
|
|
204
|
-
progress: number;
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
const defaultData: Person[] = [
|
|
208
|
-
{
|
|
209
|
-
firstName: 'tanner',
|
|
210
|
-
lastName: 'linsley',
|
|
211
|
-
age: 24,
|
|
212
|
-
visits: 100,
|
|
213
|
-
status: 'In Relationship',
|
|
214
|
-
progress: 50,
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
firstName: 'tandy',
|
|
218
|
-
lastName: 'miller',
|
|
219
|
-
age: 40,
|
|
220
|
-
visits: 40,
|
|
221
|
-
status: 'Single',
|
|
222
|
-
progress: 80,
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
firstName: 'joe',
|
|
226
|
-
lastName: 'dirte',
|
|
227
|
-
age: 45,
|
|
228
|
-
visits: 20,
|
|
229
|
-
status: 'Complicated',
|
|
230
|
-
progress: 10,
|
|
231
|
-
},
|
|
232
|
-
];
|
|
233
|
-
|
|
234
|
-
const columnHelper = createColumnHelper<Person>();
|
|
203
|
+
createColumnHelper,
|
|
204
|
+
} from '@ttoss/components/Table';
|
|
235
205
|
|
|
236
206
|
const columns = [
|
|
237
|
-
columnHelper.accessor('
|
|
238
|
-
|
|
239
|
-
return info.getValue();
|
|
240
|
-
},
|
|
241
|
-
footer: (info) => {
|
|
242
|
-
return info.column.id;
|
|
243
|
-
},
|
|
244
|
-
}),
|
|
245
|
-
columnHelper.accessor(
|
|
246
|
-
(row) => {
|
|
247
|
-
return row.lastName;
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
id: 'lastName',
|
|
251
|
-
cell: (info) => {
|
|
252
|
-
return <i>{info.getValue()}</i>;
|
|
253
|
-
},
|
|
254
|
-
header: () => {
|
|
255
|
-
return <span>Last Name</span>;
|
|
256
|
-
},
|
|
257
|
-
footer: (info) => {
|
|
258
|
-
return info.column.id;
|
|
259
|
-
},
|
|
260
|
-
}
|
|
261
|
-
),
|
|
262
|
-
columnHelper.accessor('age', {
|
|
263
|
-
header: () => {
|
|
264
|
-
return 'Age';
|
|
265
|
-
},
|
|
266
|
-
cell: (info) => {
|
|
267
|
-
return info.renderValue();
|
|
268
|
-
},
|
|
269
|
-
footer: (info) => {
|
|
270
|
-
return info.column.id;
|
|
271
|
-
},
|
|
272
|
-
}),
|
|
273
|
-
columnHelper.accessor('visits', {
|
|
274
|
-
header: () => {
|
|
275
|
-
return <span>Visits</span>;
|
|
276
|
-
},
|
|
277
|
-
footer: (info) => {
|
|
278
|
-
return info.column.id;
|
|
279
|
-
},
|
|
280
|
-
}),
|
|
281
|
-
columnHelper.accessor('status', {
|
|
282
|
-
header: 'Status',
|
|
283
|
-
footer: (info) => {
|
|
284
|
-
return info.column.id;
|
|
285
|
-
},
|
|
286
|
-
}),
|
|
287
|
-
columnHelper.accessor('progress', {
|
|
288
|
-
header: 'Profile Progress',
|
|
289
|
-
footer: (info) => {
|
|
290
|
-
return info.column.id;
|
|
291
|
-
},
|
|
292
|
-
}),
|
|
207
|
+
columnHelper.accessor('name', { header: 'Name' }),
|
|
208
|
+
columnHelper.accessor('email', { header: 'Email' }),
|
|
293
209
|
];
|
|
294
210
|
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
</Table>
|
|
364
|
-
);
|
|
365
|
-
};
|
|
211
|
+
const table = useReactTable({
|
|
212
|
+
data,
|
|
213
|
+
columns,
|
|
214
|
+
getCoreRowModel: getCoreRowModel(),
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
<Table>
|
|
218
|
+
<Table.Head>
|
|
219
|
+
{table.getHeaderGroups().map((headerGroup) => (
|
|
220
|
+
<Table.Row key={headerGroup.id}>
|
|
221
|
+
{headerGroup.headers.map((header) => (
|
|
222
|
+
<Table.Header key={header.id}>
|
|
223
|
+
{flexRender(header.column.columnDef.header, header.getContext())}
|
|
224
|
+
</Table.Header>
|
|
225
|
+
))}
|
|
226
|
+
</Table.Row>
|
|
227
|
+
))}
|
|
228
|
+
</Table.Head>
|
|
229
|
+
<Table.Body>
|
|
230
|
+
{table.getRowModel().rows.map((row) => (
|
|
231
|
+
<Table.Row key={row.id}>
|
|
232
|
+
{row.getVisibleCells().map((cell) => (
|
|
233
|
+
<Table.Cell key={cell.id}>
|
|
234
|
+
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
235
|
+
</Table.Cell>
|
|
236
|
+
))}
|
|
237
|
+
</Table.Row>
|
|
238
|
+
))}
|
|
239
|
+
</Table.Body>
|
|
240
|
+
</Table>;
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Tabs
|
|
244
|
+
|
|
245
|
+
Tab navigation with content panels. [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-tabs--docs)
|
|
246
|
+
|
|
247
|
+
```tsx
|
|
248
|
+
import { Tabs } from '@ttoss/components/Tabs';
|
|
249
|
+
|
|
250
|
+
<Tabs>
|
|
251
|
+
<Tabs.TabList>
|
|
252
|
+
<Tabs.Tab>Tab 1</Tabs.Tab>
|
|
253
|
+
<Tabs.Tab>Tab 2</Tabs.Tab>
|
|
254
|
+
</Tabs.TabList>
|
|
255
|
+
<Tabs.TabContent>
|
|
256
|
+
<Tabs.TabPanel>Content 1</Tabs.TabPanel>
|
|
257
|
+
<Tabs.TabPanel>Content 2</Tabs.TabPanel>
|
|
258
|
+
</Tabs.TabContent>
|
|
259
|
+
</Tabs>;
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Toast
|
|
263
|
+
|
|
264
|
+
Toast notification system. [📖 Docs](https://storybook.ttoss.dev/?path=/docs/components-toast--docs)
|
|
265
|
+
|
|
266
|
+
```tsx
|
|
267
|
+
import { Toast } from '@ttoss/components/Toast';
|
|
268
|
+
|
|
269
|
+
<Toast
|
|
270
|
+
message="Success message"
|
|
271
|
+
type="success"
|
|
272
|
+
isOpen={isOpen}
|
|
273
|
+
onClose={() => setIsOpen(false)}
|
|
274
|
+
/>;
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
```
|
|
278
|
+
|
|
366
279
|
```
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
type UploadResult = {
|
|
5
|
+
url: string;
|
|
6
|
+
id: string;
|
|
7
|
+
};
|
|
8
|
+
type FileUploadState = {
|
|
9
|
+
file: File;
|
|
10
|
+
status: 'pending' | 'uploading' | 'completed' | 'error';
|
|
11
|
+
progress?: number;
|
|
12
|
+
result?: UploadResult;
|
|
13
|
+
error?: Error;
|
|
14
|
+
};
|
|
15
|
+
type OnUpload = (file: File, onProgress?: (progress: number) => void) => Promise<UploadResult>;
|
|
16
|
+
type OnUploadStart = (file: File) => void;
|
|
17
|
+
type OnUploadProgress = (file: File, progress: number) => void;
|
|
18
|
+
type OnUploadComplete = (file: File, result: UploadResult) => void;
|
|
19
|
+
type OnUploadError = (file: File, error: Error) => void;
|
|
20
|
+
type OnFilesChange = (files: FileUploadState[]) => void;
|
|
21
|
+
type OnRemoveFile = (file: FileUploadState, index: number) => void;
|
|
22
|
+
type FileUploaderProps = {
|
|
23
|
+
onUpload: OnUpload;
|
|
24
|
+
onUploadStart?: OnUploadStart;
|
|
25
|
+
onUploadProgress?: OnUploadProgress;
|
|
26
|
+
onUploadComplete?: OnUploadComplete;
|
|
27
|
+
onUploadError?: OnUploadError;
|
|
28
|
+
onFilesChange?: OnFilesChange;
|
|
29
|
+
onRemoveFile?: OnRemoveFile;
|
|
30
|
+
accept?: string;
|
|
31
|
+
multiple?: boolean;
|
|
32
|
+
maxSize?: number;
|
|
33
|
+
maxFiles?: number;
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
autoUpload?: boolean;
|
|
36
|
+
retryAttempts?: number;
|
|
37
|
+
placeholder?: string;
|
|
38
|
+
error?: string;
|
|
39
|
+
children?: React.ReactNode;
|
|
40
|
+
showFileList?: boolean;
|
|
41
|
+
FileListComponent?: (props: {
|
|
42
|
+
files: FileUploadState[];
|
|
43
|
+
onRemoveFile: (index: number) => void;
|
|
44
|
+
}) => React.ReactNode;
|
|
45
|
+
};
|
|
46
|
+
declare const FileUploader: ({ onUpload, onUploadStart, onUploadProgress, onUploadComplete, onUploadError, onFilesChange, onRemoveFile, accept, multiple, maxSize, maxFiles, disabled, autoUpload, retryAttempts, placeholder, error, children, showFileList, FileListComponent, }: FileUploaderProps) => react_jsx_runtime.JSX.Element;
|
|
47
|
+
|
|
48
|
+
export { type FileUploadState, FileUploader, type FileUploaderProps, type OnFilesChange, type OnRemoveFile, type OnUpload, type OnUploadComplete, type OnUploadError, type OnUploadProgress, type OnUploadStart, type UploadResult };
|