flowbite-svelte 1.8.3 → 1.8.5
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.
|
@@ -6,10 +6,41 @@
|
|
|
6
6
|
import { Button, ToolbarButton, type DatepickerProps, cn } from "..";
|
|
7
7
|
import { datepicker } from "./theme";
|
|
8
8
|
|
|
9
|
-
let {
|
|
9
|
+
let {
|
|
10
|
+
value = $bindable(),
|
|
11
|
+
defaultDate = null,
|
|
12
|
+
range = false,
|
|
13
|
+
rangeFrom = $bindable(),
|
|
14
|
+
rangeTo = $bindable(),
|
|
15
|
+
availableFrom = null,
|
|
16
|
+
availableTo = null,
|
|
17
|
+
locale = "default",
|
|
18
|
+
translationLocale = locale, // NEW: Separate locale for translations, defaults to locale for backward compatibility
|
|
19
|
+
firstDayOfWeek = 0,
|
|
20
|
+
dateFormat,
|
|
21
|
+
placeholder = "Select date",
|
|
22
|
+
disabled = false,
|
|
23
|
+
required = false,
|
|
24
|
+
inputClass = "",
|
|
25
|
+
color = "primary",
|
|
26
|
+
inline = false,
|
|
27
|
+
autohide = true,
|
|
28
|
+
showActionButtons = false,
|
|
29
|
+
title = "",
|
|
30
|
+
onselect,
|
|
31
|
+
onclear,
|
|
32
|
+
onapply,
|
|
33
|
+
btnClass,
|
|
34
|
+
inputmode = "none",
|
|
35
|
+
classes,
|
|
36
|
+
monthColor = "alternative",
|
|
37
|
+
monthBtnSelected = "bg-primary-500 text-white",
|
|
38
|
+
monthBtn = "text-gray-700 dark:text-gray-300",
|
|
39
|
+
class: className
|
|
40
|
+
}: DatepickerProps & { translationLocale?: string } = $props();
|
|
10
41
|
|
|
11
42
|
const dateFormatDefault = { year: "numeric", month: "long", day: "numeric" };
|
|
12
|
-
|
|
43
|
+
|
|
13
44
|
// Internal state
|
|
14
45
|
let isOpen: boolean = $state(inline);
|
|
15
46
|
let showMonthSelector: boolean = $state(false);
|
|
@@ -60,17 +91,18 @@
|
|
|
60
91
|
return daysArray;
|
|
61
92
|
}
|
|
62
93
|
|
|
94
|
+
// MODIFIED: Use translationLocale for weekday names
|
|
63
95
|
const getWeekdayNames = (): string[] => {
|
|
64
|
-
return Array.from({ length: 7 }, (_, i) => new Date(1970, 0, 5 + i + firstDayOfWeek).toLocaleDateString(
|
|
96
|
+
return Array.from({ length: 7 }, (_, i) => new Date(1970, 0, 5 + i + firstDayOfWeek).toLocaleDateString(translationLocale, { weekday: "short" }));
|
|
65
97
|
};
|
|
66
|
-
let weekdays = getWeekdayNames();
|
|
98
|
+
let weekdays = $derived(getWeekdayNames());
|
|
67
99
|
|
|
100
|
+
// MODIFIED: Use translationLocale for month names
|
|
68
101
|
const getMonthNames = (): string[] => {
|
|
69
|
-
return Array.from({ length: 12 }, (_, i) => new Date(2000, i, 1).toLocaleDateString(
|
|
102
|
+
return Array.from({ length: 12 }, (_, i) => new Date(2000, i, 1).toLocaleDateString(translationLocale, { month: "short" }));
|
|
70
103
|
};
|
|
71
|
-
let monthNames = getMonthNames();
|
|
104
|
+
let monthNames = $derived(getMonthNames());
|
|
72
105
|
|
|
73
|
-
// const addMonth = (date: Date, increment: number): Date => new Date(date.getFullYear(), date.getMonth() + increment, 1);
|
|
74
106
|
const addDay = (date: Date, increment: number): Date => new Date(date.getFullYear(), date.getMonth(), date.getDate() + increment);
|
|
75
107
|
|
|
76
108
|
function changeMonth(increment: number) {
|
|
@@ -92,7 +124,6 @@
|
|
|
92
124
|
showMonthSelector = !showMonthSelector;
|
|
93
125
|
}
|
|
94
126
|
|
|
95
|
-
// Helper function to check if a date is available for selection
|
|
96
127
|
function isDateAvailable(date: Date): boolean {
|
|
97
128
|
const dateOnly = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
98
129
|
|
|
@@ -110,7 +141,6 @@
|
|
|
110
141
|
}
|
|
111
142
|
|
|
112
143
|
function handleDaySelect(day: Date) {
|
|
113
|
-
// Don't allow selection of unavailable dates
|
|
114
144
|
if (!isDateAvailable(day)) return;
|
|
115
145
|
|
|
116
146
|
if (range) {
|
|
@@ -145,6 +175,7 @@
|
|
|
145
175
|
}
|
|
146
176
|
}
|
|
147
177
|
|
|
178
|
+
// MODIFIED: Use locale for formatting (not translationLocale)
|
|
148
179
|
const formatDate = (date?: Date): string => date?.toLocaleDateString(locale, dateFormat) ?? "";
|
|
149
180
|
const isSameDate = (date1?: Date, date2?: Date): boolean => date1?.toDateString() === date2?.toDateString();
|
|
150
181
|
const isToday = (day: Date): boolean => isSameDate(day, new Date());
|
|
@@ -189,9 +220,9 @@
|
|
|
189
220
|
currentMonth = new Date(focusedDate.getFullYear(), focusedDate.getMonth(), 1);
|
|
190
221
|
}
|
|
191
222
|
|
|
192
|
-
//
|
|
223
|
+
// MODIFIED: Use translationLocale for aria-label
|
|
193
224
|
setTimeout(() => {
|
|
194
|
-
const focusedButton = calendarRef?.querySelector(`button[aria-label="${focusedDate!.toLocaleDateString(
|
|
225
|
+
const focusedButton = calendarRef?.querySelector(`button[aria-label="${focusedDate!.toLocaleDateString(translationLocale, { weekday: "long", year: "numeric", month: "long", day: "numeric" })}"]`) as HTMLButtonElement | null;
|
|
195
226
|
focusedButton?.focus();
|
|
196
227
|
}, 0);
|
|
197
228
|
}
|
|
@@ -271,8 +302,9 @@
|
|
|
271
302
|
<!-- Regular Calendar View -->
|
|
272
303
|
<div class={nav({ class: clsx(classes?.nav) })}>
|
|
273
304
|
{@render navButton(false)}
|
|
305
|
+
<!-- MODIFIED: Use translationLocale for month/year display -->
|
|
274
306
|
<Button type="button" class={cn(polite({ class: clsx(classes?.polite) }), "cursor-pointer rounded px-2 py-1 hover:bg-gray-100 dark:hover:bg-gray-700")} aria-live="polite" onclick={(event: MouseEvent) => toggleMonthSelector(event)}>
|
|
275
|
-
{currentMonth.toLocaleString(
|
|
307
|
+
{currentMonth.toLocaleString(translationLocale, { month: "long", year: "numeric" })}
|
|
276
308
|
</Button>
|
|
277
309
|
{@render navButton(true)}
|
|
278
310
|
</div>
|
|
@@ -295,7 +327,7 @@
|
|
|
295
327
|
})}
|
|
296
328
|
onclick={() => handleDaySelect(day)}
|
|
297
329
|
onkeydown={handleCalendarKeydown}
|
|
298
|
-
aria-label={day.toLocaleDateString(
|
|
330
|
+
aria-label={day.toLocaleDateString(translationLocale, { weekday: "long", year: "numeric", month: "long", day: "numeric" })}
|
|
299
331
|
aria-selected={isSelected(day)}
|
|
300
332
|
aria-disabled={!available}
|
|
301
333
|
disabled={!available}
|
|
@@ -317,40 +349,3 @@
|
|
|
317
349
|
</div>
|
|
318
350
|
{/if}
|
|
319
351
|
</div>
|
|
320
|
-
|
|
321
|
-
<!--
|
|
322
|
-
@component
|
|
323
|
-
[Go to docs](https://flowbite-svelte.com/)
|
|
324
|
-
## Type
|
|
325
|
-
[DatepickerProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L487)
|
|
326
|
-
## Props
|
|
327
|
-
@prop value = $bindable()
|
|
328
|
-
@prop defaultDate = null
|
|
329
|
-
@prop range = false
|
|
330
|
-
@prop rangeFrom = $bindable()
|
|
331
|
-
@prop rangeTo = $bindable()
|
|
332
|
-
@prop availableFrom = null
|
|
333
|
-
@prop availableTo = null
|
|
334
|
-
@prop locale = "default"
|
|
335
|
-
@prop firstDayOfWeek = 0
|
|
336
|
-
@prop dateFormat
|
|
337
|
-
@prop placeholder = "Select date"
|
|
338
|
-
@prop disabled = false
|
|
339
|
-
@prop required = false
|
|
340
|
-
@prop inputClass = ""
|
|
341
|
-
@prop color = "primary"
|
|
342
|
-
@prop inline = false
|
|
343
|
-
@prop autohide = true
|
|
344
|
-
@prop showActionButtons = false
|
|
345
|
-
@prop title = ""
|
|
346
|
-
@prop onselect
|
|
347
|
-
@prop onclear
|
|
348
|
-
@prop onapply
|
|
349
|
-
@prop btnClass
|
|
350
|
-
@prop inputmode = "none"
|
|
351
|
-
@prop classes
|
|
352
|
-
@prop monthColor = "alternative"
|
|
353
|
-
@prop monthBtnSelected = "bg-primary-500 text-white"
|
|
354
|
-
@prop monthBtn = "text-gray-700 dark:text-gray-300"
|
|
355
|
-
@prop class: className
|
|
356
|
-
-->
|
|
@@ -1,39 +1,7 @@
|
|
|
1
1
|
import { type DatepickerProps } from "..";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* ## Props
|
|
7
|
-
* @prop value = $bindable()
|
|
8
|
-
* @prop defaultDate = null
|
|
9
|
-
* @prop range = false
|
|
10
|
-
* @prop rangeFrom = $bindable()
|
|
11
|
-
* @prop rangeTo = $bindable()
|
|
12
|
-
* @prop availableFrom = null
|
|
13
|
-
* @prop availableTo = null
|
|
14
|
-
* @prop locale = "default"
|
|
15
|
-
* @prop firstDayOfWeek = 0
|
|
16
|
-
* @prop dateFormat
|
|
17
|
-
* @prop placeholder = "Select date"
|
|
18
|
-
* @prop disabled = false
|
|
19
|
-
* @prop required = false
|
|
20
|
-
* @prop inputClass = ""
|
|
21
|
-
* @prop color = "primary"
|
|
22
|
-
* @prop inline = false
|
|
23
|
-
* @prop autohide = true
|
|
24
|
-
* @prop showActionButtons = false
|
|
25
|
-
* @prop title = ""
|
|
26
|
-
* @prop onselect
|
|
27
|
-
* @prop onclear
|
|
28
|
-
* @prop onapply
|
|
29
|
-
* @prop btnClass
|
|
30
|
-
* @prop inputmode = "none"
|
|
31
|
-
* @prop classes
|
|
32
|
-
* @prop monthColor = "alternative"
|
|
33
|
-
* @prop monthBtnSelected = "bg-primary-500 text-white"
|
|
34
|
-
* @prop monthBtn = "text-gray-700 dark:text-gray-300"
|
|
35
|
-
* @prop class: className
|
|
36
|
-
*/
|
|
37
|
-
declare const Datepicker: import("svelte").Component<DatepickerProps, {}, "value" | "rangeFrom" | "rangeTo">;
|
|
2
|
+
type $$ComponentProps = DatepickerProps & {
|
|
3
|
+
translationLocale?: string;
|
|
4
|
+
};
|
|
5
|
+
declare const Datepicker: import("svelte").Component<$$ComponentProps, {}, "value" | "rangeFrom" | "rangeTo">;
|
|
38
6
|
type Datepicker = ReturnType<typeof Datepicker>;
|
|
39
7
|
export default Datepicker;
|
package/dist/modal/Modal.svelte
CHANGED
|
@@ -1,26 +1,17 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { type
|
|
3
|
-
import { twMerge } from "tailwind-merge";
|
|
2
|
+
import { type ModalProps, type ParamsType, CloseButton, trapFocus } from "..";
|
|
4
3
|
import clsx from "clsx";
|
|
5
4
|
import { sineIn } from "svelte/easing";
|
|
6
5
|
import { fade } from "svelte/transition";
|
|
7
6
|
import { modal as modalTheme } from ".";
|
|
8
7
|
|
|
9
|
-
let { children, oncancel,
|
|
8
|
+
let { children, oncancel, onsubmit, modal = true, autoclose = false, header, footer, title, open = $bindable(false), permanent = false, dismissable = true, closeBtnClass, headerClass, bodyClass, footerClass, outsideclose = true, size = "md", placement, class: className, params, transition = fade, ...restProps }: ModalProps = $props();
|
|
10
9
|
|
|
11
10
|
const paramsDefault = { duration: 100, easing: sineIn };
|
|
12
11
|
const paramsOptions = $derived(params ?? paramsDefault);
|
|
13
12
|
|
|
14
13
|
const { base, header: headerCls, footer: footerCls, body, closeBtn } = $derived(modalTheme({ placement, size }));
|
|
15
14
|
|
|
16
|
-
const closeModal = () => {
|
|
17
|
-
// Only close if not permanent
|
|
18
|
-
if (!permanent) {
|
|
19
|
-
open = false;
|
|
20
|
-
onclose?.();
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
|
|
24
15
|
function _oncancel(ev: Event & { currentTarget: HTMLDialogElement }) {
|
|
25
16
|
// this event gets called when user presses ESC key
|
|
26
17
|
// We'll handle ESC via the trapFocus action instead
|
|
@@ -35,21 +26,23 @@
|
|
|
35
26
|
function _onclick(ev: Event & { currentTarget: HTMLDialogElement }) {
|
|
36
27
|
if (ev.currentTarget instanceof HTMLDialogElement) {
|
|
37
28
|
if (outsideclose && ev.target === ev.currentTarget && !permanent) {
|
|
38
|
-
|
|
29
|
+
open = false;
|
|
39
30
|
}
|
|
40
31
|
if (autoclose && ev.target instanceof HTMLButtonElement && !permanent) {
|
|
41
|
-
|
|
32
|
+
open = false;
|
|
42
33
|
}
|
|
43
34
|
}
|
|
44
35
|
}
|
|
45
36
|
|
|
46
37
|
let dlg: HTMLDialogElement | undefined = $state();
|
|
47
38
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
39
|
+
// This prevents total dialog closing and we want only to prevent cancelling
|
|
40
|
+
// The close with user defined actions should be allowed
|
|
41
|
+
// $effect(() => {
|
|
42
|
+
// if (permanent && !open) {
|
|
43
|
+
// open = true;
|
|
44
|
+
// }
|
|
45
|
+
// });
|
|
53
46
|
|
|
54
47
|
// Handler for Escape key that respects component state
|
|
55
48
|
const handleEscape = () => {
|
|
@@ -57,32 +50,55 @@
|
|
|
57
50
|
oncancel?.({ currentTarget: dlg } as any);
|
|
58
51
|
// If oncancel prevented default, we don't close
|
|
59
52
|
if (oncancel && event?.defaultPrevented) return;
|
|
60
|
-
|
|
53
|
+
open = false;
|
|
61
54
|
}
|
|
62
55
|
};
|
|
56
|
+
|
|
57
|
+
function _onsubmit(ev: SubmitEvent) {
|
|
58
|
+
if (!dlg) return;
|
|
59
|
+
|
|
60
|
+
if (ev.submitter instanceof HTMLButtonElement || ev.submitter instanceof HTMLInputElement) {
|
|
61
|
+
dlg.returnValue = ev.submitter.value;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// @ts-ignore
|
|
65
|
+
onsubmit?.(ev); // forward event to user handle
|
|
66
|
+
|
|
67
|
+
if (!ev.defaultPrevented) {
|
|
68
|
+
// stop dialog.close() and trigger close with transition
|
|
69
|
+
ev.preventDefault();
|
|
70
|
+
open = false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function init(dlg: HTMLDialogElement) {
|
|
75
|
+
modal ? dlg?.showModal() : dlg?.show();
|
|
76
|
+
return () => dlg?.close();
|
|
77
|
+
}
|
|
63
78
|
</script>
|
|
64
79
|
|
|
65
80
|
{#if open}
|
|
66
|
-
<dialog use:trapFocus={{ onEscape: handleEscape }} bind:this={dlg} {...restProps} class={
|
|
81
|
+
<dialog use:trapFocus={{ onEscape: handleEscape }} {@attach init} onsubmit={_onsubmit} bind:this={dlg} {...restProps} class={base({ class: clsx(className) })} tabindex="-1" oncancel={_oncancel} onclick={_onclick} transition:transition|global={paramsOptions as ParamsType}>
|
|
67
82
|
{#if title || header}
|
|
68
|
-
<div class={
|
|
83
|
+
<div class={headerCls({ class: clsx(headerClass) })}>
|
|
69
84
|
{#if title}
|
|
70
85
|
<h3>{title}</h3>
|
|
86
|
+
<CloseButton onclick={() => (open = false)} class={clsx(closeBtnClass)} />
|
|
71
87
|
{:else if header}
|
|
72
88
|
{@render header()}
|
|
73
89
|
{/if}
|
|
74
90
|
</div>
|
|
75
91
|
{/if}
|
|
76
|
-
<div class={
|
|
92
|
+
<div class={body({ class: clsx(bodyClass) })}>
|
|
77
93
|
{@render children?.()}
|
|
78
94
|
</div>
|
|
79
95
|
{#if footer}
|
|
80
|
-
<div class={
|
|
96
|
+
<div class={footerCls({ class: clsx(footerClass) })}>
|
|
81
97
|
{@render footer()}
|
|
82
98
|
</div>
|
|
83
99
|
{/if}
|
|
84
|
-
{#if dismissable && !permanent}
|
|
85
|
-
<CloseButton onclick={
|
|
100
|
+
{#if dismissable && !permanent && !title}
|
|
101
|
+
<CloseButton onclick={() => (open = false)} class={closeBtn({ class: clsx(closeBtnClass) })} />
|
|
86
102
|
{/if}
|
|
87
103
|
</dialog>
|
|
88
104
|
{/if}
|
|
@@ -95,7 +111,7 @@
|
|
|
95
111
|
## Props
|
|
96
112
|
@prop children
|
|
97
113
|
@prop oncancel
|
|
98
|
-
@prop
|
|
114
|
+
@prop onsubmit
|
|
99
115
|
@prop modal = true
|
|
100
116
|
@prop autoclose = false
|
|
101
117
|
@prop header
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flowbite-svelte",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.5",
|
|
4
4
|
"description": "Flowbite components for Svelte",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"author": {
|
|
@@ -12,35 +12,34 @@
|
|
|
12
12
|
"homepage": "https://flowbite-svelte.com/",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@changesets/cli": "2.29.
|
|
15
|
+
"@changesets/cli": "2.29.5",
|
|
16
16
|
"@docsearch/css": "^3.9.0",
|
|
17
17
|
"@docsearch/js": "^3.9.0",
|
|
18
18
|
"@eslint/compat": "^1.3.1",
|
|
19
|
-
"@eslint/js": "^9.
|
|
19
|
+
"@eslint/js": "^9.30.1",
|
|
20
20
|
"@flowbite-svelte-plugins/chart": "^0.2.4",
|
|
21
|
-
"@flowbite-svelte-plugins/datatable": "^0.
|
|
22
|
-
"@flowbite-svelte-plugins/texteditor": "^0.
|
|
23
|
-
"@playwright/test": "^1.53.
|
|
21
|
+
"@flowbite-svelte-plugins/datatable": "^0.4.0",
|
|
22
|
+
"@flowbite-svelte-plugins/texteditor": "^0.24.0",
|
|
23
|
+
"@playwright/test": "^1.53.2",
|
|
24
24
|
"@sveltejs/adapter-auto": "^6.0.1",
|
|
25
25
|
"@sveltejs/adapter-vercel": "^5.7.2",
|
|
26
26
|
"@sveltejs/kit": "^2.22.2",
|
|
27
|
-
"@sveltejs/package": "2.3.
|
|
27
|
+
"@sveltejs/package": "2.3.12",
|
|
28
28
|
"@sveltejs/vite-plugin-svelte": "^5.1.0",
|
|
29
29
|
"@svitejs/changesets-changelog-github-compact": "^1.2.0",
|
|
30
30
|
"@tailwindcss/vite": "^4.1.11",
|
|
31
31
|
"@testing-library/jest-dom": "^6.6.3",
|
|
32
32
|
"@testing-library/svelte": "^5.2.8",
|
|
33
33
|
"@testing-library/user-event": "^14.6.1",
|
|
34
|
-
"@tiptap/core": "
|
|
34
|
+
"@tiptap/core": "3.0.0-beta.24",
|
|
35
35
|
"dayjs": "^1.11.13",
|
|
36
36
|
"deepmerge": "^4.3.1",
|
|
37
|
-
"eslint": "^9.
|
|
37
|
+
"eslint": "^9.30.1",
|
|
38
38
|
"eslint-config-prettier": "^10.1.5",
|
|
39
39
|
"eslint-plugin-svelte": "^3.10.1",
|
|
40
40
|
"flowbite-svelte-icons": "^2.2.1",
|
|
41
41
|
"flowbite-typography": "^1.0.5",
|
|
42
|
-
"globals": "^16.
|
|
43
|
-
"highlight.js": "^11.11.1",
|
|
42
|
+
"globals": "^16.3.0",
|
|
44
43
|
"jsdom": "^26.1.0",
|
|
45
44
|
"katex": "^0.16.22",
|
|
46
45
|
"lowlight": "^3.3.0",
|
|
@@ -52,7 +51,7 @@
|
|
|
52
51
|
"prism-themes": "^1.9.0",
|
|
53
52
|
"publint": "^0.3.12",
|
|
54
53
|
"simple-datatables": "^10.0.0",
|
|
55
|
-
"svelte": "^5.
|
|
54
|
+
"svelte": "^5.35.4",
|
|
56
55
|
"svelte-check": "^4.2.2",
|
|
57
56
|
"svelte-doc-llm": "^0.2.2",
|
|
58
57
|
"svelte-lib-helpers": "^0.4.30",
|
|
@@ -61,9 +60,9 @@
|
|
|
61
60
|
"tailwindcss": "^4.1.11",
|
|
62
61
|
"tsx": "^4.20.3",
|
|
63
62
|
"typescript": "^5.8.3",
|
|
64
|
-
"typescript-eslint": "8.
|
|
63
|
+
"typescript-eslint": "8.36.0",
|
|
65
64
|
"vite": "^6.3.5",
|
|
66
|
-
"vite-plugin-devtools-json": "^0.2.
|
|
65
|
+
"vite-plugin-devtools-json": "^0.2.1",
|
|
67
66
|
"vitest": "^3.2.4"
|
|
68
67
|
},
|
|
69
68
|
"peerDependencies": {
|
|
@@ -114,8 +113,8 @@
|
|
|
114
113
|
"url": "git+https://github.com/themesberg/flowbite-svelte.git"
|
|
115
114
|
},
|
|
116
115
|
"dependencies": {
|
|
117
|
-
"@floating-ui/dom": "^1.7.
|
|
118
|
-
"@floating-ui/utils": "^0.2.
|
|
116
|
+
"@floating-ui/dom": "^1.7.2",
|
|
117
|
+
"@floating-ui/utils": "^0.2.10",
|
|
119
118
|
"apexcharts": "^4.7.0",
|
|
120
119
|
"clsx": "^2.1.1",
|
|
121
120
|
"flowbite": "^3.1.2",
|