@rkosafo/cai.components 0.0.81 → 0.0.83

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.
@@ -0,0 +1 @@
1
+ export { default as FormSelect } from './FormSelect.svelte';
@@ -0,0 +1 @@
1
+ export { default as FormSelect } from './FormSelect.svelte';
@@ -0,0 +1,4 @@
1
+ import type { SizeType } from '../../index.js';
2
+ export { default as Input } from './Input.svelte';
3
+ export { input } from './theme.js';
4
+ export declare function clampSize(s: SizeType): "md" | "sm" | "lg";
@@ -0,0 +1,5 @@
1
+ export { default as Input } from './Input.svelte';
2
+ export { input } from './theme.js';
3
+ export function clampSize(s) {
4
+ return s && s === 'xs' ? 'sm' : s === 'xl' ? 'lg' : s;
5
+ }
@@ -0,0 +1,301 @@
1
+ import type { Classes } from '../../themes/themeUtils.js';
2
+ import { type VariantProps } from 'tailwind-variants';
3
+ export type InputVariants = VariantProps<typeof input> & Classes<typeof input>;
4
+ export declare const input: import("tailwind-variants").TVReturnType<{
5
+ size: {
6
+ sm: {
7
+ input: string;
8
+ };
9
+ md: {
10
+ input: string;
11
+ };
12
+ lg: {
13
+ input: string;
14
+ };
15
+ };
16
+ color: {
17
+ default: {
18
+ input: string;
19
+ };
20
+ tinted: {
21
+ input: string;
22
+ };
23
+ primary: {
24
+ input: string;
25
+ };
26
+ secondary: {
27
+ input: string;
28
+ };
29
+ green: {
30
+ input: string;
31
+ };
32
+ emerald: {
33
+ input: string;
34
+ };
35
+ red: {
36
+ input: string;
37
+ };
38
+ blue: {
39
+ input: string;
40
+ };
41
+ yellow: {
42
+ input: string;
43
+ };
44
+ orange: {
45
+ input: string;
46
+ };
47
+ gray: {
48
+ input: string;
49
+ };
50
+ teal: {
51
+ input: string;
52
+ };
53
+ cyan: {
54
+ input: string;
55
+ };
56
+ sky: {
57
+ input: string;
58
+ };
59
+ indigo: {
60
+ input: string;
61
+ };
62
+ lime: {
63
+ input: string;
64
+ };
65
+ amber: {
66
+ input: string;
67
+ };
68
+ violet: {
69
+ input: string;
70
+ };
71
+ purple: {
72
+ input: string;
73
+ };
74
+ fuchsia: {
75
+ input: string;
76
+ };
77
+ pink: {
78
+ input: string;
79
+ };
80
+ rose: {
81
+ input: string;
82
+ };
83
+ };
84
+ grouped: {
85
+ false: {
86
+ input: string;
87
+ };
88
+ true: {
89
+ input: string;
90
+ };
91
+ };
92
+ }, {
93
+ base: string;
94
+ input: string;
95
+ left: string;
96
+ right: string;
97
+ close: string;
98
+ combo: string;
99
+ comboItem: string;
100
+ div: string;
101
+ svg: string;
102
+ wrapper: string;
103
+ }, undefined, {
104
+ size: {
105
+ sm: {
106
+ input: string;
107
+ };
108
+ md: {
109
+ input: string;
110
+ };
111
+ lg: {
112
+ input: string;
113
+ };
114
+ };
115
+ color: {
116
+ default: {
117
+ input: string;
118
+ };
119
+ tinted: {
120
+ input: string;
121
+ };
122
+ primary: {
123
+ input: string;
124
+ };
125
+ secondary: {
126
+ input: string;
127
+ };
128
+ green: {
129
+ input: string;
130
+ };
131
+ emerald: {
132
+ input: string;
133
+ };
134
+ red: {
135
+ input: string;
136
+ };
137
+ blue: {
138
+ input: string;
139
+ };
140
+ yellow: {
141
+ input: string;
142
+ };
143
+ orange: {
144
+ input: string;
145
+ };
146
+ gray: {
147
+ input: string;
148
+ };
149
+ teal: {
150
+ input: string;
151
+ };
152
+ cyan: {
153
+ input: string;
154
+ };
155
+ sky: {
156
+ input: string;
157
+ };
158
+ indigo: {
159
+ input: string;
160
+ };
161
+ lime: {
162
+ input: string;
163
+ };
164
+ amber: {
165
+ input: string;
166
+ };
167
+ violet: {
168
+ input: string;
169
+ };
170
+ purple: {
171
+ input: string;
172
+ };
173
+ fuchsia: {
174
+ input: string;
175
+ };
176
+ pink: {
177
+ input: string;
178
+ };
179
+ rose: {
180
+ input: string;
181
+ };
182
+ };
183
+ grouped: {
184
+ false: {
185
+ input: string;
186
+ };
187
+ true: {
188
+ input: string;
189
+ };
190
+ };
191
+ }, {
192
+ base: string;
193
+ input: string;
194
+ left: string;
195
+ right: string;
196
+ close: string;
197
+ combo: string;
198
+ comboItem: string;
199
+ div: string;
200
+ svg: string;
201
+ wrapper: string;
202
+ }, import("tailwind-variants").TVReturnType<{
203
+ size: {
204
+ sm: {
205
+ input: string;
206
+ };
207
+ md: {
208
+ input: string;
209
+ };
210
+ lg: {
211
+ input: string;
212
+ };
213
+ };
214
+ color: {
215
+ default: {
216
+ input: string;
217
+ };
218
+ tinted: {
219
+ input: string;
220
+ };
221
+ primary: {
222
+ input: string;
223
+ };
224
+ secondary: {
225
+ input: string;
226
+ };
227
+ green: {
228
+ input: string;
229
+ };
230
+ emerald: {
231
+ input: string;
232
+ };
233
+ red: {
234
+ input: string;
235
+ };
236
+ blue: {
237
+ input: string;
238
+ };
239
+ yellow: {
240
+ input: string;
241
+ };
242
+ orange: {
243
+ input: string;
244
+ };
245
+ gray: {
246
+ input: string;
247
+ };
248
+ teal: {
249
+ input: string;
250
+ };
251
+ cyan: {
252
+ input: string;
253
+ };
254
+ sky: {
255
+ input: string;
256
+ };
257
+ indigo: {
258
+ input: string;
259
+ };
260
+ lime: {
261
+ input: string;
262
+ };
263
+ amber: {
264
+ input: string;
265
+ };
266
+ violet: {
267
+ input: string;
268
+ };
269
+ purple: {
270
+ input: string;
271
+ };
272
+ fuchsia: {
273
+ input: string;
274
+ };
275
+ pink: {
276
+ input: string;
277
+ };
278
+ rose: {
279
+ input: string;
280
+ };
281
+ };
282
+ grouped: {
283
+ false: {
284
+ input: string;
285
+ };
286
+ true: {
287
+ input: string;
288
+ };
289
+ };
290
+ }, {
291
+ base: string;
292
+ input: string;
293
+ left: string;
294
+ right: string;
295
+ close: string;
296
+ combo: string;
297
+ comboItem: string;
298
+ div: string;
299
+ svg: string;
300
+ wrapper: string;
301
+ }, undefined, unknown, unknown, undefined>>;
@@ -0,0 +1,100 @@
1
+ import { tv } from 'tailwind-variants';
2
+ export const input = tv({
3
+ slots: {
4
+ base: 'relative w-full',
5
+ input: 'block w-full disabled:cursor-not-allowed disabled:opacity-50 rtl:text-right focus:outline-hidden',
6
+ left: 'flex absolute inset-y-0 items-center text-gray-500 dark:text-gray-400 pointer-events-none start-0 p-2.5',
7
+ right: 'flex absolute inset-y-0 items-center text-gray-500 dark:text-gray-400 end-0 p-2.5',
8
+ close: 'absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 hover:text-black',
9
+ combo: 'absolute top-full right-0 left-0 z-20 mt-1 max-h-60 overflow-y-auto rounded-md border border-gray-200 bg-white shadow-lg dark:border-gray-700 dark:bg-gray-800',
10
+ comboItem: 'text-gray-900 dark:text-gray-50',
11
+ div: '',
12
+ svg: '',
13
+ wrapper: ''
14
+ },
15
+ variants: {
16
+ size: {
17
+ sm: { input: 'text-xs px-2 py-1' },
18
+ md: { input: 'text-sm px-2.5 py-2.5' },
19
+ lg: { input: 'sm:text-base px-3 py-3' }
20
+ },
21
+ color: {
22
+ default: {
23
+ input: 'border border-gray-300 dark:border-gray-600 focus:border-primary-500 focus:ring-primary-500 dark:focus:border-primary-500 dark:focus:ring-primary-500 bg-gray-50 text-gray-900 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 bg-gray-50 text-gray-900 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400'
24
+ },
25
+ tinted: {
26
+ input: 'border border-gray-300 dark:border-gray-500 bg-gray-50 text-gray-900 dark:bg-gray-600 dark:text-white dark:placeholder-gray-400'
27
+ },
28
+ primary: {
29
+ input: 'border border-primary-200 dark:border-primary-400 focus:ring-primary-500 focus:border-primary-600 dark:focus:ring-primary-500 dark:focus:border-primary-500 bg-primary-50 text-primary-900 placeholder-primary-700 dark:text-primary-400 dark:placeholder-primary-500 dark:bg-gray-700'
30
+ },
31
+ secondary: {
32
+ input: 'border border-secondary-200 dark:border-secondary-400 focus:ring-secondary-500 focus:border-secondary-600 dark:focus:ring-secondary-500 dark:focus:border-secondary-500 bg-secondary-50 text-secondary-900 placeholder-secondary-700 dark:text-secondary-400 dark:placeholder-secondary-500 dark:bg-gray-700'
33
+ },
34
+ green: {
35
+ input: 'border border-green-200 dark:border-green-400 focus:ring-green-500 focus:border-green-600 dark:focus:ring-green-500 dark:focus:border-green-500 bg-green-50 text-green-900 placeholder-green-700 dark:text-green-400 dark:placeholder-green-500 dark:bg-gray-700'
36
+ },
37
+ emerald: {
38
+ input: 'border border-emerald-200 dark:border-emerald-400 focus:ring-emerald-500 focus:border-emerald-600 dark:focus:ring-emerald-500 dark:focus:border-emerald-500 bg-emerald-50 text-emerald-900 placeholder-emerald-700 dark:text-emerald-400 dark:placeholder-emerald-500 dark:bg-gray-700'
39
+ },
40
+ red: {
41
+ input: 'border border-red-200 dark:border-red-400 focus:ring-red-500 focus:border-red-600 dark:focus:ring-red-500 dark:focus:border-red-500 bg-red-50 text-red-900 placeholder-red-700 dark:text-red-400 dark:placeholder-red-500 dark:bg-gray-700'
42
+ },
43
+ blue: {
44
+ input: 'border border-blue-200 dark:border-blue-400 focus:ring-blue-500 focus:border-blue-600 dark:focus:ring-blue-500 dark:focus:border-blue-500 bg-blue-50 text-blue-900 placeholder-blue-700 dark:text-blue-400 dark:placeholder-blue-500 dark:bg-gray-700'
45
+ },
46
+ yellow: {
47
+ input: 'border border-yellow-200 dark:border-yellow-400 focus:ring-yellow-500 focus:border-yellow-600 dark:focus:ring-yellow-500 dark:focus:border-yellow-500 bg-yellow-50 text-yellow-900 placeholder-yellow-700 dark:text-yellow-400 dark:placeholder-yellow-500 dark:bg-gray-700'
48
+ },
49
+ orange: {
50
+ input: 'border border-orange-200 dark:border-orange-400 focus:ring-orange-500 focus:border-orange-600 dark:focus:ring-orange-500 dark:focus:border-orange-500 bg-orange-50 text-orange-900 placeholder-orange-700 dark:text-orange-400 dark:placeholder-orange-500 dark:bg-gray-700'
51
+ },
52
+ gray: {
53
+ input: 'border border-gray-200 dark:border-gray-400 focus:ring-gray-500 focus:border-gray-600 dark:focus:ring-gray-500 dark:focus:border-gray-500 bg-gray-50 text-gray-900 placeholder-gray-700 dark:text-gray-400 dark:placeholder-gray-500 dark:bg-gray-700'
54
+ },
55
+ teal: {
56
+ input: 'border border-teal-200 dark:border-teal-400 focus:ring-teal-500 focus:border-teal-600 dark:focus:ring-teal-500 dark:focus:border-teal-500 bg-teal-50 text-teal-900 placeholder-teal-700 dark:text-teal-400 dark:placeholder-teal-500 dark:bg-gray-700'
57
+ },
58
+ cyan: {
59
+ input: 'border border-cyan-200 dark:border-cyan-400 focus:ring-cyan-500 focus:border-cyan-600 dark:focus:ring-cyan-500 dark:focus:border-cyan-500 bg-cyan-50 text-cyan-900 placeholder-cyan-700 dark:text-cyan-400 dark:placeholder-cyan-500 dark:bg-gray-700'
60
+ },
61
+ sky: {
62
+ input: 'border border-sky-200 dark:border-sky-400 focus:ring-sky-500 focus:border-sky-600 dark:focus:ring-sky-500 dark:focus:border-sky-500 bg-sky-50 text-sky-900 placeholder-sky-700 dark:text-sky-400 dark:placeholder-sky-500 dark:bg-gray-700'
63
+ },
64
+ indigo: {
65
+ input: 'border border-indigo-200 dark:border-indigo-400 focus:ring-indigo-500 focus:border-indigo-600 dark:focus:ring-indigo-500 dark:focus:border-indigo-500 bg-indigo-50 text-indigo-900 placeholder-indigo-700 dark:text-indigo-400 dark:placeholder-indigo-500 dark:bg-gray-700'
66
+ },
67
+ lime: {
68
+ input: 'border border-lime-200 dark:border-lime-400 focus:ring-lime-500 focus:border-lime-600 dark:focus:ring-lime-500 dark:focus:border-lime-500 bg-lime-50 text-lime-900 placeholder-lime-700 dark:text-lime-400 dark:placeholder-lime-500 dark:bg-gray-700'
69
+ },
70
+ amber: {
71
+ input: 'border border-amber-200 dark:border-amber-400 focus:ring-amber-500 focus:border-amber-600 dark:focus:ring-amber-500 dark:focus:border-amber-500 bg-amber-50 text-amber-900 placeholder-amber-700 dark:text-amber-400 dark:placeholder-amber-500 dark:bg-gray-700'
72
+ },
73
+ violet: {
74
+ input: 'border border-violet-200 dark:border-violet-400 focus:ring-violet-500 focus:border-violet-600 dark:focus:ring-violet-500 dark:focus:border-violet-500 bg-violet-50 text-violet-900 placeholder-violet-700 dark:text-violet-400 dark:placeholder-violet-500 dark:bg-gray-700'
75
+ },
76
+ purple: {
77
+ input: 'border border-purple-200 dark:border-purple-400 focus:ring-purple-500 focus:border-purple-600 dark:focus:ring-purple-500 dark:focus:border-purple-500 bg-purple-50 text-purple-900 placeholder-purple-700 dark:text-purple-400 dark:placeholder-purple-500 dark:bg-gray-700'
78
+ },
79
+ fuchsia: {
80
+ input: 'border border-fuchsia-200 dark:border-fuchsia-400 focus:ring-fuchsia-500 focus:border-fuchsia-600 dark:focus:ring-fuchsia-500 dark:focus:border-fuchsia-500 bg-fuchsia-50 text-fuchsia-900 placeholder-fuchsia-700 dark:text-fuchsia-400 dark:placeholder-fuchsia-500 dark:bg-gray-700'
81
+ },
82
+ pink: {
83
+ input: 'border border-pink-200 dark:border-pink-400 focus:ring-pink-500 focus:border-pink-600 dark:focus:ring-pink-500 dark:focus:border-pink-500 bg-pink-50 text-pink-900 placeholder-pink-700 dark:text-pink-400 dark:placeholder-pink-500 dark:bg-gray-700'
84
+ },
85
+ rose: {
86
+ input: 'border border-rose-200 dark:border-rose-400 focus:ring-rose-500 focus:border-rose-600 dark:focus:ring-rose-500 dark:focus:border-rose-500 bg-rose-50 text-rose-900 placeholder-rose-700 dark:text-rose-400 dark:placeholder-rose-500 dark:bg-gray-700'
87
+ }
88
+ },
89
+ grouped: {
90
+ false: { input: 'rounded-lg' },
91
+ true: {
92
+ input: 'first:rounded-s-lg last:rounded-e-lg not-first:-ms-px'
93
+ }
94
+ }
95
+ },
96
+ defaultVariants: {
97
+ size: 'md',
98
+ color: 'default'
99
+ }
100
+ });
package/dist/index.d.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  export { getTheme } from './themes/themeUtils.js';
2
2
  export { default as ThemeProvider } from './themes/ThemeProvider.svelte';
3
- import YouTube from './youtube/index.svelte';
4
- import BaseEditor from './baseEditor/index.svelte';
5
3
  export * from './layout/TF/index.js';
6
4
  export * from './ui/dropdown/index.js';
7
5
  export * from './ui/buttons/index.js';
@@ -54,4 +52,3 @@ export * from './types/index.js';
54
52
  export * from './utils/index.js';
55
53
  export * from './utils/svelte-legos.js';
56
54
  export * from './keycloak/index.js';
57
- export { YouTube, BaseEditor };
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  export { getTheme } from './themes/themeUtils.js';
2
2
  export { default as ThemeProvider } from './themes/ThemeProvider.svelte';
3
3
  // Reexport your entry components here
4
- import YouTube from './youtube/index.svelte';
5
- import BaseEditor from './baseEditor/index.svelte';
4
+ // import YouTube from './youtube/index.svelte';
5
+ // import BaseEditor from './baseEditor/index.svelte';
6
6
  export * from './layout/TF/index.js';
7
7
  export * from './ui/dropdown/index.js';
8
8
  export * from './ui/buttons/index.js';
@@ -55,4 +55,4 @@ export * from './types/index.js';
55
55
  export * from './utils/index.js';
56
56
  export * from './utils/svelte-legos.js';
57
57
  export * from './keycloak/index.js';
58
- export { YouTube, BaseEditor };
58
+ // export { YouTube, BaseEditor };
@@ -0,0 +1,67 @@
1
+ <script lang="ts" module>
2
+ export interface TFSidebarProps {
3
+ homeUrl: string;
4
+ logoUrl: string;
5
+ appShortName: string;
6
+ appName: string;
7
+ hideSidebar?: boolean;
8
+ menuItems: IMenuItem[];
9
+ }
10
+
11
+ export interface IMenuItem {
12
+ title: string;
13
+ icon?: string;
14
+ path?: string;
15
+ items?: IMenuItem[] | null;
16
+ description?: string;
17
+ iconBg?: string;
18
+ iconColor?: string;
19
+ iconSize?: number;
20
+ }
21
+ </script>
22
+
23
+ <script lang="ts">
24
+ import { cn } from '../../../utils/index.js';
25
+ import { page } from '$app/state';
26
+
27
+ let {
28
+ homeUrl,
29
+ logoUrl,
30
+ appName,
31
+ appShortName,
32
+ hideSidebar = false,
33
+ menuItems = []
34
+ }: TFSidebarProps = $props();
35
+
36
+ let activeUrl = $state('');
37
+ $effect(() => {
38
+ activeUrl = page.url.pathname;
39
+ });
40
+ </script>
41
+
42
+ {#snippet menuItemSnippet(item: IMenuItem, active: boolean)}
43
+ <li class:active class="relative">
44
+ <a class="space-x-3 pl-3" href={item.path}>
45
+ <iconify-icon icon={item.icon}></iconify-icon>
46
+
47
+ <span class="text hidden md:block">{item.title}</span>
48
+ </a>
49
+ </li>
50
+ {/snippet}
51
+ <section id="tf-sidebar" class={cn('relative')} class:hide={hideSidebar}>
52
+ <a href={homeUrl} class="brand flex flex-col pt-4">
53
+ <img src={logoUrl} alt="Logo" class={hideSidebar ? 'w-12' : 'w-12 md:w-24'} loading="lazy" />
54
+ <span class="text-base font-thin {hideSidebar ? 'block' : 'md:hidden'}">{appShortName}</span>
55
+ <p class="text-center text-lg font-medium {hideSidebar ? 'hidden' : 'hidden md:block'}">
56
+ {appName}
57
+ </p>
58
+ </a>
59
+ {#if menuItems.length > 0}
60
+ <ul class="side-menu top relative pt-4">
61
+ {#each menuItems as item}
62
+ {@const active = activeUrl === item.path}
63
+ {@render menuItemSnippet(item, active)}
64
+ {/each}
65
+ </ul>
66
+ {/if}
67
+ </section>
@@ -0,0 +1,21 @@
1
+ export interface TFSidebarProps {
2
+ homeUrl: string;
3
+ logoUrl: string;
4
+ appShortName: string;
5
+ appName: string;
6
+ hideSidebar?: boolean;
7
+ menuItems: IMenuItem[];
8
+ }
9
+ export interface IMenuItem {
10
+ title: string;
11
+ icon?: string;
12
+ path?: string;
13
+ items?: IMenuItem[] | null;
14
+ description?: string;
15
+ iconBg?: string;
16
+ iconColor?: string;
17
+ iconSize?: number;
18
+ }
19
+ declare const Sidebar: import("svelte").Component<TFSidebarProps, {}, "">;
20
+ type Sidebar = ReturnType<typeof Sidebar>;
21
+ export default Sidebar;
@@ -0,0 +1 @@
1
+ export { default as TFSidebar } from './Sidebar.svelte';
@@ -0,0 +1 @@
1
+ export { default as TFSidebar } from './Sidebar.svelte';
@@ -0,0 +1 @@
1
+ export { default as TFLayoutWrapper } from './Wrapper.svelte';
@@ -0,0 +1 @@
1
+ export { default as TFLayoutWrapper } from './Wrapper.svelte';
@@ -0,0 +1,96 @@
1
+ import type { Classes } from '../../themes/themeUtils.js';
2
+ import { type VariantProps } from 'tailwind-variants';
3
+ export type AccordionVariants = VariantProps<typeof accordion>;
4
+ export type AccordionItemVariants = VariantProps<typeof accordionItem> & Classes<typeof accordionItem>;
5
+ export declare const accordion: import("tailwind-variants").TVReturnType<{
6
+ color: {
7
+ primary: string;
8
+ secondary: string;
9
+ };
10
+ flush: {
11
+ true: string;
12
+ false: string;
13
+ };
14
+ }, undefined, "w-full", {
15
+ color: {
16
+ primary: string;
17
+ secondary: string;
18
+ };
19
+ flush: {
20
+ true: string;
21
+ false: string;
22
+ };
23
+ }, undefined, import("tailwind-variants").TVReturnType<{
24
+ color: {
25
+ primary: string;
26
+ secondary: string;
27
+ };
28
+ flush: {
29
+ true: string;
30
+ false: string;
31
+ };
32
+ }, undefined, "w-full", unknown, unknown, undefined>>;
33
+ export declare const accordionItem: import("tailwind-variants").TVReturnType<{
34
+ flush: {
35
+ true: {
36
+ button: string;
37
+ content: string;
38
+ };
39
+ false: {
40
+ button: string;
41
+ content: string;
42
+ };
43
+ };
44
+ open: {
45
+ true: {};
46
+ false: {};
47
+ };
48
+ }, {
49
+ base: string;
50
+ button: string;
51
+ content: string;
52
+ active: string;
53
+ inactive: string;
54
+ }, undefined, {
55
+ flush: {
56
+ true: {
57
+ button: string;
58
+ content: string;
59
+ };
60
+ false: {
61
+ button: string;
62
+ content: string;
63
+ };
64
+ };
65
+ open: {
66
+ true: {};
67
+ false: {};
68
+ };
69
+ }, {
70
+ base: string;
71
+ button: string;
72
+ content: string;
73
+ active: string;
74
+ inactive: string;
75
+ }, import("tailwind-variants").TVReturnType<{
76
+ flush: {
77
+ true: {
78
+ button: string;
79
+ content: string;
80
+ };
81
+ false: {
82
+ button: string;
83
+ content: string;
84
+ };
85
+ };
86
+ open: {
87
+ true: {};
88
+ false: {};
89
+ };
90
+ }, {
91
+ base: string;
92
+ button: string;
93
+ content: string;
94
+ active: string;
95
+ inactive: string;
96
+ }, undefined, unknown, unknown, undefined>>;
@@ -0,0 +1,59 @@
1
+ import { tv } from 'tailwind-variants';
2
+ export const accordion = tv({
3
+ base: 'w-full',
4
+ variants: {
5
+ color: {
6
+ primary: 'text-primary-500 dark:text-primary-400',
7
+ secondary: 'text-secondary-500 dark:text-secondary-400'
8
+ },
9
+ flush: {
10
+ true: '',
11
+ false: 'border border-gray-200 dark:border-gray-700 rounded-t-xl'
12
+ }
13
+ }
14
+ });
15
+ export const accordionItem = tv({
16
+ slots: {
17
+ base: 'group',
18
+ button: 'flex items-center justify-between w-full font-medium text-left group-first:rounded-t-xl border-gray-200 dark:border-gray-700 border-b',
19
+ content: 'border-b border-gray-200 dark:border-gray-700',
20
+ active: 'bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-800',
21
+ inactive: 'text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800'
22
+ },
23
+ variants: {
24
+ flush: {
25
+ true: {
26
+ button: 'py-5',
27
+ content: 'py-5'
28
+ },
29
+ false: {
30
+ button: 'p-5 border-s border-e group-first:border-t',
31
+ content: 'p-5 border-s border-e'
32
+ }
33
+ },
34
+ open: {
35
+ true: {},
36
+ false: {}
37
+ }
38
+ },
39
+ compoundVariants: [
40
+ {
41
+ flush: true,
42
+ open: true,
43
+ class: {
44
+ button: 'text-gray-900 dark:text-white'
45
+ }
46
+ },
47
+ {
48
+ flush: true,
49
+ open: false,
50
+ class: {
51
+ button: 'text-gray-500 dark:text-gray-400'
52
+ }
53
+ }
54
+ ],
55
+ defaultVariants: {
56
+ flush: false,
57
+ open: false
58
+ }
59
+ });
@@ -233,7 +233,7 @@
233
233
  <div
234
234
  bind:this={ref}
235
235
  use:focusTrap
236
- class="fixed inset-0 z-40 flex items-center justify-center p-4"
236
+ class="fixed inset-0 z-40 overflow-y-auto p-4"
237
237
  onclick={_onclick}
238
238
  onkeydown={(ev) => {
239
239
  if (ev.key === 'Escape' && !permanent) {
@@ -253,22 +253,22 @@
253
253
  class: clsx(
254
254
  theme?.base,
255
255
  className,
256
- 'relative z-10',
256
+ fullscreen ? 'z-10' : 'absolute z-10',
257
257
  !modal && 'shadow-xl'
258
258
  )
259
259
  })}
260
- tabindex="-1"
261
- onsubmit={_onsubmit}
262
- transition:transition|global={paramsOptions as ParamsType}
263
- {...restProps}
264
- >
265
- {#if form}
266
- <form method="dialog" class={formCls({ class: clsx(theme?.form) })}>
260
+ tabindex="-1"
261
+ onsubmit={_onsubmit}
262
+ transition:transition|global={paramsOptions as ParamsType}
263
+ {...restProps}
264
+ >
265
+ {#if form}
266
+ <form method="dialog" class={formCls({ class: clsx(theme?.form) })}>
267
+ {@render content()}
268
+ </form>
269
+ {:else}
267
270
  {@render content()}
268
- </form>
269
- {:else}
270
- {@render content()}
271
- {/if}
271
+ {/if}
272
272
  </div>
273
273
  </div>
274
274
  {/if}
@@ -0,0 +1,77 @@
1
+ <script lang="ts">
2
+ import clsx from 'clsx';
3
+ import Popper from '../../utils/Popper.svelte';
4
+ import { getSideAxis } from '@floating-ui/utils';
5
+ import { setContext, untrack } from 'svelte';
6
+ import { speedDial } from './theme.js';
7
+ import type { SpeedDialProps, SpeedCtxType } from '../../index.js';
8
+ import { getTheme, warnThemeDeprecation } from '../../themes/themeUtils.js';
9
+
10
+ let {
11
+ children,
12
+ popperClass,
13
+ placement = 'top',
14
+ pill = true,
15
+ tooltip = 'left',
16
+ trigger = 'hover',
17
+ textOutside = false,
18
+ class: className,
19
+ classes,
20
+ isOpen = $bindable(false),
21
+ ...restProps
22
+ }: SpeedDialProps = $props();
23
+
24
+ warnThemeDeprecation(
25
+ 'SpeedDial',
26
+ untrack(() => ({ popperClass })),
27
+ { popperClass: 'popper' }
28
+ );
29
+
30
+ const styling = $derived(
31
+ classes ?? {
32
+ popper: popperClass
33
+ }
34
+ );
35
+
36
+ const theme = $derived(getTheme('speedDial'));
37
+
38
+ $effect(() => {
39
+ setContext<SpeedCtxType>('speed-dial', { pill, tooltip, textOutside });
40
+ });
41
+
42
+ let vertical: boolean = $derived(getSideAxis(placement) === 'y');
43
+
44
+ let { base, popper } = $derived(speedDial({ vertical }));
45
+ </script>
46
+
47
+ <Popper
48
+ {...restProps}
49
+ bind:isOpen
50
+ {trigger}
51
+ arrow={false}
52
+ {placement}
53
+ class={base({ class: clsx(theme?.base, className) })}
54
+ >
55
+ <div class={popper({ class: clsx(theme?.popper, styling.popper) })}>
56
+ {@render children()}
57
+ </div>
58
+ </Popper>
59
+
60
+ <!--
61
+ @component
62
+ [Go to docs](https://flowbite-svelte.com/)
63
+ ## Type
64
+ [SpeedDialProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L1598)
65
+ ## Props
66
+ @prop children
67
+ @prop popperClass
68
+ @prop placement = "top"
69
+ @prop pill = true
70
+ @prop tooltip = "left"
71
+ @prop trigger = "hover"
72
+ @prop textOutside = false
73
+ @prop class: className
74
+ @prop classes
75
+ @prop isOpen = $bindable(false)
76
+ @prop ...restProps
77
+ -->
@@ -0,0 +1,21 @@
1
+ import type { SpeedDialProps } from '../../index.js';
2
+ /**
3
+ * [Go to docs](https://flowbite-svelte.com/)
4
+ * ## Type
5
+ * [SpeedDialProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L1598)
6
+ * ## Props
7
+ * @prop children
8
+ * @prop popperClass
9
+ * @prop placement = "top"
10
+ * @prop pill = true
11
+ * @prop tooltip = "left"
12
+ * @prop trigger = "hover"
13
+ * @prop textOutside = false
14
+ * @prop class: className
15
+ * @prop classes
16
+ * @prop isOpen = $bindable(false)
17
+ * @prop ...restProps
18
+ */
19
+ declare const SpeedDial: import("svelte").Component<SpeedDialProps, {}, "isOpen">;
20
+ type SpeedDial = ReturnType<typeof SpeedDial>;
21
+ export default SpeedDial;
@@ -0,0 +1,24 @@
1
+ <script>
2
+ let { bodySize = 10, headerSize = 6 } = $props();
3
+ </script>
4
+
5
+ <table class="w-full animate-pulse">
6
+ <thead>
7
+ {#each Array(headerSize) as _}
8
+ <th class="px-6 py-2 whitespace-nowrap">
9
+ <div class=" h-7 rounded-md bg-gray-300"></div>
10
+ </th>
11
+ {/each}
12
+ </thead>
13
+ <tbody class="divide-y border-t border-gray-400">
14
+ {#each Array(bodySize) as _}
15
+ <tr>
16
+ {#each Array(headerSize) as _}
17
+ <td class="px-6 py-2 whitespace-nowrap">
18
+ <div class=" h-7 rounded-md bg-gray-300"></div>
19
+ </td>
20
+ {/each}
21
+ </tr>
22
+ {/each}
23
+ </tbody>
24
+ </table>
@@ -0,0 +1,13 @@
1
+ export default TableLoader;
2
+ type TableLoader = {
3
+ $on?(type: string, callback: (e: any) => void): () => void;
4
+ $set?(props: Partial<$$ComponentProps>): void;
5
+ };
6
+ declare const TableLoader: import("svelte").Component<{
7
+ bodySize?: number;
8
+ headerSize?: number;
9
+ }, {}, "">;
10
+ type $$ComponentProps = {
11
+ bodySize?: number;
12
+ headerSize?: number;
13
+ };
@@ -34,6 +34,15 @@
34
34
  export type CustomToastOptions = ToastOptions;
35
35
  export type ToastTheme = Record<string, never>;
36
36
 
37
+ export type ToastSoundPreset =
38
+ | 'chime'
39
+ | 'ding'
40
+ | 'bell'
41
+ | 'soft'
42
+ | 'pop'
43
+ | 'pulse'
44
+ | 'airy';
45
+
37
46
  export interface ToasterProps {
38
47
  position?: ToastPosition;
39
48
  duration?: number;
@@ -43,6 +52,8 @@
43
52
  containerStyle?: string;
44
53
  containerClassName?: string;
45
54
  fireWithSound?: boolean;
55
+ /** Web Audio preset when `fireWithSound` is true. Default `chime`. */
56
+ soundPreset?: ToastSoundPreset;
46
57
  // Kept for backward compatibility (no-op in wrapper mode)
47
58
  className?: string;
48
59
  theme?: ToastTheme;
@@ -58,58 +69,188 @@
58
69
 
59
70
  let currentDuration = 4000;
60
71
  let currentFireWithSound = false;
72
+ let currentSoundPreset: ToastSoundPreset = 'chime';
61
73
 
62
- function playToastSound() {
63
- if (!currentFireWithSound || typeof window === 'undefined') return;
74
+ let sharedAudioContext: AudioContext | null = null;
64
75
 
76
+ function getSharedAudioContext(): AudioContext | null {
77
+ if (typeof window === 'undefined') return null;
65
78
  try {
66
- const AudioContextClass = window.AudioContext || (window as Window & { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;
67
- if (!AudioContextClass) return;
68
-
69
- const context = new AudioContextClass();
70
- const oscillator = context.createOscillator();
71
- const gain = context.createGain();
72
- oscillator.type = 'sine';
73
- oscillator.frequency.setValueAtTime(880, context.currentTime);
74
- gain.gain.setValueAtTime(0.0001, context.currentTime);
75
- gain.gain.exponentialRampToValueAtTime(0.06, context.currentTime + 0.01);
76
- gain.gain.exponentialRampToValueAtTime(0.0001, context.currentTime + 0.18);
77
- oscillator.connect(gain);
78
- gain.connect(context.destination);
79
- oscillator.start();
80
- oscillator.stop(context.currentTime + 0.2);
79
+ if (sharedAudioContext && sharedAudioContext.state !== 'closed') {
80
+ return sharedAudioContext;
81
+ }
82
+ sharedAudioContext = null;
83
+ const AudioContextClass =
84
+ window.AudioContext || (window as Window & { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;
85
+ if (!AudioContextClass) return null;
86
+ sharedAudioContext = new AudioContextClass();
87
+ return sharedAudioContext;
81
88
  } catch {
82
- // Ignore audio errors.
89
+ return null;
90
+ }
91
+ }
92
+
93
+ function envelopeAttackRelease(
94
+ gain: GainNode,
95
+ ctx: AudioContext,
96
+ t: number,
97
+ peak: number,
98
+ attack: number,
99
+ release: number
100
+ ) {
101
+ gain.gain.setValueAtTime(0.0001, t);
102
+ gain.gain.exponentialRampToValueAtTime(peak, t + attack);
103
+ gain.gain.exponentialRampToValueAtTime(0.0001, t + attack + release);
104
+ }
105
+
106
+ function playPresetSound(ctx: AudioContext, preset: ToastSoundPreset) {
107
+ const t0 = ctx.currentTime;
108
+
109
+ switch (preset) {
110
+ case 'chime': {
111
+ const freqs = [523.25, 659.25];
112
+ for (let i = 0; i < freqs.length; i++) {
113
+ const start = t0 + i * 0.065;
114
+ const osc = ctx.createOscillator();
115
+ const g = ctx.createGain();
116
+ osc.type = 'sine';
117
+ osc.frequency.setValueAtTime(freqs[i], start);
118
+ envelopeAttackRelease(g, ctx, start, 0.07, 0.012, 0.11);
119
+ osc.connect(g);
120
+ g.connect(ctx.destination);
121
+ osc.start(start);
122
+ osc.stop(start + 0.2);
123
+ }
124
+ break;
125
+ }
126
+ case 'ding': {
127
+ const osc = ctx.createOscillator();
128
+ const g = ctx.createGain();
129
+ osc.type = 'sine';
130
+ osc.frequency.setValueAtTime(1046.5, t0);
131
+ envelopeAttackRelease(g, ctx, t0, 0.08, 0.004, 0.14);
132
+ osc.connect(g);
133
+ g.connect(ctx.destination);
134
+ osc.start(t0);
135
+ osc.stop(t0 + 0.2);
136
+ break;
137
+ }
138
+ case 'bell': {
139
+ const osc = ctx.createOscillator();
140
+ const g = ctx.createGain();
141
+ osc.type = 'triangle';
142
+ osc.frequency.setValueAtTime(740, t0);
143
+ envelopeAttackRelease(g, ctx, t0, 0.06, 0.006, 0.22);
144
+ osc.connect(g);
145
+ g.connect(ctx.destination);
146
+ osc.start(t0);
147
+ osc.stop(t0 + 0.28);
148
+ break;
149
+ }
150
+ case 'soft': {
151
+ const osc = ctx.createOscillator();
152
+ const g = ctx.createGain();
153
+ osc.type = 'sine';
154
+ osc.frequency.setValueAtTime(392, t0);
155
+ envelopeAttackRelease(g, ctx, t0, 0.05, 0.02, 0.2);
156
+ osc.connect(g);
157
+ g.connect(ctx.destination);
158
+ osc.start(t0);
159
+ osc.stop(t0 + 0.26);
160
+ break;
161
+ }
162
+ case 'pop': {
163
+ const osc = ctx.createOscillator();
164
+ const g = ctx.createGain();
165
+ osc.type = 'sine';
166
+ osc.frequency.setValueAtTime(320, t0);
167
+ envelopeAttackRelease(g, ctx, t0, 0.06, 0.002, 0.045);
168
+ osc.connect(g);
169
+ g.connect(ctx.destination);
170
+ osc.start(t0);
171
+ osc.stop(t0 + 0.08);
172
+ break;
173
+ }
174
+ case 'pulse': {
175
+ const osc = ctx.createOscillator();
176
+ const g = ctx.createGain();
177
+ osc.type = 'sine';
178
+ osc.frequency.setValueAtTime(620, t0);
179
+ osc.frequency.exponentialRampToValueAtTime(920, t0 + 0.07);
180
+ envelopeAttackRelease(g, ctx, t0, 0.07, 0.003, 0.08);
181
+ osc.connect(g);
182
+ g.connect(ctx.destination);
183
+ osc.start(t0);
184
+ osc.stop(t0 + 0.12);
185
+ break;
186
+ }
187
+ case 'airy':
188
+ default: {
189
+ const osc = ctx.createOscillator();
190
+ const g = ctx.createGain();
191
+ osc.type = 'sine';
192
+ osc.frequency.setValueAtTime(1760, t0);
193
+ envelopeAttackRelease(g, ctx, t0, 0.025, 0.002, 0.07);
194
+ osc.connect(g);
195
+ g.connect(ctx.destination);
196
+ osc.start(t0);
197
+ osc.stop(t0 + 0.1);
198
+ break;
199
+ }
83
200
  }
84
201
  }
85
202
 
203
+ /** Schedules sound after the current frame so the toast paints first; handles suspended AudioContext. */
204
+ function scheduleToastSound() {
205
+ if (!currentFireWithSound || typeof window === 'undefined') return;
206
+
207
+ queueMicrotask(() => {
208
+ void (async () => {
209
+ const ctx = getSharedAudioContext();
210
+ if (!ctx) return;
211
+ try {
212
+ if (ctx.state === 'suspended') await ctx.resume();
213
+ playPresetSound(ctx, currentSoundPreset);
214
+ } catch {
215
+ // Ignore audio errors.
216
+ }
217
+ })();
218
+ });
219
+ }
220
+
86
221
  export function updateToastConfig(config: {
87
222
  duration?: number;
88
223
  fireWithSound?: boolean;
224
+ soundPreset?: ToastSoundPreset;
89
225
  theme?: ToastTheme;
90
226
  richColors?: boolean;
91
227
  }) {
92
228
  if (config.duration !== undefined) currentDuration = config.duration;
93
229
  if (config.fireWithSound !== undefined) currentFireWithSound = config.fireWithSound;
230
+ if (config.soundPreset !== undefined) currentSoundPreset = config.soundPreset;
94
231
  }
95
232
 
96
233
  export const toast = Object.assign(
97
234
  (message: Renderable, options?: ToastOptions) => {
98
- playToastSound();
99
- return originalToast(message, { duration: currentDuration, ...options });
235
+ const id = originalToast(message, { duration: currentDuration, ...options });
236
+ scheduleToastSound();
237
+ return id;
100
238
  },
101
239
  {
102
240
  success: (message: Renderable, options?: ToastOptions) => {
103
- playToastSound();
104
- return originalToast.success(message, { duration: currentDuration, ...options });
241
+ const id = originalToast.success(message, { duration: currentDuration, ...options });
242
+ scheduleToastSound();
243
+ return id;
105
244
  },
106
245
  error: (message: Renderable, options?: ToastOptions) => {
107
- playToastSound();
108
- return originalToast.error(message, { duration: currentDuration, ...options });
246
+ const id = originalToast.error(message, { duration: currentDuration, ...options });
247
+ scheduleToastSound();
248
+ return id;
109
249
  },
110
250
  loading: (message: Renderable, options?: ToastOptions) => {
111
- playToastSound();
112
- return originalToast.loading(message, { duration: currentDuration, ...options });
251
+ const id = originalToast.loading(message, { duration: currentDuration, ...options });
252
+ scheduleToastSound();
253
+ return id;
113
254
  },
114
255
  promise: <T,>(
115
256
  promise: Promise<T>,
@@ -120,8 +261,9 @@
120
261
  },
121
262
  opts?: DefaultToastOptions
122
263
  ) => {
123
- playToastSound();
124
- return originalToast.promise(promise, msgs, opts);
264
+ const out = originalToast.promise(promise, msgs, opts);
265
+ scheduleToastSound();
266
+ return out;
125
267
  },
126
268
  dismiss: originalToast.dismiss.bind(originalToast),
127
269
  remove: originalToast.remove.bind(originalToast),
@@ -154,7 +296,8 @@
154
296
  expand = false,
155
297
  gap = 8,
156
298
  offset = '32px',
157
- fireWithSound = false
299
+ fireWithSound = false,
300
+ soundPreset = 'chime'
158
301
  }: ToasterProps = $props();
159
302
 
160
303
  $effect(() => {
@@ -162,7 +305,7 @@
162
305
  void theme;
163
306
  void richColors;
164
307
  void customIcons;
165
- updateToastConfig({ duration, fireWithSound });
308
+ updateToastConfig({ duration, fireWithSound, soundPreset });
166
309
  });
167
310
  </script>
168
311
 
@@ -4,6 +4,7 @@ export { resolveValue };
4
4
  export type { DefaultToastOptions, IconTheme, Toast, ToastOptions, ToastPosition, ToastType, Renderable, ValueFunction, ValueOrFunction } from 'svelte-french-toast';
5
5
  export type CustomToastOptions = ToastOptions;
6
6
  export type ToastTheme = Record<string, never>;
7
+ export type ToastSoundPreset = 'chime' | 'ding' | 'bell' | 'soft' | 'pop' | 'pulse' | 'airy';
7
8
  export interface ToasterProps {
8
9
  position?: ToastPosition;
9
10
  duration?: number;
@@ -13,6 +14,8 @@ export interface ToasterProps {
13
14
  containerStyle?: string;
14
15
  containerClassName?: string;
15
16
  fireWithSound?: boolean;
17
+ /** Web Audio preset when `fireWithSound` is true. Default `chime`. */
18
+ soundPreset?: ToastSoundPreset;
16
19
  className?: string;
17
20
  theme?: ToastTheme;
18
21
  richColors?: boolean;
@@ -27,6 +30,7 @@ export interface ToasterProps {
27
30
  export declare function updateToastConfig(config: {
28
31
  duration?: number;
29
32
  fireWithSound?: boolean;
33
+ soundPreset?: ToastSoundPreset;
30
34
  theme?: ToastTheme;
31
35
  richColors?: boolean;
32
36
  }): void;
@@ -1,2 +1,2 @@
1
1
  export { default as Toaster, toast, originalToast, updateToastConfig } from './Toast.svelte';
2
- export type { ToasterProps, ToastType, CustomToastOptions, ToastTheme, ToastOptions } from './Toast.svelte';
2
+ export type { ToasterProps, ToastSoundPreset, ToastType, CustomToastOptions, ToastTheme, ToastOptions } from './Toast.svelte';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rkosafo/cai.components",
3
- "version": "0.0.81",
3
+ "version": "0.0.83",
4
4
  "files": [
5
5
  "dist",
6
6
  "!dist/**/*.test.*",