@ims360/svelte-ivory 0.3.0 → 0.3.3
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/dist/components/basic/Element.svelte +81 -0
- package/dist/components/basic/Element.svelte.d.ts +30 -0
- package/dist/components/basic/Element.svelte.d.ts.map +1 -0
- package/dist/components/basic/MarkedText.svelte +70 -0
- package/dist/components/basic/MarkedText.svelte.d.ts +17 -0
- package/dist/components/basic/MarkedText.svelte.d.ts.map +1 -0
- package/dist/components/basic/Textarea.svelte +46 -0
- package/dist/components/basic/Textarea.svelte.d.ts +15 -0
- package/dist/components/basic/Textarea.svelte.d.ts.map +1 -0
- package/dist/components/basic/checkbox/Checkbox.svelte +2 -2
- package/dist/components/basic/checkbox/Checkbox.svelte.d.ts +2 -2
- package/dist/components/basic/checkbox/Checkbox.svelte.d.ts.map +1 -1
- package/dist/components/basic/index.d.ts +5 -4
- package/dist/components/basic/index.d.ts.map +1 -1
- package/dist/components/basic/index.js +3 -2
- package/dist/components/basic/toggle/Toggle.svelte +2 -2
- package/dist/components/basic/toggle/Toggle.svelte.d.ts +2 -2
- package/dist/components/basic/toggle/Toggle.svelte.d.ts.map +1 -1
- package/dist/components/inputs/TextareaInput.svelte +23 -0
- package/dist/components/inputs/TextareaInput.svelte.d.ts +7 -0
- package/dist/components/inputs/TextareaInput.svelte.d.ts.map +1 -0
- package/dist/components/inputs/index.d.ts +1 -0
- package/dist/components/inputs/index.d.ts.map +1 -1
- package/dist/components/inputs/index.js +1 -0
- package/dist/components/table/Column.svelte +19 -19
- package/dist/components/table/Column.svelte.d.ts +1 -0
- package/dist/components/table/Column.svelte.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/lib/components/basic/Element.svelte +81 -0
- package/src/lib/components/basic/MarkedText.svelte +70 -0
- package/src/lib/components/basic/Textarea.svelte +46 -0
- package/src/lib/components/basic/checkbox/Checkbox.svelte +2 -2
- package/src/lib/components/basic/index.ts +10 -4
- package/src/lib/components/basic/toggle/Toggle.svelte +2 -2
- package/src/lib/components/inputs/TextareaInput.svelte +23 -0
- package/src/lib/components/inputs/index.ts +1 -0
- package/src/lib/components/table/Column.svelte +19 -19
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import { merge } from '../../utils/functions';
|
|
3
|
+
import type {
|
|
4
|
+
HTMLAttributeAnchorTarget,
|
|
5
|
+
HTMLAttributes,
|
|
6
|
+
MouseEventHandler
|
|
7
|
+
} from 'svelte/elements';
|
|
8
|
+
import type { TransitionConfig } from 'svelte/transition';
|
|
9
|
+
|
|
10
|
+
export type AnchorAttributes = {
|
|
11
|
+
download?: string | undefined | null;
|
|
12
|
+
href?: string | undefined | null;
|
|
13
|
+
hreflang?: string | undefined | null;
|
|
14
|
+
rel?: string | undefined | null;
|
|
15
|
+
target?: HTMLAttributeAnchorTarget | undefined | null;
|
|
16
|
+
type?: string | undefined | null;
|
|
17
|
+
referrerpolicy?: ReferrerPolicy | undefined | null;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type ButtonAttributes = {
|
|
21
|
+
onclick: MouseEventHandler<HTMLElement>;
|
|
22
|
+
disabled?: boolean | undefined | null;
|
|
23
|
+
form?: string | undefined | null;
|
|
24
|
+
name?: string | undefined | null;
|
|
25
|
+
type?: 'submit' | 'reset' | 'button' | undefined | null;
|
|
26
|
+
value?: string | string[] | number | undefined | null;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type ElementProps = HTMLAttributes<HTMLElement> & {
|
|
30
|
+
inTransition?: (element: HTMLElement) => TransitionConfig;
|
|
31
|
+
outTransition?: (element: HTMLElement) => TransitionConfig;
|
|
32
|
+
} & (AnchorAttributes | ButtonAttributes | HTMLAttributes<HTMLDivElement>);
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<script lang="ts">
|
|
36
|
+
const noop = () => ({});
|
|
37
|
+
let {
|
|
38
|
+
div = $bindable(),
|
|
39
|
+
inTransition = noop,
|
|
40
|
+
outTransition = noop,
|
|
41
|
+
...props
|
|
42
|
+
}: ElementProps & { div?: HTMLElement } = $props();
|
|
43
|
+
|
|
44
|
+
function isAnchor(props: ElementProps): props is AnchorAttributes {
|
|
45
|
+
return 'href' in props && typeof props.href !== 'undefined';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function isButton(props: ElementProps): props is ButtonAttributes {
|
|
49
|
+
return ('onclick' in props && typeof props.onclick !== 'undefined') || 'type' in props;
|
|
50
|
+
}
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
{#if 'disabled' in props && props.disabled}
|
|
54
|
+
<div
|
|
55
|
+
{...props}
|
|
56
|
+
in:inTransition
|
|
57
|
+
out:outTransition
|
|
58
|
+
class={merge(props.class, 'pointer-events-none opacity-60 grayscale')}
|
|
59
|
+
bind:this={div}
|
|
60
|
+
>
|
|
61
|
+
{@render props.children?.()}
|
|
62
|
+
</div>
|
|
63
|
+
{:else if isAnchor(props)}
|
|
64
|
+
<a {...props} in:inTransition out:outTransition bind:this={div}>
|
|
65
|
+
{@render props.children?.()}
|
|
66
|
+
</a>
|
|
67
|
+
{:else if isButton(props)}
|
|
68
|
+
<button
|
|
69
|
+
{...props}
|
|
70
|
+
in:inTransition
|
|
71
|
+
out:outTransition
|
|
72
|
+
type={props.type || 'button'}
|
|
73
|
+
bind:this={div}
|
|
74
|
+
>
|
|
75
|
+
{@render props.children?.()}
|
|
76
|
+
</button>
|
|
77
|
+
{:else}
|
|
78
|
+
<div {...props} in:inTransition out:outTransition bind:this={div}>
|
|
79
|
+
{@render props.children?.()}
|
|
80
|
+
</div>
|
|
81
|
+
{/if}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { HTMLAttributeAnchorTarget, HTMLAttributes, MouseEventHandler } from 'svelte/elements';
|
|
2
|
+
import type { TransitionConfig } from 'svelte/transition';
|
|
3
|
+
export type AnchorAttributes = {
|
|
4
|
+
download?: string | undefined | null;
|
|
5
|
+
href?: string | undefined | null;
|
|
6
|
+
hreflang?: string | undefined | null;
|
|
7
|
+
rel?: string | undefined | null;
|
|
8
|
+
target?: HTMLAttributeAnchorTarget | undefined | null;
|
|
9
|
+
type?: string | undefined | null;
|
|
10
|
+
referrerpolicy?: ReferrerPolicy | undefined | null;
|
|
11
|
+
};
|
|
12
|
+
export type ButtonAttributes = {
|
|
13
|
+
onclick: MouseEventHandler<HTMLElement>;
|
|
14
|
+
disabled?: boolean | undefined | null;
|
|
15
|
+
form?: string | undefined | null;
|
|
16
|
+
name?: string | undefined | null;
|
|
17
|
+
type?: 'submit' | 'reset' | 'button' | undefined | null;
|
|
18
|
+
value?: string | string[] | number | undefined | null;
|
|
19
|
+
};
|
|
20
|
+
export type ElementProps = HTMLAttributes<HTMLElement> & {
|
|
21
|
+
inTransition?: (element: HTMLElement) => TransitionConfig;
|
|
22
|
+
outTransition?: (element: HTMLElement) => TransitionConfig;
|
|
23
|
+
} & (AnchorAttributes | ButtonAttributes | HTMLAttributes<HTMLDivElement>);
|
|
24
|
+
type $$ComponentProps = ElementProps & {
|
|
25
|
+
div?: HTMLElement;
|
|
26
|
+
};
|
|
27
|
+
declare const Element: import("svelte").Component<$$ComponentProps, {}, "div">;
|
|
28
|
+
type Element = ReturnType<typeof Element>;
|
|
29
|
+
export default Element;
|
|
30
|
+
//# sourceMappingURL=Element.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Element.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/basic/Element.svelte.ts"],"names":[],"mappings":"AAII,OAAO,KAAK,EACR,yBAAyB,EACzB,cAAc,EACd,iBAAiB,EACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,MAAM,MAAM,gBAAgB,GAAG;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACrC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAChC,MAAM,CAAC,EAAE,yBAAyB,GAAG,SAAS,GAAG,IAAI,CAAC;IACtD,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACjC,cAAc,CAAC,EAAE,cAAc,GAAG,SAAS,GAAG,IAAI,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC3B,OAAO,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACjC,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,IAAI,CAAC;IACxD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,cAAc,CAAC,WAAW,CAAC,GAAG;IACrD,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,gBAAgB,CAAC;IAC1D,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,gBAAgB,CAAC;CAC9D,GAAG,CAAC,gBAAgB,GAAG,gBAAgB,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC;AAE9E,KAAK,gBAAgB,GAAI,YAAY,GAAG;IAAE,GAAG,CAAC,EAAE,WAAW,CAAA;CAAE,CAAC;AAyC/D,QAAA,MAAM,OAAO,yDAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { ClassValue } from 'svelte/elements';
|
|
4
|
+
|
|
5
|
+
export type MarkedTextProps = {
|
|
6
|
+
class?: ClassValue;
|
|
7
|
+
content: string | undefined;
|
|
8
|
+
search: string | undefined;
|
|
9
|
+
element?: 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
10
|
+
id?: string | undefined;
|
|
11
|
+
children?: Snippet<[{ match: string }]>;
|
|
12
|
+
};
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<script lang="ts">
|
|
16
|
+
let {
|
|
17
|
+
class: clazz = 'shrink-0 whitespace-nowrap text-ellipsis overflow-hidden max-w-full',
|
|
18
|
+
content,
|
|
19
|
+
search,
|
|
20
|
+
element = 'p',
|
|
21
|
+
id,
|
|
22
|
+
children
|
|
23
|
+
}: MarkedTextProps = $props();
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @param str
|
|
27
|
+
* @param search
|
|
28
|
+
* @return tokens: list with {match, prev}, where 'match' matches the search (case-insensitive) and prev is the string between 'match' and the prev 'match' (or start)
|
|
29
|
+
* @return tail: the string after the last match
|
|
30
|
+
*/
|
|
31
|
+
const split = (str: string, search: string) => {
|
|
32
|
+
const matchLen = search.length;
|
|
33
|
+
var tokens: { match: string; prev: string }[] = [];
|
|
34
|
+
let pos = str.toLowerCase().search(search.toLowerCase());
|
|
35
|
+
while (pos != -1) {
|
|
36
|
+
tokens.push({
|
|
37
|
+
match: str.slice(pos, pos + matchLen),
|
|
38
|
+
prev: str.slice(0, pos)
|
|
39
|
+
});
|
|
40
|
+
str = str.slice(pos + matchLen);
|
|
41
|
+
pos = str.search(search);
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
tokens,
|
|
45
|
+
tail: str
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const { tokens, tail } = $derived.by(() => {
|
|
50
|
+
if (!search || !content) return { tokens: [], tail: content };
|
|
51
|
+
return split(content, search);
|
|
52
|
+
});
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<!-- @component
|
|
56
|
+
marks text-parts matching the given search parameter
|
|
57
|
+
-->
|
|
58
|
+
<svelte:element this={element} class={[clazz]} {id}>
|
|
59
|
+
{#each tokens as token (token)}
|
|
60
|
+
{token.prev}
|
|
61
|
+
{#if children}
|
|
62
|
+
{@render children?.({ match: token.match })}
|
|
63
|
+
{:else}
|
|
64
|
+
<mark class="bg-primary-500 text-surface-50 shrink-0 rounded-sm px-px py-0.5">
|
|
65
|
+
{token.match}
|
|
66
|
+
</mark>
|
|
67
|
+
{/if}
|
|
68
|
+
{/each}
|
|
69
|
+
{tail}
|
|
70
|
+
</svelte:element>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { ClassValue } from 'svelte/elements';
|
|
3
|
+
export type MarkedTextProps = {
|
|
4
|
+
class?: ClassValue;
|
|
5
|
+
content: string | undefined;
|
|
6
|
+
search: string | undefined;
|
|
7
|
+
element?: 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
8
|
+
id?: string | undefined;
|
|
9
|
+
children?: Snippet<[{
|
|
10
|
+
match: string;
|
|
11
|
+
}]>;
|
|
12
|
+
};
|
|
13
|
+
/** marks text-parts matching the given search parameter */
|
|
14
|
+
declare const MarkedText: import("svelte").Component<MarkedTextProps, {}, "">;
|
|
15
|
+
type MarkedText = ReturnType<typeof MarkedText>;
|
|
16
|
+
export default MarkedText;
|
|
17
|
+
//# sourceMappingURL=MarkedText.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarkedText.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/basic/MarkedText.svelte.ts"],"names":[],"mappings":"AAGI,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,MAAM,eAAe,GAAG;IAC1B,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACxD,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;CAC3C,CAAC;AA6DN,2DAA2D;AAC3D,QAAA,MAAM,UAAU,qDAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { merge } from '../../utils/functions';
|
|
3
|
+
import type { ClassValue, HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
|
|
5
|
+
interface Props extends HTMLAttributes<HTMLTextAreaElement> {
|
|
6
|
+
class?: ClassValue;
|
|
7
|
+
value?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let { class: clazz, value = $bindable(), ...rest }: Props = $props();
|
|
14
|
+
|
|
15
|
+
let textareaEl = $state<HTMLTextAreaElement>();
|
|
16
|
+
|
|
17
|
+
function autoResize() {
|
|
18
|
+
if (!textareaEl) return;
|
|
19
|
+
textareaEl.style.height = 'auto';
|
|
20
|
+
textareaEl.style.height = `${textareaEl.scrollHeight}px`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
$effect(() => {
|
|
24
|
+
value;
|
|
25
|
+
autoResize();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export function focus() {
|
|
29
|
+
textareaEl?.focus();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function isActive() {
|
|
33
|
+
return document.activeElement === textareaEl;
|
|
34
|
+
}
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<textarea
|
|
38
|
+
class={merge(
|
|
39
|
+
'max-h-96 w-full resize-none overflow-y-auto border-none bg-transparent ring-0 outline-0 transition-all',
|
|
40
|
+
clazz
|
|
41
|
+
)}
|
|
42
|
+
bind:this={textareaEl}
|
|
43
|
+
bind:value
|
|
44
|
+
rows="1"
|
|
45
|
+
{...rest}
|
|
46
|
+
></textarea>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ClassValue, HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
interface Props extends HTMLAttributes<HTMLTextAreaElement> {
|
|
3
|
+
class?: ClassValue;
|
|
4
|
+
value?: string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
placeholder?: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
}
|
|
9
|
+
declare const Textarea: import("svelte").Component<Props, {
|
|
10
|
+
focus: () => void;
|
|
11
|
+
isActive: () => boolean;
|
|
12
|
+
}, "value">;
|
|
13
|
+
type Textarea = ReturnType<typeof Textarea>;
|
|
14
|
+
export default Textarea;
|
|
15
|
+
//# sourceMappingURL=Textarea.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Textarea.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/basic/Textarea.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAG9D,UAAU,KAAM,SAAQ,cAAc,CAAC,mBAAmB,CAAC;IACvD,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAqCL,QAAA,MAAM,QAAQ;;;WAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import type { ClassValue } from 'svelte/elements';
|
|
8
8
|
import { scale } from 'svelte/transition';
|
|
9
9
|
|
|
10
|
-
export
|
|
10
|
+
export type CheckboxProps = IvoryComponent<HTMLElement> & {
|
|
11
11
|
class?: ClassValue;
|
|
12
12
|
/** `checked` has prioriy over `partial` */
|
|
13
13
|
checked?: boolean | null;
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
/** if true, the onclick handler will not be called */
|
|
18
18
|
disabled?: boolean;
|
|
19
19
|
onclick?: () => void;
|
|
20
|
-
}
|
|
20
|
+
};
|
|
21
21
|
</script>
|
|
22
22
|
|
|
23
23
|
<!--
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { IvoryComponent } from '../../../types';
|
|
2
2
|
import type { ClassValue } from 'svelte/elements';
|
|
3
|
-
export
|
|
3
|
+
export type CheckboxProps = IvoryComponent<HTMLElement> & {
|
|
4
4
|
class?: ClassValue;
|
|
5
5
|
/** `checked` has prioriy over `partial` */
|
|
6
6
|
checked?: boolean | null;
|
|
@@ -10,7 +10,7 @@ export interface CheckboxProps extends IvoryComponent<HTMLElement> {
|
|
|
10
10
|
/** if true, the onclick handler will not be called */
|
|
11
11
|
disabled?: boolean;
|
|
12
12
|
onclick?: () => void;
|
|
13
|
-
}
|
|
13
|
+
};
|
|
14
14
|
/** It's a checkbox */
|
|
15
15
|
declare const Checkbox: import("svelte").Component<CheckboxProps, {}, "">;
|
|
16
16
|
type Checkbox = ReturnType<typeof Checkbox>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkbox.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/basic/checkbox/Checkbox.svelte.ts"],"names":[],"mappings":"AAII,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD,MAAM,
|
|
1
|
+
{"version":3,"file":"Checkbox.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/basic/checkbox/Checkbox.svelte.ts"],"names":[],"mappings":"AAII,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC,WAAW,CAAC,GAAG;IACtD,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,sDAAsD;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB,CAAC;AAuDN,sBAAsB;AACtB,QAAA,MAAM,QAAQ,mDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export
|
|
2
|
-
export { default as
|
|
3
|
-
export
|
|
4
|
-
export { default as
|
|
1
|
+
export { default as Checkbox, type CheckboxProps } from './checkbox/Checkbox.svelte';
|
|
2
|
+
export { default as Element, type AnchorAttributes, type ButtonAttributes, type ElementProps } from './Element.svelte';
|
|
3
|
+
export { default as MarkedText, type MarkedTextProps } from './MarkedText.svelte';
|
|
4
|
+
export { default as Textarea } from './Textarea.svelte';
|
|
5
|
+
export { default as Toggle, type ToggleProps } from './toggle/Toggle.svelte';
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/components/basic/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/components/basic/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,4BAA4B,CAAC;AACrF,OAAO,EACH,OAAO,IAAI,OAAO,EAClB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export * from './checkbox/Checkbox.svelte';
|
|
2
1
|
export { default as Checkbox } from './checkbox/Checkbox.svelte';
|
|
3
|
-
export
|
|
2
|
+
export { default as Element } from './Element.svelte';
|
|
3
|
+
export { default as MarkedText } from './MarkedText.svelte';
|
|
4
|
+
export { default as Textarea } from './Textarea.svelte';
|
|
4
5
|
export { default as Toggle } from './toggle/Toggle.svelte';
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
import type { Snippet } from 'svelte';
|
|
5
5
|
import type { ClassValue } from 'svelte/elements';
|
|
6
6
|
|
|
7
|
-
export
|
|
7
|
+
export type ToggleProps = IvoryComponent<HTMLElement> & {
|
|
8
8
|
value?: boolean;
|
|
9
9
|
class?: ClassValue;
|
|
10
10
|
children?: Snippet;
|
|
11
|
-
}
|
|
11
|
+
};
|
|
12
12
|
</script>
|
|
13
13
|
|
|
14
14
|
<script lang="ts">
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { IvoryComponent } from '../../../types';
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { ClassValue } from 'svelte/elements';
|
|
4
|
-
export
|
|
4
|
+
export type ToggleProps = IvoryComponent<HTMLElement> & {
|
|
5
5
|
value?: boolean;
|
|
6
6
|
class?: ClassValue;
|
|
7
7
|
children?: Snippet;
|
|
8
|
-
}
|
|
8
|
+
};
|
|
9
9
|
declare const Toggle: import("svelte").Component<ToggleProps, {}, "">;
|
|
10
10
|
type Toggle = ReturnType<typeof Toggle>;
|
|
11
11
|
export default Toggle;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toggle.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/basic/toggle/Toggle.svelte.ts"],"names":[],"mappings":"AAGI,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"Toggle.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/basic/toggle/Toggle.svelte.ts"],"names":[],"mappings":"AAGI,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,MAAM,WAAW,GAAG,cAAc,CAAC,WAAW,CAAC,GAAG;IACpD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AA8BN,QAAA,MAAM,MAAM,iDAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import TextArea from '../basic/Textarea.svelte';
|
|
3
|
+
import Input, { type InputProps } from './Input.svelte';
|
|
4
|
+
|
|
5
|
+
let { ...props }: InputProps<string> = $props();
|
|
6
|
+
|
|
7
|
+
let inputElement = $state<TextArea>();
|
|
8
|
+
export function focus() {
|
|
9
|
+
inputElement?.focus();
|
|
10
|
+
}
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<Input {...props}>
|
|
14
|
+
{#snippet children(inputProps)}
|
|
15
|
+
{@const { name } = props.form.as?.('text')}
|
|
16
|
+
<TextArea
|
|
17
|
+
{...inputProps}
|
|
18
|
+
{name}
|
|
19
|
+
bind:value={props.form.value, props.form.set}
|
|
20
|
+
bind:this={inputElement}
|
|
21
|
+
/>
|
|
22
|
+
{/snippet}
|
|
23
|
+
</Input>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type InputProps } from './Input.svelte';
|
|
2
|
+
declare const TextareaInput: import("svelte").Component<InputProps<string>, {
|
|
3
|
+
focus: () => void;
|
|
4
|
+
}, "">;
|
|
5
|
+
type TextareaInput = ReturnType<typeof TextareaInput>;
|
|
6
|
+
export default TextareaInput;
|
|
7
|
+
//# sourceMappingURL=TextareaInput.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextareaInput.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/inputs/TextareaInput.svelte.ts"],"names":[],"mappings":"AAIA,OAAc,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAuBxD,QAAA,MAAM,aAAa;;MAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
|
|
@@ -10,6 +10,7 @@ export { default as PasswordCreateInput, type PasswordCreateInputProps, type Pas
|
|
|
10
10
|
export { default as PasswordInput } from './PasswordInput.svelte';
|
|
11
11
|
export { default as Select } from './select/Select.svelte';
|
|
12
12
|
export { default as SelectOption } from './select/SelectOption.svelte';
|
|
13
|
+
export { default as TextareaInput } from './TextareaInput.svelte';
|
|
13
14
|
export { default as TextInput } from './TextInput.svelte';
|
|
14
15
|
export { default as ToggleInput } from './ToggleInput.svelte';
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/components/inputs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EACH,OAAO,IAAI,kBAAkB,EAC7B,KAAK,uBAAuB,EAC/B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EACH,OAAO,IAAI,mBAAmB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EAC3B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/components/inputs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EACH,OAAO,IAAI,kBAAkB,EAC7B,KAAK,uBAAuB,EAC/B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EACH,OAAO,IAAI,mBAAmB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EAC3B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -10,5 +10,6 @@ export { default as PasswordCreateInput } from './PasswordCreateInput.svelte';
|
|
|
10
10
|
export { default as PasswordInput } from './PasswordInput.svelte';
|
|
11
11
|
export { default as Select } from './select/Select.svelte';
|
|
12
12
|
export { default as SelectOption } from './select/SelectOption.svelte';
|
|
13
|
+
export { default as TextareaInput } from './TextareaInput.svelte';
|
|
13
14
|
export { default as TextInput } from './TextInput.svelte';
|
|
14
15
|
export { default as ToggleInput } from './ToggleInput.svelte';
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { merge } from '../../utils/functions';
|
|
4
4
|
import { type Snippet } from 'svelte';
|
|
5
5
|
import type { ClassValue } from 'svelte/elements';
|
|
6
|
+
import Element from '../basic/Element.svelte';
|
|
6
7
|
import type { ColumnConfig } from './columnController.svelte';
|
|
7
8
|
import { getRowContext } from './Row.svelte';
|
|
8
9
|
import { getTableContext } from './Table.svelte';
|
|
@@ -12,6 +13,7 @@
|
|
|
12
13
|
/** If the type is incorrect pass the "row" property with the right type */
|
|
13
14
|
children: Snippet;
|
|
14
15
|
onclick?: (e: Event) => void | Promise<void>;
|
|
16
|
+
href?: string;
|
|
15
17
|
/** Cannot be used with resizable columns*/
|
|
16
18
|
ignoreWidth?: boolean;
|
|
17
19
|
offsetNestingLevel?: number;
|
|
@@ -21,37 +23,38 @@
|
|
|
21
23
|
<script lang="ts">
|
|
22
24
|
let {
|
|
23
25
|
class: clazz,
|
|
24
|
-
children,
|
|
25
26
|
onclick,
|
|
27
|
+
href,
|
|
26
28
|
ignoreWidth = false,
|
|
29
|
+
offsetNestingLevel = 0,
|
|
27
30
|
// ColumnConfig
|
|
31
|
+
id,
|
|
32
|
+
width,
|
|
33
|
+
minWidth,
|
|
28
34
|
resizable = true,
|
|
29
|
-
|
|
35
|
+
header,
|
|
30
36
|
...props
|
|
31
37
|
}: ColumnProps = $props();
|
|
32
38
|
|
|
33
39
|
// Register the new column if this is the first table row that was rendered
|
|
34
40
|
const tableContext = getTableContext();
|
|
35
|
-
const column = tableContext.registerColumn({ resizable,
|
|
41
|
+
const column = tableContext.registerColumn({ id, width, minWidth, resizable, header });
|
|
36
42
|
const rowContext = getRowContext();
|
|
37
43
|
|
|
38
44
|
const finalOnClick = $derived(onclick || rowContext.onclick);
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (finalOnClick) return 'button';
|
|
43
|
-
if (rowContext.href) return 'a';
|
|
44
|
-
return 'div';
|
|
45
|
+
const finalHref = $derived.by(() => {
|
|
46
|
+
if (finalOnClick) return undefined;
|
|
47
|
+
return href || rowContext.href;
|
|
45
48
|
});
|
|
46
49
|
|
|
47
50
|
// passes updated props to the column
|
|
48
51
|
$effect(() => {
|
|
49
|
-
column.updateConfig({ resizable,
|
|
52
|
+
column.updateConfig({ resizable, minWidth, id, header });
|
|
50
53
|
});
|
|
51
54
|
|
|
52
55
|
// this must be separate to the above effect, since otherwise the width would be reset on every scroll
|
|
53
56
|
$effect(() => {
|
|
54
|
-
if (!resizable && typeof
|
|
57
|
+
if (!resizable && typeof width !== 'undefined') column.width = width;
|
|
55
58
|
});
|
|
56
59
|
|
|
57
60
|
const widthStyle = $derived(
|
|
@@ -60,11 +63,10 @@
|
|
|
60
63
|
</script>
|
|
61
64
|
|
|
62
65
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
onclick={
|
|
66
|
-
href={
|
|
67
|
-
type={allowClicking ? 'button' : undefined}
|
|
66
|
+
<Element
|
|
67
|
+
{...props}
|
|
68
|
+
onclick={finalOnClick}
|
|
69
|
+
href={finalHref}
|
|
68
70
|
style={ignoreWidth ? '' : `width: ${widthStyle}`}
|
|
69
71
|
class={merge([
|
|
70
72
|
'box-border flex h-full shrink-0 flex-row items-center justify-start gap-1 truncate',
|
|
@@ -72,6 +74,4 @@
|
|
|
72
74
|
theme.current.table?.column?.class,
|
|
73
75
|
clazz
|
|
74
76
|
])}
|
|
75
|
-
|
|
76
|
-
{@render children()}
|
|
77
|
-
</svelte:element>
|
|
77
|
+
/>
|
|
@@ -6,6 +6,7 @@ export interface ColumnProps extends ColumnConfig {
|
|
|
6
6
|
/** If the type is incorrect pass the "row" property with the right type */
|
|
7
7
|
children: Snippet;
|
|
8
8
|
onclick?: (e: Event) => void | Promise<void>;
|
|
9
|
+
href?: string;
|
|
9
10
|
/** Cannot be used with resizable columns*/
|
|
10
11
|
ignoreWidth?: boolean;
|
|
11
12
|
offsetNestingLevel?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Column.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/table/Column.svelte.ts"],"names":[],"mappings":"AAKI,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"Column.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/table/Column.svelte.ts"],"names":[],"mappings":"AAKI,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAI9D,MAAM,WAAW,WAAY,SAAQ,YAAY;IAC7C,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,2EAA2E;IAC3E,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAwDL,QAAA,MAAM,MAAM,iDAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import { merge } from '$lib/utils/functions';
|
|
3
|
+
import type {
|
|
4
|
+
HTMLAttributeAnchorTarget,
|
|
5
|
+
HTMLAttributes,
|
|
6
|
+
MouseEventHandler
|
|
7
|
+
} from 'svelte/elements';
|
|
8
|
+
import type { TransitionConfig } from 'svelte/transition';
|
|
9
|
+
|
|
10
|
+
export type AnchorAttributes = {
|
|
11
|
+
download?: string | undefined | null;
|
|
12
|
+
href?: string | undefined | null;
|
|
13
|
+
hreflang?: string | undefined | null;
|
|
14
|
+
rel?: string | undefined | null;
|
|
15
|
+
target?: HTMLAttributeAnchorTarget | undefined | null;
|
|
16
|
+
type?: string | undefined | null;
|
|
17
|
+
referrerpolicy?: ReferrerPolicy | undefined | null;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type ButtonAttributes = {
|
|
21
|
+
onclick: MouseEventHandler<HTMLElement>;
|
|
22
|
+
disabled?: boolean | undefined | null;
|
|
23
|
+
form?: string | undefined | null;
|
|
24
|
+
name?: string | undefined | null;
|
|
25
|
+
type?: 'submit' | 'reset' | 'button' | undefined | null;
|
|
26
|
+
value?: string | string[] | number | undefined | null;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type ElementProps = HTMLAttributes<HTMLElement> & {
|
|
30
|
+
inTransition?: (element: HTMLElement) => TransitionConfig;
|
|
31
|
+
outTransition?: (element: HTMLElement) => TransitionConfig;
|
|
32
|
+
} & (AnchorAttributes | ButtonAttributes | HTMLAttributes<HTMLDivElement>);
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<script lang="ts">
|
|
36
|
+
const noop = () => ({});
|
|
37
|
+
let {
|
|
38
|
+
div = $bindable(),
|
|
39
|
+
inTransition = noop,
|
|
40
|
+
outTransition = noop,
|
|
41
|
+
...props
|
|
42
|
+
}: ElementProps & { div?: HTMLElement } = $props();
|
|
43
|
+
|
|
44
|
+
function isAnchor(props: ElementProps): props is AnchorAttributes {
|
|
45
|
+
return 'href' in props && typeof props.href !== 'undefined';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function isButton(props: ElementProps): props is ButtonAttributes {
|
|
49
|
+
return ('onclick' in props && typeof props.onclick !== 'undefined') || 'type' in props;
|
|
50
|
+
}
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
{#if 'disabled' in props && props.disabled}
|
|
54
|
+
<div
|
|
55
|
+
{...props}
|
|
56
|
+
in:inTransition
|
|
57
|
+
out:outTransition
|
|
58
|
+
class={merge(props.class, 'pointer-events-none opacity-60 grayscale')}
|
|
59
|
+
bind:this={div}
|
|
60
|
+
>
|
|
61
|
+
{@render props.children?.()}
|
|
62
|
+
</div>
|
|
63
|
+
{:else if isAnchor(props)}
|
|
64
|
+
<a {...props} in:inTransition out:outTransition bind:this={div}>
|
|
65
|
+
{@render props.children?.()}
|
|
66
|
+
</a>
|
|
67
|
+
{:else if isButton(props)}
|
|
68
|
+
<button
|
|
69
|
+
{...props}
|
|
70
|
+
in:inTransition
|
|
71
|
+
out:outTransition
|
|
72
|
+
type={props.type || 'button'}
|
|
73
|
+
bind:this={div}
|
|
74
|
+
>
|
|
75
|
+
{@render props.children?.()}
|
|
76
|
+
</button>
|
|
77
|
+
{:else}
|
|
78
|
+
<div {...props} in:inTransition out:outTransition bind:this={div}>
|
|
79
|
+
{@render props.children?.()}
|
|
80
|
+
</div>
|
|
81
|
+
{/if}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { ClassValue } from 'svelte/elements';
|
|
4
|
+
|
|
5
|
+
export type MarkedTextProps = {
|
|
6
|
+
class?: ClassValue;
|
|
7
|
+
content: string | undefined;
|
|
8
|
+
search: string | undefined;
|
|
9
|
+
element?: 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
10
|
+
id?: string | undefined;
|
|
11
|
+
children?: Snippet<[{ match: string }]>;
|
|
12
|
+
};
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<script lang="ts">
|
|
16
|
+
let {
|
|
17
|
+
class: clazz = 'shrink-0 whitespace-nowrap text-ellipsis overflow-hidden max-w-full',
|
|
18
|
+
content,
|
|
19
|
+
search,
|
|
20
|
+
element = 'p',
|
|
21
|
+
id,
|
|
22
|
+
children
|
|
23
|
+
}: MarkedTextProps = $props();
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @param str
|
|
27
|
+
* @param search
|
|
28
|
+
* @return tokens: list with {match, prev}, where 'match' matches the search (case-insensitive) and prev is the string between 'match' and the prev 'match' (or start)
|
|
29
|
+
* @return tail: the string after the last match
|
|
30
|
+
*/
|
|
31
|
+
const split = (str: string, search: string) => {
|
|
32
|
+
const matchLen = search.length;
|
|
33
|
+
var tokens: { match: string; prev: string }[] = [];
|
|
34
|
+
let pos = str.toLowerCase().search(search.toLowerCase());
|
|
35
|
+
while (pos != -1) {
|
|
36
|
+
tokens.push({
|
|
37
|
+
match: str.slice(pos, pos + matchLen),
|
|
38
|
+
prev: str.slice(0, pos)
|
|
39
|
+
});
|
|
40
|
+
str = str.slice(pos + matchLen);
|
|
41
|
+
pos = str.search(search);
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
tokens,
|
|
45
|
+
tail: str
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const { tokens, tail } = $derived.by(() => {
|
|
50
|
+
if (!search || !content) return { tokens: [], tail: content };
|
|
51
|
+
return split(content, search);
|
|
52
|
+
});
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
<!-- @component
|
|
56
|
+
marks text-parts matching the given search parameter
|
|
57
|
+
-->
|
|
58
|
+
<svelte:element this={element} class={[clazz]} {id}>
|
|
59
|
+
{#each tokens as token (token)}
|
|
60
|
+
{token.prev}
|
|
61
|
+
{#if children}
|
|
62
|
+
{@render children?.({ match: token.match })}
|
|
63
|
+
{:else}
|
|
64
|
+
<mark class="bg-primary-500 text-surface-50 shrink-0 rounded-sm px-px py-0.5">
|
|
65
|
+
{token.match}
|
|
66
|
+
</mark>
|
|
67
|
+
{/if}
|
|
68
|
+
{/each}
|
|
69
|
+
{tail}
|
|
70
|
+
</svelte:element>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { merge } from '$lib/utils/functions';
|
|
3
|
+
import type { ClassValue, HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
|
|
5
|
+
interface Props extends HTMLAttributes<HTMLTextAreaElement> {
|
|
6
|
+
class?: ClassValue;
|
|
7
|
+
value?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let { class: clazz, value = $bindable(), ...rest }: Props = $props();
|
|
14
|
+
|
|
15
|
+
let textareaEl = $state<HTMLTextAreaElement>();
|
|
16
|
+
|
|
17
|
+
function autoResize() {
|
|
18
|
+
if (!textareaEl) return;
|
|
19
|
+
textareaEl.style.height = 'auto';
|
|
20
|
+
textareaEl.style.height = `${textareaEl.scrollHeight}px`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
$effect(() => {
|
|
24
|
+
value;
|
|
25
|
+
autoResize();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export function focus() {
|
|
29
|
+
textareaEl?.focus();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function isActive() {
|
|
33
|
+
return document.activeElement === textareaEl;
|
|
34
|
+
}
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<textarea
|
|
38
|
+
class={merge(
|
|
39
|
+
'max-h-96 w-full resize-none overflow-y-auto border-none bg-transparent ring-0 outline-0 transition-all',
|
|
40
|
+
clazz
|
|
41
|
+
)}
|
|
42
|
+
bind:this={textareaEl}
|
|
43
|
+
bind:value
|
|
44
|
+
rows="1"
|
|
45
|
+
{...rest}
|
|
46
|
+
></textarea>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import type { ClassValue } from 'svelte/elements';
|
|
8
8
|
import { scale } from 'svelte/transition';
|
|
9
9
|
|
|
10
|
-
export
|
|
10
|
+
export type CheckboxProps = IvoryComponent<HTMLElement> & {
|
|
11
11
|
class?: ClassValue;
|
|
12
12
|
/** `checked` has prioriy over `partial` */
|
|
13
13
|
checked?: boolean | null;
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
/** if true, the onclick handler will not be called */
|
|
18
18
|
disabled?: boolean;
|
|
19
19
|
onclick?: () => void;
|
|
20
|
-
}
|
|
20
|
+
};
|
|
21
21
|
</script>
|
|
22
22
|
|
|
23
23
|
<!--
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
export
|
|
2
|
-
export {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
export { default as Checkbox, type CheckboxProps } from './checkbox/Checkbox.svelte';
|
|
2
|
+
export {
|
|
3
|
+
default as Element,
|
|
4
|
+
type AnchorAttributes,
|
|
5
|
+
type ButtonAttributes,
|
|
6
|
+
type ElementProps
|
|
7
|
+
} from './Element.svelte';
|
|
8
|
+
export { default as MarkedText, type MarkedTextProps } from './MarkedText.svelte';
|
|
9
|
+
export { default as Textarea } from './Textarea.svelte';
|
|
10
|
+
export { default as Toggle, type ToggleProps } from './toggle/Toggle.svelte';
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
import type { Snippet } from 'svelte';
|
|
5
5
|
import type { ClassValue } from 'svelte/elements';
|
|
6
6
|
|
|
7
|
-
export
|
|
7
|
+
export type ToggleProps = IvoryComponent<HTMLElement> & {
|
|
8
8
|
value?: boolean;
|
|
9
9
|
class?: ClassValue;
|
|
10
10
|
children?: Snippet;
|
|
11
|
-
}
|
|
11
|
+
};
|
|
12
12
|
</script>
|
|
13
13
|
|
|
14
14
|
<script lang="ts">
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import TextArea from '../basic/Textarea.svelte';
|
|
3
|
+
import Input, { type InputProps } from './Input.svelte';
|
|
4
|
+
|
|
5
|
+
let { ...props }: InputProps<string> = $props();
|
|
6
|
+
|
|
7
|
+
let inputElement = $state<TextArea>();
|
|
8
|
+
export function focus() {
|
|
9
|
+
inputElement?.focus();
|
|
10
|
+
}
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<Input {...props}>
|
|
14
|
+
{#snippet children(inputProps)}
|
|
15
|
+
{@const { name } = props.form.as?.('text')}
|
|
16
|
+
<TextArea
|
|
17
|
+
{...inputProps}
|
|
18
|
+
{name}
|
|
19
|
+
bind:value={props.form.value, props.form.set}
|
|
20
|
+
bind:this={inputElement}
|
|
21
|
+
/>
|
|
22
|
+
{/snippet}
|
|
23
|
+
</Input>
|
|
@@ -17,5 +17,6 @@ export {
|
|
|
17
17
|
export { default as PasswordInput } from './PasswordInput.svelte';
|
|
18
18
|
export { default as Select } from './select/Select.svelte';
|
|
19
19
|
export { default as SelectOption } from './select/SelectOption.svelte';
|
|
20
|
+
export { default as TextareaInput } from './TextareaInput.svelte';
|
|
20
21
|
export { default as TextInput } from './TextInput.svelte';
|
|
21
22
|
export { default as ToggleInput } from './ToggleInput.svelte';
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { merge } from '$lib/utils/functions';
|
|
4
4
|
import { type Snippet } from 'svelte';
|
|
5
5
|
import type { ClassValue } from 'svelte/elements';
|
|
6
|
+
import Element from '../basic/Element.svelte';
|
|
6
7
|
import type { ColumnConfig } from './columnController.svelte';
|
|
7
8
|
import { getRowContext } from './Row.svelte';
|
|
8
9
|
import { getTableContext } from './Table.svelte';
|
|
@@ -12,6 +13,7 @@
|
|
|
12
13
|
/** If the type is incorrect pass the "row" property with the right type */
|
|
13
14
|
children: Snippet;
|
|
14
15
|
onclick?: (e: Event) => void | Promise<void>;
|
|
16
|
+
href?: string;
|
|
15
17
|
/** Cannot be used with resizable columns*/
|
|
16
18
|
ignoreWidth?: boolean;
|
|
17
19
|
offsetNestingLevel?: number;
|
|
@@ -21,37 +23,38 @@
|
|
|
21
23
|
<script lang="ts">
|
|
22
24
|
let {
|
|
23
25
|
class: clazz,
|
|
24
|
-
children,
|
|
25
26
|
onclick,
|
|
27
|
+
href,
|
|
26
28
|
ignoreWidth = false,
|
|
29
|
+
offsetNestingLevel = 0,
|
|
27
30
|
// ColumnConfig
|
|
31
|
+
id,
|
|
32
|
+
width,
|
|
33
|
+
minWidth,
|
|
28
34
|
resizable = true,
|
|
29
|
-
|
|
35
|
+
header,
|
|
30
36
|
...props
|
|
31
37
|
}: ColumnProps = $props();
|
|
32
38
|
|
|
33
39
|
// Register the new column if this is the first table row that was rendered
|
|
34
40
|
const tableContext = getTableContext();
|
|
35
|
-
const column = tableContext.registerColumn({ resizable,
|
|
41
|
+
const column = tableContext.registerColumn({ id, width, minWidth, resizable, header });
|
|
36
42
|
const rowContext = getRowContext();
|
|
37
43
|
|
|
38
44
|
const finalOnClick = $derived(onclick || rowContext.onclick);
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (finalOnClick) return 'button';
|
|
43
|
-
if (rowContext.href) return 'a';
|
|
44
|
-
return 'div';
|
|
45
|
+
const finalHref = $derived.by(() => {
|
|
46
|
+
if (finalOnClick) return undefined;
|
|
47
|
+
return href || rowContext.href;
|
|
45
48
|
});
|
|
46
49
|
|
|
47
50
|
// passes updated props to the column
|
|
48
51
|
$effect(() => {
|
|
49
|
-
column.updateConfig({ resizable,
|
|
52
|
+
column.updateConfig({ resizable, minWidth, id, header });
|
|
50
53
|
});
|
|
51
54
|
|
|
52
55
|
// this must be separate to the above effect, since otherwise the width would be reset on every scroll
|
|
53
56
|
$effect(() => {
|
|
54
|
-
if (!resizable && typeof
|
|
57
|
+
if (!resizable && typeof width !== 'undefined') column.width = width;
|
|
55
58
|
});
|
|
56
59
|
|
|
57
60
|
const widthStyle = $derived(
|
|
@@ -60,11 +63,10 @@
|
|
|
60
63
|
</script>
|
|
61
64
|
|
|
62
65
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
onclick={
|
|
66
|
-
href={
|
|
67
|
-
type={allowClicking ? 'button' : undefined}
|
|
66
|
+
<Element
|
|
67
|
+
{...props}
|
|
68
|
+
onclick={finalOnClick}
|
|
69
|
+
href={finalHref}
|
|
68
70
|
style={ignoreWidth ? '' : `width: ${widthStyle}`}
|
|
69
71
|
class={merge([
|
|
70
72
|
'box-border flex h-full shrink-0 flex-row items-center justify-start gap-1 truncate',
|
|
@@ -72,6 +74,4 @@
|
|
|
72
74
|
theme.current.table?.column?.class,
|
|
73
75
|
clazz
|
|
74
76
|
])}
|
|
75
|
-
|
|
76
|
-
{@render children()}
|
|
77
|
-
</svelte:element>
|
|
77
|
+
/>
|