@drivenets/design-system 0.0.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/CHANGELOG.md +9 -0
- package/LICENSE +201 -0
- package/dist/index.cjs +5394 -0
- package/dist/index.css +1 -0
- package/dist/index.d.cts +9157 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +9157 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5335 -0
- package/dist/index.js.map +1 -0
- package/package.json +104 -0
- package/src/components/ds-alert-banner/ds-alert-banner.module.scss +116 -0
- package/src/components/ds-alert-banner/ds-alert-banner.tsx +115 -0
- package/src/components/ds-alert-banner/ds-alert-banner.types.tsx +47 -0
- package/src/components/ds-alert-banner/index.tsx +2 -0
- package/src/components/ds-breadcrumb/ds-breadcrumb.module.scss +99 -0
- package/src/components/ds-breadcrumb/ds-breadcrumb.tsx +94 -0
- package/src/components/ds-breadcrumb/ds-breadcrumb.types.tsx +32 -0
- package/src/components/ds-breadcrumb/index.tsx +2 -0
- package/src/components/ds-button/ds-button.tsx +12 -0
- package/src/components/ds-button/ds-button.types.ts +6 -0
- package/src/components/ds-button/index.ts +2 -0
- package/src/components/ds-button/versions/ds-button-legacy/ds-button-legacy.module.scss +257 -0
- package/src/components/ds-button/versions/ds-button-legacy/ds-button-legacy.tsx +34 -0
- package/src/components/ds-button/versions/ds-button-legacy/ds-button-legacy.types.ts +41 -0
- package/src/components/ds-button/versions/ds-button-legacy/index.ts +2 -0
- package/src/components/ds-button/versions/ds-button-new/ds-button-new.module.scss +580 -0
- package/src/components/ds-button/versions/ds-button-new/ds-button-new.tsx +49 -0
- package/src/components/ds-button/versions/ds-button-new/ds-button-new.types.ts +41 -0
- package/src/components/ds-button/versions/ds-button-new/index.ts +2 -0
- package/src/components/ds-checkbox/ds-checkbox.module.scss +130 -0
- package/src/components/ds-checkbox/ds-checkbox.tsx +55 -0
- package/src/components/ds-checkbox/ds-checkbox.types.tsx +27 -0
- package/src/components/ds-checkbox/index.tsx +2 -0
- package/src/components/ds-chip/ds-chip.module.scss +71 -0
- package/src/components/ds-chip/ds-chip.tsx +73 -0
- package/src/components/ds-chip/ds-chip.types.tsx +46 -0
- package/src/components/ds-chip/index.tsx +2 -0
- package/src/components/ds-chip-group/ds-chip-group.module.scss +59 -0
- package/src/components/ds-chip-group/ds-chip-group.tsx +122 -0
- package/src/components/ds-chip-group/ds-chip-group.types.ts +52 -0
- package/src/components/ds-chip-group/hooks/use-chip-row-calculation.ts +76 -0
- package/src/components/ds-chip-group/index.ts +2 -0
- package/src/components/ds-confirmation/ds-confirmation.module.scss +58 -0
- package/src/components/ds-confirmation/ds-confirmation.tsx +121 -0
- package/src/components/ds-confirmation/ds-confirmation.types.tsx +28 -0
- package/src/components/ds-confirmation/index.ts +2 -0
- package/src/components/ds-dialog/ds-dialog.module.scss +50 -0
- package/src/components/ds-dialog/ds-dialog.tsx +70 -0
- package/src/components/ds-dialog/ds-dialog.types.tsx +48 -0
- package/src/components/ds-dialog/index.tsx +2 -0
- package/src/components/ds-drawer/ds-drawer.module.scss +212 -0
- package/src/components/ds-drawer/ds-drawer.tsx +160 -0
- package/src/components/ds-drawer/ds-drawer.types.tsx +54 -0
- package/src/components/ds-drawer/index.ts +2 -0
- package/src/components/ds-dropdown-menu/ds-dropdown-menu.module.scss +123 -0
- package/src/components/ds-dropdown-menu/ds-dropdown-menu.tsx +396 -0
- package/src/components/ds-dropdown-menu/ds-dropdown-menu.types.tsx +262 -0
- package/src/components/ds-dropdown-menu/index.tsx +2 -0
- package/src/components/ds-expandable-text-input/ds-expandable-text-input.module.scss +70 -0
- package/src/components/ds-expandable-text-input/ds-expandable-text-input.tsx +106 -0
- package/src/components/ds-expandable-text-input/ds-expandable-text-input.types.tsx +19 -0
- package/src/components/ds-expandable-text-input/index.ts +2 -0
- package/src/components/ds-file-upload/components/file-upload/file-upload.module.scss +90 -0
- package/src/components/ds-file-upload/components/file-upload/file-upload.tsx +106 -0
- package/src/components/ds-file-upload/components/file-upload/file-upload.types.tsx +94 -0
- package/src/components/ds-file-upload/components/file-upload/index.ts +2 -0
- package/src/components/ds-file-upload/components/file-upload-item/file-upload-item.module.scss +125 -0
- package/src/components/ds-file-upload/components/file-upload-item/file-upload-item.tsx +143 -0
- package/src/components/ds-file-upload/components/file-upload-item/file-upload-item.types.tsx +26 -0
- package/src/components/ds-file-upload/components/file-upload-item/index.ts +2 -0
- package/src/components/ds-file-upload/ds-file-upload-api.types.ts +38 -0
- package/src/components/ds-file-upload/ds-file-upload.tsx +46 -0
- package/src/components/ds-file-upload/ds-file-upload.types.tsx +54 -0
- package/src/components/ds-file-upload/errors/file-upload-errors.ts +27 -0
- package/src/components/ds-file-upload/hooks/index.ts +2 -0
- package/src/components/ds-file-upload/hooks/use-file-upload.ts +350 -0
- package/src/components/ds-file-upload/index.ts +7 -0
- package/src/components/ds-file-upload/types/accept-types.ts +106 -0
- package/src/components/ds-file-upload/utils/accept-utils.ts +25 -0
- package/src/components/ds-file-upload/utils/constants.ts +21 -0
- package/src/components/ds-file-upload/utils/file-factory.ts +18 -0
- package/src/components/ds-file-upload/utils/format-file-size.ts +15 -0
- package/src/components/ds-file-upload/utils/generate-helper-text.ts +39 -0
- package/src/components/ds-file-upload/utils/get-error-message.ts +17 -0
- package/src/components/ds-file-upload/utils/is-file-equal.ts +8 -0
- package/src/components/ds-form-control/ds-form-control.module.scss +135 -0
- package/src/components/ds-form-control/ds-form-control.tsx +94 -0
- package/src/components/ds-form-control/ds-form-control.types.tsx +58 -0
- package/src/components/ds-form-control/index.tsx +2 -0
- package/src/components/ds-grid/ds-grid.module.scss +0 -0
- package/src/components/ds-grid/ds-grid.tsx +43 -0
- package/src/components/ds-grid/ds-grid.types.ts +55 -0
- package/src/components/ds-grid/index.ts +2 -0
- package/src/components/ds-icon/ds-icon.module.scss +25 -0
- package/src/components/ds-icon/ds-icon.tsx +33 -0
- package/src/components/ds-icon/ds-icon.types.ts +53 -0
- package/src/components/ds-icon/index.ts +2 -0
- package/src/components/ds-icon/material-icons.ts +6203 -0
- package/src/components/ds-modal/ds-modal.module.scss +100 -0
- package/src/components/ds-modal/ds-modal.tsx +136 -0
- package/src/components/ds-modal/ds-modal.types.tsx +44 -0
- package/src/components/ds-modal/index.tsx +2 -0
- package/src/components/ds-number-input/ds-number-input.module.scss +15 -0
- package/src/components/ds-number-input/ds-number-input.tsx +74 -0
- package/src/components/ds-number-input/ds-number-input.types.tsx +76 -0
- package/src/components/ds-number-input/index.tsx +2 -0
- package/src/components/ds-panel/ds-panel.module.scss +95 -0
- package/src/components/ds-panel/ds-panel.tsx +46 -0
- package/src/components/ds-panel/ds-panel.types.ts +17 -0
- package/src/components/ds-panel/index.tsx +2 -0
- package/src/components/ds-password-input/ds-password-input.module.scss +10 -0
- package/src/components/ds-password-input/ds-password-input.tsx +67 -0
- package/src/components/ds-password-input/ds-password-input.types.tsx +62 -0
- package/src/components/ds-password-input/index.tsx +2 -0
- package/src/components/ds-popover/ds-popover.module.scss +23 -0
- package/src/components/ds-popover/ds-popover.tsx +33 -0
- package/src/components/ds-popover/ds-popover.types.tsx +24 -0
- package/src/components/ds-popover/index.tsx +2 -0
- package/src/components/ds-radio-group/ds-radio-group.module.scss +138 -0
- package/src/components/ds-radio-group/ds-radio-group.tsx +115 -0
- package/src/components/ds-radio-group/ds-radio-group.types.tsx +93 -0
- package/src/components/ds-radio-group/index.tsx +2 -0
- package/src/components/ds-select/ds-select.module.scss +66 -0
- package/src/components/ds-select/ds-select.tsx +239 -0
- package/src/components/ds-select/ds-select.types.tsx +80 -0
- package/src/components/ds-select/index.tsx +2 -0
- package/src/components/ds-select/select-items-chips.tsx +56 -0
- package/src/components/ds-smart-tabs/ds-smart-tabs.module.scss +69 -0
- package/src/components/ds-smart-tabs/ds-smart-tabs.tsx +113 -0
- package/src/components/ds-smart-tabs/ds-smart-tabs.types.tsx +74 -0
- package/src/components/ds-smart-tabs/index.tsx +2 -0
- package/src/components/ds-spinner/ds-spinner.module.scss +39 -0
- package/src/components/ds-spinner/ds-spinner.tsx +51 -0
- package/src/components/ds-spinner/ds-spinner.types.tsx +20 -0
- package/src/components/ds-spinner/index.tsx +2 -0
- package/src/components/ds-status-badge/ds-status-badge.module.scss +79 -0
- package/src/components/ds-status-badge/ds-status-badge.tsx +42 -0
- package/src/components/ds-status-badge/ds-status-badge.types.tsx +46 -0
- package/src/components/ds-status-badge/index.tsx +2 -0
- package/src/components/ds-stepper/components/ds-step-content.tsx +32 -0
- package/src/components/ds-stepper/components/ds-step-description.tsx +6 -0
- package/src/components/ds-stepper/components/ds-step-label.tsx +6 -0
- package/src/components/ds-stepper/components/ds-step-next-button.tsx +13 -0
- package/src/components/ds-stepper/components/ds-step.tsx +59 -0
- package/src/components/ds-stepper/ds-stepper.module.scss +134 -0
- package/src/components/ds-stepper/ds-stepper.tsx +34 -0
- package/src/components/ds-stepper/ds-stepper.types.ts +12 -0
- package/src/components/ds-stepper/hooks/use-stepper.ts +20 -0
- package/src/components/ds-stepper/hooks/use-steps.ts +18 -0
- package/src/components/ds-stepper/index.tsx +6 -0
- package/src/components/ds-system-status/ds-system-status.module.scss +87 -0
- package/src/components/ds-system-status/ds-system-status.tsx +33 -0
- package/src/components/ds-system-status/ds-system-status.types.tsx +37 -0
- package/src/components/ds-system-status/index.tsx +10 -0
- package/src/components/ds-table/components/core-table/core-table.module.scss +32 -0
- package/src/components/ds-table/components/core-table/core-table.tsx +83 -0
- package/src/components/ds-table/components/core-table/index.ts +1 -0
- package/src/components/ds-table/components/ds-table-bulk-actions/ds-table-bulk-actions.module.scss +115 -0
- package/src/components/ds-table/components/ds-table-bulk-actions/ds-table-bulk-actions.tsx +70 -0
- package/src/components/ds-table/components/ds-table-bulk-actions/ds-table-bulk-actions.types.ts +41 -0
- package/src/components/ds-table/components/ds-table-bulk-actions/index.ts +2 -0
- package/src/components/ds-table/components/ds-table-cell/ds-table-cell.module.scss +53 -0
- package/src/components/ds-table/components/ds-table-cell/ds-table-cell.tsx +95 -0
- package/src/components/ds-table/components/ds-table-cell/ds-table-cell.types.ts +67 -0
- package/src/components/ds-table/components/ds-table-cell/index.ts +2 -0
- package/src/components/ds-table/components/ds-table-header/ds-table-header.module.scss +81 -0
- package/src/components/ds-table/components/ds-table-header/ds-table-header.tsx +99 -0
- package/src/components/ds-table/components/ds-table-header/ds-table-header.types.ts +11 -0
- package/src/components/ds-table/components/ds-table-header/index.ts +2 -0
- package/src/components/ds-table/components/ds-table-row/ds-table-row.module.scss +137 -0
- package/src/components/ds-table/components/ds-table-row/ds-table-row.tsx +205 -0
- package/src/components/ds-table/components/ds-table-row/ds-table-row.types.ts +22 -0
- package/src/components/ds-table/components/ds-table-row/index.ts +2 -0
- package/src/components/ds-table/context/ds-table-context.tsx +39 -0
- package/src/components/ds-table/ds-table.module.scss +60 -0
- package/src/components/ds-table/ds-table.tsx +312 -0
- package/src/components/ds-table/ds-table.types.ts +377 -0
- package/src/components/ds-table/filters/adapters/create-checkbox-filter-adapter.tsx +116 -0
- package/src/components/ds-table/filters/adapters/create-dual-range-filter-adapter.tsx +171 -0
- package/src/components/ds-table/filters/adapters/create-filter-adapter.ts +131 -0
- package/src/components/ds-table/filters/adapters/index.ts +12 -0
- package/src/components/ds-table/filters/components/checkbox-filter/checkbox-filter.tsx +43 -0
- package/src/components/ds-table/filters/components/checkbox-filter/index.ts +2 -0
- package/src/components/ds-table/filters/components/range-filter/index.ts +2 -0
- package/src/components/ds-table/filters/components/range-filter/range-filter.module.scss +25 -0
- package/src/components/ds-table/filters/components/range-filter/range-filter.tsx +79 -0
- package/src/components/ds-table/filters/hooks/index.ts +1 -0
- package/src/components/ds-table/filters/hooks/use-table-filters.ts +234 -0
- package/src/components/ds-table/filters/index.ts +50 -0
- package/src/components/ds-table/filters/types/filter-adapter.types.ts +111 -0
- package/src/components/ds-table/hooks/use-drag-and-drop.tsx +107 -0
- package/src/components/ds-table/index.ts +4 -0
- package/src/components/ds-table/styles/_variables.scss +17 -0
- package/src/components/ds-table/styles/shared/ds-table-shared.module.scss +16 -0
- package/src/components/ds-table/utils/column-styling.ts +30 -0
- package/src/components/ds-table/utils/create-columns-grid-template.ts +23 -0
- package/src/components/ds-table/utils/merge-refs.ts +15 -0
- package/src/components/ds-table/utils/story-data-generator.ts +91 -0
- package/src/components/ds-text-input/ds-text-input.module.scss +27 -0
- package/src/components/ds-text-input/ds-text-input.tsx +75 -0
- package/src/components/ds-text-input/ds-text-input.types.tsx +110 -0
- package/src/components/ds-text-input/index.ts +2 -0
- package/src/components/ds-textarea/ds-textarea.module.scss +5 -0
- package/src/components/ds-textarea/ds-textarea.tsx +49 -0
- package/src/components/ds-textarea/ds-textarea.types.tsx +67 -0
- package/src/components/ds-textarea/index.tsx +2 -0
- package/src/components/ds-toast/ds-toast-context.tsx +79 -0
- package/src/components/ds-toast/ds-toast.module.scss +134 -0
- package/src/components/ds-toast/ds-toast.tsx +54 -0
- package/src/components/ds-toast/ds-toast.types.tsx +53 -0
- package/src/components/ds-toast/index.ts +3 -0
- package/src/components/ds-tooltip/ds-tooltip.module.scss +19 -0
- package/src/components/ds-tooltip/ds-tooltip.tsx +33 -0
- package/src/components/ds-tooltip/ds-tooltip.types.tsx +12 -0
- package/src/components/ds-tooltip/index.tsx +2 -0
- package/src/components/ds-typography/ds-typography.config.ts +32 -0
- package/src/components/ds-typography/ds-typography.module.scss +93 -0
- package/src/components/ds-typography/ds-typography.tsx +27 -0
- package/src/components/ds-typography/ds-typography.types.tsx +27 -0
- package/src/components/ds-typography/index.tsx +2 -0
- package/src/components/ds-vertical-tabs/ds-vertical-tabs.module.scss +60 -0
- package/src/components/ds-vertical-tabs/ds-vertical-tabs.tsx +80 -0
- package/src/components/ds-vertical-tabs/ds-vertical-tabs.types.ts +69 -0
- package/src/components/ds-vertical-tabs/index.ts +7 -0
- package/src/index.ts +34 -0
- package/src/styles/_colors.scss +65 -0
- package/src/styles/_grid.scss +111 -0
- package/src/styles/_mixin.scss +1 -0
- package/src/styles/_reset.scss +38 -0
- package/src/styles/_root.scss +390 -0
- package/src/styles/_scrollbars.scss +41 -0
- package/src/styles/_spacing.scss +47 -0
- package/src/styles/_typography.scss +301 -0
- package/src/styles/_utilities.scss +33 -0
- package/src/styles/_variables.scss +44 -0
- package/src/styles/mixins/_bounding-box.scss +53 -0
- package/src/styles/mixins/_list.scss +74 -0
- package/src/styles/shared/_dropdown.scss +89 -0
- package/src/styles/shared/_input.scss +365 -0
- package/src/styles/shared/_modal.scss +123 -0
- package/src/styles/styles.scss +12 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/* cspell:disable */
|
|
2
|
+
import type { FileUploadFileMimeType } from '@ark-ui/react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* File extension with leading dot
|
|
6
|
+
* @example '.pdf', '.jpg', '.csv'
|
|
7
|
+
*/
|
|
8
|
+
export type FileExtension = `.${string}`;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Accepted file type configuration
|
|
12
|
+
* - Use string shorthand for common MIME types (uses built-in extensions map)
|
|
13
|
+
* - Use object form to override or provide custom extensions
|
|
14
|
+
*/
|
|
15
|
+
export type AcceptedFileType =
|
|
16
|
+
| FileUploadFileMimeType
|
|
17
|
+
| {
|
|
18
|
+
mimeType: FileUploadFileMimeType;
|
|
19
|
+
extensions: [FileExtension, ...FileExtension[]];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Built-in extensions map for common MIME types
|
|
24
|
+
*/
|
|
25
|
+
export const EXTENSIONS_MAP: Record<FileUploadFileMimeType, FileExtension[]> = {
|
|
26
|
+
// Images - specific types
|
|
27
|
+
'image/png': ['.png'],
|
|
28
|
+
'image/gif': ['.gif'],
|
|
29
|
+
'image/jpeg': ['.jpg', '.jpeg'],
|
|
30
|
+
'image/svg+xml': ['.svg'],
|
|
31
|
+
'image/webp': ['.webp'],
|
|
32
|
+
'image/avif': ['.avif'],
|
|
33
|
+
'image/heic': ['.heic', '.heif'],
|
|
34
|
+
'image/bmp': ['.bmp'],
|
|
35
|
+
|
|
36
|
+
// Applications
|
|
37
|
+
'application/pdf': ['.pdf'],
|
|
38
|
+
'application/zip': ['.zip'],
|
|
39
|
+
'application/json': ['.json'],
|
|
40
|
+
'application/xml': ['.xml'],
|
|
41
|
+
'application/msword': ['.doc'],
|
|
42
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx'],
|
|
43
|
+
'application/vnd.ms-excel': ['.xls'],
|
|
44
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx'],
|
|
45
|
+
'application/vnd.ms-powerpoint': ['.ppt'],
|
|
46
|
+
'application/vnd.openxmlformats-officedocument.presentationml.presentation': ['.pptx'],
|
|
47
|
+
'application/rtf': ['.rtf'],
|
|
48
|
+
'application/x-rar': ['.rar'],
|
|
49
|
+
'application/x-7z-compressed': ['.7z'],
|
|
50
|
+
'application/x-tar': ['.tar'],
|
|
51
|
+
'application/vnd.microsoft.portable-executable': ['.exe', '.dll'],
|
|
52
|
+
|
|
53
|
+
// Text
|
|
54
|
+
'text/css': ['.css'],
|
|
55
|
+
'text/csv': ['.csv'],
|
|
56
|
+
'text/html': ['.html', '.htm'],
|
|
57
|
+
'text/markdown': ['.md', '.markdown'],
|
|
58
|
+
'text/plain': ['.txt'],
|
|
59
|
+
|
|
60
|
+
// Fonts
|
|
61
|
+
'font/ttf': ['.ttf'],
|
|
62
|
+
'font/otf': ['.otf'],
|
|
63
|
+
'font/woff': ['.woff'],
|
|
64
|
+
'font/woff2': ['.woff2'],
|
|
65
|
+
'font/eot': ['.eot'],
|
|
66
|
+
'font/svg': ['.svg'],
|
|
67
|
+
|
|
68
|
+
// Video
|
|
69
|
+
'video/mp4': ['.mp4'],
|
|
70
|
+
'video/webm': ['.webm'],
|
|
71
|
+
'video/ogg': ['.ogv'],
|
|
72
|
+
'video/quicktime': ['.mov'],
|
|
73
|
+
'video/x-msvideo': ['.avi'],
|
|
74
|
+
|
|
75
|
+
// Audio
|
|
76
|
+
'audio/mpeg': ['.mp3'],
|
|
77
|
+
'audio/ogg': ['.ogg', '.oga'],
|
|
78
|
+
'audio/wav': ['.wav'],
|
|
79
|
+
'audio/webm': ['.weba'],
|
|
80
|
+
'audio/aac': ['.aac'],
|
|
81
|
+
'audio/flac': ['.flac'],
|
|
82
|
+
'audio/x-m4a': ['.m4a'],
|
|
83
|
+
|
|
84
|
+
// Wildcards
|
|
85
|
+
'image/*': ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg', '.bmp', '.avif', '.heic', '.heif'],
|
|
86
|
+
'audio/*': ['.mp3', '.wav', '.ogg', '.oga', '.m4a', '.flac', '.aac', '.weba'],
|
|
87
|
+
'video/*': ['.mp4', '.webm', '.ogv', '.mov', '.avi'],
|
|
88
|
+
'text/*': ['.txt', '.html', '.htm', '.css', '.csv', '.md', '.markdown'],
|
|
89
|
+
'application/*': [
|
|
90
|
+
'.pdf',
|
|
91
|
+
'.zip',
|
|
92
|
+
'.json',
|
|
93
|
+
'.xml',
|
|
94
|
+
'.doc',
|
|
95
|
+
'.docx',
|
|
96
|
+
'.xls',
|
|
97
|
+
'.xlsx',
|
|
98
|
+
'.ppt',
|
|
99
|
+
'.pptx',
|
|
100
|
+
'.rtf',
|
|
101
|
+
'.rar',
|
|
102
|
+
'.7z',
|
|
103
|
+
'.tar',
|
|
104
|
+
],
|
|
105
|
+
'font/*': ['.ttf', '.otf', '.woff', '.woff2', '.eot'],
|
|
106
|
+
} as const;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { FileUploadFileMimeType } from '@ark-ui/react';
|
|
2
|
+
import { type AcceptedFileType, type FileExtension, EXTENSIONS_MAP } from '../types/accept-types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Extract file extensions from accept configuration
|
|
6
|
+
* @param accept Array of accepted file types
|
|
7
|
+
* @returns Array of file extensions
|
|
8
|
+
*/
|
|
9
|
+
export function getFileExtensions(accept: AcceptedFileType[]): FileExtension[] {
|
|
10
|
+
return accept.flatMap((item) => {
|
|
11
|
+
if (typeof item === 'string') {
|
|
12
|
+
return EXTENSIONS_MAP[item] ?? [];
|
|
13
|
+
}
|
|
14
|
+
return item.extensions;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Extract MIME types from accept configuration
|
|
20
|
+
* @param accept Array of accepted file types
|
|
21
|
+
* @returns Array of MIME types
|
|
22
|
+
*/
|
|
23
|
+
export function getMimeTypes(accept: AcceptedFileType[]): FileUploadFileMimeType[] {
|
|
24
|
+
return accept.map((item) => (typeof item === 'string' ? item : item.mimeType));
|
|
25
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AcceptedFileType } from '../types/accept-types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Default allowed file types for the file upload component
|
|
5
|
+
*/
|
|
6
|
+
export const DEFAULT_ALLOWED_FILE_TYPES: AcceptedFileType[] = [
|
|
7
|
+
'application/pdf',
|
|
8
|
+
'text/csv',
|
|
9
|
+
'application/zip',
|
|
10
|
+
'application/x-zip-compressed',
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Default maximum file size in bytes (25MB)
|
|
15
|
+
*/
|
|
16
|
+
export const DEFAULT_MAX_FILE_SIZE = 25_000_000;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Default maximum number of files allowed
|
|
20
|
+
*/
|
|
21
|
+
export const DEFAULT_MAX_FILES = 5;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FileError, UploadedFile, UploadFileStatus } from '../ds-file-upload-api.types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates an UploadedFile object from a File with additional metadata
|
|
5
|
+
*/
|
|
6
|
+
export function createUploadedFile(file: File, status: UploadFileStatus, errors?: FileError[]): UploadedFile {
|
|
7
|
+
return {
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-spread -- We're fine with losing the prototype here
|
|
9
|
+
...file,
|
|
10
|
+
id: `${file.name}-${String(Date.now())}-${String(Math.random())}`,
|
|
11
|
+
name: file.name,
|
|
12
|
+
size: file.size,
|
|
13
|
+
type: file.type,
|
|
14
|
+
progress: 0,
|
|
15
|
+
status,
|
|
16
|
+
errors,
|
|
17
|
+
} satisfies UploadedFile;
|
|
18
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format file size to human-readable format using SI units (decimal base)
|
|
3
|
+
*/
|
|
4
|
+
export function formatFileSize(bytes: number): string {
|
|
5
|
+
if (bytes === 0) {
|
|
6
|
+
return '0 B';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const k = 1000; // Decimal base (SI standard)
|
|
10
|
+
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
|
|
11
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
12
|
+
const size = bytes / Math.pow(k, i);
|
|
13
|
+
|
|
14
|
+
return `${size.toFixed(2)} ${sizes[i]}`;
|
|
15
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { AcceptedFileType } from '../types/accept-types';
|
|
2
|
+
import { getFileExtensions } from './accept-utils';
|
|
3
|
+
import { formatFileSize } from './format-file-size';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generate helper text based on validation props
|
|
7
|
+
*/
|
|
8
|
+
export function generateHelperText(
|
|
9
|
+
accept: AcceptedFileType[],
|
|
10
|
+
maxFileSize: number,
|
|
11
|
+
maxFiles: number,
|
|
12
|
+
): string {
|
|
13
|
+
// Extract file extensions from accept configuration
|
|
14
|
+
const extensions = getFileExtensions(accept);
|
|
15
|
+
const uniqueExtensions = [...new Set(extensions)];
|
|
16
|
+
const fileTypes = uniqueExtensions.map((ext) => ext.toUpperCase()).join(', ');
|
|
17
|
+
|
|
18
|
+
// Format file size
|
|
19
|
+
const maxSizeText = formatFileSize(maxFileSize);
|
|
20
|
+
|
|
21
|
+
// Build helper text
|
|
22
|
+
const parts: string[] = [];
|
|
23
|
+
|
|
24
|
+
if (fileTypes) {
|
|
25
|
+
parts.push(`Only ${fileTypes} files`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (maxFileSize < Infinity) {
|
|
29
|
+
parts.push(`File size ${maxSizeText} max`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (maxFiles === 1) {
|
|
33
|
+
parts.push('Only 1 file');
|
|
34
|
+
} else if (maxFiles > 1) {
|
|
35
|
+
parts.push(`Up to ${String(maxFiles)} files`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return parts.join('. ') + '.';
|
|
39
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FileError } from '../ds-file-upload-api.types';
|
|
2
|
+
|
|
3
|
+
const FILE_ERROR_MESSAGES: Record<FileError, string> = {
|
|
4
|
+
FILE_TOO_LARGE: 'File size exceeds the maximum limit',
|
|
5
|
+
FILE_INVALID_TYPE: 'File type is not allowed',
|
|
6
|
+
TOO_MANY_FILES: 'Too many files selected',
|
|
7
|
+
FILE_TOO_SMALL: 'File size is too small',
|
|
8
|
+
FILE_INVALID: 'File is invalid',
|
|
9
|
+
FILE_EXISTS: 'File already exists',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Map FileUploadFileError to user-friendly error message
|
|
14
|
+
*/
|
|
15
|
+
export function getErrorMessage(error: FileError): string {
|
|
16
|
+
return FILE_ERROR_MESSAGES[error] || error || 'File validation failed';
|
|
17
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if two files are equal based on name, size, and type
|
|
3
|
+
*
|
|
4
|
+
* @see https://github.com/chakra-ui/zag/blob/698fff1d2/packages/utilities/file-utils/src/is-file-equal.ts
|
|
5
|
+
*/
|
|
6
|
+
export function isFileEqual(file1: File, file2: File): boolean {
|
|
7
|
+
return file1.name === file2.name && file1.size === file2.size && file1.type === file2.type;
|
|
8
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
@use '../../styles/typography';
|
|
2
|
+
|
|
3
|
+
$form-control-description-max-lines: 2;
|
|
4
|
+
$form-control-description-line-height: 1.4;
|
|
5
|
+
$form-control-description-max-height: calc(
|
|
6
|
+
$form-control-description-line-height * $form-control-description-max-lines * 1em
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
.container {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
gap: var(--spacing-4xs);
|
|
13
|
+
|
|
14
|
+
&.success {
|
|
15
|
+
.message {
|
|
16
|
+
color: var(--color-background-success-strong);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&.warning {
|
|
21
|
+
.message {
|
|
22
|
+
color: var(--color-font-warning);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&.error {
|
|
27
|
+
--form-control-border-color: var(--color-background-danger-strong);
|
|
28
|
+
--form-control-selection-color: var(--color-background-danger-weak);
|
|
29
|
+
|
|
30
|
+
.message {
|
|
31
|
+
color: var(--color-background-danger-strong);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.labelContainer {
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
gap: var(--spacing-4xs);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.label {
|
|
43
|
+
@include typography.body-sm-reg;
|
|
44
|
+
color: var(--color-font-main);
|
|
45
|
+
|
|
46
|
+
&.required::after {
|
|
47
|
+
@include typography.body-sm-reg;
|
|
48
|
+
content: '*';
|
|
49
|
+
position: relative;
|
|
50
|
+
top: -1px;
|
|
51
|
+
right: -1px;
|
|
52
|
+
color: var(--color-icon-danger);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
&.disabled {
|
|
56
|
+
color: var(--color-background-disabled);
|
|
57
|
+
|
|
58
|
+
&::after {
|
|
59
|
+
color: var(--color-font-disabled);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.endAdornment {
|
|
65
|
+
display: flex;
|
|
66
|
+
align-items: center;
|
|
67
|
+
justify-content: center;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.description {
|
|
71
|
+
@include typography.p-s;
|
|
72
|
+
color: var(--neutral-2);
|
|
73
|
+
line-height: $form-control-description-line-height;
|
|
74
|
+
max-height: $form-control-description-max-height;
|
|
75
|
+
overflow: hidden;
|
|
76
|
+
display: -webkit-box;
|
|
77
|
+
-webkit-line-clamp: $form-control-description-max-lines;
|
|
78
|
+
-webkit-box-orient: vertical;
|
|
79
|
+
word-wrap: break-word;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.controlWrapper {
|
|
83
|
+
position: relative;
|
|
84
|
+
|
|
85
|
+
&.input {
|
|
86
|
+
.control {
|
|
87
|
+
padding: 7px 16px;
|
|
88
|
+
line-height: 24px;
|
|
89
|
+
font-style: normal;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.icon {
|
|
93
|
+
top: 50%;
|
|
94
|
+
transform: translateY(-50%);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
&.textarea {
|
|
99
|
+
.control {
|
|
100
|
+
padding: 12px 16px;
|
|
101
|
+
min-height: 100px;
|
|
102
|
+
|
|
103
|
+
&:disabled {
|
|
104
|
+
resize: none;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.icon {
|
|
109
|
+
top: 10px;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.control.withIcon {
|
|
114
|
+
padding-left: 40px;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.icon {
|
|
118
|
+
position: absolute;
|
|
119
|
+
pointer-events: none;
|
|
120
|
+
color: var(--neutral-3);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.icon {
|
|
124
|
+
left: 12px;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.message {
|
|
129
|
+
@include typography.body-xs-reg;
|
|
130
|
+
color: var(--color-font-secondary);
|
|
131
|
+
display: flex;
|
|
132
|
+
align-items: center;
|
|
133
|
+
gap: 4px;
|
|
134
|
+
padding-top: 2px;
|
|
135
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { type ComponentType, createContext, useContext, useId } from 'react';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
import { DsIcon } from '../ds-icon';
|
|
5
|
+
import { DsSelect } from '../ds-select';
|
|
6
|
+
import { DsTextInput } from '../ds-text-input';
|
|
7
|
+
import { DsTextarea } from '../ds-textarea';
|
|
8
|
+
import { DsNumberInput } from '../ds-number-input';
|
|
9
|
+
import { DsPasswordInput } from '../ds-password-input';
|
|
10
|
+
import type { DsFormControlDescriptionProps, DsFormControlProps } from './ds-form-control.types';
|
|
11
|
+
import styles from './ds-form-control.module.scss';
|
|
12
|
+
|
|
13
|
+
const FormControlContext = createContext<{ controlId: string } | null>(null);
|
|
14
|
+
|
|
15
|
+
const useFormControlContext = () => {
|
|
16
|
+
const context = useContext(FormControlContext);
|
|
17
|
+
if (!context) {
|
|
18
|
+
throw new Error('useFormControlContext must be used within DsFormControl');
|
|
19
|
+
}
|
|
20
|
+
return context;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* HOC that automatically injects the controlId from form control context
|
|
25
|
+
* into any component that expects an 'id' prop.
|
|
26
|
+
*
|
|
27
|
+
* @param Component - The component to wrap with form control context
|
|
28
|
+
* @returns A new component that automatically receives the controlId
|
|
29
|
+
*/
|
|
30
|
+
const controlify = <TProps extends { id?: string }>(Component: ComponentType<TProps>) => {
|
|
31
|
+
return function WrappedFormControl(props: TProps) {
|
|
32
|
+
const { controlId } = useFormControlContext();
|
|
33
|
+
return <Component id={controlId} {...props} />;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const DsFormControlDescription: React.FC<DsFormControlDescriptionProps> = ({ children, className }) => {
|
|
38
|
+
return <div className={classNames(styles.description, className)}>{children}</div>;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const DsFormControl = ({
|
|
42
|
+
id,
|
|
43
|
+
status,
|
|
44
|
+
label,
|
|
45
|
+
required = false,
|
|
46
|
+
slots,
|
|
47
|
+
message,
|
|
48
|
+
messageIcon = 'info',
|
|
49
|
+
className,
|
|
50
|
+
style,
|
|
51
|
+
children,
|
|
52
|
+
}: DsFormControlProps) => {
|
|
53
|
+
const generatedId = useId();
|
|
54
|
+
const controlId = id || generatedId;
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<FormControlContext.Provider value={{ controlId }}>
|
|
58
|
+
<div
|
|
59
|
+
className={classNames(styles.container, status && message && styles[status], className)}
|
|
60
|
+
style={style}
|
|
61
|
+
>
|
|
62
|
+
<div className={styles.labelContainer}>
|
|
63
|
+
<label
|
|
64
|
+
htmlFor={controlId}
|
|
65
|
+
className={classNames(styles.label, {
|
|
66
|
+
[styles.required]: required,
|
|
67
|
+
})}
|
|
68
|
+
>
|
|
69
|
+
{label}
|
|
70
|
+
</label>
|
|
71
|
+
{slots?.endAdornment && <div className={styles.endAdornment}>{slots.endAdornment}</div>}
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
{children}
|
|
75
|
+
|
|
76
|
+
{message && (
|
|
77
|
+
<div className={styles.message}>
|
|
78
|
+
<DsIcon icon={messageIcon} size="tiny" filled />
|
|
79
|
+
<span className={styles.messageText}>{message}</span>
|
|
80
|
+
</div>
|
|
81
|
+
)}
|
|
82
|
+
</div>
|
|
83
|
+
</FormControlContext.Provider>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
DsFormControl.TextInput = controlify(DsTextInput);
|
|
88
|
+
DsFormControl.NumberInput = controlify(DsNumberInput);
|
|
89
|
+
DsFormControl.PasswordInput = controlify(DsPasswordInput);
|
|
90
|
+
DsFormControl.Textarea = controlify(DsTextarea);
|
|
91
|
+
DsFormControl.Select = controlify(DsSelect);
|
|
92
|
+
DsFormControl.Description = DsFormControlDescription;
|
|
93
|
+
|
|
94
|
+
export default DsFormControl;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { IconType } from '../ds-icon';
|
|
3
|
+
|
|
4
|
+
export const controlStatuses = ['info', 'success', 'error', 'warning'] as const;
|
|
5
|
+
export type ControlStatus = (typeof controlStatuses)[number];
|
|
6
|
+
|
|
7
|
+
export interface DsFormControlProps extends React.PropsWithChildren {
|
|
8
|
+
/**
|
|
9
|
+
* Unique identifier for the control
|
|
10
|
+
*/
|
|
11
|
+
id?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Visual status
|
|
14
|
+
*/
|
|
15
|
+
status?: ControlStatus;
|
|
16
|
+
/**
|
|
17
|
+
* Label text
|
|
18
|
+
*/
|
|
19
|
+
label: string;
|
|
20
|
+
/**
|
|
21
|
+
* Marks the field as required
|
|
22
|
+
*/
|
|
23
|
+
required?: boolean;
|
|
24
|
+
|
|
25
|
+
slots?: {
|
|
26
|
+
/**
|
|
27
|
+
* Adornment to display at the end of the label
|
|
28
|
+
*/
|
|
29
|
+
endAdornment?: React.ReactNode;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Message under the control
|
|
33
|
+
*/
|
|
34
|
+
message?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Icon shown next to message
|
|
37
|
+
*/
|
|
38
|
+
messageIcon?: IconType;
|
|
39
|
+
/**
|
|
40
|
+
* Additional CSS class names
|
|
41
|
+
*/
|
|
42
|
+
className?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Additional styles to apply to the component
|
|
45
|
+
*/
|
|
46
|
+
style?: React.CSSProperties;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface DsFormControlDescriptionProps {
|
|
50
|
+
/**
|
|
51
|
+
* The description content
|
|
52
|
+
*/
|
|
53
|
+
children: React.ReactNode;
|
|
54
|
+
/**
|
|
55
|
+
* Additional CSS class names
|
|
56
|
+
*/
|
|
57
|
+
className?: string;
|
|
58
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import type { DsGridItemProps, DsGridProps } from './ds-grid.types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Design system Grid component
|
|
7
|
+
*/
|
|
8
|
+
export const DsGrid: React.FC<DsGridProps> = ({ children, columns, rows, className }) => {
|
|
9
|
+
const gridClass = classNames(
|
|
10
|
+
'ds-grid',
|
|
11
|
+
{
|
|
12
|
+
[`ds-grid-cols-${String(columns)}`]: columns,
|
|
13
|
+
[`ds-grid-rows-${String(rows)}`]: rows,
|
|
14
|
+
},
|
|
15
|
+
className,
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
return <div className={gridClass}>{children}</div>;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Design system GridItem component
|
|
23
|
+
*/
|
|
24
|
+
export const DsGridItem: React.FC<DsGridItemProps> = ({
|
|
25
|
+
children,
|
|
26
|
+
colSpan,
|
|
27
|
+
colStart,
|
|
28
|
+
rowSpan,
|
|
29
|
+
rowStart,
|
|
30
|
+
className,
|
|
31
|
+
}) => {
|
|
32
|
+
const gridItemClass = classNames(
|
|
33
|
+
{
|
|
34
|
+
[`ds-grid-col-span-${String(colSpan)}`]: colSpan,
|
|
35
|
+
[`ds-grid-col-start-${String(colStart)}`]: colStart,
|
|
36
|
+
[`ds-grid-row-span-${String(rowSpan)}`]: rowSpan,
|
|
37
|
+
[`ds-grid-row-start-${String(rowStart)}`]: rowStart,
|
|
38
|
+
},
|
|
39
|
+
className,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
return <div className={gridItemClass}>{children}</div>;
|
|
43
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface DsGridProps {
|
|
4
|
+
/**
|
|
5
|
+
* The content to be rendered inside the grid
|
|
6
|
+
*/
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Number of rows in the grid (defaults to 1)
|
|
11
|
+
*/
|
|
12
|
+
rows?: 1 | 2 | 4 | 6 | 8;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Number of columns in the grid (defaults to 12)
|
|
16
|
+
*/
|
|
17
|
+
columns?: 2 | 4 | 6 | 8 | 10 | 12;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Custom class names to apply to the grid
|
|
21
|
+
*/
|
|
22
|
+
className?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface DsGridItemProps {
|
|
26
|
+
/**
|
|
27
|
+
* The content to be rendered inside the grid item
|
|
28
|
+
*/
|
|
29
|
+
children: ReactNode;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Number of columns the item spans (1-12) or 'full'
|
|
33
|
+
*/
|
|
34
|
+
colSpan?: number | 'full';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Starting column for the item (1-11)
|
|
38
|
+
*/
|
|
39
|
+
colStart?: number;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Number of rows the item spans (1-8) or 'full'
|
|
43
|
+
*/
|
|
44
|
+
rowSpan?: number | 'full';
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Starting row for the item (1-7)
|
|
48
|
+
*/
|
|
49
|
+
rowStart?: number;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Custom class names to apply to the grid item
|
|
53
|
+
*/
|
|
54
|
+
className?: string;
|
|
55
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
.icon {
|
|
2
|
+
&.extra-large {
|
|
3
|
+
font-size: var(--icon-width-extra-large);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
&.large {
|
|
7
|
+
font-size: var(--icon-width-large);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
&.medium {
|
|
11
|
+
font-size: var(--icon-width-medium);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
&.small {
|
|
15
|
+
font-size: var(--icon-width-small);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
&.tiny {
|
|
19
|
+
font-size: var(--icon-width-tiny);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.filled {
|
|
24
|
+
font-variation-settings: 'FILL' 1;
|
|
25
|
+
}
|