uisv 0.0.22 → 0.0.24

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.
Files changed (57) hide show
  1. package/dist/components/accordion.svelte +6 -19
  2. package/dist/components/alert.svelte +58 -55
  3. package/dist/components/alert.svelte.d.ts +2 -2
  4. package/dist/components/app.svelte +28 -22
  5. package/dist/components/app.svelte.d.ts +2 -9
  6. package/dist/components/badge.svelte +16 -16
  7. package/dist/components/badge.svelte.d.ts +4 -2
  8. package/dist/components/banner.svelte +11 -15
  9. package/dist/components/banner.svelte.d.ts +2 -2
  10. package/dist/components/breadcrumb.svelte +3 -4
  11. package/dist/components/breadcrumb.svelte.d.ts +1 -1
  12. package/dist/components/button.svelte +10 -8
  13. package/dist/components/card.svelte +1 -1
  14. package/dist/components/checkbox-group.svelte +3 -5
  15. package/dist/components/checkbox-group.svelte.d.ts +3 -3
  16. package/dist/components/checkbox.svelte +12 -22
  17. package/dist/components/checkbox.svelte.d.ts +4 -5
  18. package/dist/components/collapsible.svelte +3 -1
  19. package/dist/components/index.d.ts +5 -0
  20. package/dist/components/index.js +5 -0
  21. package/dist/components/input-number.svelte +3 -2
  22. package/dist/components/input.svelte +9 -18
  23. package/dist/components/kbd.svelte +8 -8
  24. package/dist/components/modal.svelte +2 -2
  25. package/dist/components/navigation-menu.svelte +416 -0
  26. package/dist/components/navigation-menu.svelte.d.ts +20 -0
  27. package/dist/components/progress.svelte +42 -7
  28. package/dist/components/progress.svelte.d.ts +3 -2
  29. package/dist/components/radio-group.svelte +102 -0
  30. package/dist/components/radio-group.svelte.d.ts +27 -0
  31. package/dist/components/select.svelte +19 -11
  32. package/dist/components/select.svelte.d.ts +5 -6
  33. package/dist/components/seperator.svelte +1 -1
  34. package/dist/components/switch.svelte +2 -1
  35. package/dist/components/tabs.svelte +3 -13
  36. package/dist/components/tabs.svelte.d.ts +1 -1
  37. package/dist/components/toast.svelte +173 -0
  38. package/dist/components/toast.svelte.d.ts +8 -0
  39. package/dist/components/toast.svelte.js +11 -0
  40. package/dist/contexts.d.ts +10 -3
  41. package/dist/contexts.js +2 -2
  42. package/dist/index.d.ts +1 -2
  43. package/dist/index.js +1 -2
  44. package/dist/utilities/index.d.ts +5 -0
  45. package/dist/utilities/index.js +5 -0
  46. package/dist/utilities/isComponent.d.ts +7 -0
  47. package/dist/utilities/isComponent.js +10 -0
  48. package/dist/utilities/isSnippet.d.ts +7 -0
  49. package/dist/utilities/isSnippet.js +8 -0
  50. package/dist/utilities/useElementRects.svelte.d.ts +11 -0
  51. package/dist/{utilities.svelte.js → utilities/useElementRects.svelte.js} +0 -38
  52. package/dist/utilities/useRafFn.svelte.d.ts +43 -0
  53. package/dist/utilities/useRafFn.svelte.js +56 -0
  54. package/dist/utilities/useStyle.svelte.d.ts +8 -0
  55. package/dist/utilities/useStyle.svelte.js +21 -0
  56. package/package.json +37 -27
  57. package/dist/utilities.svelte.d.ts +0 -31
@@ -4,6 +4,7 @@
4
4
  import type { Component, Snippet } from 'svelte';
5
5
  import { tv, type ClassValue } from 'tailwind-variants';
6
6
  import Icon from './icon.svelte';
7
+ import { getAppContext } from '../contexts.js';
7
8
 
8
9
  export type SelectItem<T> =
9
10
  | T
@@ -16,7 +17,6 @@
16
17
 
17
18
  export type SelectProps<T> = {
18
19
  items: (SelectItem<T> | SelectItem<T>[])[];
19
- defaultvalue?: T;
20
20
  item?: Snippet<[{ item: SelectItem<T> }]>;
21
21
  color?: PropColor;
22
22
  size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
@@ -56,20 +56,19 @@
56
56
  );
57
57
  </script>
58
58
 
59
- <script lang="ts" generics="T extends unknown">
59
+ <script lang="ts" generics="T">
60
60
  let {
61
61
  value = $bindable(),
62
62
  items,
63
63
  type = 'single',
64
- defaultvalue,
65
- item,
64
+ item: item_snippet,
66
65
  color = 'primary',
67
66
  size = 'md',
68
67
  variant = 'outline',
69
68
  highlight,
70
69
  placeholder,
71
70
  ui = {},
72
- dropdownicon = 'i-lucide:chevron-down',
71
+ dropdownicon = getAppContext().icons.chevrondown,
73
72
  }: SelectProps<T> = $props();
74
73
 
75
74
  const variants = $derived(
@@ -109,7 +108,7 @@
109
108
  itemLeadingChip: 'shrink-0',
110
109
  itemLeadingChipSize: '',
111
110
  itemTrailing: 'ms-auto inline-flex gap-1.5 items-center',
112
- itemTrailingIcon: 'shrink-0',
111
+ itemtrailingicon: 'shrink-0',
113
112
  itemWrapper: 'flex-1 flex flex-col min-w-0',
114
113
  itemLabel: 'truncate',
115
114
  itemDescription: 'truncate text-label-muted',
@@ -425,11 +424,20 @@
425
424
  </Select.Group>
426
425
  {:else}
427
426
  {@const is_object = typeof item === 'object' && item !== null && 'value' in item}
428
- <Select.Item
429
- class={variants.item({ class: ui.item })}
430
- value={(is_object ? item.value : item) as string}
431
- >
432
- {item}
427
+ {@const item_value = is_object ? item.value : item}
428
+ {@const item_selected = item_value === value}
429
+
430
+ <Select.Item class={variants.item({ class: ui.item })} value={item_value as string}>
431
+ {#if item_snippet}
432
+ {@render item_snippet({ item })}
433
+ {:else}
434
+ {item}
435
+
436
+ <Icon
437
+ name={getAppContext().icons.check}
438
+ class={['ml-auto', !item_selected && 'opacity-0']}
439
+ />
440
+ {/if}
433
441
  </Select.Item>
434
442
  {/if}
435
443
  {/each}
@@ -10,7 +10,6 @@ export type SelectItem<T> = T | {
10
10
  };
11
11
  export type SelectProps<T> = {
12
12
  items: (SelectItem<T> | SelectItem<T>[])[];
13
- defaultvalue?: T;
14
13
  item?: Snippet<[{
15
14
  item: SelectItem<T>;
16
15
  }]>;
@@ -47,14 +46,14 @@ export type SelectProps<T> = {
47
46
  value?: T[];
48
47
  type?: 'multiple';
49
48
  });
50
- declare function $$render<T extends unknown>(): {
49
+ declare function $$render<T>(): {
51
50
  props: SelectProps<T>;
52
51
  exports: {};
53
52
  bindings: "value";
54
53
  slots: {};
55
54
  events: {};
56
55
  };
57
- declare class __sveltets_Render<T extends unknown> {
56
+ declare class __sveltets_Render<T> {
58
57
  props(): ReturnType<typeof $$render<T>>['props'];
59
58
  events(): ReturnType<typeof $$render<T>>['events'];
60
59
  slots(): ReturnType<typeof $$render<T>>['slots'];
@@ -62,12 +61,12 @@ declare class __sveltets_Render<T extends unknown> {
62
61
  exports(): {};
63
62
  }
64
63
  interface $$IsomorphicComponent {
65
- new <T extends unknown>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
64
+ new <T>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
66
65
  $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
67
66
  } & ReturnType<__sveltets_Render<T>['exports']>;
68
- <T extends unknown>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
67
+ <T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
69
68
  z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
70
69
  }
71
70
  declare const Select: $$IsomorphicComponent;
72
- type Select<T extends unknown> = InstanceType<typeof Select<T>>;
71
+ type Select<T> = InstanceType<typeof Select<T>>;
73
72
  export default Select;
@@ -198,7 +198,7 @@
198
198
  {:else if typeof label === 'string' && label.length > 0}
199
199
  <span class={variants.label({ class: ui.label })}>{label}</span>
200
200
  {:else if isSnippet(label)}
201
- {@render label()}
201
+ {@render label(variants.label({ class: ui.label }))}
202
202
  {:else if isComponent(label)}
203
203
  {@const Label = label}
204
204
  <Label class={variants.label({ class: ui.label })} />
@@ -1,4 +1,5 @@
1
1
  <script module lang="ts">
2
+ import { getAppContext } from '../contexts.js';
2
3
  import { type PropColor, Icon } from '../index.js';
3
4
  import type { Snippet, Component } from 'svelte';
4
5
  import { tv, type ClassValue } from 'tailwind-variants';
@@ -32,7 +33,7 @@
32
33
  size = 'md',
33
34
  disabled,
34
35
  loading,
35
- loadingicon = 'i-lucide-loader-circle',
36
+ loadingicon = getAppContext().icons.loading,
36
37
  uncheckedicon,
37
38
  checkedicon,
38
39
  label,
@@ -1,6 +1,6 @@
1
1
  <script module lang="ts">
2
2
  import { Tabs } from 'bits-ui';
3
- import { isComponent, isSnippet, useElementRects, type PropColor } from '../index.js';
3
+ import { isComponent, Icon, useElementRects, type PropColor } from '../index.js';
4
4
  import { tv, type ClassValue } from 'tailwind-variants';
5
5
  import { type Component, type Snippet } from 'svelte';
6
6
  import { ElementRect } from 'runed';
@@ -9,7 +9,7 @@
9
9
  | string
10
10
  | {
11
11
  label: string;
12
- icon?: string | Component | Snippet;
12
+ icon?: string | Component;
13
13
  iconposition?: 'before' | 'after';
14
14
  content?: string | Component;
15
15
  };
@@ -203,7 +203,7 @@
203
203
  class={variants.item({ class: ui.item })}
204
204
  data-variant={variant}
205
205
  >
206
- {@render RenderIcon(typeof item === 'string' ? undefined : item.icon)}
206
+ <Icon name={typeof item === 'string' ? undefined : item.icon} />
207
207
 
208
208
  {label}
209
209
  </Tabs.Trigger>
@@ -232,13 +232,3 @@
232
232
  {/if}
233
233
  {/each}
234
234
  </Tabs.Root>
235
-
236
- {#snippet RenderIcon(IconProp?: string | Component | Snippet)}
237
- {#if isSnippet(IconProp)}
238
- {@render IconProp()}
239
- {:else if isComponent(IconProp)}
240
- <IconProp class={variants.icon({ class: ui.icon })} />
241
- {:else if typeof IconProp === 'string'}
242
- <div class={variants.icon({ class: [IconProp, ui.icon] })}></div>
243
- {/if}
244
- {/snippet}
@@ -4,7 +4,7 @@ import { type ClassValue } from 'tailwind-variants';
4
4
  import { type Component, type Snippet } from 'svelte';
5
5
  export type TabItem = string | {
6
6
  label: string;
7
- icon?: string | Component | Snippet;
7
+ icon?: string | Component;
8
8
  iconposition?: 'before' | 'after';
9
9
  content?: string | Component;
10
10
  };
@@ -0,0 +1,173 @@
1
+ <script module lang="ts">
2
+ import {
3
+ Button,
4
+ Icon,
5
+ Progress,
6
+ type ButtonProps,
7
+ type ProgressProps,
8
+ type ToastOptions,
9
+ useRafFn,
10
+ } from '../index.js';
11
+ import { boxWith } from 'svelte-toolbelt';
12
+ import { tv } from 'tailwind-variants';
13
+ import defu from 'defu';
14
+ import { onDestroy, onMount } from 'svelte';
15
+ import { getAppContext } from '../contexts.js';
16
+
17
+ export type ToastProps = ToastOptions & {
18
+ closeToast?: () => void;
19
+ expanded?: boolean;
20
+ };
21
+ </script>
22
+
23
+ <script lang="ts">
24
+ let {
25
+ title,
26
+ description,
27
+ closeToast = () => {},
28
+ actions = [],
29
+ close = true,
30
+ color = 'primary',
31
+ duration = getAppContext().toaster.duration!,
32
+ icon,
33
+ progress = true,
34
+ orientation = 'vertical',
35
+ expanded = false,
36
+ ui = {},
37
+ }: ToastProps = $props();
38
+
39
+ let remaining = $state(boxWith(() => duration).current);
40
+
41
+ const { pause, resume } = useRafFn(({ delta }) => (remaining = remaining - delta));
42
+
43
+ const variants = $derived(
44
+ tv({
45
+ slots: {
46
+ base: 'overflow-hidden bg-surface-base shadow-lg rounded-lg border border-surface-accented space-y-4',
47
+ wrapper: 'm-4 flex gap-4',
48
+ title: 'text-sm font-medium text-labe-highlighted',
49
+ description: 'text-sm text-label-muted',
50
+ icon: 'shrink-0 size-5',
51
+ avatar: 'shrink-0',
52
+ avatarSize: '2xl',
53
+ actions: 'flex gap-1.5 shrink-0 m-4',
54
+ progress: '',
55
+ close: 'p-0',
56
+ },
57
+ variants: {
58
+ color: {
59
+ primary: {
60
+ base: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary',
61
+ icon: 'text-primary',
62
+ },
63
+ surface: {
64
+ base: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-inverted',
65
+ icon: 'text-highlighted',
66
+ },
67
+ success: {
68
+ base: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-success',
69
+ icon: 'text-success',
70
+ },
71
+ info: {
72
+ base: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-info',
73
+ icon: 'text-info',
74
+ },
75
+ warning: {
76
+ base: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-warning',
77
+ icon: 'text-warning',
78
+ },
79
+ error: {
80
+ base: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-error',
81
+ icon: 'text-error',
82
+ },
83
+ },
84
+ orientation: {
85
+ horizontal: {
86
+ base: 'items-center',
87
+ actions: 'items-center',
88
+ },
89
+ vertical: {
90
+ base: 'items-start',
91
+ actions: 'items-start mt-2.5',
92
+ },
93
+ },
94
+ title: {
95
+ true: {
96
+ description: 'mt-1',
97
+ },
98
+ },
99
+ },
100
+ })({ color, title: !!title, orientation }),
101
+ );
102
+
103
+ $effect(() => {
104
+ if (expanded) pause();
105
+ else resume();
106
+ });
107
+
108
+ onMount(resume);
109
+ onDestroy(pause);
110
+ </script>
111
+
112
+ <div class={variants.base({ class: ui.base })}>
113
+ <div class={variants.wrapper({ class: ui.wrapper })}>
114
+ <Icon name={icon} class={variants.icon({ class: ui.icon })} />
115
+
116
+ <div>
117
+ <h1 class={variants.title({ class: ui.title })}>
118
+ {title}
119
+ </h1>
120
+
121
+ {#if description}
122
+ <p class={variants.description({ class: ui.description })}>
123
+ {description}
124
+ </p>
125
+ {/if}
126
+ </div>
127
+
128
+ {#if orientation === 'horizontal'}
129
+ {@render actions_snippet()}
130
+ {/if}
131
+
132
+ {#if close}
133
+ <Button
134
+ {...defu(typeof close === 'boolean' ? {} : close, <ButtonProps>{
135
+ icon: getAppContext().icons.close,
136
+ color: 'surface',
137
+ variant: 'link',
138
+ onclick: closeToast,
139
+ ui: { base: variants.icon({ class: ui.icon }) },
140
+ })}
141
+ />
142
+ {/if}
143
+ </div>
144
+
145
+ {#if orientation === 'vertical'}
146
+ {@render actions_snippet()}
147
+ {/if}
148
+
149
+ {#if progress}
150
+ <Progress
151
+ max={duration}
152
+ value={remaining}
153
+ {...defu(typeof progress === 'object' ? progress : {}, <ProgressProps>{
154
+ size: 'sm',
155
+ ui: { base: variants.progress({ class: ui.progress }) },
156
+ })}
157
+ />
158
+ {/if}
159
+ </div>
160
+
161
+ {#snippet actions_snippet()}
162
+ {#if actions.length > 0}
163
+ <div class={variants.actions({ class: ui.actions })}>
164
+ {#each actions as action, idx (idx)}
165
+ <Button
166
+ {...defu(action, <ButtonProps>{
167
+ size: 'xs',
168
+ })}
169
+ />
170
+ {/each}
171
+ </div>
172
+ {/if}
173
+ {/snippet}
@@ -0,0 +1,8 @@
1
+ import { type ToastOptions } from '../index.js';
2
+ export type ToastProps = ToastOptions & {
3
+ closeToast?: () => void;
4
+ expanded?: boolean;
5
+ };
6
+ declare const Toast: import("svelte").Component<any, {}, "">;
7
+ type Toast = ReturnType<typeof Toast>;
8
+ export default Toast;
@@ -0,0 +1,11 @@
1
+ import { toast as _toast } from 'svelte-sonner';
2
+ import Toast from './toast.svelte';
3
+ import {} from 'svelte';
4
+ import {} from '../index.js';
5
+ export function toast(opts) {
6
+ return _toast.custom(Toast, {
7
+ componentProps: opts,
8
+ id: opts.id,
9
+ });
10
+ }
11
+ export const useToasts = _toast.getActiveToasts;
@@ -1,6 +1,6 @@
1
- import { Context } from 'runed';
2
- export declare const app_icons: Context<Record<"arrowdown" | "arrowleft" | "arrowright" | "arrowup" | "caution" | "check" | "chevrondoubleleft" | "chevrondoubleright" | "chevrondown" | "chevronleft" | "chevronright" | "chevronup" | "close" | "copy" | "copycheck" | "dark" | "drag" | "ellipsis" | "error" | "external" | "eye" | "eyeoff" | "file" | "folder" | "folderopen" | "hash" | "info" | "light" | "loading" | "menu" | "minus" | "panelclose" | "panelopen" | "plus" | "reload" | "search" | "stop" | "success" | "system" | "tip" | "upload" | "warning", string>>;
3
- export type AppIcons = keyof typeof DEFAULT_ICONS;
1
+ import type { ToasterProps } from 'svelte-sonner';
2
+ import type { ModeWatcherProps } from './mode.js';
3
+ import type { TooltipProviderProps } from 'bits-ui';
4
4
  export declare const DEFAULT_ICONS: {
5
5
  arrowdown: string;
6
6
  arrowleft: string;
@@ -45,3 +45,10 @@ export declare const DEFAULT_ICONS: {
45
45
  upload: string;
46
46
  warning: string;
47
47
  };
48
+ export type AppContext = {
49
+ icons: Partial<typeof DEFAULT_ICONS>;
50
+ toaster: Partial<ToasterProps>;
51
+ modewatcher: ModeWatcherProps;
52
+ tooltip: TooltipProviderProps;
53
+ };
54
+ export declare const getAppContext: () => AppContext, setAppContext: (context: AppContext) => AppContext;
package/dist/contexts.js CHANGED
@@ -1,5 +1,4 @@
1
- import { Context } from 'runed';
2
- export const app_icons = new Context('app-config');
1
+ import { createContext } from 'svelte';
3
2
  export const DEFAULT_ICONS = {
4
3
  arrowdown: 'i-lucide:arrow-down',
5
4
  arrowleft: 'i-lucide:arrow-left',
@@ -44,3 +43,4 @@ export const DEFAULT_ICONS = {
44
43
  upload: 'i-lucide:upload',
45
44
  warning: 'i-lucide:warning',
46
45
  };
46
+ export const [getAppContext, setAppContext] = createContext();
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from './components/index.js';
2
- export * from './utilities.svelte.js';
2
+ export * from './utilities/index.js';
3
3
  export * from './types.js';
4
4
  export { ModeWatcher } from 'mode-watcher';
5
- export { toast, type ToastOptions } from 'svelte-sonner';
package/dist/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from './components/index.js';
2
- export * from './utilities.svelte.js';
2
+ export * from './utilities/index.js';
3
3
  export * from './types.js';
4
4
  export { ModeWatcher } from 'mode-watcher';
5
- export { toast } from 'svelte-sonner';
@@ -0,0 +1,5 @@
1
+ export * from './isComponent.js';
2
+ export * from './isSnippet.js';
3
+ export * from './useElementRects.svelte.js';
4
+ export * from './useRafFn.svelte.js';
5
+ export * from './useStyle.svelte.js';
@@ -0,0 +1,5 @@
1
+ export * from './isComponent.js';
2
+ export * from './isSnippet.js';
3
+ export * from './useElementRects.svelte.js';
4
+ export * from './useRafFn.svelte.js';
5
+ export * from './useStyle.svelte.js';
@@ -0,0 +1,7 @@
1
+ import type { Component } from 'svelte';
2
+ /**
3
+ * Checks if a value is a Svelte component
4
+ * @param v - The value to check
5
+ * @returns true if the value is a component, false otherwise
6
+ */
7
+ export declare function isComponent(v: unknown): v is Component;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Checks if a value is a Svelte component
3
+ * @param v - The value to check
4
+ * @returns true if the value is a component, false otherwise
5
+ */
6
+ export function isComponent(v) {
7
+ if (typeof document !== 'undefined')
8
+ return typeof v === 'function';
9
+ return typeof v === 'function' && 'render' in v;
10
+ }
@@ -0,0 +1,7 @@
1
+ import type { Snippet } from 'svelte';
2
+ /**
3
+ * Checks if a value is a Svelte snippet
4
+ * @param v - The value to check
5
+ * @returns true if the value is a snippet, false otherwise
6
+ */
7
+ export declare function isSnippet<T>(v: unknown): v is Snippet<[T]>;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Checks if a value is a Svelte snippet
3
+ * @param v - The value to check
4
+ * @returns true if the value is a snippet, false otherwise
5
+ */
6
+ export function isSnippet(v) {
7
+ return typeof v === 'function' && !('render' in v);
8
+ }
@@ -0,0 +1,11 @@
1
+ import { type ElementSizeOptions, type MaybeGetter } from 'runed';
2
+ /**
3
+ * Returns a reactive value holding the dom rect of `node`s.
4
+ *
5
+ * Accepts an `options` object with the following properties:
6
+ * - `initialSize`: The initial size of the element. Defaults to `{ width: 0, height: 0 }`.
7
+ * - `box`: The box model to use. Can be either `"content-box"` or `"border-box"`. Defaults to `"border-box"`.
8
+ *
9
+ * @returns an array of dom rects.
10
+ */
11
+ export declare function useElementRects(nodes: MaybeGetter<HTMLElement[]>, options?: ElementSizeOptions): DOMRect[];
@@ -1,22 +1,4 @@
1
1
  import { extract, useMutationObserver, useResizeObserver, } from 'runed';
2
- /**
3
- * Checks if a value is a Svelte component
4
- * @param v - The value to check
5
- * @returns true if the value is a component, false otherwise
6
- */
7
- export function isComponent(v) {
8
- if (typeof document !== 'undefined')
9
- return typeof v === 'function';
10
- return typeof v === 'function' && 'render' in v;
11
- }
12
- /**
13
- * Checks if a value is a Svelte snippet
14
- * @param v - The value to check
15
- * @returns true if the value is a snippet, false otherwise
16
- */
17
- export function isSnippet(v) {
18
- return typeof v === 'function' && !('render' in v);
19
- }
20
2
  /**
21
3
  * Returns a reactive value holding the dom rect of `node`s.
22
4
  *
@@ -47,23 +29,3 @@ export function useElementRects(nodes, options = {}) {
47
29
  });
48
30
  return rects;
49
31
  }
50
- let uisv_usestyle_id = 0;
51
- /**
52
- * Inject reactive style element in head.
53
- * @param css string
54
- */
55
- export function useStyle(css) {
56
- const id = `uisv_styletag_${++uisv_usestyle_id}`;
57
- let el = $state();
58
- $effect(() => {
59
- if (!el) {
60
- el = (document.getElementById(id) || document.createElement('style'));
61
- if (!el.isConnected) {
62
- el.id = id;
63
- document.head.appendChild(el);
64
- }
65
- }
66
- el.textContent = extract(css);
67
- });
68
- return { id };
69
- }
@@ -0,0 +1,43 @@
1
+ export interface UseRafFnCallbackArguments {
2
+ /**
3
+ * Time elapsed between this and the last frame.
4
+ */
5
+ delta: number;
6
+ /**
7
+ * Time elapsed since the creation of the web page. See {@link https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp#the_time_origin Time origin}.
8
+ */
9
+ timestamp: DOMHighResTimeStamp;
10
+ }
11
+ export interface UseRafFnOptions {
12
+ /**
13
+ * Start the requestAnimationFrame loop immediately on creation
14
+ *
15
+ * @default true
16
+ */
17
+ immediate?: boolean;
18
+ /**
19
+ * The maximum frame per second to execute the function.
20
+ * Set to `-1` to disable the limit.
21
+ *
22
+ * @default -1
23
+ */
24
+ fpslimit?: number;
25
+ /**
26
+ * After the requestAnimationFrame loop executed once, it will be automatically stopped.
27
+ *
28
+ * @default false
29
+ */
30
+ once?: boolean;
31
+ }
32
+ /**
33
+ * Call function on every `requestAnimationFrame`. With controls of pausing and resuming.
34
+ *
35
+ * @see https://vueuse.org/useRafFn
36
+ * @param fn
37
+ * @param options
38
+ */
39
+ export declare function useRafFn(fn: (args: UseRafFnCallbackArguments) => void, options?: UseRafFnOptions): {
40
+ is_active: boolean;
41
+ pause: () => void;
42
+ resume: () => void;
43
+ };
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Call function on every `requestAnimationFrame`. With controls of pausing and resuming.
3
+ *
4
+ * @see https://vueuse.org/useRafFn
5
+ * @param fn
6
+ * @param options
7
+ */
8
+ export function useRafFn(fn, options = {}) {
9
+ const { immediate = true, fpslimit = -1, once = false } = options;
10
+ let is_active = $state(false);
11
+ const interval_limit = $derived.by(() => {
12
+ return fpslimit ? 1000 / fpslimit : null;
13
+ });
14
+ let previousFrameTimestamp = 0;
15
+ let rafId = null;
16
+ function loop(timestamp) {
17
+ if (!is_active || !window)
18
+ return;
19
+ if (!previousFrameTimestamp)
20
+ previousFrameTimestamp = timestamp;
21
+ const delta = timestamp - previousFrameTimestamp;
22
+ if (interval_limit && delta < interval_limit) {
23
+ rafId = window.requestAnimationFrame(loop);
24
+ return;
25
+ }
26
+ previousFrameTimestamp = timestamp;
27
+ fn({ delta, timestamp });
28
+ if (once) {
29
+ is_active = false;
30
+ rafId = null;
31
+ return;
32
+ }
33
+ rafId = window.requestAnimationFrame(loop);
34
+ }
35
+ function resume() {
36
+ if (!is_active && window) {
37
+ is_active = true;
38
+ previousFrameTimestamp = 0;
39
+ rafId = window.requestAnimationFrame(loop);
40
+ }
41
+ }
42
+ function pause() {
43
+ is_active = false;
44
+ if (rafId != null && window) {
45
+ window.cancelAnimationFrame(rafId);
46
+ rafId = null;
47
+ }
48
+ }
49
+ if (immediate)
50
+ resume();
51
+ return {
52
+ is_active,
53
+ pause,
54
+ resume,
55
+ };
56
+ }
@@ -0,0 +1,8 @@
1
+ import { type MaybeGetter } from 'runed';
2
+ /**
3
+ * Inject reactive style element in head.
4
+ * @param css string
5
+ */
6
+ export declare function useStyle(css: MaybeGetter<string>): {
7
+ id: string;
8
+ };