@makolabs/ripple 1.7.11 → 1.9.0
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 +16 -0
- package/dist/adapters/ai/OpenAIAdapter.d.ts +8 -1
- package/dist/adapters/ai/OpenAIAdapter.js +2 -2
- package/dist/adapters/storage/BaseAdapter.js +2 -2
- package/dist/adapters/storage/S3Adapter.js +1 -6
- package/dist/adapters/storage/types.d.ts +3 -3
- package/dist/ai/AIChatInterface.svelte +0 -1
- package/dist/ai/ai-chat-interface.d.ts +21 -22
- package/dist/ai/ai-types.d.ts +44 -0
- package/dist/ai/ai-types.js +1 -0
- package/dist/ai/content-detector.js +0 -1
- package/dist/button/Button.svelte +9 -2
- package/dist/button/button-types.d.ts +25 -0
- package/dist/button/button-types.js +1 -0
- package/dist/button/button.d.ts +39 -40
- package/dist/charts/Chart.svelte +11 -23
- package/dist/charts/chart-types.d.ts +137 -0
- package/dist/charts/chart-types.js +1 -0
- package/dist/drawer/Drawer.svelte +57 -23
- package/dist/drawer/drawer-types.d.ts +33 -0
- package/dist/drawer/drawer-types.js +1 -0
- package/dist/drawer/drawer.d.ts +18 -19
- package/dist/elements/accordion/Accordion.svelte +39 -18
- package/dist/elements/accordion/accordion-types.d.ts +29 -0
- package/dist/elements/accordion/accordion-types.js +1 -0
- package/dist/elements/accordion/accordion.d.ts +21 -22
- package/dist/elements/alert/Alert.svelte +20 -8
- package/dist/elements/badge/Badge.svelte +5 -2
- package/dist/elements/badge/badge-types.d.ts +11 -0
- package/dist/elements/badge/badge-types.js +1 -0
- package/dist/elements/badge/badge.d.ts +39 -40
- package/dist/elements/dropdown/Dropdown.svelte +18 -2
- package/dist/elements/dropdown/Select.svelte +17 -5
- package/dist/elements/dropdown/dropdown-types.d.ts +68 -0
- package/dist/elements/dropdown/dropdown-types.js +1 -0
- package/dist/elements/dropdown/dropdown.d.ts +18 -19
- package/dist/elements/dropdown/select.d.ts +18 -19
- package/dist/elements/file-upload/file-upload-types.d.ts +68 -0
- package/dist/elements/file-upload/file-upload-types.js +1 -0
- package/dist/elements/pagination/Pagination.svelte +15 -2
- package/dist/elements/pagination/Pagination.svelte.d.ts +1 -0
- package/dist/elements/progress/progress-types.d.ts +22 -0
- package/dist/elements/progress/progress-types.js +1 -0
- package/dist/elements/timeline/timeline-types.d.ts +11 -0
- package/dist/elements/timeline/timeline-types.js +1 -0
- package/dist/filters/filter-types.d.ts +24 -0
- package/dist/filters/filter-types.js +1 -0
- package/dist/forms/Checkbox.svelte +16 -4
- package/dist/forms/Form.svelte +0 -2
- package/dist/forms/Input.svelte +19 -5
- package/dist/forms/NumberInput.svelte +8 -1
- package/dist/forms/RadioInputs.svelte +14 -5
- package/dist/forms/Slider.svelte +6 -4
- package/dist/forms/Toggle.svelte +67 -29
- package/dist/forms/form-types.d.ts +168 -0
- package/dist/forms/form-types.js +1 -0
- package/dist/forms/slider.d.ts +72 -10
- package/dist/forms/slider.js +21 -0
- package/dist/header/Breadcrumbs.svelte +47 -24
- package/dist/header/PageHeader.svelte +12 -2
- package/dist/header/breadcrumbs.d.ts +47 -39
- package/dist/header/header-types.d.ts +43 -0
- package/dist/header/header-types.js +1 -0
- package/dist/helper/deprecation.d.ts +14 -0
- package/dist/helper/deprecation.js +24 -0
- package/dist/helper/testid.d.ts +10 -0
- package/dist/helper/testid.js +17 -0
- package/dist/index.d.ts +37 -1007
- package/dist/index.js +38 -14
- package/dist/layout/activity-list/activity-list-types.d.ts +30 -0
- package/dist/layout/activity-list/activity-list-types.js +1 -0
- package/dist/layout/activity-list/activity-list.d.ts +21 -22
- package/dist/layout/card/Card.svelte +19 -5
- package/dist/layout/card/card-types.d.ts +43 -0
- package/dist/layout/card/card-types.js +1 -0
- package/dist/layout/card/card.d.ts +21 -22
- package/dist/layout/card/metric-card.d.ts +3 -3
- package/dist/layout/card/ranked-card.d.ts +2 -1
- package/dist/layout/navbar/Navbar.svelte +14 -16
- package/dist/layout/navbar/navbar-types.d.ts +19 -0
- package/dist/layout/navbar/navbar-types.js +1 -0
- package/dist/layout/navbar/navbar.d.ts +19 -19
- package/dist/layout/sidebar/Sidebar.svelte +6 -3
- package/dist/layout/sidebar/sidebar-types.d.ts +59 -0
- package/dist/layout/sidebar/sidebar-types.js +1 -0
- package/dist/layout/table/Table.svelte +237 -303
- package/dist/layout/table/table-types.d.ts +82 -0
- package/dist/layout/table/table-types.js +1 -0
- package/dist/layout/table/table.d.ts +24 -25
- package/dist/layout/tabs/Tab.svelte +3 -1
- package/dist/layout/tabs/TabGroup.svelte +7 -4
- package/dist/layout/tabs/tabs-types.d.ts +43 -0
- package/dist/layout/tabs/tabs-types.js +1 -0
- package/dist/layout/tabs/tabs.d.ts +39 -40
- package/dist/modal/Modal.svelte +124 -21
- package/dist/modal/modal-types.d.ts +34 -0
- package/dist/modal/modal-types.js +1 -0
- package/dist/modal/modal.d.ts +18 -19
- package/dist/modal/modal.js +2 -2
- package/dist/types/echarts.d.ts +27 -0
- package/dist/user-management/UserModal.svelte +1 -1
- package/dist/user-management/UserTable.svelte +3 -3
- package/dist/user-management/UserViewModal.svelte +2 -2
- package/dist/user-management/user-management-types.d.ts +156 -0
- package/dist/user-management/user-management-types.js +1 -0
- package/dist/variants.d.ts +13 -13
- package/package.json +9 -7
- package/dist/ai/AIChatInterfaceTestWrapper.svelte +0 -26
- package/dist/ai/AIChatInterfaceTestWrapper.svelte.d.ts +0 -17
- package/dist/button/ButtonTestWrapper.svelte +0 -10
- package/dist/button/ButtonTestWrapper.svelte.d.ts +0 -7
- package/dist/drawer/DrawerTestWrapper.svelte +0 -19
- package/dist/drawer/DrawerTestWrapper.svelte.d.ts +0 -9
- package/dist/elements/accordion/AccordionTestWrapper.svelte +0 -21
- package/dist/elements/accordion/AccordionTestWrapper.svelte.d.ts +0 -10
- package/dist/elements/badge/BadgeTestWrapper.svelte +0 -14
- package/dist/elements/badge/BadgeTestWrapper.svelte.d.ts +0 -9
- package/dist/forms/CheckboxTestWrapper.svelte +0 -8
- package/dist/forms/CheckboxTestWrapper.svelte.d.ts +0 -4
- package/dist/forms/InputTestWrapper.svelte +0 -8
- package/dist/forms/InputTestWrapper.svelte.d.ts +0 -4
- package/dist/forms/ToggleTestWrapper.svelte +0 -8
- package/dist/forms/ToggleTestWrapper.svelte.d.ts +0 -7
- package/dist/layout/card/CardTestWrapper.svelte +0 -15
- package/dist/layout/card/CardTestWrapper.svelte.d.ts +0 -7
- package/dist/modal/ModalTestWrapper.svelte +0 -20
- package/dist/modal/ModalTestWrapper.svelte.d.ts +0 -8
- package/dist/user-management/UserManagementTestWrapper.svelte +0 -32
- package/dist/user-management/UserManagementTestWrapper.svelte.d.ts +0 -12
- package/dist/user-management/UserModalTestWrapper.svelte +0 -22
- package/dist/user-management/UserModalTestWrapper.svelte.d.ts +0 -7
- package/dist/user-management/UserTableTestWrapper.svelte +0 -41
- package/dist/user-management/UserTableTestWrapper.svelte.d.ts +0 -7
- package/dist/user-management/UserViewModalTestWrapper.svelte +0 -22
- package/dist/user-management/UserViewModalTestWrapper.svelte.d.ts +0 -7
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { ClassValue } from 'tailwind-variants';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
export type DataRow = Record<string, any>;
|
|
4
|
+
export type KeyType = keyof DataRow;
|
|
5
|
+
export type StatusType = 'active' | 'inactive' | 'pending' | 'error' | 'default';
|
|
6
|
+
export type TableColumn<T extends DataRow = any> = {
|
|
7
|
+
key: KeyType;
|
|
8
|
+
header: string;
|
|
9
|
+
cell?: Snippet<[row: T, key: KeyType, index?: number]>;
|
|
10
|
+
sortable?: boolean;
|
|
11
|
+
sortKey?: string;
|
|
12
|
+
align?: 'left' | 'center' | 'right';
|
|
13
|
+
width?: string;
|
|
14
|
+
class?: ClassValue;
|
|
15
|
+
};
|
|
16
|
+
export type SortDirection = 'asc' | 'desc' | null;
|
|
17
|
+
export type SortState = {
|
|
18
|
+
column: string | null;
|
|
19
|
+
direction: SortDirection;
|
|
20
|
+
};
|
|
21
|
+
export type TableProps<T extends DataRow = any> = {
|
|
22
|
+
data: T[];
|
|
23
|
+
columns: TableColumn<T>[];
|
|
24
|
+
bordered?: boolean;
|
|
25
|
+
striped?: boolean;
|
|
26
|
+
pageSize?: number;
|
|
27
|
+
currentPage?: number;
|
|
28
|
+
totalItems?: number;
|
|
29
|
+
selectable?: boolean;
|
|
30
|
+
selected?: T[];
|
|
31
|
+
class?: ClassValue;
|
|
32
|
+
/** @deprecated Use wrapperClass instead */
|
|
33
|
+
wrapperclass?: ClassValue;
|
|
34
|
+
wrapperClass?: ClassValue;
|
|
35
|
+
/** @deprecated Use tableClass instead */
|
|
36
|
+
tableclass?: ClassValue;
|
|
37
|
+
tableClass?: ClassValue;
|
|
38
|
+
/** @deprecated Use theadClass instead */
|
|
39
|
+
theadclass?: ClassValue;
|
|
40
|
+
theadClass?: ClassValue;
|
|
41
|
+
/** @deprecated Use tbodyClass instead */
|
|
42
|
+
tbodyclass?: ClassValue;
|
|
43
|
+
tbodyClass?: ClassValue;
|
|
44
|
+
/** @deprecated Use trClass instead */
|
|
45
|
+
trclass?: ClassValue;
|
|
46
|
+
trClass?: ClassValue;
|
|
47
|
+
/** @deprecated Use thClass instead */
|
|
48
|
+
thclass?: ClassValue;
|
|
49
|
+
thClass?: ClassValue;
|
|
50
|
+
/** @deprecated Use tdClass instead */
|
|
51
|
+
tdclass?: ClassValue;
|
|
52
|
+
tdClass?: ClassValue;
|
|
53
|
+
/** @deprecated Use footerClass instead */
|
|
54
|
+
footerclass?: ClassValue;
|
|
55
|
+
footerClass?: ClassValue;
|
|
56
|
+
/** @deprecated Use paginationClass instead */
|
|
57
|
+
paginationclass?: ClassValue;
|
|
58
|
+
paginationClass?: ClassValue;
|
|
59
|
+
onrowclick?: (row: T, index: number) => void;
|
|
60
|
+
onsort?: (sortState: SortState) => void;
|
|
61
|
+
onselect?: (selected: T[]) => void;
|
|
62
|
+
onpagechange?: (page: number) => void;
|
|
63
|
+
/** @deprecated Use rowClass instead */
|
|
64
|
+
rowclass?: (row: T, index: number) => ClassValue;
|
|
65
|
+
rowClass?: (row: T, index: number) => ClassValue;
|
|
66
|
+
loading?: boolean;
|
|
67
|
+
expandedContent?: Snippet<[T]>;
|
|
68
|
+
pagination?: boolean;
|
|
69
|
+
showPagination?: boolean;
|
|
70
|
+
showPageSize?: boolean;
|
|
71
|
+
pageSizeOptions?: number[];
|
|
72
|
+
onpagesizechange?: (pageSize: number) => void;
|
|
73
|
+
paginationPosition?: 'top' | 'bottom' | 'both';
|
|
74
|
+
paginationTemplate?: 'simple' | 'full';
|
|
75
|
+
title?: string;
|
|
76
|
+
subtitle?: string;
|
|
77
|
+
headerActions?: Snippet;
|
|
78
|
+
selectAllScope?: 'page' | 'all';
|
|
79
|
+
rowKey?: string;
|
|
80
|
+
expandable?: boolean;
|
|
81
|
+
testId?: string;
|
|
82
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Color } from '../../variants.js';
|
|
2
1
|
export declare const table: import("tailwind-variants").TVReturnType<{
|
|
3
2
|
size: {
|
|
4
3
|
xs: {
|
|
@@ -27,32 +26,32 @@ export declare const table: import("tailwind-variants").TVReturnType<{
|
|
|
27
26
|
};
|
|
28
27
|
};
|
|
29
28
|
color: {
|
|
30
|
-
|
|
29
|
+
default: {
|
|
31
30
|
th: string;
|
|
32
|
-
tr: string;
|
|
33
31
|
};
|
|
34
|
-
|
|
32
|
+
primary: {
|
|
35
33
|
th: string;
|
|
36
34
|
tr: string;
|
|
37
35
|
};
|
|
38
|
-
|
|
36
|
+
secondary: {
|
|
39
37
|
th: string;
|
|
40
38
|
tr: string;
|
|
41
39
|
};
|
|
42
|
-
|
|
40
|
+
info: {
|
|
43
41
|
th: string;
|
|
44
42
|
tr: string;
|
|
45
43
|
};
|
|
46
|
-
|
|
44
|
+
success: {
|
|
47
45
|
th: string;
|
|
48
46
|
tr: string;
|
|
49
47
|
};
|
|
50
|
-
|
|
48
|
+
warning: {
|
|
51
49
|
th: string;
|
|
52
50
|
tr: string;
|
|
53
51
|
};
|
|
54
|
-
|
|
52
|
+
danger: {
|
|
55
53
|
th: string;
|
|
54
|
+
tr: string;
|
|
56
55
|
};
|
|
57
56
|
};
|
|
58
57
|
bordered: {
|
|
@@ -112,32 +111,32 @@ export declare const table: import("tailwind-variants").TVReturnType<{
|
|
|
112
111
|
};
|
|
113
112
|
};
|
|
114
113
|
color: {
|
|
115
|
-
|
|
114
|
+
default: {
|
|
116
115
|
th: string;
|
|
117
|
-
tr: string;
|
|
118
116
|
};
|
|
119
|
-
|
|
117
|
+
primary: {
|
|
120
118
|
th: string;
|
|
121
119
|
tr: string;
|
|
122
120
|
};
|
|
123
|
-
|
|
121
|
+
secondary: {
|
|
124
122
|
th: string;
|
|
125
123
|
tr: string;
|
|
126
124
|
};
|
|
127
|
-
|
|
125
|
+
info: {
|
|
128
126
|
th: string;
|
|
129
127
|
tr: string;
|
|
130
128
|
};
|
|
131
|
-
|
|
129
|
+
success: {
|
|
132
130
|
th: string;
|
|
133
131
|
tr: string;
|
|
134
132
|
};
|
|
135
|
-
|
|
133
|
+
warning: {
|
|
136
134
|
th: string;
|
|
137
135
|
tr: string;
|
|
138
136
|
};
|
|
139
|
-
|
|
137
|
+
danger: {
|
|
140
138
|
th: string;
|
|
139
|
+
tr: string;
|
|
141
140
|
};
|
|
142
141
|
};
|
|
143
142
|
bordered: {
|
|
@@ -197,32 +196,32 @@ export declare const table: import("tailwind-variants").TVReturnType<{
|
|
|
197
196
|
};
|
|
198
197
|
};
|
|
199
198
|
color: {
|
|
200
|
-
|
|
199
|
+
default: {
|
|
201
200
|
th: string;
|
|
202
|
-
tr: string;
|
|
203
201
|
};
|
|
204
|
-
|
|
202
|
+
primary: {
|
|
205
203
|
th: string;
|
|
206
204
|
tr: string;
|
|
207
205
|
};
|
|
208
|
-
|
|
206
|
+
secondary: {
|
|
209
207
|
th: string;
|
|
210
208
|
tr: string;
|
|
211
209
|
};
|
|
212
|
-
|
|
210
|
+
info: {
|
|
213
211
|
th: string;
|
|
214
212
|
tr: string;
|
|
215
213
|
};
|
|
216
|
-
|
|
214
|
+
success: {
|
|
217
215
|
th: string;
|
|
218
216
|
tr: string;
|
|
219
217
|
};
|
|
220
|
-
|
|
218
|
+
warning: {
|
|
221
219
|
th: string;
|
|
222
220
|
tr: string;
|
|
223
221
|
};
|
|
224
|
-
|
|
222
|
+
danger: {
|
|
225
223
|
th: string;
|
|
224
|
+
tr: string;
|
|
226
225
|
};
|
|
227
226
|
};
|
|
228
227
|
bordered: {
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
color = Color.PRIMARY,
|
|
13
13
|
size = Size.BASE,
|
|
14
14
|
onclick = () => {},
|
|
15
|
-
variant = 'line'
|
|
15
|
+
variant = 'line',
|
|
16
|
+
testId
|
|
16
17
|
}: TabProps = $props();
|
|
17
18
|
|
|
18
19
|
function handleClick(event: Event & { currentTarget: EventTarget & HTMLButtonElement }) {
|
|
@@ -43,6 +44,7 @@
|
|
|
43
44
|
id={`tab-${value}`}
|
|
44
45
|
aria-controls={`panel-${value}`}
|
|
45
46
|
aria-selected={selected ? 'true' : 'false'}
|
|
47
|
+
data-testid={testId}
|
|
46
48
|
onclick={handleClick}
|
|
47
49
|
onkeydown={(e) => {
|
|
48
50
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { cn } from '../../helper/cls.js';
|
|
3
|
+
import { buildTestId } from '../../helper/testid.js';
|
|
3
4
|
import Tab from './Tab.svelte';
|
|
4
5
|
import { tabs } from './tabs.js';
|
|
5
6
|
import type { TabsGroupProps } from '../../index.js';
|
|
@@ -16,7 +17,8 @@
|
|
|
16
17
|
listClass = '',
|
|
17
18
|
panelClass = '',
|
|
18
19
|
onchange = () => {},
|
|
19
|
-
children
|
|
20
|
+
children,
|
|
21
|
+
testId
|
|
20
22
|
}: TabsGroupProps = $props();
|
|
21
23
|
|
|
22
24
|
const { base, list, panel } = $derived(
|
|
@@ -40,8 +42,8 @@
|
|
|
40
42
|
</script>
|
|
41
43
|
|
|
42
44
|
<div class={baseClass}>
|
|
43
|
-
<div class={listClass_} role="tablist">
|
|
44
|
-
{#each tabItems as tab (tab.value)}
|
|
45
|
+
<div class={listClass_} role="tablist" data-testid={buildTestId('tabgroup', 'list', testId)}>
|
|
46
|
+
{#each tabItems as tab, index (tab.value)}
|
|
45
47
|
<Tab
|
|
46
48
|
value={tab.value}
|
|
47
49
|
label={tab.label}
|
|
@@ -51,12 +53,13 @@
|
|
|
51
53
|
{color}
|
|
52
54
|
{size}
|
|
53
55
|
{variant}
|
|
56
|
+
testId={buildTestId('tabgroup', 'tab', testId, index)}
|
|
54
57
|
onclick={() => handleTabClick(tab.value)}
|
|
55
58
|
/>
|
|
56
59
|
{/each}
|
|
57
60
|
</div>
|
|
58
61
|
|
|
59
|
-
<div class={panelClass_}>
|
|
62
|
+
<div class={panelClass_} data-testid={buildTestId('tabgroup', 'panel', testId)}>
|
|
60
63
|
{@render children?.(selected)}
|
|
61
64
|
</div>
|
|
62
65
|
</div>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ClassValue } from 'tailwind-variants';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { Component } from 'svelte';
|
|
4
|
+
import type { VariantColors, VariantSizes } from '../../index.js';
|
|
5
|
+
export type TabItem = {
|
|
6
|
+
value: string;
|
|
7
|
+
label: string;
|
|
8
|
+
icon?: Component;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
};
|
|
11
|
+
export type TabProps = {
|
|
12
|
+
value: string;
|
|
13
|
+
label: string;
|
|
14
|
+
icon?: Component;
|
|
15
|
+
selected?: boolean;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
color?: VariantColors;
|
|
18
|
+
size?: VariantSizes;
|
|
19
|
+
variant?: 'line' | 'pill';
|
|
20
|
+
onclick?: (event: Event) => void;
|
|
21
|
+
testId?: string;
|
|
22
|
+
};
|
|
23
|
+
export type TabsGroupProps = {
|
|
24
|
+
tabs: TabItem[];
|
|
25
|
+
selected?: string;
|
|
26
|
+
color?: VariantColors;
|
|
27
|
+
size?: VariantSizes;
|
|
28
|
+
variant?: 'line' | 'pill';
|
|
29
|
+
class?: ClassValue;
|
|
30
|
+
listClass?: ClassValue;
|
|
31
|
+
triggerClass?: ClassValue;
|
|
32
|
+
panelClass?: ClassValue;
|
|
33
|
+
children?: Snippet<[active: string]>;
|
|
34
|
+
onchange?: (value: string) => void;
|
|
35
|
+
testId?: string;
|
|
36
|
+
};
|
|
37
|
+
export type TabContentProps = {
|
|
38
|
+
value: string;
|
|
39
|
+
persisted?: boolean;
|
|
40
|
+
panelClass?: ClassValue;
|
|
41
|
+
children?: Snippet<[value: string]>;
|
|
42
|
+
testId?: string;
|
|
43
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,31 +1,30 @@
|
|
|
1
|
-
import { Color, Size } from '../../index.js';
|
|
2
1
|
export declare const tabs: import("tailwind-variants").TVReturnType<{
|
|
3
2
|
color: {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
primary: {};
|
|
4
|
+
secondary: {};
|
|
5
|
+
success: {};
|
|
6
|
+
warning: {};
|
|
7
|
+
danger: {};
|
|
8
|
+
info: {};
|
|
9
|
+
default: {};
|
|
11
10
|
};
|
|
12
11
|
size: {
|
|
13
|
-
|
|
12
|
+
xs: {
|
|
14
13
|
trigger: string;
|
|
15
14
|
};
|
|
16
|
-
|
|
15
|
+
sm: {
|
|
17
16
|
trigger: string;
|
|
18
17
|
};
|
|
19
|
-
|
|
18
|
+
base: {
|
|
20
19
|
trigger: string;
|
|
21
20
|
};
|
|
22
|
-
|
|
21
|
+
lg: {
|
|
23
22
|
trigger: string;
|
|
24
23
|
};
|
|
25
|
-
|
|
24
|
+
xl: {
|
|
26
25
|
trigger: string;
|
|
27
26
|
};
|
|
28
|
-
|
|
27
|
+
"2xl": {
|
|
29
28
|
trigger: string;
|
|
30
29
|
};
|
|
31
30
|
};
|
|
@@ -47,31 +46,31 @@ export declare const tabs: import("tailwind-variants").TVReturnType<{
|
|
|
47
46
|
panel: string;
|
|
48
47
|
}, undefined, {
|
|
49
48
|
color: {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
primary: {};
|
|
50
|
+
secondary: {};
|
|
51
|
+
success: {};
|
|
52
|
+
warning: {};
|
|
53
|
+
danger: {};
|
|
54
|
+
info: {};
|
|
55
|
+
default: {};
|
|
57
56
|
};
|
|
58
57
|
size: {
|
|
59
|
-
|
|
58
|
+
xs: {
|
|
60
59
|
trigger: string;
|
|
61
60
|
};
|
|
62
|
-
|
|
61
|
+
sm: {
|
|
63
62
|
trigger: string;
|
|
64
63
|
};
|
|
65
|
-
|
|
64
|
+
base: {
|
|
66
65
|
trigger: string;
|
|
67
66
|
};
|
|
68
|
-
|
|
67
|
+
lg: {
|
|
69
68
|
trigger: string;
|
|
70
69
|
};
|
|
71
|
-
|
|
70
|
+
xl: {
|
|
72
71
|
trigger: string;
|
|
73
72
|
};
|
|
74
|
-
|
|
73
|
+
"2xl": {
|
|
75
74
|
trigger: string;
|
|
76
75
|
};
|
|
77
76
|
};
|
|
@@ -93,31 +92,31 @@ export declare const tabs: import("tailwind-variants").TVReturnType<{
|
|
|
93
92
|
panel: string;
|
|
94
93
|
}, import("tailwind-variants").TVReturnType<{
|
|
95
94
|
color: {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
95
|
+
primary: {};
|
|
96
|
+
secondary: {};
|
|
97
|
+
success: {};
|
|
98
|
+
warning: {};
|
|
99
|
+
danger: {};
|
|
100
|
+
info: {};
|
|
101
|
+
default: {};
|
|
103
102
|
};
|
|
104
103
|
size: {
|
|
105
|
-
|
|
104
|
+
xs: {
|
|
106
105
|
trigger: string;
|
|
107
106
|
};
|
|
108
|
-
|
|
107
|
+
sm: {
|
|
109
108
|
trigger: string;
|
|
110
109
|
};
|
|
111
|
-
|
|
110
|
+
base: {
|
|
112
111
|
trigger: string;
|
|
113
112
|
};
|
|
114
|
-
|
|
113
|
+
lg: {
|
|
115
114
|
trigger: string;
|
|
116
115
|
};
|
|
117
|
-
|
|
116
|
+
xl: {
|
|
118
117
|
trigger: string;
|
|
119
118
|
};
|
|
120
|
-
|
|
119
|
+
"2xl": {
|
|
121
120
|
trigger: string;
|
|
122
121
|
};
|
|
123
122
|
};
|
package/dist/modal/Modal.svelte
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { onDestroy, tick } from 'svelte';
|
|
3
|
+
import { browser } from '$app/environment';
|
|
2
4
|
import { fade, scale } from 'svelte/transition';
|
|
3
5
|
import { quintOut } from 'svelte/easing';
|
|
4
6
|
import { cn } from '../helper/cls.js';
|
|
7
|
+
import { buildTestId } from '../helper/testid.js';
|
|
8
|
+
import { warnDeprecatedProps } from '../helper/deprecation.js';
|
|
5
9
|
import { modal } from './modal.js';
|
|
6
10
|
import type { ModalProps } from '../index.js';
|
|
7
11
|
|
|
@@ -13,32 +17,55 @@
|
|
|
13
17
|
size,
|
|
14
18
|
hideCloseButton = false,
|
|
15
19
|
class: className = '',
|
|
16
|
-
contentclass
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
contentclass,
|
|
21
|
+
contentClass = contentclass ?? '',
|
|
22
|
+
bodyclass,
|
|
23
|
+
bodyClass = bodyclass ?? '',
|
|
24
|
+
titleclass,
|
|
25
|
+
titleClass = titleclass ?? '',
|
|
26
|
+
headerclass,
|
|
27
|
+
headerClass = headerclass ?? '',
|
|
28
|
+
backdropclass,
|
|
29
|
+
backdropClass = backdropclass ?? '',
|
|
30
|
+
footerclass,
|
|
31
|
+
footerClass = footerclass ?? '',
|
|
21
32
|
children,
|
|
22
33
|
footer,
|
|
23
|
-
header
|
|
34
|
+
header,
|
|
35
|
+
testId
|
|
24
36
|
}: ModalProps = $props();
|
|
25
37
|
|
|
38
|
+
warnDeprecatedProps(
|
|
39
|
+
'Modal',
|
|
40
|
+
{ contentclass, bodyclass, titleclass, headerclass, backdropclass, footerclass },
|
|
41
|
+
{
|
|
42
|
+
contentclass: 'contentClass',
|
|
43
|
+
bodyclass: 'bodyClass',
|
|
44
|
+
titleclass: 'titleClass',
|
|
45
|
+
headerclass: 'headerClass',
|
|
46
|
+
backdropclass: 'backdropClass',
|
|
47
|
+
footerclass: 'footerClass'
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
let modalElement: HTMLDivElement | undefined = $state();
|
|
52
|
+
|
|
26
53
|
const styles = $derived(modal({ size }));
|
|
27
54
|
|
|
28
55
|
const baseClass = $derived(cn(styles.base(), className));
|
|
29
|
-
const
|
|
30
|
-
const containerClass = $derived(cn(styles.container(),
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
const
|
|
56
|
+
const backdropClasses = $derived(cn(styles.backdrop(), backdropClass));
|
|
57
|
+
const containerClass = $derived(cn(styles.container(), contentClass));
|
|
58
|
+
const headerClasses = $derived(cn(styles.header(), headerClass));
|
|
59
|
+
const titleClasses = $derived(cn(styles.title(), titleClass));
|
|
60
|
+
const bodyClasses = $derived(
|
|
34
61
|
cn(
|
|
35
62
|
'flex-1 px-6 overflow-y-auto',
|
|
36
63
|
// Adjust top padding based on header presence
|
|
37
64
|
title || description ? 'py-4' : 'pt-6 pb-4',
|
|
38
|
-
|
|
65
|
+
bodyClass
|
|
39
66
|
)
|
|
40
67
|
);
|
|
41
|
-
const
|
|
68
|
+
const footerClasses = $derived(cn(styles.footer(), footerClass));
|
|
42
69
|
const closeClass = $derived(cn(styles.close(), ''));
|
|
43
70
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
44
71
|
const descriptionClass = $derived(cn(styles.description(), ''));
|
|
@@ -53,13 +80,59 @@
|
|
|
53
80
|
}
|
|
54
81
|
}
|
|
55
82
|
|
|
83
|
+
let previouslyFocusedElement: HTMLElement | null = null;
|
|
84
|
+
|
|
85
|
+
function trapFocus(element: HTMLElement) {
|
|
86
|
+
const focusableElements = element.querySelectorAll(
|
|
87
|
+
'a[href], button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])'
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
if (focusableElements.length === 0) return;
|
|
91
|
+
|
|
92
|
+
const firstElement = focusableElements[0] as HTMLElement;
|
|
93
|
+
const lastElement = focusableElements[focusableElements.length - 1] as HTMLElement;
|
|
94
|
+
|
|
95
|
+
function handleTabKey(e: KeyboardEvent) {
|
|
96
|
+
if (e.key !== 'Tab') return;
|
|
97
|
+
|
|
98
|
+
if (e.shiftKey) {
|
|
99
|
+
if (document.activeElement === firstElement) {
|
|
100
|
+
lastElement.focus();
|
|
101
|
+
e.preventDefault();
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
if (document.activeElement === lastElement) {
|
|
105
|
+
firstElement.focus();
|
|
106
|
+
e.preventDefault();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
element.addEventListener('keydown', handleTabKey);
|
|
112
|
+
firstElement.focus();
|
|
113
|
+
|
|
114
|
+
return () => {
|
|
115
|
+
element.removeEventListener('keydown', handleTabKey);
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
56
119
|
$effect(() => {
|
|
57
120
|
if (open) {
|
|
121
|
+
previouslyFocusedElement = document.activeElement as HTMLElement;
|
|
58
122
|
document.body.style.overflow = 'hidden';
|
|
59
123
|
document.addEventListener('keydown', handleKeydown);
|
|
124
|
+
|
|
125
|
+
tick().then(() => {
|
|
126
|
+
if (modalElement) {
|
|
127
|
+
trapFocus(modalElement);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
60
130
|
} else {
|
|
61
131
|
document.body.style.overflow = '';
|
|
62
132
|
document.removeEventListener('keydown', handleKeydown);
|
|
133
|
+
if (previouslyFocusedElement) {
|
|
134
|
+
previouslyFocusedElement.focus();
|
|
135
|
+
}
|
|
63
136
|
}
|
|
64
137
|
|
|
65
138
|
return () => {
|
|
@@ -67,18 +140,36 @@
|
|
|
67
140
|
document.removeEventListener('keydown', handleKeydown);
|
|
68
141
|
};
|
|
69
142
|
});
|
|
143
|
+
|
|
144
|
+
onDestroy(() => {
|
|
145
|
+
if (browser && document.body.style.overflow === 'hidden') {
|
|
146
|
+
document.body.style.overflow = '';
|
|
147
|
+
}
|
|
148
|
+
});
|
|
70
149
|
</script>
|
|
71
150
|
|
|
72
151
|
{#snippet predefinedHeader()}
|
|
73
152
|
{#if title || description}
|
|
74
|
-
<header class={
|
|
153
|
+
<header class={headerClasses}>
|
|
75
154
|
<div class="flex-1">
|
|
76
155
|
{#if title}
|
|
77
|
-
<h2
|
|
156
|
+
<h2
|
|
157
|
+
id="modal-title"
|
|
158
|
+
class={titleClasses}
|
|
159
|
+
data-testid={buildTestId('modal', 'title', testId)}
|
|
160
|
+
>
|
|
161
|
+
{title}
|
|
162
|
+
</h2>
|
|
78
163
|
{/if}
|
|
79
164
|
</div>
|
|
80
165
|
{#if !hideCloseButton}
|
|
81
|
-
<button
|
|
166
|
+
<button
|
|
167
|
+
type="button"
|
|
168
|
+
class={closeClass}
|
|
169
|
+
onclick={onclose}
|
|
170
|
+
aria-label="Close"
|
|
171
|
+
data-testid={buildTestId('modal', 'close', testId)}
|
|
172
|
+
>
|
|
82
173
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
83
174
|
<path
|
|
84
175
|
d="M15 5L5 15M5 5L15 15"
|
|
@@ -99,6 +190,7 @@
|
|
|
99
190
|
class="text-default-400 hover:bg-default-100 hover:text-default-600 absolute top-4 right-4 z-10 rounded-lg p-2 transition-colors"
|
|
100
191
|
onclick={onclose}
|
|
101
192
|
aria-label="Close"
|
|
193
|
+
data-testid={buildTestId('modal', 'close', testId)}
|
|
102
194
|
>
|
|
103
195
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
104
196
|
<path
|
|
@@ -113,17 +205,28 @@
|
|
|
113
205
|
{/snippet}
|
|
114
206
|
|
|
115
207
|
{#if open}
|
|
116
|
-
<div
|
|
208
|
+
<div
|
|
209
|
+
class={baseClass}
|
|
210
|
+
role="dialog"
|
|
211
|
+
aria-modal="true"
|
|
212
|
+
aria-labelledby={title ? 'modal-title' : undefined}
|
|
213
|
+
bind:this={modalElement}
|
|
214
|
+
>
|
|
117
215
|
<!-- Backdrop -->
|
|
118
216
|
<div
|
|
119
|
-
class={
|
|
217
|
+
class={backdropClasses}
|
|
120
218
|
onclick={handleBackdropClick}
|
|
121
219
|
transition:fade={{ duration: 200 }}
|
|
122
220
|
role="presentation"
|
|
221
|
+
data-testid={buildTestId('modal', 'backdrop', testId)}
|
|
123
222
|
></div>
|
|
124
223
|
|
|
125
224
|
<!-- Modal Container -->
|
|
126
|
-
<div
|
|
225
|
+
<div
|
|
226
|
+
class={containerClass}
|
|
227
|
+
transition:scale={{ duration: 200, easing: quintOut, start: 0.95 }}
|
|
228
|
+
data-testid={buildTestId('modal', 'dialog', testId)}
|
|
229
|
+
>
|
|
127
230
|
<!-- Header -->
|
|
128
231
|
{#if header}
|
|
129
232
|
{@render header()}
|
|
@@ -133,14 +236,14 @@
|
|
|
133
236
|
|
|
134
237
|
<!-- Body -->
|
|
135
238
|
{#if children}
|
|
136
|
-
<div class={
|
|
239
|
+
<div class={bodyClasses} data-testid={buildTestId('modal', 'body', testId)}>
|
|
137
240
|
{@render children()}
|
|
138
241
|
</div>
|
|
139
242
|
{/if}
|
|
140
243
|
|
|
141
244
|
<!-- Footer -->
|
|
142
245
|
{#if footer}
|
|
143
|
-
<footer class={
|
|
246
|
+
<footer class={footerClasses} data-testid={buildTestId('modal', 'footer', testId)}>
|
|
144
247
|
{@render footer()}
|
|
145
248
|
</footer>
|
|
146
249
|
{/if}
|