@ibis-design/svelte 0.5.0 → 0.7.0
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/README.md +42 -10
- package/dist/components/buttons/Button.svelte +106 -0
- package/dist/components/buttons/Button.svelte.d.ts +69 -0
- package/dist/components/buttons/DropdownButton.svelte +91 -0
- package/dist/components/buttons/DropdownButton.svelte.d.ts +33 -0
- package/dist/components/buttons/PillTab.svelte +84 -0
- package/dist/components/buttons/PillTab.svelte.d.ts +55 -0
- package/dist/components/containers/Banner.svelte +73 -0
- package/dist/components/containers/Banner.svelte.d.ts +16 -0
- package/dist/components/containers/Card.svelte +34 -0
- package/dist/components/containers/Card.svelte.d.ts +14 -0
- package/dist/components/containers/PillTabs.svelte +22 -0
- package/dist/components/containers/PillTabs.svelte.d.ts +6 -0
- package/dist/components/containers/TipIndicator.svelte +78 -0
- package/dist/components/containers/TipIndicator.svelte.d.ts +28 -0
- package/dist/components/containers/Toaster.svelte +75 -0
- package/dist/components/containers/Toaster.svelte.d.ts +16 -0
- package/dist/components/containers/Tooltip.svelte.d.ts +26 -0
- package/dist/components/inputs/.gitkeep +0 -0
- package/dist/components/inputs/Checkbox.svelte +95 -0
- package/dist/components/inputs/Checkbox.svelte.d.ts +33 -0
- package/dist/components/inputs/Chips.svelte +104 -0
- package/dist/components/inputs/Chips.svelte.d.ts +48 -0
- package/dist/components/inputs/Dropdown.svelte +83 -0
- package/dist/components/inputs/Dropdown.svelte.d.ts +15 -0
- package/dist/components/inputs/Radio.svelte +109 -0
- package/dist/components/inputs/Radio.svelte.d.ts +49 -0
- package/dist/components/inputs/Switch.svelte +45 -0
- package/dist/components/inputs/Switch.svelte.d.ts +21 -0
- package/dist/components/inputs/TextArea.svelte +65 -0
- package/dist/components/inputs/TextArea.svelte.d.ts +14 -0
- package/dist/components/inputs/TextInput.svelte +273 -0
- package/dist/components/inputs/TextInput.svelte.d.ts +140 -0
- package/dist/components/inputs/TextLink.svelte +102 -0
- package/dist/components/inputs/TextLink.svelte.d.ts +21 -0
- package/dist/index.d.ts +21 -20
- package/dist/index.js +36 -3187
- package/dist/layouts/AppLayout.svelte +83 -0
- package/dist/layouts/AppLayout.svelte.d.ts +20 -0
- package/dist/layouts/AuthLayout.svelte +63 -0
- package/dist/layouts/AuthLayout.svelte.d.ts +18 -0
- package/dist/layouts/DashboardLayout.svelte +88 -0
- package/dist/layouts/DashboardLayout.svelte.d.ts +20 -0
- package/dist/types/button.js +5 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +5 -0
- package/dist/types/layout.d.ts +1 -1
- package/dist/types/layout.js +1 -0
- package/package.json +16 -11
- package/dist/index.css +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/components/buttons/Button.svelte.d.ts +0 -1
- package/dist/lib/components/buttons/DropdownButton.svelte.d.ts +0 -1
- package/dist/lib/components/buttons/PillTab.svelte.d.ts +0 -1
- package/dist/lib/components/containers/Banner.svelte.d.ts +0 -1
- package/dist/lib/components/containers/Card.svelte.d.ts +0 -1
- package/dist/lib/components/containers/Toaster.svelte.d.ts +0 -1
- package/dist/lib/components/inputs/Checkbox.svelte.d.ts +0 -1
- package/dist/lib/components/inputs/Chips.svelte.d.ts +0 -1
- package/dist/lib/components/inputs/DateInput.svelte.d.ts +0 -1
- package/dist/lib/components/inputs/DateInput2.svelte.d.ts +0 -1
- package/dist/lib/components/inputs/Dropdown.svelte.d.ts +0 -1
- package/dist/lib/components/inputs/Password.svelte.d.ts +0 -1
- package/dist/lib/components/inputs/Radio.svelte.d.ts +0 -1
- package/dist/lib/components/inputs/TextArea.svelte.d.ts +0 -1
- package/dist/lib/components/inputs/TextInput.svelte.d.ts +0 -1
- package/dist/lib/components/inputs/TextLink.svelte.d.ts +0 -1
- package/dist/lib/layouts/AppLayout.svelte.d.ts +0 -1
- package/dist/lib/layouts/AuthLayout.svelte.d.ts +0 -1
- package/dist/lib/layouts/DashboardLayout.svelte.d.ts +0 -1
- /package/dist/{types/input.d.ts → components/containers/Tooltip.svelte} +0 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import '@ibis-design/css/components/tipIndicator.css';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
/**
|
|
6
|
+
* Controls the position of the tooltip relative to the indicator.
|
|
7
|
+
*
|
|
8
|
+
* @default "top"
|
|
9
|
+
*/
|
|
10
|
+
position?: 'top' | 'bottom' | 'left' | 'right';
|
|
11
|
+
/**
|
|
12
|
+
* The plain text content displayed inside the tooltip.
|
|
13
|
+
*/
|
|
14
|
+
text: string;
|
|
15
|
+
/**
|
|
16
|
+
* Disables the tooltip from appearing on hover.
|
|
17
|
+
*
|
|
18
|
+
* @default false
|
|
19
|
+
*/
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Controls the width of the tooltip.
|
|
23
|
+
*
|
|
24
|
+
* @default "auto"
|
|
25
|
+
*/
|
|
26
|
+
width?: 'auto' | '240' | '360';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let { position = 'top', text, disabled = false, width = 'auto' }: Props = $props();
|
|
30
|
+
|
|
31
|
+
let visible = $state(false);
|
|
32
|
+
|
|
33
|
+
const show = () => {
|
|
34
|
+
if (!disabled) visible = true;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const hide = () => {
|
|
38
|
+
visible = false;
|
|
39
|
+
};
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<span
|
|
43
|
+
class="ibis-tip-indicator"
|
|
44
|
+
onmouseenter={show}
|
|
45
|
+
onmouseleave={hide}
|
|
46
|
+
onfocus={show}
|
|
47
|
+
onblur={hide}
|
|
48
|
+
tabindex="0"
|
|
49
|
+
role="button"
|
|
50
|
+
aria-describedby="ibis-tip"
|
|
51
|
+
>
|
|
52
|
+
<svg
|
|
53
|
+
class="ibis-tip-indicator__icon"
|
|
54
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
55
|
+
viewBox="0 0 24 24"
|
|
56
|
+
fill="none"
|
|
57
|
+
aria-hidden="true"
|
|
58
|
+
>
|
|
59
|
+
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" />
|
|
60
|
+
<line
|
|
61
|
+
x1="12"
|
|
62
|
+
y1="11"
|
|
63
|
+
x2="12"
|
|
64
|
+
y2="17"
|
|
65
|
+
stroke="currentColor"
|
|
66
|
+
stroke-width="2"
|
|
67
|
+
stroke-linecap="round"
|
|
68
|
+
/>
|
|
69
|
+
<circle cx="12" cy="7.5" r="1.2" fill="currentColor" />
|
|
70
|
+
</svg>
|
|
71
|
+
|
|
72
|
+
{#if visible}
|
|
73
|
+
<div id="ibis-tip" class="ibis-tip ibis-tip--{position} ibis-tip--width-{width}" role="tooltip">
|
|
74
|
+
<span class="ibis-tip__text">{text}</span>
|
|
75
|
+
<span class="ibis-tip__arrow"></span>
|
|
76
|
+
</div>
|
|
77
|
+
{/if}
|
|
78
|
+
</span>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import '@ibis-design/css/components/tipIndicator.css';
|
|
2
|
+
interface Props {
|
|
3
|
+
/**
|
|
4
|
+
* Controls the position of the tooltip relative to the indicator.
|
|
5
|
+
*
|
|
6
|
+
* @default "top"
|
|
7
|
+
*/
|
|
8
|
+
position?: 'top' | 'bottom' | 'left' | 'right';
|
|
9
|
+
/**
|
|
10
|
+
* The plain text content displayed inside the tooltip.
|
|
11
|
+
*/
|
|
12
|
+
text: string;
|
|
13
|
+
/**
|
|
14
|
+
* Disables the tooltip from appearing on hover.
|
|
15
|
+
*
|
|
16
|
+
* @default false
|
|
17
|
+
*/
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Controls the width of the tooltip.
|
|
21
|
+
*
|
|
22
|
+
* @default "auto"
|
|
23
|
+
*/
|
|
24
|
+
width?: 'auto' | '240' | '360';
|
|
25
|
+
}
|
|
26
|
+
declare const TipIndicator: import("svelte").Component<Props, {}, "">;
|
|
27
|
+
type TipIndicator = ReturnType<typeof TipIndicator>;
|
|
28
|
+
export default TipIndicator;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import '@ibis-design/css/components/toaster.css';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
|
|
5
|
+
type ToastType = 'success' | 'error' | 'accent' | 'default';
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
type?: ToastType;
|
|
9
|
+
title?: string;
|
|
10
|
+
message?: string;
|
|
11
|
+
children?: Snippet;
|
|
12
|
+
icon?: Snippet;
|
|
13
|
+
iconText?: string;
|
|
14
|
+
closable?: boolean;
|
|
15
|
+
loading?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
type = 'default',
|
|
20
|
+
title,
|
|
21
|
+
message,
|
|
22
|
+
children,
|
|
23
|
+
icon,
|
|
24
|
+
iconText,
|
|
25
|
+
closable,
|
|
26
|
+
loading
|
|
27
|
+
}: Props = $props();
|
|
28
|
+
|
|
29
|
+
let visible = $state(true);
|
|
30
|
+
|
|
31
|
+
const close = () => {
|
|
32
|
+
visible = false;
|
|
33
|
+
};
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
{#if visible}
|
|
37
|
+
<div
|
|
38
|
+
class="ibis-toaster"
|
|
39
|
+
role="status"
|
|
40
|
+
class:ibis-toaster--success={type === 'success'}
|
|
41
|
+
class:ibis-toaster--error={type === 'error'}
|
|
42
|
+
class:ibis-toaster--accent={type === 'accent'}
|
|
43
|
+
class:ibis-toaster--default={type === 'default'}
|
|
44
|
+
>
|
|
45
|
+
{#if loading || icon || iconText}
|
|
46
|
+
<div class="ibis-toaster__icon">
|
|
47
|
+
{#if loading}
|
|
48
|
+
<span class="ibis-toaster__loader" aria-hidden="true"></span>
|
|
49
|
+
{:else if icon}
|
|
50
|
+
{@render icon?.()}
|
|
51
|
+
{:else}
|
|
52
|
+
{iconText}
|
|
53
|
+
{/if}
|
|
54
|
+
</div>
|
|
55
|
+
{/if}
|
|
56
|
+
|
|
57
|
+
<div class="ibis-toaster__content">
|
|
58
|
+
{#if title}
|
|
59
|
+
<div class="ibis-toaster__title">{title}</div>
|
|
60
|
+
{/if}
|
|
61
|
+
|
|
62
|
+
<div class="ibis-toaster__message">
|
|
63
|
+
{#if children}
|
|
64
|
+
{@render children?.()}
|
|
65
|
+
{:else if message}
|
|
66
|
+
{message}
|
|
67
|
+
{/if}
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
{#if closable}
|
|
72
|
+
<button class="ibis-toaster__close" onclick={close} aria-label="Close"> x </button>
|
|
73
|
+
{/if}
|
|
74
|
+
</div>
|
|
75
|
+
{/if}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import '@ibis-design/css/components/toaster.css';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
type ToastType = 'success' | 'error' | 'accent' | 'default';
|
|
4
|
+
interface Props {
|
|
5
|
+
type?: ToastType;
|
|
6
|
+
title?: string;
|
|
7
|
+
message?: string;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
icon?: Snippet;
|
|
10
|
+
iconText?: string;
|
|
11
|
+
closable?: boolean;
|
|
12
|
+
loading?: boolean;
|
|
13
|
+
}
|
|
14
|
+
declare const Toaster: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type Toaster = ReturnType<typeof Toaster>;
|
|
16
|
+
export default Toaster;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export default Tooltip;
|
|
2
|
+
type Tooltip = SvelteComponent<{
|
|
3
|
+
[x: string]: never;
|
|
4
|
+
}, {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
}, {}> & {
|
|
7
|
+
$$bindings?: string | undefined;
|
|
8
|
+
};
|
|
9
|
+
declare const Tooltip: $$__sveltets_2_IsomorphicComponent<{
|
|
10
|
+
[x: string]: never;
|
|
11
|
+
}, {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
}, {}, {}, string>;
|
|
14
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
15
|
+
new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
|
|
16
|
+
$$bindings?: Bindings;
|
|
17
|
+
} & Exports;
|
|
18
|
+
(internal: unknown, props: {
|
|
19
|
+
$$events?: Events;
|
|
20
|
+
$$slots?: Slots;
|
|
21
|
+
}): Exports & {
|
|
22
|
+
$set?: any;
|
|
23
|
+
$on?: any;
|
|
24
|
+
};
|
|
25
|
+
z_$$bindings?: Bindings;
|
|
26
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import "@ibis-design/css/components/checkbox.css";
|
|
3
|
+
import type { Snippet } from "svelte";
|
|
4
|
+
import type { HTMLInputAttributes } from "svelte/elements";
|
|
5
|
+
|
|
6
|
+
interface Props extends HTMLInputAttributes {
|
|
7
|
+
label?: string;
|
|
8
|
+
id?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Defines whether the checkbox is checked.
|
|
11
|
+
*
|
|
12
|
+
* @default false
|
|
13
|
+
*/
|
|
14
|
+
checked?: boolean;
|
|
15
|
+
inputSize?: "sm" | "md" | "lg";
|
|
16
|
+
/**
|
|
17
|
+
* Defines whether the checkbox is disabled.
|
|
18
|
+
*
|
|
19
|
+
* @default false
|
|
20
|
+
*/
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Defines whether the checkbox is in an invalid state.
|
|
24
|
+
*
|
|
25
|
+
* @default false
|
|
26
|
+
*/
|
|
27
|
+
invalid?: boolean;
|
|
28
|
+
description?: string;
|
|
29
|
+
error?: string;
|
|
30
|
+
helpText?: string;
|
|
31
|
+
checkboxSnippet?: Snippet;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let {
|
|
35
|
+
id,
|
|
36
|
+
label,
|
|
37
|
+
checked = $bindable(false),
|
|
38
|
+
inputSize = "md",
|
|
39
|
+
disabled = false,
|
|
40
|
+
invalid = false,
|
|
41
|
+
description,
|
|
42
|
+
error,
|
|
43
|
+
helpText,
|
|
44
|
+
checkboxSnippet,
|
|
45
|
+
...rest
|
|
46
|
+
}: Props = $props();
|
|
47
|
+
|
|
48
|
+
const fallbackId = `ibis-checkbox-${Math.random().toString(36).slice(2)}`;
|
|
49
|
+
const inputId = $derived(id ?? fallbackId);
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<div
|
|
53
|
+
class="ibis-checkbox
|
|
54
|
+
ibis-checkbox--{inputSize}
|
|
55
|
+
{disabled ? 'ibis-checkbox--disabled' : ''}
|
|
56
|
+
{invalid ? 'ibis-checkbox--invalid' : ''}">
|
|
57
|
+
{#if label}
|
|
58
|
+
<div class="ibis-checkbox__label-wrapper">
|
|
59
|
+
<label class="ibis-checkbox__label" for={inputId}>{label}</label>
|
|
60
|
+
|
|
61
|
+
{#if description}
|
|
62
|
+
<div class="ibis-checkbox__description">{description}</div>
|
|
63
|
+
{/if}
|
|
64
|
+
</div>
|
|
65
|
+
{/if}
|
|
66
|
+
|
|
67
|
+
<div class="ibis-checkbox__wrapper">
|
|
68
|
+
<label class="ibis-checkbox__control">
|
|
69
|
+
<input
|
|
70
|
+
{...rest}
|
|
71
|
+
id={inputId}
|
|
72
|
+
type="checkbox"
|
|
73
|
+
bind:checked
|
|
74
|
+
{disabled}
|
|
75
|
+
aria-invalid={invalid}
|
|
76
|
+
class="ibis-checkbox__input" />
|
|
77
|
+
|
|
78
|
+
<span class="ibis-checkbox__box">
|
|
79
|
+
<span class="ibis-checkbox__icon">
|
|
80
|
+
{@render checkboxSnippet?.()}
|
|
81
|
+
</span>
|
|
82
|
+
</span>
|
|
83
|
+
|
|
84
|
+
{#if label}
|
|
85
|
+
<span class="ibis-checkbox__text">{label}</span>
|
|
86
|
+
{/if}
|
|
87
|
+
</label>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
{#if invalid && error}
|
|
91
|
+
<div class="ibis-checkbox__error" role="alert">{error}</div>
|
|
92
|
+
{:else if helpText}
|
|
93
|
+
<div class="ibis-checkbox__help">{helpText}</div>
|
|
94
|
+
{/if}
|
|
95
|
+
</div>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import "@ibis-design/css/components/checkbox.css";
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
import type { HTMLInputAttributes } from "svelte/elements";
|
|
4
|
+
interface Props extends HTMLInputAttributes {
|
|
5
|
+
label?: string;
|
|
6
|
+
id?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Defines whether the checkbox is checked.
|
|
9
|
+
*
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
checked?: boolean;
|
|
13
|
+
inputSize?: "sm" | "md" | "lg";
|
|
14
|
+
/**
|
|
15
|
+
* Defines whether the checkbox is disabled.
|
|
16
|
+
*
|
|
17
|
+
* @default false
|
|
18
|
+
*/
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Defines whether the checkbox is in an invalid state.
|
|
22
|
+
*
|
|
23
|
+
* @default false
|
|
24
|
+
*/
|
|
25
|
+
invalid?: boolean;
|
|
26
|
+
description?: string;
|
|
27
|
+
error?: string;
|
|
28
|
+
helpText?: string;
|
|
29
|
+
checkboxSnippet?: Snippet;
|
|
30
|
+
}
|
|
31
|
+
declare const Checkbox: import("svelte").Component<Props, {}, "checked">;
|
|
32
|
+
type Checkbox = ReturnType<typeof Checkbox>;
|
|
33
|
+
export default Checkbox;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import "@ibis-design/css/components/chips.css";
|
|
3
|
+
import type { HTMLButtonAttributes } from "svelte/elements";
|
|
4
|
+
import type { Snippet } from "svelte";
|
|
5
|
+
// define props
|
|
6
|
+
interface Props extends HTMLButtonAttributes {
|
|
7
|
+
/**
|
|
8
|
+
* Defines the size of the chip.
|
|
9
|
+
*
|
|
10
|
+
* @default "md"
|
|
11
|
+
*/
|
|
12
|
+
size?: "sm" | "md" | "lg";
|
|
13
|
+
/**
|
|
14
|
+
* Defines whether the chip is disabled.
|
|
15
|
+
*
|
|
16
|
+
* @default false
|
|
17
|
+
*/
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Defines whether the chip is selected.
|
|
21
|
+
*
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
selected?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Shows a loading spinner and disables the chip.
|
|
27
|
+
*
|
|
28
|
+
* @default false
|
|
29
|
+
*/
|
|
30
|
+
loading?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Disables the chip and applies skeleton styling
|
|
33
|
+
*
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
skeleton?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Plain text label for the chip. Use children snippet for complex content.
|
|
39
|
+
*/
|
|
40
|
+
label?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Plain text or emoji icon. Use icon snippet for complex content.
|
|
43
|
+
*/
|
|
44
|
+
iconText?: string;
|
|
45
|
+
children?: Snippet;
|
|
46
|
+
icon?: Snippet<[]>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let {
|
|
50
|
+
size = "md",
|
|
51
|
+
selected = $bindable(false),
|
|
52
|
+
disabled = false,
|
|
53
|
+
loading = false,
|
|
54
|
+
skeleton = false,
|
|
55
|
+
label,
|
|
56
|
+
iconText,
|
|
57
|
+
children,
|
|
58
|
+
icon,
|
|
59
|
+
...rest
|
|
60
|
+
}: Props = $props();
|
|
61
|
+
|
|
62
|
+
const toggleSelected = () => {
|
|
63
|
+
if (disabled || loading || skeleton) return;
|
|
64
|
+
selected = !selected;
|
|
65
|
+
};
|
|
66
|
+
</script>
|
|
67
|
+
|
|
68
|
+
<!-- add how it would look in the DOM -->
|
|
69
|
+
<button
|
|
70
|
+
{...rest}
|
|
71
|
+
{disabled}
|
|
72
|
+
aria-pressed={selected}
|
|
73
|
+
aria-busy={loading}
|
|
74
|
+
onclick={toggleSelected}
|
|
75
|
+
class="ibis-chips
|
|
76
|
+
ibis-chips--{size}
|
|
77
|
+
{selected ? 'ibis-chips--selected' : ''}
|
|
78
|
+
{skeleton ? 'ibis-chips--skeleton' : ''}">
|
|
79
|
+
<span class="ibis-chips__content {skeleton ? 'ibis-chips__content--hidden' : ''}">
|
|
80
|
+
{#if icon || iconText}
|
|
81
|
+
<span class="ibis-chips__icon">
|
|
82
|
+
{#if icon}
|
|
83
|
+
{@render icon()}
|
|
84
|
+
{:else}
|
|
85
|
+
{iconText}
|
|
86
|
+
{/if}
|
|
87
|
+
</span>
|
|
88
|
+
{/if}
|
|
89
|
+
|
|
90
|
+
{#if children || label}
|
|
91
|
+
<span class="ibis-chips__label">
|
|
92
|
+
{#if children}
|
|
93
|
+
{@render children?.()}
|
|
94
|
+
{:else}
|
|
95
|
+
{label}
|
|
96
|
+
{/if}
|
|
97
|
+
</span>
|
|
98
|
+
{/if}
|
|
99
|
+
</span>
|
|
100
|
+
|
|
101
|
+
{#if loading}
|
|
102
|
+
<span class="ibis-chips__loader" aria-hidden="true"></span>
|
|
103
|
+
{/if}
|
|
104
|
+
</button>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import "@ibis-design/css/components/chips.css";
|
|
2
|
+
import type { HTMLButtonAttributes } from "svelte/elements";
|
|
3
|
+
import type { Snippet } from "svelte";
|
|
4
|
+
interface Props extends HTMLButtonAttributes {
|
|
5
|
+
/**
|
|
6
|
+
* Defines the size of the chip.
|
|
7
|
+
*
|
|
8
|
+
* @default "md"
|
|
9
|
+
*/
|
|
10
|
+
size?: "sm" | "md" | "lg";
|
|
11
|
+
/**
|
|
12
|
+
* Defines whether the chip is disabled.
|
|
13
|
+
*
|
|
14
|
+
* @default false
|
|
15
|
+
*/
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Defines whether the chip is selected.
|
|
19
|
+
*
|
|
20
|
+
* @default false
|
|
21
|
+
*/
|
|
22
|
+
selected?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Shows a loading spinner and disables the chip.
|
|
25
|
+
*
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
loading?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Disables the chip and applies skeleton styling
|
|
31
|
+
*
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
skeleton?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Plain text label for the chip. Use children snippet for complex content.
|
|
37
|
+
*/
|
|
38
|
+
label?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Plain text or emoji icon. Use icon snippet for complex content.
|
|
41
|
+
*/
|
|
42
|
+
iconText?: string;
|
|
43
|
+
children?: Snippet;
|
|
44
|
+
icon?: Snippet<[]>;
|
|
45
|
+
}
|
|
46
|
+
declare const Chips: import("svelte").Component<Props, {}, "selected">;
|
|
47
|
+
type Chips = ReturnType<typeof Chips>;
|
|
48
|
+
export default Chips;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import "@ibis-design/css/components/dropdown.css";
|
|
3
|
+
import TextInput from "./TextInput.svelte";
|
|
4
|
+
|
|
5
|
+
interface Options {
|
|
6
|
+
label: string;
|
|
7
|
+
value: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
label?: string;
|
|
12
|
+
value?: string;
|
|
13
|
+
options?: Options[];
|
|
14
|
+
placeholder?: string;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
label,
|
|
20
|
+
value = $bindable(""),
|
|
21
|
+
options = [],
|
|
22
|
+
placeholder = "Select...",
|
|
23
|
+
disabled = false,
|
|
24
|
+
}: Props = $props();
|
|
25
|
+
|
|
26
|
+
let open = $state(false);
|
|
27
|
+
let dropdownRef = $state<HTMLDivElement | null>(null);
|
|
28
|
+
|
|
29
|
+
const listboxId = `ibis-dropdown-listbox-${Math.random().toString(36).slice(2)}`;
|
|
30
|
+
|
|
31
|
+
const selectOption = (option: Options) => {
|
|
32
|
+
value = option.value;
|
|
33
|
+
open = false;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const toggleDropdown = () => {
|
|
37
|
+
if (!disabled) open = !open;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const handleKeydown = (e: KeyboardEvent) => {
|
|
41
|
+
if (e.key === "Escape") open = false;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const handleClickOutside = (e: MouseEvent) => {
|
|
45
|
+
if (dropdownRef && !dropdownRef.contains(e.target as Node)) {
|
|
46
|
+
open = false;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const selectedLabel = $derived(options.find((o) => o.value === value)?.label ?? value);
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<svelte:window onclick={handleClickOutside} />
|
|
54
|
+
|
|
55
|
+
{#snippet suffixSnippet()}
|
|
56
|
+
▾
|
|
57
|
+
{/snippet}
|
|
58
|
+
|
|
59
|
+
<div
|
|
60
|
+
class="ibis-dropdown {open ? 'ibis-dropdown--open' : ''}"
|
|
61
|
+
role="combobox"
|
|
62
|
+
tabindex="0"
|
|
63
|
+
aria-expanded={open}
|
|
64
|
+
aria-haspopup="listbox"
|
|
65
|
+
aria-controls={listboxId}
|
|
66
|
+
bind:this={dropdownRef}
|
|
67
|
+
onkeydown={handleKeydown}>
|
|
68
|
+
<button type="button" class="ibis-dropdown__trigger" onclick={toggleDropdown} {disabled}>
|
|
69
|
+
<TextInput {label} value={selectedLabel} {placeholder} {disabled} readonly {suffixSnippet} />
|
|
70
|
+
</button>
|
|
71
|
+
|
|
72
|
+
{#if open}
|
|
73
|
+
<ul id={listboxId} role="listbox" class="ibis-dropdown__menu">
|
|
74
|
+
{#each options as option (option.value)}
|
|
75
|
+
<li role="option" aria-selected={option.value === value}>
|
|
76
|
+
<button type="button" class="ibis-dropdown__item" onclick={() => selectOption(option)}>
|
|
77
|
+
{option.label}
|
|
78
|
+
</button>
|
|
79
|
+
</li>
|
|
80
|
+
{/each}
|
|
81
|
+
</ul>
|
|
82
|
+
{/if}
|
|
83
|
+
</div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import "@ibis-design/css/components/dropdown.css";
|
|
2
|
+
interface Options {
|
|
3
|
+
label: string;
|
|
4
|
+
value: string;
|
|
5
|
+
}
|
|
6
|
+
interface Props {
|
|
7
|
+
label?: string;
|
|
8
|
+
value?: string;
|
|
9
|
+
options?: Options[];
|
|
10
|
+
placeholder?: string;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
}
|
|
13
|
+
declare const Dropdown: import("svelte").Component<Props, {}, "value">;
|
|
14
|
+
type Dropdown = ReturnType<typeof Dropdown>;
|
|
15
|
+
export default Dropdown;
|