@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.
Files changed (71) hide show
  1. package/README.md +42 -10
  2. package/dist/components/buttons/Button.svelte +106 -0
  3. package/dist/components/buttons/Button.svelte.d.ts +69 -0
  4. package/dist/components/buttons/DropdownButton.svelte +91 -0
  5. package/dist/components/buttons/DropdownButton.svelte.d.ts +33 -0
  6. package/dist/components/buttons/PillTab.svelte +84 -0
  7. package/dist/components/buttons/PillTab.svelte.d.ts +55 -0
  8. package/dist/components/containers/Banner.svelte +73 -0
  9. package/dist/components/containers/Banner.svelte.d.ts +16 -0
  10. package/dist/components/containers/Card.svelte +34 -0
  11. package/dist/components/containers/Card.svelte.d.ts +14 -0
  12. package/dist/components/containers/PillTabs.svelte +22 -0
  13. package/dist/components/containers/PillTabs.svelte.d.ts +6 -0
  14. package/dist/components/containers/TipIndicator.svelte +78 -0
  15. package/dist/components/containers/TipIndicator.svelte.d.ts +28 -0
  16. package/dist/components/containers/Toaster.svelte +75 -0
  17. package/dist/components/containers/Toaster.svelte.d.ts +16 -0
  18. package/dist/components/containers/Tooltip.svelte.d.ts +26 -0
  19. package/dist/components/inputs/.gitkeep +0 -0
  20. package/dist/components/inputs/Checkbox.svelte +95 -0
  21. package/dist/components/inputs/Checkbox.svelte.d.ts +33 -0
  22. package/dist/components/inputs/Chips.svelte +104 -0
  23. package/dist/components/inputs/Chips.svelte.d.ts +48 -0
  24. package/dist/components/inputs/Dropdown.svelte +83 -0
  25. package/dist/components/inputs/Dropdown.svelte.d.ts +15 -0
  26. package/dist/components/inputs/Radio.svelte +109 -0
  27. package/dist/components/inputs/Radio.svelte.d.ts +49 -0
  28. package/dist/components/inputs/Switch.svelte +45 -0
  29. package/dist/components/inputs/Switch.svelte.d.ts +21 -0
  30. package/dist/components/inputs/TextArea.svelte +65 -0
  31. package/dist/components/inputs/TextArea.svelte.d.ts +14 -0
  32. package/dist/components/inputs/TextInput.svelte +273 -0
  33. package/dist/components/inputs/TextInput.svelte.d.ts +140 -0
  34. package/dist/components/inputs/TextLink.svelte +102 -0
  35. package/dist/components/inputs/TextLink.svelte.d.ts +21 -0
  36. package/dist/index.d.ts +21 -20
  37. package/dist/index.js +36 -3187
  38. package/dist/layouts/AppLayout.svelte +83 -0
  39. package/dist/layouts/AppLayout.svelte.d.ts +20 -0
  40. package/dist/layouts/AuthLayout.svelte +63 -0
  41. package/dist/layouts/AuthLayout.svelte.d.ts +18 -0
  42. package/dist/layouts/DashboardLayout.svelte +88 -0
  43. package/dist/layouts/DashboardLayout.svelte.d.ts +20 -0
  44. package/dist/types/button.js +5 -0
  45. package/dist/types/index.d.ts +2 -2
  46. package/dist/types/index.js +5 -0
  47. package/dist/types/layout.d.ts +1 -1
  48. package/dist/types/layout.js +1 -0
  49. package/package.json +16 -11
  50. package/dist/index.css +0 -1
  51. package/dist/index.js.map +0 -1
  52. package/dist/lib/components/buttons/Button.svelte.d.ts +0 -1
  53. package/dist/lib/components/buttons/DropdownButton.svelte.d.ts +0 -1
  54. package/dist/lib/components/buttons/PillTab.svelte.d.ts +0 -1
  55. package/dist/lib/components/containers/Banner.svelte.d.ts +0 -1
  56. package/dist/lib/components/containers/Card.svelte.d.ts +0 -1
  57. package/dist/lib/components/containers/Toaster.svelte.d.ts +0 -1
  58. package/dist/lib/components/inputs/Checkbox.svelte.d.ts +0 -1
  59. package/dist/lib/components/inputs/Chips.svelte.d.ts +0 -1
  60. package/dist/lib/components/inputs/DateInput.svelte.d.ts +0 -1
  61. package/dist/lib/components/inputs/DateInput2.svelte.d.ts +0 -1
  62. package/dist/lib/components/inputs/Dropdown.svelte.d.ts +0 -1
  63. package/dist/lib/components/inputs/Password.svelte.d.ts +0 -1
  64. package/dist/lib/components/inputs/Radio.svelte.d.ts +0 -1
  65. package/dist/lib/components/inputs/TextArea.svelte.d.ts +0 -1
  66. package/dist/lib/components/inputs/TextInput.svelte.d.ts +0 -1
  67. package/dist/lib/components/inputs/TextLink.svelte.d.ts +0 -1
  68. package/dist/lib/layouts/AppLayout.svelte.d.ts +0 -1
  69. package/dist/lib/layouts/AuthLayout.svelte.d.ts +0 -1
  70. package/dist/lib/layouts/DashboardLayout.svelte.d.ts +0 -1
  71. /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. The consuming application must load the token stylesheet once so `:root` variables are available.
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 the design tokens in your application entry or root layout so all components receive the correct variables:
18
+ Import tokens and set the theme on the document root:
19
19
 
20
- ```js
21
- // e.g. in your app entry (main.ts, +layout.svelte, or App.svelte)
22
- import '@ibis-design/css';
23
- // or
24
- import '@ibis-design/css/ibis-design.css';
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
- Without this import, components will not have colors, spacing, or typography from the design system.
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 --workspaces
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>