/
Checkbox.svelte
70 lines (61 loc) · 2.35 KB
/
Checkbox.svelte
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<script lang="ts">
import { twMerge } from 'tailwind-merge';
import { getContext } from 'svelte';
import type { FormColorType } from '../types';
import { labelClass, inputClass } from './Radio.svelte';
import Label from './Label.svelte';
// properties forwarding
export let color: FormColorType = 'primary';
export let custom: boolean = false;
export let inline: boolean = false;
export let group: (string | number)[] = [];
export let value: string | number = 'on';
export let checked: boolean | undefined = undefined;
export let spacing: string = $$slots.default ? 'me-2' : '';
// tinted if put in component having its own background
let background: boolean = getContext('background');
// react on external group changes
function init(_: HTMLElement, _group: (string | number)[]) {
if (checked === undefined) checked = _group.includes(value);
onChange();
return {
update(_group: (string | number)[]) {
checked = _group.includes(value);
}
};
}
function onChange() {
// There's a bug in Svelte and bind:group is not working with wrapped checkbox
// This workaround is taken from:
// https://svelte.dev/repl/de117399559f4e7e9e14e2fc9ab243cc?version=3.12.1
const index = group.indexOf(value);
if (checked === undefined) checked = index >= 0;
if (checked) {
if (index < 0) {
group.push(value);
group = group;
}
} else {
if (index >= 0) {
group.splice(index, 1);
group = group;
}
}
}
</script>
<Label class={labelClass(inline, $$props.class)} show={$$slots.default}>
<input use:init={group} type="checkbox" bind:checked on:keyup on:keydown on:keypress on:focus on:blur on:click on:mouseover on:mouseenter on:mouseleave on:paste on:change={onChange} on:change {value} {...$$restProps} class={inputClass(custom, color, true, background, spacing, $$slots.default || $$props.class)} />
<slot />
</Label>
<!--
@component
[Go to docs](https://flowbite-svelte.com/)
## Props
@prop export let color: FormColorType = 'primary';
@prop export let custom: boolean = false;
@prop export let inline: boolean = false;
@prop export let group: (string | number)[] = [];
@prop export let value: string | number = 'on';
@prop export let checked: boolean | undefined = undefined;
@prop export let spacing: string = $$slots.default ? 'me-2' : '';
-->