@websline/system-components 1.4.3 → 1.4.6
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/atoms/checkbox/checkbox.variants.d.ts +2 -2
- package/dist/components/atoms/checkbox/checkbox.variants.js +1 -1
- package/dist/components/atoms/inputDate/InputDate.svelte +114 -0
- package/dist/components/atoms/inputDate/InputDate.svelte.d.ts +97 -0
- package/dist/components/atoms/inputDate/Picker.svelte +36 -0
- package/dist/components/atoms/inputDate/Picker.svelte.d.ts +21 -0
- package/dist/components/atoms/inputDate/input.variants.d.ts +64 -0
- package/dist/components/atoms/inputDate/input.variants.js +20 -0
- package/dist/components/atoms/radio/Radio.svelte +55 -2
- package/dist/components/atoms/tag/Tag.svelte +9 -7
- package/dist/components/atoms/tag/Tag.svelte.d.ts +8 -8
- package/dist/components/atoms/tag/tag.variants.d.ts +0 -9
- package/dist/components/atoms/tag/tag.variants.js +1 -4
- package/dist/components/molecules/calendar/Calendar.svelte +95 -0
- package/dist/components/molecules/calendar/Calendar.svelte.d.ts +42 -0
- package/dist/components/molecules/calendar/Container.svelte +25 -0
- package/dist/components/molecules/calendar/Container.svelte.d.ts +25 -0
- package/dist/components/molecules/calendar/DayCell.svelte +47 -0
- package/dist/components/molecules/calendar/RootContext.svelte +28 -0
- package/dist/components/molecules/calendar/RootContext.svelte.d.ts +21 -0
- package/dist/components/molecules/calendar/WeekRow.svelte +65 -0
- package/dist/components/molecules/calendar/Weekdays.svelte +27 -0
- package/dist/components/molecules/calendar/Weekdays.svelte.d.ts +17 -0
- package/dist/components/molecules/calendar/calendar.variant.d.ts +79 -0
- package/dist/components/molecules/calendar/calendar.variant.js +36 -0
- package/dist/components/molecules/calendar/index.d.ts +8 -0
- package/dist/components/molecules/calendar/index.js +10 -0
- package/dist/components/molecules/formField/FormField.svelte +1 -1
- package/dist/components/molecules/formField/FormField.svelte.d.ts +2 -2
- package/dist/components/molecules/formField/formField.variants.d.ts +12 -12
- package/dist/components/molecules/formField/formField.variants.js +21 -5
- package/dist/components/molecules/richTextEditor/RichTextEditor.svelte +9 -4
- package/dist/components/molecules/selectorCard/SelectorCard.svelte +8 -2
- package/dist/components/molecules/selectorCard/SelectorCard.svelte.d.ts +2 -2
- package/dist/components/molecules/tagSelector/TagSelector.svelte +12 -0
- package/dist/components/molecules/tagSelector/TagSelector.svelte.d.ts +16 -0
- package/dist/components/molecules/tagSelector/ValueList.svelte +12 -2
- package/dist/components/molecules/tagSelector/ValueList.svelte.d.ts +4 -0
- package/dist/components/molecules/tagSelector/tagSelector.variants.js +2 -2
- package/dist/components/organisms/tooltip/Content.svelte +51 -0
- package/dist/components/organisms/tooltip/Content.svelte.d.ts +57 -0
- package/dist/components/organisms/tooltip/Tooltip.svelte +15 -0
- package/dist/components/organisms/tooltip/Tooltip.svelte.d.ts +17 -0
- package/dist/components/organisms/tooltip/Trigger.svelte +13 -0
- package/dist/components/organisms/tooltip/Trigger.svelte.d.ts +17 -0
- package/dist/components/organisms/tooltip/index.d.ts +4 -0
- package/dist/components/organisms/tooltip/index.js +5 -0
- package/dist/components/organisms/tooltip/tooltip.variant.d.ts +24 -0
- package/dist/components/organisms/tooltip/tooltip.variant.js +20 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/package.json +25 -25
|
@@ -5,7 +5,7 @@ export const checkboxVariants: import("tailwind-variants").TVReturnType<{
|
|
|
5
5
|
error: {
|
|
6
6
|
true: string;
|
|
7
7
|
};
|
|
8
|
-
}, undefined, "size-4 cursor-pointer rounded border border-
|
|
8
|
+
}, undefined, "size-4 cursor-pointer rounded-xs border border-neutral-300 bg-transparent bg-none text-neutral-900 ring-0 ring-transparent ring-offset-transparent outline-transparent duration-300 after:block after:size-full checked:bg-none checked:after:bg-current focus:outline-1 focus:outline-offset-1 focus:outline-blue-300 dark:border-neutral-600 dark:text-white", {
|
|
9
9
|
disabled: {
|
|
10
10
|
true: string;
|
|
11
11
|
};
|
|
@@ -19,4 +19,4 @@ export const checkboxVariants: import("tailwind-variants").TVReturnType<{
|
|
|
19
19
|
error: {
|
|
20
20
|
true: string;
|
|
21
21
|
};
|
|
22
|
-
}, undefined, "size-4 cursor-pointer rounded border border-
|
|
22
|
+
}, undefined, "size-4 cursor-pointer rounded-xs border border-neutral-300 bg-transparent bg-none text-neutral-900 ring-0 ring-transparent ring-offset-transparent outline-transparent duration-300 after:block after:size-full checked:bg-none checked:after:bg-current focus:outline-1 focus:outline-offset-1 focus:outline-blue-300 dark:border-neutral-600 dark:text-white", unknown, unknown, undefined>>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { tv } from "../../../utils/tailwind.js";
|
|
2
2
|
|
|
3
3
|
const checkboxVariants = tv({
|
|
4
|
-
base: "size-4 cursor-pointer rounded border border-
|
|
4
|
+
base: "size-4 cursor-pointer rounded-xs border border-neutral-300 bg-transparent bg-none text-neutral-900 ring-0 ring-transparent ring-offset-transparent outline-transparent duration-300 after:block after:size-full checked:bg-none checked:after:bg-current focus:outline-1 focus:outline-offset-1 focus:outline-blue-300 dark:border-neutral-600 dark:text-white",
|
|
5
5
|
variants: {
|
|
6
6
|
disabled: {
|
|
7
7
|
true: "cursor-not-allowed",
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { Popover } from "bits-ui";
|
|
3
|
+
import { getContext } from "svelte";
|
|
4
|
+
import { IconButton } from "../../../index.js";
|
|
5
|
+
import Picker from "./Picker.svelte";
|
|
6
|
+
import { inputVariants } from "./input.variants.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {Object} Props
|
|
10
|
+
* @property {string|import("svelte").SvelteComponent|Function} [adornmentStart=""] Content to display at the start of the input (e.g., icon or text)
|
|
11
|
+
* @property {import("svelte").SvelteComponent} [children] Additional content to render inside the input component
|
|
12
|
+
* @property {string} [class=""] Additional CSS classes to apply to the component
|
|
13
|
+
* @property {boolean} [disabled] Whether the input is disabled
|
|
14
|
+
* @property {boolean} [error] Whether the input has an error state
|
|
15
|
+
* @property {string} [id] The ID of the input element
|
|
16
|
+
* @property {string} [name] The name of the input, used for form submission
|
|
17
|
+
* @property {string} [placeholder=""] Placeholder text for the input
|
|
18
|
+
* @property {boolean} [readonly=false] Whether the input is read-only
|
|
19
|
+
* @property {boolean} [required] Whether the input is required
|
|
20
|
+
* @property {string} [value=""] The value of the input, bound to the component
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/** @type {Props} */
|
|
24
|
+
let {
|
|
25
|
+
adornmentStart = "",
|
|
26
|
+
children,
|
|
27
|
+
class: className = "",
|
|
28
|
+
disabled,
|
|
29
|
+
error,
|
|
30
|
+
id,
|
|
31
|
+
name,
|
|
32
|
+
placeholder = "",
|
|
33
|
+
readonly = false,
|
|
34
|
+
required,
|
|
35
|
+
value = $bindable(),
|
|
36
|
+
// TODO
|
|
37
|
+
preventScroll = false,
|
|
38
|
+
portalDisabled = true,
|
|
39
|
+
portalTarget = "body",
|
|
40
|
+
side = "bottom",
|
|
41
|
+
sideOffset = 8,
|
|
42
|
+
...rest
|
|
43
|
+
} = $props();
|
|
44
|
+
|
|
45
|
+
let store = getContext("form-field-store") ?? null;
|
|
46
|
+
|
|
47
|
+
let localValues = $derived.by(() => {
|
|
48
|
+
const storeValues = typeof store === "function" ? store() : {};
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
disabled: disabled ?? storeValues.disabled ?? false,
|
|
52
|
+
error: error ?? storeValues.error ?? false,
|
|
53
|
+
id: id ?? storeValues.id ?? "",
|
|
54
|
+
required: required ?? storeValues.required ?? false,
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
let styles = $derived(
|
|
59
|
+
inputVariants({
|
|
60
|
+
disabled: localValues.disabled,
|
|
61
|
+
error: localValues.error,
|
|
62
|
+
}),
|
|
63
|
+
);
|
|
64
|
+
</script>
|
|
65
|
+
|
|
66
|
+
<Popover.Root>
|
|
67
|
+
<div class={styles.base({ class: className })}>
|
|
68
|
+
{#if adornmentStart}
|
|
69
|
+
<div class={styles.adornmentStart()}>
|
|
70
|
+
{#if typeof adornmentStart === "function"}
|
|
71
|
+
{@render adornmentStart()}
|
|
72
|
+
{:else}
|
|
73
|
+
{adornmentStart}
|
|
74
|
+
{/if}
|
|
75
|
+
</div>
|
|
76
|
+
{/if}
|
|
77
|
+
|
|
78
|
+
{#if children}
|
|
79
|
+
<!-- The date picker -->
|
|
80
|
+
<Picker
|
|
81
|
+
{children}
|
|
82
|
+
{preventScroll}
|
|
83
|
+
{portalDisabled}
|
|
84
|
+
{portalTarget}
|
|
85
|
+
{side}
|
|
86
|
+
{sideOffset} />
|
|
87
|
+
{/if}
|
|
88
|
+
|
|
89
|
+
<input
|
|
90
|
+
class={styles.input()}
|
|
91
|
+
disabled={localValues.disabled}
|
|
92
|
+
id={localValues.id}
|
|
93
|
+
{name}
|
|
94
|
+
{placeholder}
|
|
95
|
+
{readonly}
|
|
96
|
+
required={localValues.required}
|
|
97
|
+
{...rest}
|
|
98
|
+
bind:value />
|
|
99
|
+
|
|
100
|
+
<div class={styles.adornmentEnd()}>
|
|
101
|
+
<Popover.Trigger>
|
|
102
|
+
{#snippet child({ props })}
|
|
103
|
+
<IconButton
|
|
104
|
+
color="transparent"
|
|
105
|
+
icon="calendar"
|
|
106
|
+
iconSize={24}
|
|
107
|
+
shape="square"
|
|
108
|
+
size="small"
|
|
109
|
+
{...props} />
|
|
110
|
+
{/snippet}
|
|
111
|
+
</Popover.Trigger>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
</Popover.Root>
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
export default InputDate;
|
|
2
|
+
type InputDate = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<Props>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const InputDate: import("svelte").Component<{
|
|
7
|
+
/**
|
|
8
|
+
* Content to display at the start of the input (e.g., icon or text)
|
|
9
|
+
*/
|
|
10
|
+
adornmentStart?: string | import("svelte").SvelteComponent | Function;
|
|
11
|
+
/**
|
|
12
|
+
* Additional content to render inside the input component
|
|
13
|
+
*/
|
|
14
|
+
children?: import("svelte").SvelteComponent;
|
|
15
|
+
/**
|
|
16
|
+
* Additional CSS classes to apply to the component
|
|
17
|
+
*/
|
|
18
|
+
class?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Whether the input is disabled
|
|
21
|
+
*/
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Whether the input has an error state
|
|
25
|
+
*/
|
|
26
|
+
error?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* The ID of the input element
|
|
29
|
+
*/
|
|
30
|
+
id?: string;
|
|
31
|
+
/**
|
|
32
|
+
* The name of the input, used for form submission
|
|
33
|
+
*/
|
|
34
|
+
name?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Placeholder text for the input
|
|
37
|
+
*/
|
|
38
|
+
placeholder?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Whether the input is read-only
|
|
41
|
+
*/
|
|
42
|
+
readonly?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Whether the input is required
|
|
45
|
+
*/
|
|
46
|
+
required?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* The value of the input, bound to the component
|
|
49
|
+
*/
|
|
50
|
+
value?: string;
|
|
51
|
+
}, {}, "value">;
|
|
52
|
+
type Props = {
|
|
53
|
+
/**
|
|
54
|
+
* Content to display at the start of the input (e.g., icon or text)
|
|
55
|
+
*/
|
|
56
|
+
adornmentStart?: string | import("svelte").SvelteComponent | Function;
|
|
57
|
+
/**
|
|
58
|
+
* Additional content to render inside the input component
|
|
59
|
+
*/
|
|
60
|
+
children?: import("svelte").SvelteComponent;
|
|
61
|
+
/**
|
|
62
|
+
* Additional CSS classes to apply to the component
|
|
63
|
+
*/
|
|
64
|
+
class?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Whether the input is disabled
|
|
67
|
+
*/
|
|
68
|
+
disabled?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Whether the input has an error state
|
|
71
|
+
*/
|
|
72
|
+
error?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* The ID of the input element
|
|
75
|
+
*/
|
|
76
|
+
id?: string;
|
|
77
|
+
/**
|
|
78
|
+
* The name of the input, used for form submission
|
|
79
|
+
*/
|
|
80
|
+
name?: string;
|
|
81
|
+
/**
|
|
82
|
+
* Placeholder text for the input
|
|
83
|
+
*/
|
|
84
|
+
placeholder?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Whether the input is read-only
|
|
87
|
+
*/
|
|
88
|
+
readonly?: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Whether the input is required
|
|
91
|
+
*/
|
|
92
|
+
required?: boolean;
|
|
93
|
+
/**
|
|
94
|
+
* The value of the input, bound to the component
|
|
95
|
+
*/
|
|
96
|
+
value?: string;
|
|
97
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { Popover } from "bits-ui";
|
|
3
|
+
import { quintOut } from "svelte/easing";
|
|
4
|
+
import { scale } from "svelte/transition";
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
children,
|
|
8
|
+
preventScroll = false,
|
|
9
|
+
portalDisabled = true,
|
|
10
|
+
portalTarget = "body",
|
|
11
|
+
side = "bottom",
|
|
12
|
+
sideOffset = 8,
|
|
13
|
+
...rest
|
|
14
|
+
} = $props();
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<Popover.Portal disabled={portalDisabled} to={portalTarget}>
|
|
18
|
+
<Popover.Content
|
|
19
|
+
align="end"
|
|
20
|
+
alignOffset={0}
|
|
21
|
+
forceMount
|
|
22
|
+
{preventScroll}
|
|
23
|
+
{side}
|
|
24
|
+
{sideOffset}
|
|
25
|
+
{...rest}>
|
|
26
|
+
{#snippet child({ open, props, wrapperProps })}
|
|
27
|
+
{#if open}
|
|
28
|
+
<div {...wrapperProps}>
|
|
29
|
+
<div {...props} in:scale={{ duration: 300, easing: quintOut, start: 0.75 }}>
|
|
30
|
+
{@render children()}
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
{/if}
|
|
34
|
+
{/snippet}
|
|
35
|
+
</Popover.Content>
|
|
36
|
+
</Popover.Portal>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export default Picker;
|
|
2
|
+
type Picker = {
|
|
3
|
+
$on?(type: string, callback: (e: any) => void): () => void;
|
|
4
|
+
$set?(props: Partial<$$ComponentProps>): void;
|
|
5
|
+
};
|
|
6
|
+
declare const Picker: import("svelte").Component<{
|
|
7
|
+
children: any;
|
|
8
|
+
preventScroll?: boolean;
|
|
9
|
+
portalDisabled?: boolean;
|
|
10
|
+
portalTarget?: string;
|
|
11
|
+
side?: string;
|
|
12
|
+
sideOffset?: number;
|
|
13
|
+
} & Record<string, any>, {}, "">;
|
|
14
|
+
type $$ComponentProps = {
|
|
15
|
+
children: any;
|
|
16
|
+
preventScroll?: boolean;
|
|
17
|
+
portalDisabled?: boolean;
|
|
18
|
+
portalTarget?: string;
|
|
19
|
+
side?: string;
|
|
20
|
+
sideOffset?: number;
|
|
21
|
+
} & Record<string, any>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export const inputVariants: import("tailwind-variants").TVReturnType<{
|
|
2
|
+
disabled: {
|
|
3
|
+
true: {
|
|
4
|
+
input: string;
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
}, {
|
|
8
|
+
adornmentStart: string;
|
|
9
|
+
adornmentEnd: string;
|
|
10
|
+
base: string;
|
|
11
|
+
input: string;
|
|
12
|
+
}, undefined, {
|
|
13
|
+
disabled: {
|
|
14
|
+
true: {
|
|
15
|
+
base: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
error: {
|
|
19
|
+
true: {
|
|
20
|
+
base: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
}, {
|
|
24
|
+
base: string[];
|
|
25
|
+
}, import("tailwind-variants").TVReturnType<{
|
|
26
|
+
disabled: {
|
|
27
|
+
true: {
|
|
28
|
+
base: string;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
error: {
|
|
32
|
+
true: {
|
|
33
|
+
base: string;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
}, {
|
|
37
|
+
base: string[];
|
|
38
|
+
}, undefined, {
|
|
39
|
+
disabled: {
|
|
40
|
+
true: {
|
|
41
|
+
base: string;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
error: {
|
|
45
|
+
true: {
|
|
46
|
+
base: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
}, {
|
|
50
|
+
base: string[];
|
|
51
|
+
}, import("tailwind-variants").TVReturnType<{
|
|
52
|
+
disabled: {
|
|
53
|
+
true: {
|
|
54
|
+
base: string;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
error: {
|
|
58
|
+
true: {
|
|
59
|
+
base: string;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
}, {
|
|
63
|
+
base: string[];
|
|
64
|
+
}, undefined, unknown, unknown, undefined>>>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { inputBaseVariant, tv } from "../../../utils/tailwind.js";
|
|
2
|
+
|
|
3
|
+
const inputVariants = tv({
|
|
4
|
+
extend: inputBaseVariant,
|
|
5
|
+
slots: {
|
|
6
|
+
adornmentStart:
|
|
7
|
+
"pointer-events-none shrink-0 body-small text-neutral-900 dark:text-neutral-200",
|
|
8
|
+
adornmentEnd: "shrink-0 body-small text-neutral-900 dark:text-neutral-200",
|
|
9
|
+
base: "flex h-10 items-center gap-2 pr-1",
|
|
10
|
+
input:
|
|
11
|
+
"h-full w-full appearance-none border-0 bg-transparent p-0 [font-size:inherit] leading-[inherit] focus:shadow-none focus:ring-0 focus:outline-0",
|
|
12
|
+
},
|
|
13
|
+
variants: {
|
|
14
|
+
disabled: {
|
|
15
|
+
true: { input: "cursor-not-allowed" },
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export { inputVariants };
|
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
<script module>
|
|
2
|
+
/** @type {Map<string, Set>} valueCheckers */
|
|
3
|
+
// eslint-disable-next-line svelte/prefer-svelte-reactivity
|
|
4
|
+
const valueCheckers = new Map();
|
|
5
|
+
|
|
6
|
+
const checkValues = (name) => {
|
|
7
|
+
const checkers = valueCheckers.get(name);
|
|
8
|
+
for (const fn of checkers?.values() ?? []) {
|
|
9
|
+
fn?.();
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const addValueUpdater = (name, checker) => {
|
|
14
|
+
let checkerSet = valueCheckers.get(name);
|
|
15
|
+
if (!checkerSet) {
|
|
16
|
+
// eslint-disable-next-line svelte/prefer-svelte-reactivity
|
|
17
|
+
checkerSet = new Set();
|
|
18
|
+
valueCheckers.set(name, checkerSet);
|
|
19
|
+
}
|
|
20
|
+
checkerSet.add(checker);
|
|
21
|
+
|
|
22
|
+
return () => {
|
|
23
|
+
checkerSet.delete(checker);
|
|
24
|
+
if (!checkerSet.size) {
|
|
25
|
+
valueCheckers.delete(name);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
</script>
|
|
30
|
+
|
|
1
31
|
<script>
|
|
2
32
|
import { getContext } from "svelte";
|
|
3
33
|
import { radioVariants } from "./radio.variants.js";
|
|
@@ -27,6 +57,7 @@
|
|
|
27
57
|
...rest
|
|
28
58
|
} = $props();
|
|
29
59
|
|
|
60
|
+
let element = $state();
|
|
30
61
|
let store = getContext("form-field-store") ?? null;
|
|
31
62
|
|
|
32
63
|
let localValues = $derived.by(() => {
|
|
@@ -39,10 +70,31 @@
|
|
|
39
70
|
required: required ?? storeValues.required ?? false,
|
|
40
71
|
};
|
|
41
72
|
});
|
|
73
|
+
|
|
74
|
+
const handleChange = (e) => {
|
|
75
|
+
if (name?.length) {
|
|
76
|
+
checkValues(name);
|
|
77
|
+
} else {
|
|
78
|
+
checked = e.target.checked;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
$effect(() => {
|
|
83
|
+
let offUpdater;
|
|
84
|
+
if (name) {
|
|
85
|
+
offUpdater = addValueUpdater(name, () => {
|
|
86
|
+
checked = element?.checked || false;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return () => {
|
|
91
|
+
offUpdater?.();
|
|
92
|
+
};
|
|
93
|
+
});
|
|
42
94
|
</script>
|
|
43
95
|
|
|
44
96
|
<input
|
|
45
|
-
|
|
97
|
+
bind:this={element}
|
|
46
98
|
{checked}
|
|
47
99
|
class={radioVariants({
|
|
48
100
|
checked,
|
|
@@ -53,7 +105,8 @@
|
|
|
53
105
|
disabled={localValues.disabled}
|
|
54
106
|
id={localValues.id}
|
|
55
107
|
{name}
|
|
108
|
+
onchange={handleChange}
|
|
56
109
|
required={localValues.required}
|
|
57
|
-
type="
|
|
110
|
+
type="radio"
|
|
58
111
|
{value}
|
|
59
112
|
{...rest} />
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* @typedef {Object} Props
|
|
7
7
|
* @property {import('svelte').Snippet} [children] Content inside the tag – can be text, HTML, or Svelte components
|
|
8
8
|
* @property {string} [class=""] Additional CSS classes for the tag
|
|
9
|
-
* @property {string} [
|
|
10
|
-
* @property {
|
|
9
|
+
* @property {string} [iconEnd=""] Name of the icon to display at the end
|
|
10
|
+
* @property {string} [iconStart=""] Name of the icon to display at the start
|
|
11
11
|
* @property {boolean} [selected=false] Whether the tag is in a visually selected state
|
|
12
12
|
* @property {"round" | "round-big"} [shape="round"] Shape of the tag
|
|
13
13
|
* @property {"small" | "big"} [size="small"] Size of the tag
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
let {
|
|
19
19
|
children,
|
|
20
20
|
class: className,
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
iconEnd = "",
|
|
22
|
+
iconStart = "",
|
|
23
23
|
selected = false,
|
|
24
24
|
shape = "round",
|
|
25
25
|
size = "small",
|
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
<button
|
|
32
32
|
class={tagVariants({
|
|
33
33
|
class: className,
|
|
34
|
-
iconPosition,
|
|
35
34
|
selected,
|
|
36
35
|
shape,
|
|
37
36
|
size,
|
|
@@ -39,10 +38,13 @@
|
|
|
39
38
|
})}
|
|
40
39
|
type="button"
|
|
41
40
|
{...rest}>
|
|
42
|
-
{#if
|
|
43
|
-
<Icon name={
|
|
41
|
+
{#if iconStart}
|
|
42
|
+
<Icon name={iconStart} size={14} />
|
|
44
43
|
{/if}
|
|
45
44
|
<span>
|
|
46
45
|
{@render children?.()}
|
|
47
46
|
</span>
|
|
47
|
+
{#if iconEnd}
|
|
48
|
+
<Icon name={iconEnd} size={14} />
|
|
49
|
+
{/if}
|
|
48
50
|
</button>
|
|
@@ -13,13 +13,13 @@ declare const Tag: import("svelte").Component<{
|
|
|
13
13
|
*/
|
|
14
14
|
class?: string;
|
|
15
15
|
/**
|
|
16
|
-
* Name of the icon to display
|
|
16
|
+
* Name of the icon to display at the end
|
|
17
17
|
*/
|
|
18
|
-
|
|
18
|
+
iconEnd?: string;
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* Name of the icon to display at the start
|
|
21
21
|
*/
|
|
22
|
-
|
|
22
|
+
iconStart?: string;
|
|
23
23
|
/**
|
|
24
24
|
* Whether the tag is in a visually selected state
|
|
25
25
|
*/
|
|
@@ -47,13 +47,13 @@ type Props = {
|
|
|
47
47
|
*/
|
|
48
48
|
class?: string;
|
|
49
49
|
/**
|
|
50
|
-
* Name of the icon to display
|
|
50
|
+
* Name of the icon to display at the end
|
|
51
51
|
*/
|
|
52
|
-
|
|
52
|
+
iconEnd?: string;
|
|
53
53
|
/**
|
|
54
|
-
*
|
|
54
|
+
* Name of the icon to display at the start
|
|
55
55
|
*/
|
|
56
|
-
|
|
56
|
+
iconStart?: string;
|
|
57
57
|
/**
|
|
58
58
|
* Whether the tag is in a visually selected state
|
|
59
59
|
*/
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
export const tagVariants: import("tailwind-variants").TVReturnType<{
|
|
2
|
-
iconPosition: {
|
|
3
|
-
end: string;
|
|
4
|
-
};
|
|
5
2
|
selected: {
|
|
6
3
|
true: string;
|
|
7
4
|
};
|
|
@@ -18,9 +15,6 @@ export const tagVariants: import("tailwind-variants").TVReturnType<{
|
|
|
18
15
|
outline: string;
|
|
19
16
|
};
|
|
20
17
|
}, undefined, string[], {
|
|
21
|
-
iconPosition: {
|
|
22
|
-
end: string;
|
|
23
|
-
};
|
|
24
18
|
selected: {
|
|
25
19
|
true: string;
|
|
26
20
|
};
|
|
@@ -37,9 +31,6 @@ export const tagVariants: import("tailwind-variants").TVReturnType<{
|
|
|
37
31
|
outline: string;
|
|
38
32
|
};
|
|
39
33
|
}, undefined, import("tailwind-variants").TVReturnType<{
|
|
40
|
-
iconPosition: {
|
|
41
|
-
end: string;
|
|
42
|
-
};
|
|
43
34
|
selected: {
|
|
44
35
|
true: string;
|
|
45
36
|
};
|
|
@@ -8,11 +8,8 @@ const tagVariants = tv({
|
|
|
8
8
|
"border border-neutral-100 hover:border-neutral-200 dark:border-neutral-700 hover:dark:border-neutral-700",
|
|
9
9
|
],
|
|
10
10
|
variants: {
|
|
11
|
-
iconPosition: {
|
|
12
|
-
end: "flex-row-reverse",
|
|
13
|
-
},
|
|
14
11
|
selected: {
|
|
15
|
-
true: "border-neutral-900
|
|
12
|
+
true: "border-neutral-900 bg-neutral-900! text-neutral-100 dark:border-blue-400 dark:bg-blue-400!",
|
|
16
13
|
},
|
|
17
14
|
shape: {
|
|
18
15
|
round: "rounded-sm",
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { Calendar } from "bits-ui";
|
|
3
|
+
import { Icon } from "../../../index.js";
|
|
4
|
+
import { calendarVariants } from "./calendar.variant.js";
|
|
5
|
+
import RootContext from "./RootContext.svelte";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {import("bits-ui").CalendarRootPropsWithoutHTML} CalendarRootProps
|
|
9
|
+
*
|
|
10
|
+
* @typedef {Object} Props
|
|
11
|
+
* @property {import('svelte').Snippet} [children] Children content – can be text, HTML, or other Svelte components
|
|
12
|
+
* @property {string} [class=""] Additional CSS classes to apply to the component
|
|
13
|
+
* @property {boolean} [hideHeader=false] Whether to show the header or not
|
|
14
|
+
* @property {number} [maxMonths=false] The maximum of months to display side by side
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** @type {Omit<CalendarRootProps, "disabled" | "disableDaysOutsideMonth" | "isDateDisabled" | "numberOfMonths" | "pagedNavigation" | "weekStartsOn"> & Props} */
|
|
18
|
+
let {
|
|
19
|
+
children: _children,
|
|
20
|
+
class: className = "",
|
|
21
|
+
hideHeader = false,
|
|
22
|
+
locale = "de",
|
|
23
|
+
maxDays = 2,
|
|
24
|
+
maxMonths = 1,
|
|
25
|
+
ref = $bindable(null),
|
|
26
|
+
type,
|
|
27
|
+
value = $bindable(),
|
|
28
|
+
weekdayFormat = "short",
|
|
29
|
+
...rest
|
|
30
|
+
} = $props();
|
|
31
|
+
|
|
32
|
+
let ro;
|
|
33
|
+
let numberOfMonths = $state(1);
|
|
34
|
+
let styles = $derived(calendarVariants());
|
|
35
|
+
|
|
36
|
+
const setValue = (newValue) => {
|
|
37
|
+
if (Array.isArray(newValue)) {
|
|
38
|
+
// make sure dates are sorted for the range selection
|
|
39
|
+
value = newValue.toSorted();
|
|
40
|
+
} else {
|
|
41
|
+
value = newValue;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const updateVisibleMonths = (table, parentElement) => {
|
|
46
|
+
numberOfMonths = Math.min(
|
|
47
|
+
Math.max(Math.floor(parentElement.offsetWidth / table.offsetWidth), 1),
|
|
48
|
+
maxMonths,
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
$effect(() => {
|
|
53
|
+
if (maxMonths > 1 && ref?.parentElement) {
|
|
54
|
+
const firstTable = ref.querySelector("[data-calendar-grid]");
|
|
55
|
+
ro = new ResizeObserver(() => {
|
|
56
|
+
updateVisibleMonths(firstTable, ref.parentElement);
|
|
57
|
+
});
|
|
58
|
+
ro.observe(ref.parentElement);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return () => {
|
|
62
|
+
numberOfMonths = 1;
|
|
63
|
+
ro?.disconnect();
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
</script>
|
|
67
|
+
|
|
68
|
+
<Calendar.Root
|
|
69
|
+
class={styles.base({ class: className })}
|
|
70
|
+
{locale}
|
|
71
|
+
{maxDays}
|
|
72
|
+
{numberOfMonths}
|
|
73
|
+
pagedNavigation
|
|
74
|
+
bind:ref
|
|
75
|
+
{type}
|
|
76
|
+
bind:value={() => value, setValue}
|
|
77
|
+
{weekdayFormat}
|
|
78
|
+
{...rest}>
|
|
79
|
+
{#snippet children({ months, weekdays })}
|
|
80
|
+
{#if !hideHeader}
|
|
81
|
+
<Calendar.Header class={styles.header({ class: className })} {...rest}>
|
|
82
|
+
<Calendar.PrevButton class={styles.headerBtn({ class: "rotate-90" })}>
|
|
83
|
+
<Icon name="chevronDown" size={20} />
|
|
84
|
+
</Calendar.PrevButton>
|
|
85
|
+
<Calendar.Heading class={styles.heading()} />
|
|
86
|
+
<Calendar.NextButton class={styles.headerBtn({ class: "rotate-270" })}>
|
|
87
|
+
<Icon name="chevronDown" size={20} />
|
|
88
|
+
</Calendar.NextButton>
|
|
89
|
+
</Calendar.Header>
|
|
90
|
+
{/if}
|
|
91
|
+
<RootContext {maxDays} {months} {value} {weekdays}>
|
|
92
|
+
{@render _children?.()}
|
|
93
|
+
</RootContext>
|
|
94
|
+
{/snippet}
|
|
95
|
+
</Calendar.Root>
|