@rkosafo/cai.components 0.0.78 → 0.0.80
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 +8 -8
- package/dist/baseEditor/index.svelte +32 -32
- package/dist/builders/filters/FilterBuilder.svelte +641 -641
- package/dist/forms/FormCheckbox/FormCheckbox.svelte +53 -53
- package/dist/forms/FormClEditor/ClEdito.svelte +68 -68
- package/dist/forms/FormDatepicker/FormDatepicker.svelte +159 -159
- package/dist/forms/FormFileUpload/FormFileUplad.svelte +134 -134
- package/dist/forms/FormInput/FormInput.svelte +87 -87
- package/dist/forms/FormRadio/FormRadio.svelte +53 -53
- package/dist/forms/FormSelect/FormSelect.svelte +88 -88
- package/dist/forms/FormTextarea/FormTextarea.svelte +78 -78
- package/dist/forms/button-toggle/ButtonToggle.svelte +119 -119
- package/dist/forms/button-toggle/CheckIcon.svelte +28 -28
- package/dist/forms/checkbox/Checkbox.svelte +82 -82
- package/dist/forms/checkbox/CheckboxButton.svelte +92 -92
- package/dist/forms/datepicker/Datepicker.svelte +707 -707
- package/dist/forms/form/Form.svelte +69 -69
- package/dist/forms/input/Input.svelte +363 -363
- package/dist/forms/label/Label.svelte +38 -38
- package/dist/forms/radio/Radio.svelte +48 -48
- package/dist/forms/radio/RadioButton.svelte +22 -22
- package/dist/forms/select/Select.svelte +56 -56
- package/dist/forms/textarea/Textarea.svelte +165 -165
- package/dist/forms/toggle/Toggle.svelte +70 -70
- package/dist/layout/Chat/CategorySelector.svelte +52 -52
- package/dist/layout/Chat/ChatEntry.svelte +246 -246
- package/dist/layout/Chat/ChatEntrySkeleton.svelte +81 -81
- package/dist/layout/Chat/ChatHeader.svelte +172 -172
- package/dist/layout/Chat/ChatInput.svelte +207 -207
- package/dist/layout/Chat/DraggableWindow.svelte +230 -230
- package/dist/layout/Chat/PreviewPage.svelte +182 -182
- package/dist/layout/Chat/RichText.svelte +216 -216
- package/dist/layout/ComponentCanvas/Canvas.svelte +40 -40
- package/dist/layout/ComponentCanvas/ComponentRenderer.svelte +85 -85
- package/dist/layout/TF/Content/Content.svelte +21 -21
- package/dist/layout/TF/Header/Header.svelte +166 -166
- package/dist/layout/TF/Sidebar/Sidebar.svelte +148 -148
- package/dist/layout/TF/Wrapper/Wrapper.svelte +17 -17
- package/dist/layout/mailing/MailPaginator.svelte +36 -36
- package/dist/layout/mailing/MailSidebar.svelte +39 -39
- package/dist/layout/mailing/MailToolBar.svelte +174 -174
- package/dist/layout/mailing/MailingContent.svelte +10 -10
- package/dist/layout/mailing/MailingHeader.svelte +55 -55
- package/dist/layout/mailing/MailingMessageCard.svelte +112 -112
- package/dist/layout/mailing/MailingMessageViewer.svelte +87 -87
- package/dist/layout/mailing/MailingModule.svelte +448 -448
- package/dist/styles/docs.css +615 -615
- package/dist/styles/tf-layout.css +185 -185
- package/dist/themes/ThemeProvider.svelte +20 -20
- package/dist/types/index.d.ts +2 -0
- package/dist/typography/heading/Heading.svelte +35 -35
- package/dist/ui/accordion/Accordion.svelte +49 -49
- package/dist/ui/accordion/AccordionItem.svelte +173 -173
- package/dist/ui/alert/Alert.svelte +83 -83
- package/dist/ui/alertDialog/AlertDialog.svelte +40 -40
- package/dist/ui/avatar/Avatar.svelte +77 -77
- package/dist/ui/box/Box.svelte +28 -28
- package/dist/ui/breadcrumb/Breadcrumb.svelte +39 -39
- package/dist/ui/buttons/ActionButton.svelte +234 -234
- package/dist/ui/buttons/Button.svelte +102 -102
- package/dist/ui/buttons/GradientButton.svelte +59 -59
- package/dist/ui/datatable/Datatable.svelte +525 -525
- package/dist/ui/drawer/Drawer.svelte +300 -300
- package/dist/ui/dropdown/Dropdown.svelte +36 -36
- package/dist/ui/dropdown/DropdownDivider.svelte +11 -11
- package/dist/ui/dropdown/DropdownGroup.svelte +14 -14
- package/dist/ui/dropdown/DropdownHeader.svelte +14 -14
- package/dist/ui/dropdown/DropdownItem.svelte +52 -52
- package/dist/ui/footer/Footer.svelte +15 -15
- package/dist/ui/footer/FooterBrand.svelte +37 -37
- package/dist/ui/footer/FooterCopyright.svelte +45 -45
- package/dist/ui/footer/FooterIcon.svelte +22 -22
- package/dist/ui/footer/FooterLink.svelte +33 -33
- package/dist/ui/footer/FooterLinkGroup.svelte +13 -13
- package/dist/ui/icons/IconifyIcon.svelte +7 -7
- package/dist/ui/indicator/Indicator.svelte +42 -42
- package/dist/ui/modal/Modal.svelte +265 -265
- package/dist/ui/notificationList/NotificationList.svelte +123 -123
- package/dist/ui/pageLoader/PageLoader.svelte +14 -14
- package/dist/ui/pageLoader/PageLoader2.svelte +99 -0
- package/dist/ui/pageLoader/PageLoader2.svelte.d.ts +24 -0
- package/dist/ui/pageLoader/index.d.ts +2 -1
- package/dist/ui/pageLoader/index.js +2 -1
- package/dist/ui/paginate/Paginate.svelte +96 -96
- package/dist/ui/speedDial/SpeedDial.svelte +77 -77
- package/dist/ui/speedDial/SpeedDialButton.svelte +75 -75
- package/dist/ui/speedDial/SpeedDialTrigger.svelte +79 -79
- package/dist/ui/tab/Tab.svelte +93 -67
- package/dist/ui/table/Table.svelte +396 -396
- package/dist/ui/tableLoader/TableLoader.svelte +24 -24
- package/dist/ui/toast/Toast.svelte +337 -337
- package/dist/ui/toast/Toast.svelte.d.ts +10 -10
- package/dist/ui/toolbar/Toolbar.svelte +59 -59
- package/dist/ui/toolbar/ToolbarButton.svelte +56 -56
- package/dist/ui/toolbar/ToolbarGroup.svelte +43 -43
- package/dist/ui/tooltip/Tooltip.svelte +51 -51
- package/dist/utils/Popper.svelte +257 -257
- package/dist/utils/closeButton/CloseButton.svelte +88 -88
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/index.js +3 -3
- package/dist/utils/singleSelection.svelte.js +48 -48
- package/dist/youtube/index.svelte +12 -12
- package/package.json +1 -1
|
@@ -1,300 +1,300 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import clsx, { type ClassValue } from 'clsx';
|
|
3
|
-
import { fly } from 'svelte/transition';
|
|
4
|
-
import { sineIn } from 'svelte/easing';
|
|
5
|
-
import { drawer } from './index.js';
|
|
6
|
-
import { CloseButton } from '../../utils/closeButton/index.js';
|
|
7
|
-
import { createDismissableContext } from '../../utils/dismissable.js';
|
|
8
|
-
import { trapFocus } from '../../utils/index.js';
|
|
9
|
-
import { type ParamsType, type DrawerProps } from '../../index.js';
|
|
10
|
-
import { getTheme, warnThemeDeprecation } from '../../themes/themeUtils.js';
|
|
11
|
-
|
|
12
|
-
let {
|
|
13
|
-
children,
|
|
14
|
-
onaction = () => true,
|
|
15
|
-
oncancel,
|
|
16
|
-
onsubmit,
|
|
17
|
-
ontoggle,
|
|
18
|
-
onclose,
|
|
19
|
-
form = false,
|
|
20
|
-
hidden = $bindable(),
|
|
21
|
-
activateClickOutside = true,
|
|
22
|
-
position,
|
|
23
|
-
width,
|
|
24
|
-
size, // NEW: Added size prop
|
|
25
|
-
backdrop = true,
|
|
26
|
-
backdropClass,
|
|
27
|
-
placement = 'left',
|
|
28
|
-
class: className,
|
|
29
|
-
classes,
|
|
30
|
-
transitionParams,
|
|
31
|
-
transitionType = fly,
|
|
32
|
-
bodyScrolling = false,
|
|
33
|
-
dismissable = true,
|
|
34
|
-
closeBtnClass,
|
|
35
|
-
headerClass,
|
|
36
|
-
bodyClass,
|
|
37
|
-
footerClass,
|
|
38
|
-
header,
|
|
39
|
-
footer,
|
|
40
|
-
title,
|
|
41
|
-
permanent = false,
|
|
42
|
-
autoclose = false,
|
|
43
|
-
...restProps
|
|
44
|
-
}: DrawerProps = $props();
|
|
45
|
-
|
|
46
|
-
warnThemeDeprecation(
|
|
47
|
-
'Drawer',
|
|
48
|
-
{ backdropClass, headerClass, bodyClass, footerClass, closeBtnClass },
|
|
49
|
-
{
|
|
50
|
-
backdropClass: 'backdrop',
|
|
51
|
-
bodyClass: 'body',
|
|
52
|
-
headerClass: 'header',
|
|
53
|
-
footerClass: 'footer',
|
|
54
|
-
closeBtnClass: 'close'
|
|
55
|
-
}
|
|
56
|
-
);
|
|
57
|
-
const styling = $derived(
|
|
58
|
-
classes ?? {
|
|
59
|
-
backdrop: backdropClass,
|
|
60
|
-
header: headerClass,
|
|
61
|
-
body: bodyClass,
|
|
62
|
-
footer: footerClass,
|
|
63
|
-
close: closeBtnClass
|
|
64
|
-
}
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
const theme = getTheme('drawer');
|
|
68
|
-
|
|
69
|
-
const {
|
|
70
|
-
base,
|
|
71
|
-
backdrop: backdropCls,
|
|
72
|
-
header: headerCls,
|
|
73
|
-
body,
|
|
74
|
-
footer: footerCls,
|
|
75
|
-
close: closeCls,
|
|
76
|
-
form: formCls
|
|
77
|
-
} = $derived(
|
|
78
|
-
drawer({
|
|
79
|
-
position,
|
|
80
|
-
placement,
|
|
81
|
-
width,
|
|
82
|
-
size, // NEW: Pass size to drawer function
|
|
83
|
-
backdrop
|
|
84
|
-
})
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
let innerWidth: number = $state(-1);
|
|
88
|
-
let innerHeight: number = $state(-1);
|
|
89
|
-
|
|
90
|
-
// Updated x and y calculations to consider different sizes
|
|
91
|
-
let x = $derived(() => {
|
|
92
|
-
if (placement === 'left') return -320;
|
|
93
|
-
if (placement === 'right') return innerWidth + 320;
|
|
94
|
-
return undefined;
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
let y = $derived(() => {
|
|
98
|
-
if (placement === 'top') return -100;
|
|
99
|
-
if (placement === 'bottom') return innerHeight + 100;
|
|
100
|
-
return undefined;
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
let transition_params = $derived(Object.assign({}, { x, y, duration: 200, easing: sineIn }));
|
|
104
|
-
|
|
105
|
-
let ref: HTMLDivElement | undefined = $state(undefined);
|
|
106
|
-
|
|
107
|
-
function close(ev: MouseEvent) {
|
|
108
|
-
if (ref?.dispatchEvent(new Event('close', { bubbles: true, cancelable: true }))) {
|
|
109
|
-
hidden = true;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function _oncancel(ev: Event & { currentTarget: HTMLDivElement }) {
|
|
114
|
-
if (ev.target !== ev.currentTarget) {
|
|
115
|
-
return; // ignore if not on drawer
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
oncancel?.(ev);
|
|
119
|
-
if (ev.defaultPrevented) return;
|
|
120
|
-
|
|
121
|
-
ev.preventDefault();
|
|
122
|
-
if (!permanent) hidden = true;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function _onclick(ev: Event & { currentTarget: HTMLDivElement }) {
|
|
126
|
-
const drawer: HTMLDivElement = ev.currentTarget;
|
|
127
|
-
if (activateClickOutside && ev.target === drawer) {
|
|
128
|
-
return close(ev as unknown as MouseEvent);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (autoclose && ev.target instanceof HTMLButtonElement && !permanent) {
|
|
132
|
-
return (hidden = true);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
function _onsubmit(ev: SubmitEvent & { currentTarget: HTMLFormElement }) {
|
|
136
|
-
onsubmit?.(ev as any);
|
|
137
|
-
if (ev.defaultPrevented) return;
|
|
138
|
-
|
|
139
|
-
ev.preventDefault();
|
|
140
|
-
|
|
141
|
-
const mainForm = ev.currentTarget;
|
|
142
|
-
let returnValue = '';
|
|
143
|
-
|
|
144
|
-
const nestedForms = mainForm.querySelectorAll('form');
|
|
145
|
-
const combinedFormData = new FormData();
|
|
146
|
-
|
|
147
|
-
// Collect all form data
|
|
148
|
-
new FormData(mainForm).forEach((value, key) => combinedFormData.append(key, value));
|
|
149
|
-
nestedForms.forEach((nestedForm) => {
|
|
150
|
-
new FormData(nestedForm).forEach((value, key) => combinedFormData.append(key, value));
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
if (ev.submitter instanceof HTMLButtonElement || ev.submitter instanceof HTMLInputElement) {
|
|
154
|
-
returnValue = ev.submitter.value;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (!returnValue) {
|
|
158
|
-
return (hidden = true);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Convert FormData → object
|
|
162
|
-
const data: Record<string, any> = {};
|
|
163
|
-
for (const [key, value] of combinedFormData.entries()) {
|
|
164
|
-
if (data[key] !== undefined) {
|
|
165
|
-
if (!Array.isArray(data[key])) data[key] = [data[key]];
|
|
166
|
-
data[key].push(value);
|
|
167
|
-
} else {
|
|
168
|
-
data[key] = value;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Cast values and normalize arrays
|
|
173
|
-
Object.keys(data).forEach((key) => {
|
|
174
|
-
const val = data[key];
|
|
175
|
-
if (Array.isArray(val)) {
|
|
176
|
-
data[key] = val.map((v) => tryCast(v));
|
|
177
|
-
} else {
|
|
178
|
-
// Force array for certain fields
|
|
179
|
-
if (['dashboards', 'permissions', 'reports'].includes(key)) {
|
|
180
|
-
data[key] = [tryCast(val)];
|
|
181
|
-
} else {
|
|
182
|
-
data[key] = tryCast(val);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
if (typeof onaction === 'function' && onaction({ action: returnValue, data }) === false) {
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
function tryCast(v: any) {
|
|
193
|
-
if (v === 'true') return true;
|
|
194
|
-
if (v === 'false') return false;
|
|
195
|
-
if (!isNaN(Number(v)) && v !== '') return Number(v);
|
|
196
|
-
return v;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
createDismissableContext(close);
|
|
200
|
-
</script>
|
|
201
|
-
|
|
202
|
-
<svelte:window bind:innerWidth bind:innerHeight />
|
|
203
|
-
|
|
204
|
-
{#snippet content()}
|
|
205
|
-
<div class="flex h-screen flex-col">
|
|
206
|
-
{#if title || header}
|
|
207
|
-
<div class={headerCls({ class: clsx(theme?.header, styling.header) })}>
|
|
208
|
-
{#if title}
|
|
209
|
-
<h3 class="text-base">{title}</h3>
|
|
210
|
-
{#if dismissable && !permanent}
|
|
211
|
-
<CloseButton type="submit" formnovalidate class={clsx(styling.close)} />
|
|
212
|
-
{/if}
|
|
213
|
-
{:else if header}
|
|
214
|
-
{@render header()}
|
|
215
|
-
{/if}
|
|
216
|
-
</div>
|
|
217
|
-
{/if}
|
|
218
|
-
<div class="h-full flex-grow overflow-y-auto overscroll-contain">
|
|
219
|
-
<div class={body({ class: clsx(theme?.body, styling.body) })}>
|
|
220
|
-
{@render children?.()}
|
|
221
|
-
</div>
|
|
222
|
-
</div>
|
|
223
|
-
|
|
224
|
-
{#if footer}
|
|
225
|
-
<div class={footerCls({ class: clsx(theme?.footer, styling.footer) })}>
|
|
226
|
-
{@render footer()}
|
|
227
|
-
</div>
|
|
228
|
-
{/if}
|
|
229
|
-
{#if dismissable && !permanent && !title}
|
|
230
|
-
<CloseButton
|
|
231
|
-
type="submit"
|
|
232
|
-
formnovalidate
|
|
233
|
-
class={closeCls({ class: clsx(theme?.close, styling.close) })}
|
|
234
|
-
/>
|
|
235
|
-
{/if}
|
|
236
|
-
</div>
|
|
237
|
-
{/snippet}
|
|
238
|
-
|
|
239
|
-
{#if !hidden}
|
|
240
|
-
<div
|
|
241
|
-
role="presentation"
|
|
242
|
-
bind:this={ref}
|
|
243
|
-
class={backdropCls({ class: clsx(theme?.backdrop, styling.backdrop) })}
|
|
244
|
-
onclick={activateClickOutside ? close : undefined}
|
|
245
|
-
style={bodyScrolling ? 'pointer-events: none;' : ''}
|
|
246
|
-
></div>
|
|
247
|
-
<div
|
|
248
|
-
use:trapFocus={{ onEscape: close as () => void }}
|
|
249
|
-
{...restProps}
|
|
250
|
-
class={base({ class: clsx(theme?.base, className) })}
|
|
251
|
-
transition:transitionType={transitionParams
|
|
252
|
-
? transitionParams
|
|
253
|
-
: (transition_params as ParamsType)}
|
|
254
|
-
tabindex="-1"
|
|
255
|
-
onclick={_onclick}
|
|
256
|
-
>
|
|
257
|
-
{#if form}
|
|
258
|
-
<form method="dialog" onsubmit={_onsubmit} class={formCls({ class: clsx(theme?.form) })}>
|
|
259
|
-
{@render content()}
|
|
260
|
-
</form>
|
|
261
|
-
{:else}
|
|
262
|
-
{@render content()}
|
|
263
|
-
{/if}
|
|
264
|
-
</div>
|
|
265
|
-
{/if}
|
|
266
|
-
|
|
267
|
-
<!--
|
|
268
|
-
@component
|
|
269
|
-
## Props
|
|
270
|
-
@prop children
|
|
271
|
-
@prop onaction = () => true
|
|
272
|
-
@prop oncancel
|
|
273
|
-
@prop onsubmit
|
|
274
|
-
@prop ontoggle
|
|
275
|
-
@prop form = false
|
|
276
|
-
@prop hidden = $bindable()
|
|
277
|
-
@prop activateClickOutside = true
|
|
278
|
-
@prop position
|
|
279
|
-
@prop width
|
|
280
|
-
@prop size // NEW: Added size prop documentation
|
|
281
|
-
@prop backdrop = true
|
|
282
|
-
@prop backdropClass
|
|
283
|
-
@prop placement = "left"
|
|
284
|
-
@prop class: className
|
|
285
|
-
@prop classes
|
|
286
|
-
@prop transitionParams
|
|
287
|
-
@prop transitionType = fly
|
|
288
|
-
@prop bodyScrolling = false
|
|
289
|
-
@prop dismissable = true
|
|
290
|
-
@prop closeBtnClass
|
|
291
|
-
@prop headerClass
|
|
292
|
-
@prop bodyClass
|
|
293
|
-
@prop footerClass
|
|
294
|
-
@prop header
|
|
295
|
-
@prop footer
|
|
296
|
-
@prop title
|
|
297
|
-
@prop permanent = false
|
|
298
|
-
@prop autoclose = false
|
|
299
|
-
@prop ...restProps
|
|
300
|
-
-->
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import clsx, { type ClassValue } from 'clsx';
|
|
3
|
+
import { fly } from 'svelte/transition';
|
|
4
|
+
import { sineIn } from 'svelte/easing';
|
|
5
|
+
import { drawer } from './index.js';
|
|
6
|
+
import { CloseButton } from '../../utils/closeButton/index.js';
|
|
7
|
+
import { createDismissableContext } from '../../utils/dismissable.js';
|
|
8
|
+
import { trapFocus } from '../../utils/index.js';
|
|
9
|
+
import { type ParamsType, type DrawerProps } from '../../index.js';
|
|
10
|
+
import { getTheme, warnThemeDeprecation } from '../../themes/themeUtils.js';
|
|
11
|
+
|
|
12
|
+
let {
|
|
13
|
+
children,
|
|
14
|
+
onaction = () => true,
|
|
15
|
+
oncancel,
|
|
16
|
+
onsubmit,
|
|
17
|
+
ontoggle,
|
|
18
|
+
onclose,
|
|
19
|
+
form = false,
|
|
20
|
+
hidden = $bindable(),
|
|
21
|
+
activateClickOutside = true,
|
|
22
|
+
position,
|
|
23
|
+
width,
|
|
24
|
+
size, // NEW: Added size prop
|
|
25
|
+
backdrop = true,
|
|
26
|
+
backdropClass,
|
|
27
|
+
placement = 'left',
|
|
28
|
+
class: className,
|
|
29
|
+
classes,
|
|
30
|
+
transitionParams,
|
|
31
|
+
transitionType = fly,
|
|
32
|
+
bodyScrolling = false,
|
|
33
|
+
dismissable = true,
|
|
34
|
+
closeBtnClass,
|
|
35
|
+
headerClass,
|
|
36
|
+
bodyClass,
|
|
37
|
+
footerClass,
|
|
38
|
+
header,
|
|
39
|
+
footer,
|
|
40
|
+
title,
|
|
41
|
+
permanent = false,
|
|
42
|
+
autoclose = false,
|
|
43
|
+
...restProps
|
|
44
|
+
}: DrawerProps = $props();
|
|
45
|
+
|
|
46
|
+
warnThemeDeprecation(
|
|
47
|
+
'Drawer',
|
|
48
|
+
{ backdropClass, headerClass, bodyClass, footerClass, closeBtnClass },
|
|
49
|
+
{
|
|
50
|
+
backdropClass: 'backdrop',
|
|
51
|
+
bodyClass: 'body',
|
|
52
|
+
headerClass: 'header',
|
|
53
|
+
footerClass: 'footer',
|
|
54
|
+
closeBtnClass: 'close'
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
const styling = $derived(
|
|
58
|
+
classes ?? {
|
|
59
|
+
backdrop: backdropClass,
|
|
60
|
+
header: headerClass,
|
|
61
|
+
body: bodyClass,
|
|
62
|
+
footer: footerClass,
|
|
63
|
+
close: closeBtnClass
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const theme = getTheme('drawer');
|
|
68
|
+
|
|
69
|
+
const {
|
|
70
|
+
base,
|
|
71
|
+
backdrop: backdropCls,
|
|
72
|
+
header: headerCls,
|
|
73
|
+
body,
|
|
74
|
+
footer: footerCls,
|
|
75
|
+
close: closeCls,
|
|
76
|
+
form: formCls
|
|
77
|
+
} = $derived(
|
|
78
|
+
drawer({
|
|
79
|
+
position,
|
|
80
|
+
placement,
|
|
81
|
+
width,
|
|
82
|
+
size, // NEW: Pass size to drawer function
|
|
83
|
+
backdrop
|
|
84
|
+
})
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
let innerWidth: number = $state(-1);
|
|
88
|
+
let innerHeight: number = $state(-1);
|
|
89
|
+
|
|
90
|
+
// Updated x and y calculations to consider different sizes
|
|
91
|
+
let x = $derived(() => {
|
|
92
|
+
if (placement === 'left') return -320;
|
|
93
|
+
if (placement === 'right') return innerWidth + 320;
|
|
94
|
+
return undefined;
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
let y = $derived(() => {
|
|
98
|
+
if (placement === 'top') return -100;
|
|
99
|
+
if (placement === 'bottom') return innerHeight + 100;
|
|
100
|
+
return undefined;
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
let transition_params = $derived(Object.assign({}, { x, y, duration: 200, easing: sineIn }));
|
|
104
|
+
|
|
105
|
+
let ref: HTMLDivElement | undefined = $state(undefined);
|
|
106
|
+
|
|
107
|
+
function close(ev: MouseEvent) {
|
|
108
|
+
if (ref?.dispatchEvent(new Event('close', { bubbles: true, cancelable: true }))) {
|
|
109
|
+
hidden = true;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function _oncancel(ev: Event & { currentTarget: HTMLDivElement }) {
|
|
114
|
+
if (ev.target !== ev.currentTarget) {
|
|
115
|
+
return; // ignore if not on drawer
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
oncancel?.(ev);
|
|
119
|
+
if (ev.defaultPrevented) return;
|
|
120
|
+
|
|
121
|
+
ev.preventDefault();
|
|
122
|
+
if (!permanent) hidden = true;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function _onclick(ev: Event & { currentTarget: HTMLDivElement }) {
|
|
126
|
+
const drawer: HTMLDivElement = ev.currentTarget;
|
|
127
|
+
if (activateClickOutside && ev.target === drawer) {
|
|
128
|
+
return close(ev as unknown as MouseEvent);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (autoclose && ev.target instanceof HTMLButtonElement && !permanent) {
|
|
132
|
+
return (hidden = true);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function _onsubmit(ev: SubmitEvent & { currentTarget: HTMLFormElement }) {
|
|
136
|
+
onsubmit?.(ev as any);
|
|
137
|
+
if (ev.defaultPrevented) return;
|
|
138
|
+
|
|
139
|
+
ev.preventDefault();
|
|
140
|
+
|
|
141
|
+
const mainForm = ev.currentTarget;
|
|
142
|
+
let returnValue = '';
|
|
143
|
+
|
|
144
|
+
const nestedForms = mainForm.querySelectorAll('form');
|
|
145
|
+
const combinedFormData = new FormData();
|
|
146
|
+
|
|
147
|
+
// Collect all form data
|
|
148
|
+
new FormData(mainForm).forEach((value, key) => combinedFormData.append(key, value));
|
|
149
|
+
nestedForms.forEach((nestedForm) => {
|
|
150
|
+
new FormData(nestedForm).forEach((value, key) => combinedFormData.append(key, value));
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
if (ev.submitter instanceof HTMLButtonElement || ev.submitter instanceof HTMLInputElement) {
|
|
154
|
+
returnValue = ev.submitter.value;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (!returnValue) {
|
|
158
|
+
return (hidden = true);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Convert FormData → object
|
|
162
|
+
const data: Record<string, any> = {};
|
|
163
|
+
for (const [key, value] of combinedFormData.entries()) {
|
|
164
|
+
if (data[key] !== undefined) {
|
|
165
|
+
if (!Array.isArray(data[key])) data[key] = [data[key]];
|
|
166
|
+
data[key].push(value);
|
|
167
|
+
} else {
|
|
168
|
+
data[key] = value;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Cast values and normalize arrays
|
|
173
|
+
Object.keys(data).forEach((key) => {
|
|
174
|
+
const val = data[key];
|
|
175
|
+
if (Array.isArray(val)) {
|
|
176
|
+
data[key] = val.map((v) => tryCast(v));
|
|
177
|
+
} else {
|
|
178
|
+
// Force array for certain fields
|
|
179
|
+
if (['dashboards', 'permissions', 'reports'].includes(key)) {
|
|
180
|
+
data[key] = [tryCast(val)];
|
|
181
|
+
} else {
|
|
182
|
+
data[key] = tryCast(val);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
if (typeof onaction === 'function' && onaction({ action: returnValue, data }) === false) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function tryCast(v: any) {
|
|
193
|
+
if (v === 'true') return true;
|
|
194
|
+
if (v === 'false') return false;
|
|
195
|
+
if (!isNaN(Number(v)) && v !== '') return Number(v);
|
|
196
|
+
return v;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
createDismissableContext(close);
|
|
200
|
+
</script>
|
|
201
|
+
|
|
202
|
+
<svelte:window bind:innerWidth bind:innerHeight />
|
|
203
|
+
|
|
204
|
+
{#snippet content()}
|
|
205
|
+
<div class="flex h-screen flex-col">
|
|
206
|
+
{#if title || header}
|
|
207
|
+
<div class={headerCls({ class: clsx(theme?.header, styling.header) })}>
|
|
208
|
+
{#if title}
|
|
209
|
+
<h3 class="text-base">{title}</h3>
|
|
210
|
+
{#if dismissable && !permanent}
|
|
211
|
+
<CloseButton type="submit" formnovalidate class={clsx(styling.close)} />
|
|
212
|
+
{/if}
|
|
213
|
+
{:else if header}
|
|
214
|
+
{@render header()}
|
|
215
|
+
{/if}
|
|
216
|
+
</div>
|
|
217
|
+
{/if}
|
|
218
|
+
<div class="h-full flex-grow overflow-y-auto overscroll-contain">
|
|
219
|
+
<div class={body({ class: clsx(theme?.body, styling.body) })}>
|
|
220
|
+
{@render children?.()}
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
|
|
224
|
+
{#if footer}
|
|
225
|
+
<div class={footerCls({ class: clsx(theme?.footer, styling.footer) })}>
|
|
226
|
+
{@render footer()}
|
|
227
|
+
</div>
|
|
228
|
+
{/if}
|
|
229
|
+
{#if dismissable && !permanent && !title}
|
|
230
|
+
<CloseButton
|
|
231
|
+
type="submit"
|
|
232
|
+
formnovalidate
|
|
233
|
+
class={closeCls({ class: clsx(theme?.close, styling.close) })}
|
|
234
|
+
/>
|
|
235
|
+
{/if}
|
|
236
|
+
</div>
|
|
237
|
+
{/snippet}
|
|
238
|
+
|
|
239
|
+
{#if !hidden}
|
|
240
|
+
<div
|
|
241
|
+
role="presentation"
|
|
242
|
+
bind:this={ref}
|
|
243
|
+
class={backdropCls({ class: clsx(theme?.backdrop, styling.backdrop) })}
|
|
244
|
+
onclick={activateClickOutside ? close : undefined}
|
|
245
|
+
style={bodyScrolling ? 'pointer-events: none;' : ''}
|
|
246
|
+
></div>
|
|
247
|
+
<div
|
|
248
|
+
use:trapFocus={{ onEscape: close as () => void }}
|
|
249
|
+
{...restProps}
|
|
250
|
+
class={base({ class: clsx(theme?.base, className) })}
|
|
251
|
+
transition:transitionType={transitionParams
|
|
252
|
+
? transitionParams
|
|
253
|
+
: (transition_params as ParamsType)}
|
|
254
|
+
tabindex="-1"
|
|
255
|
+
onclick={_onclick}
|
|
256
|
+
>
|
|
257
|
+
{#if form}
|
|
258
|
+
<form method="dialog" onsubmit={_onsubmit} class={formCls({ class: clsx(theme?.form) })}>
|
|
259
|
+
{@render content()}
|
|
260
|
+
</form>
|
|
261
|
+
{:else}
|
|
262
|
+
{@render content()}
|
|
263
|
+
{/if}
|
|
264
|
+
</div>
|
|
265
|
+
{/if}
|
|
266
|
+
|
|
267
|
+
<!--
|
|
268
|
+
@component
|
|
269
|
+
## Props
|
|
270
|
+
@prop children
|
|
271
|
+
@prop onaction = () => true
|
|
272
|
+
@prop oncancel
|
|
273
|
+
@prop onsubmit
|
|
274
|
+
@prop ontoggle
|
|
275
|
+
@prop form = false
|
|
276
|
+
@prop hidden = $bindable()
|
|
277
|
+
@prop activateClickOutside = true
|
|
278
|
+
@prop position
|
|
279
|
+
@prop width
|
|
280
|
+
@prop size // NEW: Added size prop documentation
|
|
281
|
+
@prop backdrop = true
|
|
282
|
+
@prop backdropClass
|
|
283
|
+
@prop placement = "left"
|
|
284
|
+
@prop class: className
|
|
285
|
+
@prop classes
|
|
286
|
+
@prop transitionParams
|
|
287
|
+
@prop transitionType = fly
|
|
288
|
+
@prop bodyScrolling = false
|
|
289
|
+
@prop dismissable = true
|
|
290
|
+
@prop closeBtnClass
|
|
291
|
+
@prop headerClass
|
|
292
|
+
@prop bodyClass
|
|
293
|
+
@prop footerClass
|
|
294
|
+
@prop header
|
|
295
|
+
@prop footer
|
|
296
|
+
@prop title
|
|
297
|
+
@prop permanent = false
|
|
298
|
+
@prop autoclose = false
|
|
299
|
+
@prop ...restProps
|
|
300
|
+
-->
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import clsx from 'clsx';
|
|
3
|
-
import { setContext } from 'svelte';
|
|
4
|
-
import { dropdown, DropdownGroup } from './index.js';
|
|
5
|
-
import Popper from '../../utils/Popper.svelte';
|
|
6
|
-
import { type DropdownProps } from '../../index.js';
|
|
7
|
-
|
|
8
|
-
let {
|
|
9
|
-
children,
|
|
10
|
-
simple = false,
|
|
11
|
-
placement = 'bottom',
|
|
12
|
-
offset = 2,
|
|
13
|
-
class: className,
|
|
14
|
-
activeUrl = '',
|
|
15
|
-
isOpen = $bindable(false),
|
|
16
|
-
...restProps
|
|
17
|
-
}: DropdownProps = $props();
|
|
18
|
-
|
|
19
|
-
const base = $derived(dropdown({ class: clsx(dropdown, className) }));
|
|
20
|
-
const activeUrlStore = $state({ value: '' });
|
|
21
|
-
setContext('activeUrl', activeUrlStore);
|
|
22
|
-
|
|
23
|
-
$effect(() => {
|
|
24
|
-
activeUrlStore.value = activeUrl ?? '';
|
|
25
|
-
});
|
|
26
|
-
</script>
|
|
27
|
-
|
|
28
|
-
<Popper {...restProps} {placement} {offset} bind:isOpen class={base}>
|
|
29
|
-
{#if simple}
|
|
30
|
-
<DropdownGroup>
|
|
31
|
-
{@render children()}
|
|
32
|
-
</DropdownGroup>
|
|
33
|
-
{:else}
|
|
34
|
-
{@render children()}
|
|
35
|
-
{/if}
|
|
36
|
-
</Popper>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { setContext } from 'svelte';
|
|
4
|
+
import { dropdown, DropdownGroup } from './index.js';
|
|
5
|
+
import Popper from '../../utils/Popper.svelte';
|
|
6
|
+
import { type DropdownProps } from '../../index.js';
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
children,
|
|
10
|
+
simple = false,
|
|
11
|
+
placement = 'bottom',
|
|
12
|
+
offset = 2,
|
|
13
|
+
class: className,
|
|
14
|
+
activeUrl = '',
|
|
15
|
+
isOpen = $bindable(false),
|
|
16
|
+
...restProps
|
|
17
|
+
}: DropdownProps = $props();
|
|
18
|
+
|
|
19
|
+
const base = $derived(dropdown({ class: clsx(dropdown, className) }));
|
|
20
|
+
const activeUrlStore = $state({ value: '' });
|
|
21
|
+
setContext('activeUrl', activeUrlStore);
|
|
22
|
+
|
|
23
|
+
$effect(() => {
|
|
24
|
+
activeUrlStore.value = activeUrl ?? '';
|
|
25
|
+
});
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<Popper {...restProps} {placement} {offset} bind:isOpen class={base}>
|
|
29
|
+
{#if simple}
|
|
30
|
+
<DropdownGroup>
|
|
31
|
+
{@render children()}
|
|
32
|
+
</DropdownGroup>
|
|
33
|
+
{:else}
|
|
34
|
+
{@render children()}
|
|
35
|
+
{/if}
|
|
36
|
+
</Popper>
|