seblify 0.1.4

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 (138) hide show
  1. package/README.md +18 -0
  2. package/dist/components/AppShell.svelte +136 -0
  3. package/dist/components/AppShell.svelte.d.ts +13 -0
  4. package/dist/components/Banner.svelte +56 -0
  5. package/dist/components/Banner.svelte.d.ts +9 -0
  6. package/dist/components/Button.svelte +64 -0
  7. package/dist/components/Button.svelte.d.ts +13 -0
  8. package/dist/components/Icon.svelte +67 -0
  9. package/dist/components/Icon.svelte.d.ts +8 -0
  10. package/dist/components/Sidebar.svelte +106 -0
  11. package/dist/components/Sidebar.svelte.d.ts +14 -0
  12. package/dist/components/Snackbar.svelte +26 -0
  13. package/dist/components/Snackbar.svelte.d.ts +7 -0
  14. package/dist/components/Toast.svelte +27 -0
  15. package/dist/components/Toast.svelte.d.ts +7 -0
  16. package/dist/components/action/input/field/pin-input/PinInput.svelte +156 -0
  17. package/dist/components/action/input/field/pin-input/PinInput.svelte.d.ts +10 -0
  18. package/dist/components/action/input/select/checkbox/Checkbox.svelte +71 -0
  19. package/dist/components/action/input/select/checkbox/Checkbox.svelte.d.ts +10 -0
  20. package/dist/components/action/input/select/segment-control/SegmentControl.svelte +150 -0
  21. package/dist/components/action/input/select/segment-control/SegmentControl.svelte.d.ts +15 -0
  22. package/dist/components/action/input/select/slider/Slider.svelte +79 -0
  23. package/dist/components/action/input/select/slider/Slider.svelte.d.ts +11 -0
  24. package/dist/components/action/input/select/switch/Switch.svelte +122 -0
  25. package/dist/components/action/input/select/switch/Switch.svelte.d.ts +10 -0
  26. package/dist/components/action/input/select/theme-switch/ThemeSwitch.svelte +43 -0
  27. package/dist/components/action/input/select/theme-switch/ThemeSwitch.svelte.d.ts +10 -0
  28. package/dist/components/component-doc.d.ts +23 -0
  29. package/dist/components/component-doc.js +1 -0
  30. package/dist/components/display/annotation/badge/Badge.svelte +296 -0
  31. package/dist/components/display/annotation/badge/Badge.svelte.d.ts +16 -0
  32. package/dist/components/display/annotation/tag/Tag.svelte +227 -0
  33. package/dist/components/display/annotation/tag/Tag.svelte.d.ts +16 -0
  34. package/dist/components/display/annotation/tag-group/TagGroup.svelte +33 -0
  35. package/dist/components/display/annotation/tag-group/TagGroup.svelte.d.ts +12 -0
  36. package/dist/components/display/feedback/loading/loading-dots/LoadingDots.svelte +136 -0
  37. package/dist/components/display/feedback/loading/loading-dots/LoadingDots.svelte.d.ts +8 -0
  38. package/dist/components/display/feedback/loading/spinner/Spinner.svelte +110 -0
  39. package/dist/components/display/feedback/loading/spinner/Spinner.svelte.d.ts +8 -0
  40. package/dist/components/display/media/icon/Icon.svelte +41 -0
  41. package/dist/components/display/media/icon/Icon.svelte.d.ts +8 -0
  42. package/dist/components/display/media/icon/IconGlyph.svelte +56 -0
  43. package/dist/components/display/media/icon/IconGlyph.svelte.d.ts +8 -0
  44. package/dist/components/display/typography/eyebrow/Eyebrow.svelte +48 -0
  45. package/dist/components/display/typography/eyebrow/Eyebrow.svelte.d.ts +8 -0
  46. package/dist/components/display/typography/highlight/Highlight.svelte +160 -0
  47. package/dist/components/display/typography/highlight/Highlight.svelte.d.ts +10 -0
  48. package/dist/components/framework/layout/alignment/cluster/Cluster.svelte +142 -0
  49. package/dist/components/framework/layout/alignment/cluster/Cluster.svelte.d.ts +17 -0
  50. package/dist/components/framework/layout/alignment/grid/Grid.svelte +120 -0
  51. package/dist/components/framework/layout/alignment/grid/Grid.svelte.d.ts +18 -0
  52. package/dist/components/framework/layout/alignment/row/Row.svelte +142 -0
  53. package/dist/components/framework/layout/alignment/row/Row.svelte.d.ts +17 -0
  54. package/dist/components/framework/layout/alignment/stack/Stack.svelte +142 -0
  55. package/dist/components/framework/layout/alignment/stack/Stack.svelte.d.ts +17 -0
  56. package/dist/components/framework/layout/container/app-shell/AppShell.svelte +82 -0
  57. package/dist/components/framework/layout/container/app-shell/AppShell.svelte.d.ts +9 -0
  58. package/dist/components/framework/layout/container/page-header/PageHeader.svelte +114 -0
  59. package/dist/components/framework/layout/container/page-header/PageHeader.svelte.d.ts +11 -0
  60. package/dist/components/framework/layout/container/sidebar/Sidebar.svelte +134 -0
  61. package/dist/components/framework/layout/container/sidebar/Sidebar.svelte.d.ts +9 -0
  62. package/dist/components/framework/navigation/context/breadcrumb/Breadcrumb.svelte +72 -0
  63. package/dist/components/framework/navigation/context/breadcrumb/Breadcrumb.svelte.d.ts +10 -0
  64. package/dist/components/framework/navigation/sidenav/Sidenav.svelte +86 -0
  65. package/dist/components/framework/navigation/sidenav/Sidenav.svelte.d.ts +8 -0
  66. package/dist/components/framework/navigation/sidenav/SidenavTree.svelte +265 -0
  67. package/dist/components/framework/navigation/sidenav/SidenavTree.svelte.d.ts +14 -0
  68. package/dist/components/framework/navigation/sidenav/sidenav.d.ts +6 -0
  69. package/dist/components/framework/navigation/sidenav/sidenav.js +1 -0
  70. package/dist/components/framework/surface/paper/Paper.svelte +179 -0
  71. package/dist/components/framework/surface/paper/Paper.svelte.d.ts +18 -0
  72. package/dist/design-system/reserved-props/allowed-options.d.ts +46 -0
  73. package/dist/design-system/reserved-props/allowed-options.js +1 -0
  74. package/dist/design-system/reserved-props/blocked-props.d.ts +9 -0
  75. package/dist/design-system/reserved-props/blocked-props.js +1 -0
  76. package/dist/design-system/reserved-props/complex-types.d.ts +1 -0
  77. package/dist/design-system/reserved-props/complex-types.js +1 -0
  78. package/dist/design-system/reserved-props/type.d.ts +16 -0
  79. package/dist/design-system/reserved-props/type.js +1 -0
  80. package/dist/design-system/theme/tokens.d.ts +7 -0
  81. package/dist/design-system/theme/tokens.js +219 -0
  82. package/dist/icons/generated/chevron-double-down.svelte +16 -0
  83. package/dist/icons/generated/chevron-double-down.svelte.d.ts +7 -0
  84. package/dist/icons/generated/chevron-double-left.svelte +16 -0
  85. package/dist/icons/generated/chevron-double-left.svelte.d.ts +7 -0
  86. package/dist/icons/generated/chevron-double-right.svelte +16 -0
  87. package/dist/icons/generated/chevron-double-right.svelte.d.ts +7 -0
  88. package/dist/icons/generated/chevron-double-up.svelte +16 -0
  89. package/dist/icons/generated/chevron-double-up.svelte.d.ts +7 -0
  90. package/dist/icons/generated/chevron-down.svelte +16 -0
  91. package/dist/icons/generated/chevron-down.svelte.d.ts +7 -0
  92. package/dist/icons/generated/chevron-left.svelte +16 -0
  93. package/dist/icons/generated/chevron-left.svelte.d.ts +7 -0
  94. package/dist/icons/generated/chevron-right.svelte +16 -0
  95. package/dist/icons/generated/chevron-right.svelte.d.ts +7 -0
  96. package/dist/icons/generated/chevron-up.svelte +16 -0
  97. package/dist/icons/generated/chevron-up.svelte.d.ts +7 -0
  98. package/dist/icons/generated/fallback.svelte +17 -0
  99. package/dist/icons/generated/fallback.svelte.d.ts +7 -0
  100. package/dist/icons/generated/heart-circle-outline.svelte +16 -0
  101. package/dist/icons/generated/heart-circle-outline.svelte.d.ts +7 -0
  102. package/dist/icons/generated/heart-circle.svelte +16 -0
  103. package/dist/icons/generated/heart-circle.svelte.d.ts +7 -0
  104. package/dist/icons/generated/heart-half-full.svelte +16 -0
  105. package/dist/icons/generated/heart-half-full.svelte.d.ts +7 -0
  106. package/dist/icons/generated/heart-half-outline.svelte +16 -0
  107. package/dist/icons/generated/heart-half-outline.svelte.d.ts +7 -0
  108. package/dist/icons/generated/heart-half.svelte +16 -0
  109. package/dist/icons/generated/heart-half.svelte.d.ts +7 -0
  110. package/dist/icons/generated/heart-multiple-outline.svelte +23 -0
  111. package/dist/icons/generated/heart-multiple-outline.svelte.d.ts +7 -0
  112. package/dist/icons/generated/heart-multiple.svelte +23 -0
  113. package/dist/icons/generated/heart-multiple.svelte.d.ts +7 -0
  114. package/dist/icons/generated/heart-outline.svelte +16 -0
  115. package/dist/icons/generated/heart-outline.svelte.d.ts +7 -0
  116. package/dist/icons/generated/heart.svelte +16 -0
  117. package/dist/icons/generated/heart.svelte.d.ts +7 -0
  118. package/dist/icons/generated/home-edit-outline.svelte +16 -0
  119. package/dist/icons/generated/home-edit-outline.svelte.d.ts +7 -0
  120. package/dist/icons/generated/home-edit.svelte +16 -0
  121. package/dist/icons/generated/home-edit.svelte.d.ts +7 -0
  122. package/dist/icons/generated/home-outline.svelte +16 -0
  123. package/dist/icons/generated/home-outline.svelte.d.ts +7 -0
  124. package/dist/icons/generated/home.svelte +16 -0
  125. package/dist/icons/generated/home.svelte.d.ts +7 -0
  126. package/dist/icons/generated/index.d.ts +24 -0
  127. package/dist/icons/generated/index.js +24 -0
  128. package/dist/icons/generated/manifest.d.ts +7 -0
  129. package/dist/icons/generated/manifest.js +198 -0
  130. package/dist/icons/generated/tag-heart-outline.svelte +16 -0
  131. package/dist/icons/generated/tag-heart-outline.svelte.d.ts +7 -0
  132. package/dist/icons/generated/tag-heart.svelte +16 -0
  133. package/dist/icons/generated/tag-heart.svelte.d.ts +7 -0
  134. package/dist/index.d.ts +32 -0
  135. package/dist/index.js +28 -0
  136. package/dist/svelte.d.ts +18 -0
  137. package/dist/theme.css +161 -0
  138. package/package.json +69 -0
@@ -0,0 +1,156 @@
1
+ <script lang="ts">
2
+ import type { SeblifyProps } from 'seblify';
3
+
4
+ type Props = SeblifyProps<{
5
+ value?: string;
6
+ length?: number;
7
+ disabled?: boolean;
8
+ label?: string;
9
+ description?: string;
10
+ name?: string;
11
+ }>;
12
+
13
+ let {
14
+ value = $bindable(''),
15
+ length = 6,
16
+ disabled = false,
17
+ label,
18
+ description,
19
+ name,
20
+ }: Props = $props();
21
+
22
+ let inputElement: HTMLInputElement | undefined = $state();
23
+
24
+ const normalizedValue = $derived(value.slice(0, length));
25
+ const cells = $derived(
26
+ Array.from({ length }, (_, index) => normalizedValue[index] ?? ''),
27
+ );
28
+
29
+ function handleInput(event: Event): void {
30
+ const input = event.currentTarget as HTMLInputElement;
31
+ value = input.value.replace(/\D/g, '').slice(0, length);
32
+ }
33
+
34
+ function focusInput(): void {
35
+ inputElement?.focus();
36
+ }
37
+ </script>
38
+
39
+ <label class:disabled class="pin-input">
40
+ {#if label}
41
+ <span class="label">{label}</span>
42
+ {/if}
43
+ {#if description}
44
+ <span class="description">{description}</span>
45
+ {/if}
46
+
47
+ <button
48
+ aria-label={label ?? 'Pin code'}
49
+ class="cells"
50
+ {disabled}
51
+ onclick={focusInput}
52
+ type="button"
53
+ >
54
+ {#each cells as cell, index}
55
+ <span class:filled={Boolean(cell)} class="cell">
56
+ {cell}
57
+ {#if !cell && index === normalizedValue.length}
58
+ <span class="caret"></span>
59
+ {/if}
60
+ </span>
61
+ {/each}
62
+ </button>
63
+
64
+ <input
65
+ bind:this={inputElement}
66
+ autocomplete="one-time-code"
67
+ class="input"
68
+ {disabled}
69
+ inputmode="numeric"
70
+ {name}
71
+ oninput={handleInput}
72
+ pattern="[0-9]*"
73
+ type="text"
74
+ value={normalizedValue}
75
+ />
76
+ </label>
77
+
78
+ <style>
79
+ .pin-input {
80
+ display: grid;
81
+ gap: 8px;
82
+ color: var(--seblify-color-text, #172033);
83
+ }
84
+
85
+ .label {
86
+ font-weight: 700;
87
+ line-height: 1.35;
88
+ }
89
+
90
+ .description {
91
+ color: var(--seblify-color-text-muted, #516176);
92
+ font-size: 0.875rem;
93
+ line-height: 1.45;
94
+ }
95
+
96
+ .cells {
97
+ display: flex;
98
+ flex-wrap: wrap;
99
+ gap: 8px;
100
+ width: fit-content;
101
+ border: 0;
102
+ padding: 0;
103
+ background: transparent;
104
+ cursor: text;
105
+ }
106
+
107
+ .cells:focus-visible .cell {
108
+ border-color: var(--seblify-color-fill-accent, #146a6f);
109
+ box-shadow: 0 0 0 3px var(--seblify-color-focus-ring, #9bd4d8);
110
+ }
111
+
112
+ .cell {
113
+ position: relative;
114
+ display: grid;
115
+ width: 42px;
116
+ height: 46px;
117
+ place-items: center;
118
+ border: 1px solid var(--seblify-color-border, #c8d2df);
119
+ border-radius: 8px;
120
+ background: var(--seblify-color-surface, #ffffff);
121
+ color: var(--seblify-color-text, #172033);
122
+ font-size: 1.2rem;
123
+ font-variant-numeric: tabular-nums;
124
+ font-weight: 800;
125
+ }
126
+
127
+ .filled {
128
+ border-color: var(--seblify-color-border-accent, #9ab7ba);
129
+ background: var(--seblify-color-surface-accent, #f7fbfb);
130
+ }
131
+
132
+ .caret {
133
+ width: 2px;
134
+ height: 20px;
135
+ background: var(--seblify-color-fill-accent, #146a6f);
136
+ }
137
+
138
+ .input {
139
+ position: absolute;
140
+ width: 1px;
141
+ height: 1px;
142
+ overflow: hidden;
143
+ clip: rect(0 0 0 0);
144
+ clip-path: inset(50%);
145
+ white-space: nowrap;
146
+ }
147
+
148
+ .disabled {
149
+ cursor: not-allowed;
150
+ opacity: var(--seblify-opacity-disabled, 0.56);
151
+ }
152
+
153
+ .disabled .cells {
154
+ cursor: not-allowed;
155
+ }
156
+ </style>
@@ -0,0 +1,10 @@
1
+ declare const PinInput: import("svelte").Component<{
2
+ value?: string | undefined;
3
+ length?: number | undefined;
4
+ disabled?: boolean | undefined;
5
+ label?: string | undefined;
6
+ description?: string | undefined;
7
+ name?: string | undefined;
8
+ }, {}, "value">;
9
+ type PinInput = ReturnType<typeof PinInput>;
10
+ export default PinInput;
@@ -0,0 +1,71 @@
1
+ <script lang="ts">
2
+ import type { SeblifyProps } from 'seblify';
3
+
4
+ type Props = SeblifyProps<{
5
+ checked?: boolean;
6
+ disabled?: boolean;
7
+ label?: string;
8
+ description?: string;
9
+ name?: string;
10
+ value?: string;
11
+ }>;
12
+
13
+ let {
14
+ checked = $bindable(false),
15
+ disabled = false,
16
+ label,
17
+ description,
18
+ name,
19
+ value,
20
+ }: Props = $props();
21
+ </script>
22
+
23
+ <label class:disabled class="checkbox">
24
+ <input bind:checked {disabled} {name} type="checkbox" {value} />
25
+ <span class="content">
26
+ {#if label}
27
+ <span class="label">{label}</span>
28
+ {/if}
29
+ {#if description}
30
+ <span class="description">{description}</span>
31
+ {/if}
32
+ </span>
33
+ </label>
34
+
35
+ <style>
36
+ .checkbox {
37
+ display: inline-flex;
38
+ gap: 10px;
39
+ align-items: flex-start;
40
+ color: var(--seblify-color-text, #172033);
41
+ cursor: pointer;
42
+ }
43
+
44
+ input {
45
+ width: 18px;
46
+ height: 18px;
47
+ margin: 2px 0 0;
48
+ accent-color: var(--seblify-color-fill-accent, #146a6f);
49
+ }
50
+
51
+ .content {
52
+ display: grid;
53
+ gap: 2px;
54
+ }
55
+
56
+ .label {
57
+ font-weight: 700;
58
+ line-height: 1.35;
59
+ }
60
+
61
+ .description {
62
+ color: var(--seblify-color-text-muted, #516176);
63
+ font-size: 0.875rem;
64
+ line-height: 1.45;
65
+ }
66
+
67
+ .disabled {
68
+ cursor: not-allowed;
69
+ opacity: var(--seblify-opacity-disabled, 0.56);
70
+ }
71
+ </style>
@@ -0,0 +1,10 @@
1
+ declare const Checkbox: import("svelte").Component<{
2
+ checked?: boolean | undefined;
3
+ disabled?: boolean | undefined;
4
+ label?: string | undefined;
5
+ description?: string | undefined;
6
+ name?: string | undefined;
7
+ value?: string | undefined;
8
+ }, {}, "checked">;
9
+ type Checkbox = ReturnType<typeof Checkbox>;
10
+ export default Checkbox;
@@ -0,0 +1,150 @@
1
+ <script lang="ts">
2
+ import type { SeblifyProps } from 'seblify';
3
+
4
+ export interface SegmentControlOption {
5
+ value: string;
6
+ label: string;
7
+ disabled?: boolean;
8
+ }
9
+
10
+ type Props = SeblifyProps<{
11
+ value?: string;
12
+ options: SegmentControlOption[];
13
+ label?: string;
14
+ description?: string;
15
+ name?: string;
16
+ disabled?: boolean;
17
+ }>;
18
+
19
+ let {
20
+ value = $bindable(''),
21
+ options,
22
+ label,
23
+ description,
24
+ name = 'segment-control',
25
+ disabled = false,
26
+ }: Props = $props();
27
+ </script>
28
+
29
+ <fieldset class="segment-control" class:disabled>
30
+ {#if label || description}
31
+ <legend>
32
+ {#if label}
33
+ <span class="label">{label}</span>
34
+ {/if}
35
+ {#if description}
36
+ <span class="description">{description}</span>
37
+ {/if}
38
+ </legend>
39
+ {/if}
40
+
41
+ <span
42
+ class="options"
43
+ style={`--segment-count: ${Math.max(options.length, 1)}`}
44
+ >
45
+ {#each options as option}
46
+ <label>
47
+ <input
48
+ bind:group={value}
49
+ disabled={disabled || option.disabled}
50
+ {name}
51
+ type="radio"
52
+ value={option.value}
53
+ />
54
+ <span>{option.label}</span>
55
+ </label>
56
+ {/each}
57
+ </span>
58
+ </fieldset>
59
+
60
+ <style>
61
+ .segment-control {
62
+ display: grid;
63
+ gap: 10px;
64
+ min-width: min(100%, 280px);
65
+ border: 0;
66
+ margin: 0;
67
+ padding: 0;
68
+ color: var(--seblify-color-text, #172033);
69
+ }
70
+
71
+ legend {
72
+ display: grid;
73
+ gap: 2px;
74
+ padding: 0;
75
+ }
76
+
77
+ .label {
78
+ font-weight: 700;
79
+ line-height: 1.35;
80
+ }
81
+
82
+ .description {
83
+ color: var(--seblify-color-text-muted, #516176);
84
+ font-size: 0.875rem;
85
+ line-height: 1.45;
86
+ }
87
+
88
+ .options {
89
+ display: grid;
90
+ grid-template-columns: repeat(var(--segment-count), minmax(0, 1fr));
91
+ width: fit-content;
92
+ max-width: 100%;
93
+ border: 1px solid var(--seblify-color-border-strong, #aab7c5);
94
+ border-radius: 999px;
95
+ background: var(--seblify-color-surface-muted, #d9e0e8);
96
+ padding: 3px;
97
+ }
98
+
99
+ label {
100
+ position: relative;
101
+ display: grid;
102
+ min-width: 76px;
103
+ cursor: pointer;
104
+ }
105
+
106
+ input {
107
+ position: absolute;
108
+ width: 1px;
109
+ height: 1px;
110
+ margin: -1px;
111
+ overflow: hidden;
112
+ clip: rect(0 0 0 0);
113
+ clip-path: inset(50%);
114
+ white-space: nowrap;
115
+ }
116
+
117
+ label span {
118
+ display: grid;
119
+ min-height: 32px;
120
+ place-items: center;
121
+ border-radius: 999px;
122
+ padding: 6px 12px;
123
+ color: var(--seblify-color-text-muted, #516176);
124
+ font-size: 0.875rem;
125
+ font-weight: 800;
126
+ line-height: 1;
127
+ transition:
128
+ color 160ms ease,
129
+ background 160ms ease;
130
+ }
131
+
132
+ input:checked + span {
133
+ color: var(--seblify-color-fill-accent-text, #ffffff);
134
+ background: var(--seblify-color-fill-accent, #146a6f);
135
+ }
136
+
137
+ input:focus-visible + span {
138
+ outline: 3px solid var(--seblify-color-focus-ring, #9bd4d8);
139
+ outline-offset: 2px;
140
+ }
141
+
142
+ input:disabled + span {
143
+ cursor: not-allowed;
144
+ opacity: var(--seblify-opacity-disabled, 0.56);
145
+ }
146
+
147
+ .disabled {
148
+ cursor: not-allowed;
149
+ }
150
+ </style>
@@ -0,0 +1,15 @@
1
+ export interface SegmentControlOption {
2
+ value: string;
3
+ label: string;
4
+ disabled?: boolean;
5
+ }
6
+ declare const SegmentControl: import("svelte").Component<{
7
+ value?: string | undefined;
8
+ options: SegmentControlOption[];
9
+ label?: string | undefined;
10
+ description?: string | undefined;
11
+ name?: string | undefined;
12
+ disabled?: boolean | undefined;
13
+ }, {}, "value">;
14
+ type SegmentControl = ReturnType<typeof SegmentControl>;
15
+ export default SegmentControl;
@@ -0,0 +1,79 @@
1
+ <script lang="ts">
2
+ import type { SeblifyProps } from 'seblify';
3
+
4
+ type Props = SeblifyProps<{
5
+ value?: number;
6
+ min?: number;
7
+ max?: number;
8
+ step?: number;
9
+ disabled?: boolean;
10
+ label?: string;
11
+ name?: string;
12
+ }>;
13
+
14
+ let {
15
+ value = $bindable(0),
16
+ min = 0,
17
+ max = 100,
18
+ step = 1,
19
+ disabled = false,
20
+ label,
21
+ name,
22
+ }: Props = $props();
23
+ </script>
24
+
25
+ <label class:disabled class="slider">
26
+ {#if label}
27
+ <span class="label">{label}</span>
28
+ {/if}
29
+ <span class="control-row">
30
+ <input
31
+ bind:value
32
+ {disabled}
33
+ max={String(max)}
34
+ min={String(min)}
35
+ {name}
36
+ step={String(step)}
37
+ type="range"
38
+ />
39
+ <output>{value}</output>
40
+ </span>
41
+ </label>
42
+
43
+ <style>
44
+ .slider {
45
+ display: grid;
46
+ gap: 8px;
47
+ min-width: 240px;
48
+ color: var(--seblify-color-text, #172033);
49
+ }
50
+
51
+ .label {
52
+ font-weight: 700;
53
+ line-height: 1.35;
54
+ }
55
+
56
+ .control-row {
57
+ display: grid;
58
+ grid-template-columns: minmax(0, 1fr) auto;
59
+ gap: 12px;
60
+ align-items: center;
61
+ }
62
+
63
+ input {
64
+ width: 100%;
65
+ accent-color: var(--seblify-color-fill-accent, #146a6f);
66
+ }
67
+
68
+ output {
69
+ min-width: 4ch;
70
+ color: var(--seblify-color-text-muted, #516176);
71
+ font-variant-numeric: tabular-nums;
72
+ text-align: right;
73
+ }
74
+
75
+ .disabled {
76
+ cursor: not-allowed;
77
+ opacity: var(--seblify-opacity-disabled, 0.56);
78
+ }
79
+ </style>
@@ -0,0 +1,11 @@
1
+ declare const Slider: import("svelte").Component<{
2
+ value?: number | undefined;
3
+ min?: number | undefined;
4
+ max?: number | undefined;
5
+ step?: number | undefined;
6
+ disabled?: boolean | undefined;
7
+ label?: string | undefined;
8
+ name?: string | undefined;
9
+ }, {}, "value">;
10
+ type Slider = ReturnType<typeof Slider>;
11
+ export default Slider;
@@ -0,0 +1,122 @@
1
+ <script lang="ts">
2
+ import type { SeblifyProps } from 'seblify';
3
+
4
+ type Props = SeblifyProps<{
5
+ checked?: boolean;
6
+ disabled?: boolean;
7
+ label?: string;
8
+ description?: string;
9
+ name?: string;
10
+ value?: string;
11
+ }>;
12
+
13
+ let {
14
+ checked = $bindable(false),
15
+ disabled = false,
16
+ label,
17
+ description,
18
+ name,
19
+ value,
20
+ }: Props = $props();
21
+ </script>
22
+
23
+ <label class:disabled class="switch">
24
+ <input bind:checked {disabled} {name} role="switch" type="checkbox" {value} />
25
+ <span class="control" aria-hidden="true">
26
+ <span class="thumb"></span>
27
+ </span>
28
+ <span class="content">
29
+ {#if label}
30
+ <span class="label">{label}</span>
31
+ {/if}
32
+ {#if description}
33
+ <span class="description">{description}</span>
34
+ {/if}
35
+ </span>
36
+ </label>
37
+
38
+ <style>
39
+ .switch {
40
+ position: relative;
41
+ display: inline-flex;
42
+ gap: 12px;
43
+ align-items: flex-start;
44
+ color: var(--seblify-color-text, #172033);
45
+ cursor: pointer;
46
+ }
47
+
48
+ input {
49
+ position: absolute;
50
+ width: 1px;
51
+ height: 1px;
52
+ margin: -1px;
53
+ overflow: hidden;
54
+ clip: rect(0 0 0 0);
55
+ clip-path: inset(50%);
56
+ white-space: nowrap;
57
+ }
58
+
59
+ .control {
60
+ display: inline-flex;
61
+ width: 42px;
62
+ height: 24px;
63
+ flex: 0 0 auto;
64
+ align-items: center;
65
+ border: 1px solid var(--seblify-color-border-strong, #aab7c5);
66
+ border-radius: 999px;
67
+ background: var(--seblify-color-surface-muted, #d9e0e8);
68
+ padding: 2px;
69
+ transition:
70
+ border-color 160ms ease,
71
+ background 160ms ease;
72
+ }
73
+
74
+ .thumb {
75
+ width: 18px;
76
+ height: 18px;
77
+ border-radius: 999px;
78
+ background: var(--seblify-color-surface, #ffffff);
79
+ box-shadow: var(--seblify-shadow-control, 0 1px 3px rgb(16 24 40 / 24%));
80
+ transition: transform 160ms ease;
81
+ }
82
+
83
+ input:checked + .control {
84
+ border-color: var(--seblify-color-fill-accent, #146a6f);
85
+ background: var(--seblify-color-fill-accent, #146a6f);
86
+ }
87
+
88
+ input:checked + .control .thumb {
89
+ background: var(--seblify-color-fill-accent-text, #ffffff);
90
+ }
91
+
92
+ input:checked + .control .thumb {
93
+ transform: translateX(18px);
94
+ }
95
+
96
+ input:focus-visible + .control {
97
+ outline: 3px solid var(--seblify-color-focus-ring, #9bd4d8);
98
+ outline-offset: 2px;
99
+ }
100
+
101
+ .content {
102
+ display: grid;
103
+ gap: 2px;
104
+ min-width: 0;
105
+ }
106
+
107
+ .label {
108
+ font-weight: 700;
109
+ line-height: 1.35;
110
+ }
111
+
112
+ .description {
113
+ color: var(--seblify-color-text-muted, #516176);
114
+ font-size: 0.875rem;
115
+ line-height: 1.45;
116
+ }
117
+
118
+ .disabled {
119
+ cursor: not-allowed;
120
+ opacity: var(--seblify-opacity-disabled, 0.56);
121
+ }
122
+ </style>
@@ -0,0 +1,10 @@
1
+ declare const Switch: import("svelte").Component<{
2
+ checked?: boolean | undefined;
3
+ disabled?: boolean | undefined;
4
+ label?: string | undefined;
5
+ description?: string | undefined;
6
+ name?: string | undefined;
7
+ value?: string | undefined;
8
+ }, {}, "checked">;
9
+ type Switch = ReturnType<typeof Switch>;
10
+ export default Switch;
@@ -0,0 +1,43 @@
1
+ <script lang="ts">
2
+ import type { SeblifyProps } from 'seblify';
3
+ import SegmentControl from '../segment-control/SegmentControl.svelte';
4
+
5
+ type ThemeMode = 'system' | 'light' | 'dark';
6
+
7
+ type Props = SeblifyProps<{
8
+ value?: ThemeMode;
9
+ label?: string;
10
+ description?: string;
11
+ name?: string;
12
+ applyToDocument?: boolean;
13
+ }>;
14
+
15
+ let {
16
+ value = $bindable('system'),
17
+ label = 'Theme',
18
+ description = 'Choose how Seblify should resolve colors.',
19
+ name = 'seblify-theme',
20
+ applyToDocument = true,
21
+ }: Props = $props();
22
+
23
+ const options: { value: ThemeMode; label: string }[] = [
24
+ { value: 'system', label: 'System' },
25
+ { value: 'light', label: 'Light' },
26
+ { value: 'dark', label: 'Dark' },
27
+ ];
28
+
29
+ $effect(() => {
30
+ if (!applyToDocument || typeof document === 'undefined') {
31
+ return;
32
+ }
33
+
34
+ if (value === 'system') {
35
+ delete document.documentElement.dataset.theme;
36
+ return;
37
+ }
38
+
39
+ document.documentElement.dataset.theme = value;
40
+ });
41
+ </script>
42
+
43
+ <SegmentControl bind:value {description} {label} {name} {options} />
@@ -0,0 +1,10 @@
1
+ type ThemeMode = 'system' | 'light' | 'dark';
2
+ declare const ThemeSwitch: import("svelte").Component<{
3
+ value?: ThemeMode | undefined;
4
+ label?: string | undefined;
5
+ description?: string | undefined;
6
+ name?: string | undefined;
7
+ applyToDocument?: boolean | undefined;
8
+ }, {}, "value">;
9
+ type ThemeSwitch = ReturnType<typeof ThemeSwitch>;
10
+ export default ThemeSwitch;