@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
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Svelte 5 component library for the IBIS design system. Provides primitives (Butt
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
7
|
- **Svelte 5** (runes and snippets; no slots).
|
|
8
|
-
- **@ibis-design/css** — design tokens.
|
|
8
|
+
- **@ibis-design/css** — design tokens. Load the stylesheet once and set `data-theme` on `<html>` (`ib-light`, `ib-dark`, `alc-light`, `alc-dark`).
|
|
9
9
|
|
|
10
10
|
## Installation
|
|
11
11
|
|
|
@@ -15,16 +15,38 @@ npm install @ibis-design/svelte @ibis-design/css
|
|
|
15
15
|
|
|
16
16
|
## Token CSS
|
|
17
17
|
|
|
18
|
-
Import
|
|
18
|
+
Import tokens and set the theme on the document root:
|
|
19
19
|
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
import '@ibis-design/css';
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
```svelte
|
|
21
|
+
<script>
|
|
22
|
+
import '@ibis-design/css';
|
|
23
|
+
|
|
24
|
+
if (typeof document !== 'undefined') {
|
|
25
|
+
document.documentElement.dataset.theme = 'ib-light'; // or alc-dark, etc.
|
|
26
|
+
}
|
|
27
|
+
</script>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Without the CSS import and `data-theme`, components will not resolve design-system variables.
|
|
31
|
+
|
|
32
|
+
### Canonical variable names
|
|
33
|
+
|
|
34
|
+
Use semantic tokens from the active theme, for example:
|
|
35
|
+
|
|
36
|
+
- `--font-size-body-sm` (not legacy `normal-text` names)
|
|
37
|
+
- `--color-brand-secondary` for secondary actions
|
|
38
|
+
- `--shadow-focus-default` for focus rings
|
|
39
|
+
- `--border-radius-md`, `--border-color-button`
|
|
40
|
+
|
|
41
|
+
### Shared component CSS
|
|
42
|
+
|
|
43
|
+
All component styles live in `@ibis-design/css` (`packages/css/src/styles/components/`). Each Svelte component imports its stylesheet from the CSS package, for example in `Button.svelte`:
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import '@ibis-design/css/components/button.css';
|
|
25
47
|
```
|
|
26
48
|
|
|
27
|
-
|
|
49
|
+
Consumers get styles automatically when they import the component; no separate CSS import is required unless you use the classes outside these components.
|
|
28
50
|
|
|
29
51
|
## Usage
|
|
30
52
|
|
|
@@ -115,16 +137,26 @@ With inline snippets:
|
|
|
115
137
|
|
|
116
138
|
## Build
|
|
117
139
|
|
|
140
|
+
This package is built with **`@sveltejs/package`** (`svelte-package`), the supported Svelte library pipeline. It preprocesses Svelte, transpiles TypeScript, and emits **`.d.ts` next to outputs** so consumers get correct component prop types (not a separate Vite “library mode” + `vite-plugin-dts` flow).
|
|
141
|
+
|
|
118
142
|
From the package directory:
|
|
119
143
|
|
|
120
144
|
```bash
|
|
121
145
|
npm run build
|
|
122
146
|
```
|
|
123
147
|
|
|
148
|
+
This runs `svelte-kit sync` (generates `.svelte-kit` types for the minimal Kit shell) then `svelte-package`, writing output to `dist/`.
|
|
149
|
+
|
|
150
|
+
Watch mode during development:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
npm run dev
|
|
154
|
+
```
|
|
155
|
+
|
|
124
156
|
From the monorepo root:
|
|
125
157
|
|
|
126
158
|
```bash
|
|
127
|
-
npm run build
|
|
159
|
+
npm run build -w @ibis-design/svelte
|
|
128
160
|
```
|
|
129
161
|
|
|
130
162
|
## Type checking
|
|
@@ -133,4 +165,4 @@ npm run build --workspaces
|
|
|
133
165
|
npm run check
|
|
134
166
|
```
|
|
135
167
|
|
|
136
|
-
Runs `svelte-check` with the package `tsconfig.json`.
|
|
168
|
+
Runs `svelte-kit sync` then `svelte-check` with the package `tsconfig.json`.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import '@ibis-design/css/components/button.css';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import type { ButtonVariant, ButtonSize } from '../../types/button';
|
|
5
|
+
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
6
|
+
|
|
7
|
+
interface Props extends HTMLButtonAttributes {
|
|
8
|
+
/**
|
|
9
|
+
* Native button variants.
|
|
10
|
+
*
|
|
11
|
+
* Determines the visual style of the button, affecting its colors and borders.
|
|
12
|
+
*
|
|
13
|
+
* @default "primary"
|
|
14
|
+
* @example
|
|
15
|
+
* - `primary`: <Button variant="primary">Save</Button>
|
|
16
|
+
* - `secondary`: <Button variant="secondary">Cancel</Button>
|
|
17
|
+
*/
|
|
18
|
+
variant?: ButtonVariant;
|
|
19
|
+
/**
|
|
20
|
+
* Native button sizes.
|
|
21
|
+
*
|
|
22
|
+
* Determines the size of the button, affecting its padding and font size.
|
|
23
|
+
*
|
|
24
|
+
* @default "md"
|
|
25
|
+
* @example
|
|
26
|
+
* - `sm`: <Button size="sm">Small</Button>
|
|
27
|
+
* - `md`: <Button size="md">Medium</Button>
|
|
28
|
+
* - `lg`: <Button size="lg">Large</Button>
|
|
29
|
+
*/
|
|
30
|
+
size?: ButtonSize;
|
|
31
|
+
/**
|
|
32
|
+
* Native button behavior types.
|
|
33
|
+
*
|
|
34
|
+
* Determines how the button behaves when clicked.
|
|
35
|
+
*
|
|
36
|
+
* @default "button"
|
|
37
|
+
* @remarks
|
|
38
|
+
* Use `submit` for form submission and `reset` to clear form fields.
|
|
39
|
+
* Avoid using `submit` for non-form actions
|
|
40
|
+
*/
|
|
41
|
+
type?: 'button' | 'submit' | 'reset';
|
|
42
|
+
/**
|
|
43
|
+
* Disables the button, preventing user interaction and applying disabled styles.
|
|
44
|
+
*
|
|
45
|
+
* @default false
|
|
46
|
+
*/
|
|
47
|
+
disabled?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Shows a loading spinner and disables the button to indicate an ongoing action.
|
|
50
|
+
*
|
|
51
|
+
* @default false
|
|
52
|
+
*/
|
|
53
|
+
loading?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Applies a skeleton loading state to the button, showing a placeholder style while content is loading.
|
|
56
|
+
*
|
|
57
|
+
* @default false`
|
|
58
|
+
*/
|
|
59
|
+
skeleton?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* If true, the button is styled for icon-only content, removing extra padding and centering the icon.
|
|
62
|
+
*
|
|
63
|
+
* @default false
|
|
64
|
+
*/
|
|
65
|
+
iconOnly?: boolean;
|
|
66
|
+
label?: string;
|
|
67
|
+
children?: Snippet;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let {
|
|
71
|
+
variant = 'primary',
|
|
72
|
+
size = 'md',
|
|
73
|
+
type = 'button',
|
|
74
|
+
disabled = false,
|
|
75
|
+
loading = false,
|
|
76
|
+
skeleton = false,
|
|
77
|
+
iconOnly = false,
|
|
78
|
+
label,
|
|
79
|
+
children,
|
|
80
|
+
...rest
|
|
81
|
+
}: Props = $props();
|
|
82
|
+
</script>
|
|
83
|
+
|
|
84
|
+
<button
|
|
85
|
+
{...rest}
|
|
86
|
+
{type}
|
|
87
|
+
{disabled}
|
|
88
|
+
aria-busy={loading}
|
|
89
|
+
class="ibis-button
|
|
90
|
+
ibis-button--{variant}
|
|
91
|
+
ibis-button--{size}
|
|
92
|
+
{loading ? 'ibis-button--loading' : ''}
|
|
93
|
+
{skeleton ? 'ibis-button--skeleton' : ''}
|
|
94
|
+
{iconOnly ? 'ibis-button--icon-only' : ''}"
|
|
95
|
+
>
|
|
96
|
+
<span class="ibis-button__content {loading || skeleton ? 'ibis-button__content--hidden' : ''}">
|
|
97
|
+
{#if children}
|
|
98
|
+
{@render children?.()}
|
|
99
|
+
{:else if label}
|
|
100
|
+
{label}
|
|
101
|
+
{/if}
|
|
102
|
+
</span>
|
|
103
|
+
{#if loading}
|
|
104
|
+
<span class="ibis-button__loader" aria-hidden="true"></span>
|
|
105
|
+
{/if}
|
|
106
|
+
</button>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import '@ibis-design/css/components/button.css';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { ButtonVariant, ButtonSize } from '../../types/button';
|
|
4
|
+
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
5
|
+
interface Props extends HTMLButtonAttributes {
|
|
6
|
+
/**
|
|
7
|
+
* Native button variants.
|
|
8
|
+
*
|
|
9
|
+
* Determines the visual style of the button, affecting its colors and borders.
|
|
10
|
+
*
|
|
11
|
+
* @default "primary"
|
|
12
|
+
* @example
|
|
13
|
+
* - `primary`: <Button variant="primary">Save</Button>
|
|
14
|
+
* - `secondary`: <Button variant="secondary">Cancel</Button>
|
|
15
|
+
*/
|
|
16
|
+
variant?: ButtonVariant;
|
|
17
|
+
/**
|
|
18
|
+
* Native button sizes.
|
|
19
|
+
*
|
|
20
|
+
* Determines the size of the button, affecting its padding and font size.
|
|
21
|
+
*
|
|
22
|
+
* @default "md"
|
|
23
|
+
* @example
|
|
24
|
+
* - `sm`: <Button size="sm">Small</Button>
|
|
25
|
+
* - `md`: <Button size="md">Medium</Button>
|
|
26
|
+
* - `lg`: <Button size="lg">Large</Button>
|
|
27
|
+
*/
|
|
28
|
+
size?: ButtonSize;
|
|
29
|
+
/**
|
|
30
|
+
* Native button behavior types.
|
|
31
|
+
*
|
|
32
|
+
* Determines how the button behaves when clicked.
|
|
33
|
+
*
|
|
34
|
+
* @default "button"
|
|
35
|
+
* @remarks
|
|
36
|
+
* Use `submit` for form submission and `reset` to clear form fields.
|
|
37
|
+
* Avoid using `submit` for non-form actions
|
|
38
|
+
*/
|
|
39
|
+
type?: 'button' | 'submit' | 'reset';
|
|
40
|
+
/**
|
|
41
|
+
* Disables the button, preventing user interaction and applying disabled styles.
|
|
42
|
+
*
|
|
43
|
+
* @default false
|
|
44
|
+
*/
|
|
45
|
+
disabled?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Shows a loading spinner and disables the button to indicate an ongoing action.
|
|
48
|
+
*
|
|
49
|
+
* @default false
|
|
50
|
+
*/
|
|
51
|
+
loading?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Applies a skeleton loading state to the button, showing a placeholder style while content is loading.
|
|
54
|
+
*
|
|
55
|
+
* @default false`
|
|
56
|
+
*/
|
|
57
|
+
skeleton?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* If true, the button is styled for icon-only content, removing extra padding and centering the icon.
|
|
60
|
+
*
|
|
61
|
+
* @default false
|
|
62
|
+
*/
|
|
63
|
+
iconOnly?: boolean;
|
|
64
|
+
label?: string;
|
|
65
|
+
children?: Snippet;
|
|
66
|
+
}
|
|
67
|
+
declare const Button: import("svelte").Component<Props, {}, "">;
|
|
68
|
+
type Button = ReturnType<typeof Button>;
|
|
69
|
+
export default Button;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import '@ibis-design/css/components/dropdownButton.css';
|
|
3
|
+
import Button from './Button.svelte';
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
/**
|
|
8
|
+
* The label shown in the trigger button when an option is selected.
|
|
9
|
+
*/
|
|
10
|
+
label?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Placeholder text shown in the trigger button when no option is selected.
|
|
13
|
+
*
|
|
14
|
+
* @default "Select..."
|
|
15
|
+
*/
|
|
16
|
+
placeholder?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Custom trigger content via Snippet.
|
|
19
|
+
* Falls back to label or placeholder if not provided.
|
|
20
|
+
*/
|
|
21
|
+
trigger?: Snippet;
|
|
22
|
+
/**
|
|
23
|
+
* Custom menu content via Snippet.
|
|
24
|
+
* Use this to pass menu items.
|
|
25
|
+
*/
|
|
26
|
+
menu?: Snippet<[close: () => void]>;
|
|
27
|
+
/**
|
|
28
|
+
* Disables the dropdown, preventing interaction.
|
|
29
|
+
*
|
|
30
|
+
* @default false
|
|
31
|
+
*/
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let { label, placeholder = 'Select...', trigger, menu, disabled = false }: Props = $props();
|
|
36
|
+
|
|
37
|
+
let open = $state(false);
|
|
38
|
+
let dropdownRef = $state<HTMLDivElement | null>(null);
|
|
39
|
+
|
|
40
|
+
const menuId = `ibis-dropdown-button-${Math.random().toString(36).slice(2)}`;
|
|
41
|
+
|
|
42
|
+
const toggle = () => {
|
|
43
|
+
if (disabled) return;
|
|
44
|
+
open = !open;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const handleKeydown = (e: KeyboardEvent) => {
|
|
48
|
+
if (e.key === 'Escape') open = false;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const handleClickOutside = (e: MouseEvent) => {
|
|
52
|
+
if (dropdownRef && !dropdownRef.contains(e.target as Node)) {
|
|
53
|
+
open = false;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<svelte:window onclick={handleClickOutside} />
|
|
59
|
+
|
|
60
|
+
<div
|
|
61
|
+
class="dropdown-button {open ? 'dropdown-button--open' : ''}"
|
|
62
|
+
bind:this={dropdownRef}
|
|
63
|
+
onkeydown={handleKeydown}
|
|
64
|
+
role="combobox"
|
|
65
|
+
tabindex="0"
|
|
66
|
+
aria-expanded={open}
|
|
67
|
+
aria-haspopup="listbox"
|
|
68
|
+
aria-controls={menuId}
|
|
69
|
+
>
|
|
70
|
+
<!-- Trigger -->
|
|
71
|
+
<Button onclick={toggle} {disabled}>
|
|
72
|
+
{#if trigger}
|
|
73
|
+
{@render trigger()}
|
|
74
|
+
{:else}
|
|
75
|
+
{label || placeholder}
|
|
76
|
+
{/if}
|
|
77
|
+
|
|
78
|
+
<svg class="caret {open ? 'caret--open' : ''}" viewBox="0 0 16 16" aria-hidden="true">
|
|
79
|
+
<path d="M4 6l4 4 4-4" stroke="currentColor" stroke-width="2" fill="none" />
|
|
80
|
+
</svg>
|
|
81
|
+
</Button>
|
|
82
|
+
|
|
83
|
+
<!-- Menu -->
|
|
84
|
+
{#if open}
|
|
85
|
+
<ul class="dropdown-menu" role="listbox">
|
|
86
|
+
{#if menu}
|
|
87
|
+
{@render menu(() => (open = false))}
|
|
88
|
+
{/if}
|
|
89
|
+
</ul>
|
|
90
|
+
{/if}
|
|
91
|
+
</div>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import '@ibis-design/css/components/dropdownButton.css';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
interface Props {
|
|
4
|
+
/**
|
|
5
|
+
* The label shown in the trigger button when an option is selected.
|
|
6
|
+
*/
|
|
7
|
+
label?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Placeholder text shown in the trigger button when no option is selected.
|
|
10
|
+
*
|
|
11
|
+
* @default "Select..."
|
|
12
|
+
*/
|
|
13
|
+
placeholder?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Custom trigger content via Snippet.
|
|
16
|
+
* Falls back to label or placeholder if not provided.
|
|
17
|
+
*/
|
|
18
|
+
trigger?: Snippet;
|
|
19
|
+
/**
|
|
20
|
+
* Custom menu content via Snippet.
|
|
21
|
+
* Use this to pass menu items.
|
|
22
|
+
*/
|
|
23
|
+
menu?: Snippet<[close: () => void]>;
|
|
24
|
+
/**
|
|
25
|
+
* Disables the dropdown, preventing interaction.
|
|
26
|
+
*
|
|
27
|
+
* @default false
|
|
28
|
+
*/
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
}
|
|
31
|
+
declare const DropdownButton: import("svelte").Component<Props, {}, "">;
|
|
32
|
+
type DropdownButton = ReturnType<typeof DropdownButton>;
|
|
33
|
+
export default DropdownButton;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import '@ibis-design/css/components/pillTab.css';
|
|
3
|
+
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
4
|
+
|
|
5
|
+
interface Props extends HTMLInputAttributes {
|
|
6
|
+
/**
|
|
7
|
+
* The visible text label displayed inside the pill tab.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* <PillTab label="Overview" value="overview" />
|
|
11
|
+
*/
|
|
12
|
+
label?: string;
|
|
13
|
+
/**
|
|
14
|
+
* The unique identifier for the input element.
|
|
15
|
+
*
|
|
16
|
+
* If not provided, a random ID is generated automatically.
|
|
17
|
+
*/
|
|
18
|
+
id?: string;
|
|
19
|
+
/**
|
|
20
|
+
* The currently selected value in the radio group.
|
|
21
|
+
*
|
|
22
|
+
* When `group` matches `value`, the pill tab appears active.
|
|
23
|
+
* Bind this to a shared variable across all tabs in the same group.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* <PillTab bind:group={activeTab} value="overview" label="Overview" />
|
|
27
|
+
*/
|
|
28
|
+
group?: string | number;
|
|
29
|
+
/**
|
|
30
|
+
* The value this pill tab represents in the radio group.
|
|
31
|
+
*
|
|
32
|
+
* When `group === value`, this tab is considered active.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* <PillTab value="settings" label="Settings" />
|
|
36
|
+
*/
|
|
37
|
+
value: string | number;
|
|
38
|
+
/**
|
|
39
|
+
* The name attribute shared across all radio inputs in the same group.
|
|
40
|
+
*
|
|
41
|
+
* Required for native radio group behavior — all tabs in the same
|
|
42
|
+
* group must share the same `name`.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* <PillTab name="main-nav" value="overview" label="Overview" />
|
|
46
|
+
*/
|
|
47
|
+
name?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Disables the pill tab, preventing user interaction and applying disabled styles.
|
|
50
|
+
*
|
|
51
|
+
* @default false
|
|
52
|
+
*/
|
|
53
|
+
disabled?: boolean;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let { id, label, group = $bindable(), value, name, disabled = false, ...rest }: Props = $props();
|
|
57
|
+
|
|
58
|
+
const fallbackId = `ibis-pill-tab-${Math.random().toString(36).slice(2)}`;
|
|
59
|
+
const inputId = $derived(id ?? fallbackId);
|
|
60
|
+
|
|
61
|
+
const checked = $derived(group === value);
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<label
|
|
65
|
+
class="ibis-pill-tab
|
|
66
|
+
{checked ? 'ibis-pill-tab--active' : ''}
|
|
67
|
+
{disabled ? 'ibis-pill-tab--disabled' : ''}"
|
|
68
|
+
for={inputId}
|
|
69
|
+
>
|
|
70
|
+
<input
|
|
71
|
+
{...rest}
|
|
72
|
+
id={inputId}
|
|
73
|
+
type="radio"
|
|
74
|
+
{name}
|
|
75
|
+
bind:group
|
|
76
|
+
{value}
|
|
77
|
+
{disabled}
|
|
78
|
+
class="ibis-pill-tab__input"
|
|
79
|
+
/>
|
|
80
|
+
|
|
81
|
+
<span class="ibis-pill-tab__content">
|
|
82
|
+
{label}
|
|
83
|
+
</span>
|
|
84
|
+
</label>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import '@ibis-design/css/components/pillTab.css';
|
|
2
|
+
import type { HTMLInputAttributes } from 'svelte/elements';
|
|
3
|
+
interface Props extends HTMLInputAttributes {
|
|
4
|
+
/**
|
|
5
|
+
* The visible text label displayed inside the pill tab.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* <PillTab label="Overview" value="overview" />
|
|
9
|
+
*/
|
|
10
|
+
label?: string;
|
|
11
|
+
/**
|
|
12
|
+
* The unique identifier for the input element.
|
|
13
|
+
*
|
|
14
|
+
* If not provided, a random ID is generated automatically.
|
|
15
|
+
*/
|
|
16
|
+
id?: string;
|
|
17
|
+
/**
|
|
18
|
+
* The currently selected value in the radio group.
|
|
19
|
+
*
|
|
20
|
+
* When `group` matches `value`, the pill tab appears active.
|
|
21
|
+
* Bind this to a shared variable across all tabs in the same group.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* <PillTab bind:group={activeTab} value="overview" label="Overview" />
|
|
25
|
+
*/
|
|
26
|
+
group?: string | number;
|
|
27
|
+
/**
|
|
28
|
+
* The value this pill tab represents in the radio group.
|
|
29
|
+
*
|
|
30
|
+
* When `group === value`, this tab is considered active.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* <PillTab value="settings" label="Settings" />
|
|
34
|
+
*/
|
|
35
|
+
value: string | number;
|
|
36
|
+
/**
|
|
37
|
+
* The name attribute shared across all radio inputs in the same group.
|
|
38
|
+
*
|
|
39
|
+
* Required for native radio group behavior — all tabs in the same
|
|
40
|
+
* group must share the same `name`.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* <PillTab name="main-nav" value="overview" label="Overview" />
|
|
44
|
+
*/
|
|
45
|
+
name?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Disables the pill tab, preventing user interaction and applying disabled styles.
|
|
48
|
+
*
|
|
49
|
+
* @default false
|
|
50
|
+
*/
|
|
51
|
+
disabled?: boolean;
|
|
52
|
+
}
|
|
53
|
+
declare const PillTab: import("svelte").Component<Props, {}, "group">;
|
|
54
|
+
type PillTab = ReturnType<typeof PillTab>;
|
|
55
|
+
export default PillTab;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import "@ibis-design/css/components/banner.css";
|
|
3
|
+
import type { Snippet } from "svelte";
|
|
4
|
+
|
|
5
|
+
type BannerType = "success" | "error" | "default";
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
type?: BannerType;
|
|
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-banner"
|
|
39
|
+
role="status"
|
|
40
|
+
class:ibis-banner--success={type === "success"}
|
|
41
|
+
class:ibis-banner--error={type === "error"}
|
|
42
|
+
class:ibis-banner--default={type === "default"}>
|
|
43
|
+
{#if loading || icon || iconText}
|
|
44
|
+
<div class="ibis-banner__icon">
|
|
45
|
+
{#if loading}
|
|
46
|
+
<span class="ibis-banner__loader" aria-hidden="true"></span>
|
|
47
|
+
{:else if icon}
|
|
48
|
+
{@render icon?.()}
|
|
49
|
+
{:else}
|
|
50
|
+
{iconText}
|
|
51
|
+
{/if}
|
|
52
|
+
</div>
|
|
53
|
+
{/if}
|
|
54
|
+
|
|
55
|
+
<div class="ibis-banner__content">
|
|
56
|
+
{#if title}
|
|
57
|
+
<div class="ibis-banner__title">{title}</div>
|
|
58
|
+
{/if}
|
|
59
|
+
|
|
60
|
+
<div class="ibis-banner__message">
|
|
61
|
+
{#if children}
|
|
62
|
+
{@render children?.()}
|
|
63
|
+
{:else if message}
|
|
64
|
+
{message}
|
|
65
|
+
{/if}
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
{#if closable}
|
|
70
|
+
<button class="ibis-banner__close" onclick={close} aria-label="Close"> x </button>
|
|
71
|
+
{/if}
|
|
72
|
+
</div>
|
|
73
|
+
{/if}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import "@ibis-design/css/components/banner.css";
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
type BannerType = "success" | "error" | "default";
|
|
4
|
+
interface Props {
|
|
5
|
+
type?: BannerType;
|
|
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 Banner: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type Banner = ReturnType<typeof Banner>;
|
|
16
|
+
export default Banner;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Card – Container with token-based padding, radius, and shadow.
|
|
3
|
+
@component
|
|
4
|
+
@param {Snippet} [children] - Snippet content for the card body.
|
|
5
|
+
@example
|
|
6
|
+
<Card>Card content</Card>
|
|
7
|
+
-->
|
|
8
|
+
<script lang="ts">
|
|
9
|
+
import type { Snippet } from "svelte";
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
children?: Snippet;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let { children }: Props = $props();
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<div class="ibis-card">
|
|
19
|
+
{#if children}
|
|
20
|
+
{@render children()}
|
|
21
|
+
{/if}
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<style>
|
|
25
|
+
.ibis-card {
|
|
26
|
+
background-color: var(--color-backgrounds-classic-light);
|
|
27
|
+
border-radius: var(--border-radius-md);
|
|
28
|
+
box-shadow: var(--shadow-default);
|
|
29
|
+
padding: var(--spacing-4);
|
|
30
|
+
font-family: var(--font-family-sans);
|
|
31
|
+
font-size: var(--font-size-body-md);
|
|
32
|
+
line-height: var(--line-height-normal);
|
|
33
|
+
}
|
|
34
|
+
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
interface Props {
|
|
3
|
+
children?: Snippet;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Card – Container with token-based padding, radius, and shadow.
|
|
7
|
+
*
|
|
8
|
+
* @param {Snippet} [children] - Snippet content for the card body.
|
|
9
|
+
* @example
|
|
10
|
+
* <Card>Card content</Card>
|
|
11
|
+
*/
|
|
12
|
+
declare const Card: import("svelte").Component<Props, {}, "">;
|
|
13
|
+
type Card = ReturnType<typeof Card>;
|
|
14
|
+
export default Card;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
interface Props {
|
|
3
|
+
children?: () => any;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
let { children }: Props = $props();
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<div class="ibis-pill-tabs">
|
|
10
|
+
{@render children?.()}
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<style>
|
|
14
|
+
.ibis-pill-tabs {
|
|
15
|
+
display: inline-flex;
|
|
16
|
+
align-items: stretch;
|
|
17
|
+
border-radius: var(--border-radius-full);
|
|
18
|
+
background: var(--color-white);
|
|
19
|
+
padding: 4px;
|
|
20
|
+
gap: 4px;
|
|
21
|
+
}
|
|
22
|
+
</style>
|