odj-svelte-ui 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,11 +18,20 @@ This is a fork from [Flowbite for Svelte 5 with Runes](https://svelte-5-ui-lib.c
18
18
  - `Label` now has `space-y-1` by default, a new default color and the `disabled` prop;
19
19
  - `Input:Search` has a better X button for Chromium browsers;
20
20
  - `Radio` has a new design and it's animated;
21
+ - `Header` has blur, some small design tweaks and a fixed design for the menu on mobile;
22
+ - `Dropdown` is more modern;
23
+ - `Avatar` has better borders;
24
+ - `Sidebar` has better hover colors and some other design tweaks, like border radius;
21
25
  - `Tabs` styles are fixed and introduced underline animations and a complete modern redesign for "Full" style;
22
26
  - The `Tooltip` component received a rework;
23
27
  - `Modal` has <kbd>Esc</kbd> to close again;
24
28
  - `Button` has now a built-in loading state and can be controlled by the `loading` prop;
25
29
  - `Textarea` can autoexpand as user type, control this by `autoexpand` and `maxRows` props;
30
+ - `Dropdown` now locks the page scroll and you can disable this default behaviour setting `lock` to `false`;
31
+ - `Avatar` supports a `fallback` snippet to show when the image is loading or can't be loaded;
32
+ - `Sidebar` can not be opened or closed anymore. If you want this behaviour, this component should be inside the `Drawer` component. On mobile, `Sidebar` will look like tabs;
33
+ - `SidebarButton` has been removed. Please use the `Drawer` component to maintain the old sidebar behaviour;
34
+
26
35
 
27
36
  ## Installation
28
37
 
@@ -1,10 +1,11 @@
1
1
  <script lang="ts">
2
2
  import { Indicator } from "..";
3
- import { type AvatarProps as Props, avatar } from ".";
3
+ import { onMount } from "svelte";
4
+ import { type AvatarProps as Props, avatar, fallback as fallbackTheme } from ".";
4
5
 
5
- let { children, src, href, target, cornerStyle = "circular", border = false, stacked = false, dot, class: className, alt, size = "md", onclick, ...restProps }: Props = $props();
6
+ let { children, src, href, target, cornerStyle = "circular", border = false, stacked = false, dot, class: className, alt, size = "md", onclick, fallback, fallbackClass: fallbackClassName, ...restProps }: Props = $props();
6
7
 
7
- dot = dot && { placement: "top-right", color: "gray", size: "lg", ...dot };
8
+ dot = dot && { placement: "top-right", color: "red", size: "lg", ...dot };
8
9
 
9
10
  let avatarClass = $derived(
10
11
  avatar({
@@ -15,12 +16,43 @@
15
16
  className
16
17
  })
17
18
  );
19
+ let fallbackClass = $derived(
20
+ fallbackTheme({
21
+ cornerStyle,
22
+ border,
23
+ stacked,
24
+ size,
25
+ className: fallbackClassName
26
+ })
27
+ );
28
+
29
+ let imageState: "loading" | "loaded" | "error" = $state("loading");
30
+ onMount(() => {
31
+ const img = new Image();
32
+ if (!src) return;
33
+
34
+ img.src = src;
35
+ imageState = "loading";
36
+
37
+ img.onload = () => {
38
+ imageState = "loaded";
39
+ };
40
+ img.onerror = () => {
41
+ imageState = "error";
42
+ };
43
+ });
18
44
  </script>
19
45
 
20
46
  {#if !src || !!href || children || dot}
21
47
  <svelte:element this={href ? "a" : "div"} role={href ? undefined : "button"} {onclick} {href} {target} {...restProps} class={avatarClass}>
22
48
  {#if src}
23
- <img {alt} {src} class={cornerStyle === "circular" ? "rounded-full" : "rounded-sm"} />
49
+ {#if fallback && imageState !== "loaded"}
50
+ <div class={fallbackClass}>
51
+ {@render fallback()}
52
+ </div>
53
+ {:else}
54
+ <img {alt} {src} class={cornerStyle === "circular" ? "rounded-full" : "rounded-sm"} />
55
+ {/if}
24
56
  {:else if children}
25
57
  {@render children()}
26
58
  {:else}
@@ -32,6 +64,10 @@
32
64
  <Indicator border offset={cornerStyle === "circular" ? true : false} {...dot} />
33
65
  {/if}
34
66
  </svelte:element>
67
+ {:else if fallback && imageState !== "loaded"}
68
+ <div class={fallbackClass}>
69
+ {@render fallback()}
70
+ </div>
35
71
  {:else}
36
72
  <img {alt} {src} {...restProps} class={avatarClass} />
37
73
  {/if}
@@ -40,7 +76,8 @@
40
76
  @component
41
77
  [Go to docs](https://svelte-5-ui-lib.codewithshin.com/)
42
78
  ## Props
43
- @props: children: any;
79
+ @props:children: any;
80
+ @props:fallback: any;
44
81
  @props:src: any;
45
82
  @props:href: any;
46
83
  @props:target: any;
@@ -49,6 +86,7 @@
49
86
  @props:stacked: any = false;
50
87
  @props:dot: any;
51
88
  @props:class: string;
89
+ @props:fallbackClass: string;
52
90
  @props:alt: any;
53
91
  @props:size: any = "md";
54
92
  @props:onclick: any;
@@ -2,7 +2,8 @@ import { type AvatarProps as Props } from ".";
2
2
  /**
3
3
  * [Go to docs](https://svelte-5-ui-lib.codewithshin.com/)
4
4
  * ## Props
5
- * @props: children: any;
5
+ * @props:children: any;
6
+ * @props:fallback: any;
6
7
  * @props:src: any;
7
8
  * @props:href: any;
8
9
  * @props:target: any;
@@ -11,6 +12,7 @@ import { type AvatarProps as Props } from ".";
11
12
  * @props:stacked: any = false;
12
13
  * @props:dot: any;
13
14
  * @props:class: string;
15
+ * @props:fallbackClass: string;
14
16
  * @props:alt: any;
15
17
  * @props:size: any = "md";
16
18
  * @props:onclick: any;
@@ -1,4 +1,4 @@
1
1
  import type { AvatarProps } from "./type";
2
2
  import Avatar from "./Avatar.svelte";
3
- import { avatar } from "./theme";
4
- export { Avatar, avatar, type AvatarProps };
3
+ import { avatar, fallback } from "./theme";
4
+ export { Avatar, avatar, fallback, type AvatarProps };
@@ -1,3 +1,3 @@
1
1
  import Avatar from "./Avatar.svelte";
2
- import { avatar } from "./theme";
3
- export { Avatar, avatar };
2
+ import { avatar, fallback } from "./theme";
3
+ export { Avatar, avatar, fallback };
@@ -18,7 +18,7 @@ declare const avatar: import("tailwind-variants").TVReturnType<{
18
18
  lg: string;
19
19
  xl: string;
20
20
  };
21
- }, undefined, "relative flex items-center justify-center bg-gray-100 dark:bg-gray-600 text-gray-600 dark:text-gray-300", import("tailwind-variants/dist/config").TVConfig<{
21
+ }, undefined, "relative flex items-center justify-center box-content bg-light-surface-100 dark:bg-dark-surface-600 text-light-surface-600 dark:text-dark-surface-300", import("tailwind-variants/dist/config").TVConfig<{
22
22
  cornerStyle: {
23
23
  rounded: string;
24
24
  circular: string;
@@ -98,7 +98,7 @@ declare const avatar: import("tailwind-variants").TVReturnType<{
98
98
  lg: string;
99
99
  xl: string;
100
100
  };
101
- }, undefined, "relative flex items-center justify-center bg-gray-100 dark:bg-gray-600 text-gray-600 dark:text-gray-300", import("tailwind-variants/dist/config").TVConfig<{
101
+ }, undefined, "relative flex items-center justify-center box-content bg-light-surface-100 dark:bg-dark-surface-600 text-light-surface-600 dark:text-dark-surface-300", import("tailwind-variants/dist/config").TVConfig<{
102
102
  cornerStyle: {
103
103
  rounded: string;
104
104
  circular: string;
@@ -139,4 +139,145 @@ declare const avatar: import("tailwind-variants").TVReturnType<{
139
139
  xl: string;
140
140
  };
141
141
  }>, unknown, unknown, undefined>>;
142
- export { avatar };
142
+ declare const fallback: import("tailwind-variants").TVReturnType<{
143
+ cornerStyle: {
144
+ rounded: string;
145
+ circular: string;
146
+ };
147
+ border: {
148
+ true: string;
149
+ false: string;
150
+ };
151
+ stacked: {
152
+ true: string;
153
+ false: string;
154
+ };
155
+ size: {
156
+ xs: string;
157
+ sm: string;
158
+ md: string;
159
+ lg: string;
160
+ xl: string;
161
+ };
162
+ }, undefined, "relative flex items-center justify-center box-content bg-light-surface-100 dark:bg-dark-surface-600 text-light-surface-600 dark:text-dark-surface-300 uppercase", import("tailwind-variants/dist/config").TVConfig<{
163
+ cornerStyle: {
164
+ rounded: string;
165
+ circular: string;
166
+ };
167
+ border: {
168
+ true: string;
169
+ false: string;
170
+ };
171
+ stacked: {
172
+ true: string;
173
+ false: string;
174
+ };
175
+ size: {
176
+ xs: string;
177
+ sm: string;
178
+ md: string;
179
+ lg: string;
180
+ xl: string;
181
+ };
182
+ }, {
183
+ cornerStyle: {
184
+ rounded: string;
185
+ circular: string;
186
+ };
187
+ border: {
188
+ true: string;
189
+ false: string;
190
+ };
191
+ stacked: {
192
+ true: string;
193
+ false: string;
194
+ };
195
+ size: {
196
+ xs: string;
197
+ sm: string;
198
+ md: string;
199
+ lg: string;
200
+ xl: string;
201
+ };
202
+ }>, {
203
+ cornerStyle: {
204
+ rounded: string;
205
+ circular: string;
206
+ };
207
+ border: {
208
+ true: string;
209
+ false: string;
210
+ };
211
+ stacked: {
212
+ true: string;
213
+ false: string;
214
+ };
215
+ size: {
216
+ xs: string;
217
+ sm: string;
218
+ md: string;
219
+ lg: string;
220
+ xl: string;
221
+ };
222
+ }, undefined, import("tailwind-variants").TVReturnType<{
223
+ cornerStyle: {
224
+ rounded: string;
225
+ circular: string;
226
+ };
227
+ border: {
228
+ true: string;
229
+ false: string;
230
+ };
231
+ stacked: {
232
+ true: string;
233
+ false: string;
234
+ };
235
+ size: {
236
+ xs: string;
237
+ sm: string;
238
+ md: string;
239
+ lg: string;
240
+ xl: string;
241
+ };
242
+ }, undefined, "relative flex items-center justify-center box-content bg-light-surface-100 dark:bg-dark-surface-600 text-light-surface-600 dark:text-dark-surface-300 uppercase", import("tailwind-variants/dist/config").TVConfig<{
243
+ cornerStyle: {
244
+ rounded: string;
245
+ circular: string;
246
+ };
247
+ border: {
248
+ true: string;
249
+ false: string;
250
+ };
251
+ stacked: {
252
+ true: string;
253
+ false: string;
254
+ };
255
+ size: {
256
+ xs: string;
257
+ sm: string;
258
+ md: string;
259
+ lg: string;
260
+ xl: string;
261
+ };
262
+ }, {
263
+ cornerStyle: {
264
+ rounded: string;
265
+ circular: string;
266
+ };
267
+ border: {
268
+ true: string;
269
+ false: string;
270
+ };
271
+ stacked: {
272
+ true: string;
273
+ false: string;
274
+ };
275
+ size: {
276
+ xs: string;
277
+ sm: string;
278
+ md: string;
279
+ lg: string;
280
+ xl: string;
281
+ };
282
+ }>, unknown, unknown, undefined>>;
283
+ export { avatar, fallback };
@@ -1,17 +1,17 @@
1
1
  import { tv } from "tailwind-variants";
2
2
  const avatar = tv({
3
- base: "relative flex items-center justify-center bg-gray-100 dark:bg-gray-600 text-gray-600 dark:text-gray-300",
3
+ base: "relative flex items-center justify-center box-content bg-light-surface-100 dark:bg-dark-surface-600 text-light-surface-600 dark:text-dark-surface-300",
4
4
  variants: {
5
5
  cornerStyle: {
6
6
  rounded: "rounded-sm",
7
7
  circular: "rounded-full"
8
8
  },
9
9
  border: {
10
- true: "p-1 ring-2 ring-gray-300 dark:ring-gray-500",
10
+ true: "border-2 border-light-surface-300 dark:border-dark-surface-500",
11
11
  false: ""
12
12
  },
13
13
  stacked: {
14
- true: "border-2 -ms-4 border-white dark:border-gray-800",
14
+ true: "border-2 -ms-4 border-white dark:border-dark-surface-800",
15
15
  false: ""
16
16
  },
17
17
  size: {
@@ -29,4 +29,34 @@ const avatar = tv({
29
29
  size: "md"
30
30
  }
31
31
  });
32
- export { avatar };
32
+ const fallback = tv({
33
+ base: "relative flex items-center justify-center box-content bg-light-surface-100 dark:bg-dark-surface-600 text-light-surface-600 dark:text-dark-surface-300 uppercase",
34
+ variants: {
35
+ cornerStyle: {
36
+ rounded: "rounded-sm",
37
+ circular: "rounded-full"
38
+ },
39
+ border: {
40
+ true: "border-2 border-light-surface-300 dark:border-dark-surface-500",
41
+ false: ""
42
+ },
43
+ stacked: {
44
+ true: "border-2 -ms-4 border-white dark:border-dark-surface-800",
45
+ false: ""
46
+ },
47
+ size: {
48
+ xs: "w-6 h-6",
49
+ sm: "w-8 h-8",
50
+ md: "w-10 h-10",
51
+ lg: "w-20 h-20",
52
+ xl: "w-36 h-36"
53
+ }
54
+ },
55
+ defaultVariants: {
56
+ cornerStyle: "circular",
57
+ border: false,
58
+ stacked: false,
59
+ size: "md"
60
+ }
61
+ });
62
+ export { avatar, fallback };
@@ -12,5 +12,7 @@ interface AvatarProps extends HTMLAttributes<HTMLDivElement> {
12
12
  size?: "xs" | "sm" | "md" | "lg" | "xl";
13
13
  onclick?: () => void;
14
14
  border?: boolean;
15
+ fallback?: Snippet;
16
+ fallbackClass?: string;
15
17
  }
16
18
  export { type AvatarProps };
@@ -5,7 +5,7 @@
5
5
  import { setContext } from "svelte";
6
6
  import { writable } from "svelte/store";
7
7
 
8
- let { children, dropdownStatus = $bindable(), closeDropdown, class: className, backdropClass, params, transition = fly, activeUrl = "", ...restProps }: Props = $props();
8
+ let { children, dropdownStatus = $bindable(), closeDropdown, class: className, backdropClass, params = { y: -5 }, transition = fly, activeUrl = "", lock = true, ...restProps }: Props = $props();
9
9
 
10
10
  const { base, backdrop } = $derived(dropdown());
11
11
  const activeUrlStore = writable("");
@@ -14,6 +14,17 @@
14
14
  $effect(() => {
15
15
  activeUrlStore.set(activeUrl ?? "");
16
16
  });
17
+
18
+ $effect(() => {
19
+ if (dropdownStatus && lock) {
20
+ const scrollWidth = window.innerWidth - document.documentElement.clientWidth;
21
+ document.body.style.overflow = "hidden";
22
+ document.body.style.paddingRight = `${scrollWidth}px`;
23
+ } else if (lock) {
24
+ document.body.style.overflow = "";
25
+ document.body.style.paddingRight = "";
26
+ }
27
+ });
17
28
  </script>
18
29
 
19
30
  <!-- Dropdown menu -->
@@ -2,12 +2,11 @@
2
2
  import { getContext } from "svelte";
3
3
  import { type DropdownLiProps as Props, dropdownli } from "./";
4
4
 
5
- let { aClass, children, href, activeClass, liClass, ...restProps }: Props = $props();
5
+ let { aClass, children, href, activeClass, liClass, custom = false, ...restProps }: Props = $props();
6
6
 
7
7
  const activeUrlStore = getContext("activeUrl") as { subscribe: (callback: (value: string) => void) => void };
8
8
  let sidebarUrl = $state("");
9
9
  activeUrlStore.subscribe((value) => {
10
- // console.log('value: ', value)
11
10
  sidebarUrl = value;
12
11
  });
13
12
  let active = $state(false);
@@ -23,8 +22,14 @@
23
22
  <a {href} {...restProps} class={active ? activeAnchor({ class: activeClass }) : anchor({ class: aClass })}>
24
23
  {@render children()}
25
24
  </a>
25
+ {:else if custom}
26
+ <button {...restProps} class={active ? activeAnchor({ class: activeClass }) : anchor({ class: aClass })}>
27
+ {@render children()}
28
+ </button>
26
29
  {:else}
27
- {@render children()}
30
+ <a {href} {...restProps} class={active ? activeAnchor({ class: activeClass }) : anchor({ class: aClass })}>
31
+ {@render children()}
32
+ </a>
28
33
  {/if}
29
34
  </li>
30
35
 
@@ -37,4 +42,5 @@
37
42
  @props:href: any;
38
43
  @props:activeClass: any;
39
44
  @props:liClass: any;
45
+ @props:custom: boolean;
40
46
  -->
@@ -7,6 +7,7 @@ import { type DropdownLiProps as Props } from "./";
7
7
  * @props:href: any;
8
8
  * @props:activeClass: any;
9
9
  * @props:liClass: any;
10
+ * @props:custom: boolean;
10
11
  */
11
12
  declare const DropdownLi: import("svelte").Component<Props, {}, "">;
12
13
  type DropdownLi = ReturnType<typeof DropdownLi>;
@@ -43,9 +43,9 @@ export declare const dropdown: import("tailwind-variants").TVReturnType<{
43
43
  };
44
44
  };
45
45
  } | {}>, unknown, unknown, undefined>>;
46
- export declare const dropdowndivider: import("tailwind-variants").TVReturnType<{} | {} | {}, undefined, "my-1 h-px bg-gray-100 dark:bg-gray-500", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, {} | {}, undefined, import("tailwind-variants").TVReturnType<unknown, undefined, "my-1 h-px bg-gray-100 dark:bg-gray-500", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, unknown, unknown, undefined>>;
47
- export declare const dropdownHeader: import("tailwind-variants").TVReturnType<{} | {} | {}, undefined, "px-4 py-3 text-sm text-gray-900 dark:text-white", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, {} | {}, undefined, import("tailwind-variants").TVReturnType<unknown, undefined, "px-4 py-3 text-sm text-gray-900 dark:text-white", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, unknown, unknown, undefined>>;
48
- export declare const dropdownFooter: import("tailwind-variants").TVReturnType<{} | {} | {}, undefined, "overflow-hidden rounded-b-lg py-1", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, {} | {}, undefined, import("tailwind-variants").TVReturnType<unknown, undefined, "overflow-hidden rounded-b-lg py-1", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, unknown, unknown, undefined>>;
46
+ export declare const dropdowndivider: import("tailwind-variants").TVReturnType<{} | {} | {}, undefined, "my-1 h-px bg-light-surface-200 dark:bg-dark-surface-600", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, {} | {}, undefined, import("tailwind-variants").TVReturnType<unknown, undefined, "my-1 h-px bg-light-surface-200 dark:bg-dark-surface-600", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, unknown, unknown, undefined>>;
47
+ export declare const dropdownHeader: import("tailwind-variants").TVReturnType<{} | {} | {}, undefined, "px-4 py-3 rounded-t-xl text-sm text-light-surface-900 dark:text-white", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, {} | {}, undefined, import("tailwind-variants").TVReturnType<unknown, undefined, "px-4 py-3 rounded-t-xl text-sm text-light-surface-900 dark:text-white", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, unknown, unknown, undefined>>;
48
+ export declare const dropdownFooter: import("tailwind-variants").TVReturnType<{} | {} | {}, undefined, "overflow-hidden rounded-b-xl", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, {} | {}, undefined, import("tailwind-variants").TVReturnType<unknown, undefined, "overflow-hidden rounded-b-xl", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, unknown, unknown, undefined>>;
49
49
  export declare const dropdownli: import("tailwind-variants").TVReturnType<{
50
50
  [key: string]: {
51
51
  [key: string]: import("tailwind-variants").ClassValue | {
@@ -91,4 +91,4 @@ export declare const dropdownli: import("tailwind-variants").TVReturnType<{
91
91
  };
92
92
  };
93
93
  } | {}>, unknown, unknown, undefined>>;
94
- export declare const dropdownul: import("tailwind-variants").TVReturnType<{} | {} | {}, undefined, "py-2 text-sm text-gray-700 dark:text-gray-200", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, {} | {}, undefined, import("tailwind-variants").TVReturnType<unknown, undefined, "py-2 text-sm text-gray-700 dark:text-gray-200", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, unknown, unknown, undefined>>;
94
+ export declare const dropdownul: import("tailwind-variants").TVReturnType<{} | {} | {}, undefined, "p-1 flex flex-col", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, {} | {}, undefined, import("tailwind-variants").TVReturnType<unknown, undefined, "p-1 flex flex-col", import("tailwind-variants/dist/config").TVConfig<unknown, {} | {}>, unknown, unknown, undefined>>;
@@ -1,25 +1,25 @@
1
1
  import { tv } from "tailwind-variants";
2
2
  export const dropdown = tv({
3
3
  slots: {
4
- base: "z-10 w-44 mt-2 divide-y divide-gray-300 dark:divide-gray-500 overflow-hidden rounded-lg bg-white shadow-sm dark:bg-gray-700",
4
+ base: "z-10 w-max mt-2 rounded-xl shadow-lg bg-white dark:bg-dark-surface-700 text-light-surface-700 dark:text-dark-surface-200 border border-light-surface-200 dark:border-dark-surface-600 divide-y divide-light-surface-100 dark:divide-dark-surface-600 overflow-hidden",
5
5
  backdrop: "fixed top-0 start-0 w-full h-full"
6
6
  }
7
7
  });
8
8
  export const dropdowndivider = tv({
9
- base: "my-1 h-px bg-gray-100 dark:bg-gray-500"
9
+ base: "my-1 h-px bg-light-surface-200 dark:bg-dark-surface-600"
10
10
  });
11
11
  export const dropdownHeader = tv({
12
- base: "px-4 py-3 text-sm text-gray-900 dark:text-white"
12
+ base: "px-4 py-3 rounded-t-xl text-sm text-light-surface-900 dark:text-white"
13
13
  });
14
14
  export const dropdownFooter = tv({
15
- base: "overflow-hidden rounded-b-lg py-1"
15
+ base: "overflow-hidden rounded-b-xl"
16
16
  });
17
17
  export const dropdownli = tv({
18
18
  slots: {
19
- anchor: "block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white",
20
- activeAnchor: "block px-4 py-2 text-primary-700 dark:text-primary-600 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
19
+ anchor: "cursor-pointer flex flex-row gap-3 items-center py-2 px-3 rounded-lg text-sm hover:bg-light-surface-200/70 dark:hover:bg-dark-surface-600 hover:text-light-surface-900 dark:hover:text-white",
20
+ activeAnchor: "cursor-pointer flex flex-row gap-3 items-center py-2 px-3 rounded-lg text-sm bg-primary-700 dark:bg-primary-600 text-white dark:text-white hover:bg-primary-800 dark:hover:bg-primary-700"
21
21
  }
22
22
  });
23
23
  export const dropdownul = tv({
24
- base: "py-2 text-sm text-gray-700 dark:text-gray-200"
24
+ base: "p-1 flex flex-col"
25
25
  });
@@ -13,6 +13,7 @@ interface DropdownProps extends HTMLAttributes<HTMLDivElement> {
13
13
  params?: ParamsType;
14
14
  transition?: TransitionFunc;
15
15
  activeUrl?: string;
16
+ lock?: boolean;
16
17
  }
17
18
  interface DropdownDividerProps extends HTMLAttributes<HTMLDivElement> {
18
19
  class?: string;
@@ -29,6 +30,7 @@ interface DropdownLiProps extends HTMLAnchorAttributes {
29
30
  href?: string;
30
31
  activeClass?: string;
31
32
  liClass?: string;
33
+ custom?: boolean;
32
34
  }
33
35
  interface DropdownUlProps extends HTMLAttributes<HTMLUListElement> {
34
36
  children: Snippet;
@@ -2,24 +2,53 @@
2
2
  import Label from "../label/Label.svelte";
3
3
  import { type CheckboxProps as Props, checkbox } from ".";
4
4
 
5
- let { children, aria_describedby, color = "primary", custom, inline, tinted, rounded, group = $bindable([]), choices = [], checked = $bindable(false), classLabel, indeterminate, class: className, ...restProps }: Props = $props();
5
+ let { children, aria_describedby, color = "primary", custom, inline, tinted, rounded, group = $bindable([]), choices = [], checked = $bindable(false), classLabel, indeterminate, class: className, disabled = false, ...restProps }: Props = $props();
6
6
 
7
7
  const { base, label } = $derived(checkbox({ color, tinted, custom, rounded, inline }));
8
8
  </script>
9
9
 
10
+ <style>
11
+ [type="checkbox"]:checked {
12
+ background-image: url("data:image/svg+xml,%3csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 12'%3e %3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M1 5.917 5.724 10.5 15 1.5'/%3e %3c/svg%3e");
13
+ background-color: currentColor;
14
+ border-color: transparent;
15
+ background-position: center;
16
+ background-repeat: no-repeat;
17
+ background-size: 0.55em 0.55em;
18
+ -webkit-print-color-adjust: exact;
19
+ print-color-adjust: exact;
20
+ }
21
+
22
+ .dark [type="radio"]:checked {
23
+ background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e");
24
+ background-size: 1em 1em;
25
+ }
26
+
27
+ [type="checkbox"]:indeterminate {
28
+ background-image: url("data:image/svg+xml,%3csvg aria-hidden='true' xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 12'%3e %3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M0.5 6h14'/%3e %3c/svg%3e");
29
+ background-color: currentColor;
30
+ border-color: transparent;
31
+ background-position: center;
32
+ background-repeat: no-repeat;
33
+ background-size: 0.55em 0.55em;
34
+ -webkit-print-color-adjust: exact;
35
+ print-color-adjust: exact;
36
+ }
37
+ </style>
38
+
10
39
  {#if choices.length > 0}
11
40
  {#each choices as { value, checkboxLabel }, i}
12
- <Label class={label({ class: classLabel })} for={`checkbox-${i}`}>
41
+ <Label class={label({ class: classLabel })} for={`checkbox-${i}`} {disabled}>
13
42
  {checkboxLabel}
14
- <input id={`checkbox-${i}`} type="checkbox" {value} bind:group {...restProps} class={base({ class: className })} />
43
+ <input id={`checkbox-${i}`} type="checkbox" {value} bind:group {disabled} {...restProps} class={base({ class: className })} />
15
44
  {#if children}
16
45
  {@render children()}
17
46
  {/if}
18
47
  </Label>
19
48
  {/each}
20
49
  {:else}
21
- <Label class={label({ class: classLabel })}>
22
- <input type="checkbox" bind:checked aria-describedby={aria_describedby} {indeterminate} {...restProps} class={base({ class: className })} />
50
+ <Label class={label({ class: classLabel })} {disabled}>
51
+ <input type="checkbox" bind:checked aria-describedby={aria_describedby} {indeterminate} {disabled} {...restProps} class={base({ class: className })} />
23
52
  {#if children}
24
53
  {@render children()}
25
54
  {/if}