@ims360/svelte-ivory 0.0.50 → 0.0.52

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,85 @@
1
+ <script lang="ts" module>
2
+ import { FileUp } from '@lucide/svelte';
3
+ import type { Snippet } from 'svelte';
4
+ import { scale } from 'svelte/transition';
5
+ import { HiddenBackground, Portal } from '../layout';
6
+
7
+ export interface FullscreenDropzoneProps {
8
+ ondrop: (files: File[]) => void;
9
+ disabled: boolean;
10
+ children?: Snippet;
11
+ }
12
+ </script>
13
+
14
+ <script lang="ts">
15
+ let { ondrop, disabled, children = defaultChildren }: FullscreenDropzoneProps = $props();
16
+
17
+ let open = $state(false);
18
+
19
+ // This counter correctly handles dragenter/dragleave events as the
20
+ // cursor moves over different elements within the window.
21
+ let counter = $state(0);
22
+
23
+ function handleDragEnter(e: DragEvent) {
24
+ if (disabled) return;
25
+ e.preventDefault();
26
+ // We only want to react to file drags.
27
+ if (e.dataTransfer?.types.includes('Files')) {
28
+ counter++;
29
+ open = true;
30
+ }
31
+ }
32
+
33
+ function handleDragLeave(e: DragEvent) {
34
+ e.preventDefault();
35
+ counter = Math.max(counter - 1, 0);
36
+ // Only close the overlay when the counter is 0, meaning the cursor
37
+ // has truly left the window.
38
+ if (counter === 0) {
39
+ open = false;
40
+ }
41
+ }
42
+
43
+ function handleDrop(e: DragEvent) {
44
+ // Prevent the browser from opening the file.
45
+ e.preventDefault();
46
+
47
+ // Reset state and close the overlay.
48
+ open = false;
49
+ counter = 0;
50
+
51
+ const files = Array.from(e.dataTransfer?.files ?? []);
52
+
53
+ if (files.length > 0) {
54
+ ondrop(files);
55
+ }
56
+ }
57
+ </script>
58
+
59
+ <svelte:window
60
+ ondragenter={handleDragEnter}
61
+ ondragleave={handleDragLeave}
62
+ ondrop={handleDrop}
63
+ ondragover={(e) => e.preventDefault()}
64
+ />
65
+
66
+ {#if open}
67
+ <Portal>
68
+ <HiddenBackground class="flex items-center justify-center">
69
+ {@render children()}
70
+ </HiddenBackground>
71
+ </Portal>
72
+ {/if}
73
+
74
+ {#snippet defaultChildren()}
75
+ <div
76
+ class="border-surface-400 text-surface-50 relative flex flex-col items-center gap-4 p-12 text-xl"
77
+ in:scale|global={{ duration: 100, delay: 100 }}
78
+ out:scale|global={{ duration: 100 }}
79
+ >
80
+ <div
81
+ class="absolute top-0 left-0 h-full w-full rounded-xl bg-black/75 opacity-50 blur-lg"
82
+ ></div>
83
+ <FileUp size={40} />
84
+ </div>
85
+ {/snippet}
@@ -0,0 +1,10 @@
1
+ import type { Snippet } from 'svelte';
2
+ export interface FullscreenDropzoneProps {
3
+ ondrop: (files: File[]) => void;
4
+ disabled: boolean;
5
+ children?: Snippet;
6
+ }
7
+ declare const FullscreenDropzone: import("svelte").Component<FullscreenDropzoneProps, {}, "">;
8
+ type FullscreenDropzone = ReturnType<typeof FullscreenDropzone>;
9
+ export default FullscreenDropzone;
10
+ //# sourceMappingURL=FullscreenDropzone.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FullscreenDropzone.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/inputs/FullscreenDropzone.svelte.ts"],"names":[],"mappings":"AAII,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAItC,MAAM,WAAW,uBAAuB;IACpC,MAAM,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAoEL,QAAA,MAAM,kBAAkB,6DAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { default as FullscreenDropzone, type FullscreenDropzoneProps } from './FullscreenDropzone.svelte';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/components/inputs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,OAAO,IAAI,kBAAkB,EAC7B,KAAK,uBAAuB,EAC/B,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1 @@
1
+ export { default as FullscreenDropzone } from './FullscreenDropzone.svelte';
@@ -75,7 +75,7 @@
75
75
  class={twMerge(
76
76
  clsx([
77
77
  'box-border flex h-full shrink-0 flex-row items-center justify-start gap-1 truncate',
78
- column.width !== 0 && 'pr-2',
78
+ column.width !== 0 && 'border-r-[calc(var(--spacing)_*_2)] border-transparent',
79
79
  defaultClasses,
80
80
  clazz
81
81
  ])
@@ -5,10 +5,10 @@
5
5
  import type { ClassValue } from 'svelte/elements';
6
6
  import { SvelteSet } from 'svelte/reactivity';
7
7
  import { twMerge } from 'tailwind-merge';
8
- import { Column as ColumnComponent, type TableRow } from '.';
8
+ import ColumnComponent from './Column.svelte';
9
9
  import { ColumnController, type ColumnConfig } from './columnController.svelte';
10
10
  import ColumnHead from './ColumnHead.svelte';
11
- import { treeWalker } from './controller';
11
+ import { treeWalker, type TableRow } from './controller';
12
12
  import Row from './Row.svelte';
13
13
  import { applyHidden, searchTable } from './search.svelte';
14
14
  import VirtualList from './VirtualList.svelte';
@@ -1,8 +1,8 @@
1
1
  import { type Snippet } from 'svelte';
2
2
  import type { ClassValue } from 'svelte/elements';
3
3
  import { SvelteSet } from 'svelte/reactivity';
4
- import { type TableRow } from '.';
5
4
  import { ColumnController, type ColumnConfig } from './columnController.svelte';
5
+ import { type TableRow } from './controller';
6
6
  export interface TableProps<T extends TableRow<T>> {
7
7
  class?: ClassValue;
8
8
  data: T[];
@@ -1 +1 @@
1
- {"version":3,"file":"Table.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/table/Table.svelte.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Table.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/table/Table.svelte.ts"],"names":[],"mappings":"AAKI,OAAO,EAAmC,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9C,OAAO,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEhF,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAKzD,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC;IAC7C,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC;IAC3B,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,GAAG,SAAS,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,GAAG,EAAE,CAAC,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACvE,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,GAAG,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,WAAW,CAAC,EAAE,UAAU,CAAC;IACzB,MAAM,CAAC,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,OAAO,CAAC;KAChC,CAAC;IACF;;OAEG;IACH,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAC7B;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAGD,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,IAAI;IAC9C,QAAQ,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,gBAAgB,CAAC;IACpE,QAAQ,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC9B,CAAC;AAMF,wBAAgB,eAAe,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,CAExE;AAIH,iBAAS,QAAQ,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC;WAqKZ,UAAU,CAAC,CAAC,CAAC;;;;;EAAoG;AAC9I,cAAM,iBAAiB,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC;IACzC,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAChD,MAAM,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAClD,KAAK,IAAI,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAChD,QAAQ;IACR,OAAO;CACV;AAED,UAAU,qBAAqB;IAC3B,KAAK,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAA;KAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAChZ,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC/I,YAAY,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;CACjE;AACD,QAAA,MAAM,KAAK,EAAE,qBAAmC,CAAC;AAC/B,KAAK,KAAK,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACpE,eAAe,KAAK,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function createDebouncedValue<T>(delay: number, value: T): {
2
+ current: T;
3
+ readonly debounced: T;
4
+ };
5
+ //# sourceMappingURL=debouncedValue.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debouncedValue.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/functions/debouncedValue.svelte.ts"],"names":[],"mappings":"AAAA,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;aAKpC,CAAC;;EAc3B"}
@@ -0,0 +1,21 @@
1
+ export function createDebouncedValue(delay, value) {
2
+ let current = $state(value);
3
+ let debounced = $state(value);
4
+ let timeout;
5
+ return {
6
+ set current(value) {
7
+ current = value;
8
+ if (timeout)
9
+ clearTimeout(timeout);
10
+ timeout = setTimeout(() => {
11
+ debounced = value;
12
+ }, delay);
13
+ },
14
+ get current() {
15
+ return current;
16
+ },
17
+ get debounced() {
18
+ return debounced;
19
+ }
20
+ };
21
+ }
@@ -1,4 +1,5 @@
1
1
  export { cookie } from './cookie';
2
+ export { createDebouncedValue } from './debouncedValue.svelte';
2
3
  export { pseudoRandomId } from './pseudoRandomId';
3
4
  export { queryParams } from './queryParams';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/functions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/functions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
@@ -1,3 +1,4 @@
1
1
  export { cookie } from './cookie';
2
+ export { createDebouncedValue } from './debouncedValue.svelte';
2
3
  export { pseudoRandomId } from './pseudoRandomId';
3
4
  export { queryParams } from './queryParams';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ims360/svelte-ivory",
3
- "version": "0.0.50",
3
+ "version": "0.0.52",
4
4
  "keywords": [
5
5
  "svelte"
6
6
  ],
@@ -34,6 +34,10 @@
34
34
  "types": "./dist/components/toast/index.d.ts",
35
35
  "svelte": "./dist/components/toast/index.js"
36
36
  },
37
+ "./components/inputs": {
38
+ "types": "./dist/components/inputs/index.d.ts",
39
+ "svelte": "./dist/components/inputs/index.js"
40
+ },
37
41
  "./utils/actions": {
38
42
  "types": "./dist/utils/actions/index.d.ts",
39
43
  "svelte": "./dist/utils/actions/index.js"
@@ -0,0 +1,85 @@
1
+ <script lang="ts" module>
2
+ import { FileUp } from '@lucide/svelte';
3
+ import type { Snippet } from 'svelte';
4
+ import { scale } from 'svelte/transition';
5
+ import { HiddenBackground, Portal } from '../layout';
6
+
7
+ export interface FullscreenDropzoneProps {
8
+ ondrop: (files: File[]) => void;
9
+ disabled: boolean;
10
+ children?: Snippet;
11
+ }
12
+ </script>
13
+
14
+ <script lang="ts">
15
+ let { ondrop, disabled, children = defaultChildren }: FullscreenDropzoneProps = $props();
16
+
17
+ let open = $state(false);
18
+
19
+ // This counter correctly handles dragenter/dragleave events as the
20
+ // cursor moves over different elements within the window.
21
+ let counter = $state(0);
22
+
23
+ function handleDragEnter(e: DragEvent) {
24
+ if (disabled) return;
25
+ e.preventDefault();
26
+ // We only want to react to file drags.
27
+ if (e.dataTransfer?.types.includes('Files')) {
28
+ counter++;
29
+ open = true;
30
+ }
31
+ }
32
+
33
+ function handleDragLeave(e: DragEvent) {
34
+ e.preventDefault();
35
+ counter = Math.max(counter - 1, 0);
36
+ // Only close the overlay when the counter is 0, meaning the cursor
37
+ // has truly left the window.
38
+ if (counter === 0) {
39
+ open = false;
40
+ }
41
+ }
42
+
43
+ function handleDrop(e: DragEvent) {
44
+ // Prevent the browser from opening the file.
45
+ e.preventDefault();
46
+
47
+ // Reset state and close the overlay.
48
+ open = false;
49
+ counter = 0;
50
+
51
+ const files = Array.from(e.dataTransfer?.files ?? []);
52
+
53
+ if (files.length > 0) {
54
+ ondrop(files);
55
+ }
56
+ }
57
+ </script>
58
+
59
+ <svelte:window
60
+ ondragenter={handleDragEnter}
61
+ ondragleave={handleDragLeave}
62
+ ondrop={handleDrop}
63
+ ondragover={(e) => e.preventDefault()}
64
+ />
65
+
66
+ {#if open}
67
+ <Portal>
68
+ <HiddenBackground class="flex items-center justify-center">
69
+ {@render children()}
70
+ </HiddenBackground>
71
+ </Portal>
72
+ {/if}
73
+
74
+ {#snippet defaultChildren()}
75
+ <div
76
+ class="border-surface-400 text-surface-50 relative flex flex-col items-center gap-4 p-12 text-xl"
77
+ in:scale|global={{ duration: 100, delay: 100 }}
78
+ out:scale|global={{ duration: 100 }}
79
+ >
80
+ <div
81
+ class="absolute top-0 left-0 h-full w-full rounded-xl bg-black/75 opacity-50 blur-lg"
82
+ ></div>
83
+ <FileUp size={40} />
84
+ </div>
85
+ {/snippet}
@@ -0,0 +1,4 @@
1
+ export {
2
+ default as FullscreenDropzone,
3
+ type FullscreenDropzoneProps
4
+ } from './FullscreenDropzone.svelte';
@@ -75,7 +75,7 @@
75
75
  class={twMerge(
76
76
  clsx([
77
77
  'box-border flex h-full shrink-0 flex-row items-center justify-start gap-1 truncate',
78
- column.width !== 0 && 'pr-2',
78
+ column.width !== 0 && 'border-r-[calc(var(--spacing)_*_2)] border-transparent',
79
79
  defaultClasses,
80
80
  clazz
81
81
  ])
@@ -5,10 +5,10 @@
5
5
  import type { ClassValue } from 'svelte/elements';
6
6
  import { SvelteSet } from 'svelte/reactivity';
7
7
  import { twMerge } from 'tailwind-merge';
8
- import { Column as ColumnComponent, type TableRow } from '.';
8
+ import ColumnComponent from './Column.svelte';
9
9
  import { ColumnController, type ColumnConfig } from './columnController.svelte';
10
10
  import ColumnHead from './ColumnHead.svelte';
11
- import { treeWalker } from './controller';
11
+ import { treeWalker, type TableRow } from './controller';
12
12
  import Row from './Row.svelte';
13
13
  import { applyHidden, searchTable } from './search.svelte';
14
14
  import VirtualList from './VirtualList.svelte';
@@ -0,0 +1,20 @@
1
+ export function createDebouncedValue<T>(delay: number, value: T) {
2
+ let current = $state<T>(value);
3
+ let debounced = $state<T>(value);
4
+ let timeout: ReturnType<typeof setTimeout>;
5
+ return {
6
+ set current(value: T) {
7
+ current = value;
8
+ if (timeout) clearTimeout(timeout);
9
+ timeout = setTimeout(() => {
10
+ debounced = value;
11
+ }, delay);
12
+ },
13
+ get current() {
14
+ return current;
15
+ },
16
+ get debounced() {
17
+ return debounced;
18
+ }
19
+ };
20
+ }
@@ -1,3 +1,4 @@
1
1
  export { cookie } from './cookie';
2
+ export { createDebouncedValue } from './debouncedValue.svelte';
2
3
  export { pseudoRandomId } from './pseudoRandomId';
3
4
  export { queryParams } from './queryParams';