@noahbaumgartner/svelte-ui 0.0.1

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 (149) hide show
  1. package/README.md +65 -0
  2. package/dist/components/alert-dialog/AlertDialog.svelte +161 -0
  3. package/dist/components/alert-dialog/AlertDialog.svelte.d.ts +20 -0
  4. package/dist/components/avatar/Avatar.svelte +85 -0
  5. package/dist/components/avatar/Avatar.svelte.d.ts +12 -0
  6. package/dist/components/badge/Badge.svelte +49 -0
  7. package/dist/components/badge/Badge.svelte.d.ts +12 -0
  8. package/dist/components/breadcrumb/Breadcrumb.svelte +37 -0
  9. package/dist/components/breadcrumb/Breadcrumb.svelte.d.ts +9 -0
  10. package/dist/components/breadcrumb/BreadcrumbEllipsis.svelte +32 -0
  11. package/dist/components/breadcrumb/BreadcrumbEllipsis.svelte.d.ts +10 -0
  12. package/dist/components/breadcrumb/BreadcrumbItem.svelte +71 -0
  13. package/dist/components/breadcrumb/BreadcrumbItem.svelte.d.ts +12 -0
  14. package/dist/components/breadcrumb/BreadcrumbSeparator.svelte +18 -0
  15. package/dist/components/breadcrumb/BreadcrumbSeparator.svelte.d.ts +18 -0
  16. package/dist/components/button/Button.svelte +247 -0
  17. package/dist/components/button/Button.svelte.d.ts +24 -0
  18. package/dist/components/button-group/ButtonGroup.svelte +89 -0
  19. package/dist/components/button-group/ButtonGroup.svelte.d.ts +12 -0
  20. package/dist/components/calendar/Calendar.svelte +401 -0
  21. package/dist/components/calendar/Calendar.svelte.d.ts +17 -0
  22. package/dist/components/calendar/dates.d.ts +12 -0
  23. package/dist/components/calendar/dates.js +48 -0
  24. package/dist/components/card/Card.svelte +55 -0
  25. package/dist/components/card/Card.svelte.d.ts +10 -0
  26. package/dist/components/card/CardAction.svelte +24 -0
  27. package/dist/components/card/CardAction.svelte.d.ts +9 -0
  28. package/dist/components/card/CardContent.svelte +20 -0
  29. package/dist/components/card/CardContent.svelte.d.ts +8 -0
  30. package/dist/components/card/CardDescription.svelte +23 -0
  31. package/dist/components/card/CardDescription.svelte.d.ts +8 -0
  32. package/dist/components/card/CardFooter.svelte +28 -0
  33. package/dist/components/card/CardFooter.svelte.d.ts +9 -0
  34. package/dist/components/card/CardHeader.svelte +29 -0
  35. package/dist/components/card/CardHeader.svelte.d.ts +9 -0
  36. package/dist/components/card/CardTitle.svelte +23 -0
  37. package/dist/components/card/CardTitle.svelte.d.ts +8 -0
  38. package/dist/components/checkbox/Checkbox.svelte +93 -0
  39. package/dist/components/checkbox/Checkbox.svelte.d.ts +5 -0
  40. package/dist/components/color-picker/ColorPicker.svelte +233 -0
  41. package/dist/components/color-picker/ColorPicker.svelte.d.ts +10 -0
  42. package/dist/components/context-menu/ContextMenu.svelte +201 -0
  43. package/dist/components/context-menu/ContextMenu.svelte.d.ts +14 -0
  44. package/dist/components/context-menu/ContextMenuItem.svelte +105 -0
  45. package/dist/components/context-menu/ContextMenuItem.svelte.d.ts +14 -0
  46. package/dist/components/context-menu/context.d.ts +14 -0
  47. package/dist/components/context-menu/context.js +2 -0
  48. package/dist/components/dialog/Dialog.svelte +225 -0
  49. package/dist/components/dialog/Dialog.svelte.d.ts +22 -0
  50. package/dist/components/field/Field.svelte +78 -0
  51. package/dist/components/field/Field.svelte.d.ts +11 -0
  52. package/dist/components/field/FieldContent.svelte +25 -0
  53. package/dist/components/field/FieldContent.svelte.d.ts +9 -0
  54. package/dist/components/field/FieldDescription.svelte +34 -0
  55. package/dist/components/field/FieldDescription.svelte.d.ts +9 -0
  56. package/dist/components/field/FieldError.svelte +45 -0
  57. package/dist/components/field/FieldError.svelte.d.ts +11 -0
  58. package/dist/components/field/FieldGroup.svelte +30 -0
  59. package/dist/components/field/FieldGroup.svelte.d.ts +9 -0
  60. package/dist/components/field/FieldLegend.svelte +34 -0
  61. package/dist/components/field/FieldLegend.svelte.d.ts +10 -0
  62. package/dist/components/field/FieldSeparator.svelte +31 -0
  63. package/dist/components/field/FieldSeparator.svelte.d.ts +9 -0
  64. package/dist/components/field/FieldSet.svelte +33 -0
  65. package/dist/components/field/FieldSet.svelte.d.ts +9 -0
  66. package/dist/components/input/Input.svelte +459 -0
  67. package/dist/components/input/Input.svelte.d.ts +10 -0
  68. package/dist/components/input-group/InputGroup.svelte +88 -0
  69. package/dist/components/input-group/InputGroup.svelte.d.ts +9 -0
  70. package/dist/components/input-group/InputGroupAddon.svelte +88 -0
  71. package/dist/components/input-group/InputGroupAddon.svelte.d.ts +11 -0
  72. package/dist/components/kbd/Kbd.svelte +46 -0
  73. package/dist/components/kbd/Kbd.svelte.d.ts +8 -0
  74. package/dist/components/kbd/KbdGroup.svelte +27 -0
  75. package/dist/components/kbd/KbdGroup.svelte.d.ts +8 -0
  76. package/dist/components/label/Label.svelte +48 -0
  77. package/dist/components/label/Label.svelte.d.ts +9 -0
  78. package/dist/components/link/Link.svelte +40 -0
  79. package/dist/components/link/Link.svelte.d.ts +10 -0
  80. package/dist/components/navbar/Navbar.svelte +266 -0
  81. package/dist/components/navbar/Navbar.svelte.d.ts +26 -0
  82. package/dist/components/navigation-menu/NavigationMenu.svelte +95 -0
  83. package/dist/components/navigation-menu/NavigationMenu.svelte.d.ts +12 -0
  84. package/dist/components/navigation-menu/NavigationMenuItem.svelte +257 -0
  85. package/dist/components/navigation-menu/NavigationMenuItem.svelte.d.ts +15 -0
  86. package/dist/components/navigation-menu/NavigationMenuLink.svelte +91 -0
  87. package/dist/components/navigation-menu/NavigationMenuLink.svelte.d.ts +16 -0
  88. package/dist/components/navigation-menu/context.d.ts +15 -0
  89. package/dist/components/navigation-menu/context.js +2 -0
  90. package/dist/components/popover/Popover.svelte +295 -0
  91. package/dist/components/popover/Popover.svelte.d.ts +34 -0
  92. package/dist/components/radio-group/RadioGroup.svelte +86 -0
  93. package/dist/components/radio-group/RadioGroup.svelte.d.ts +16 -0
  94. package/dist/components/radio-group/RadioGroupItem.svelte +95 -0
  95. package/dist/components/radio-group/RadioGroupItem.svelte.d.ts +7 -0
  96. package/dist/components/radio-group/context.d.ts +9 -0
  97. package/dist/components/radio-group/context.js +2 -0
  98. package/dist/components/separator/Separator.svelte +41 -0
  99. package/dist/components/separator/Separator.svelte.d.ts +10 -0
  100. package/dist/components/sidebar/Sidebar.svelte +180 -0
  101. package/dist/components/sidebar/Sidebar.svelte.d.ts +14 -0
  102. package/dist/components/sidebar/SidebarContent.svelte +30 -0
  103. package/dist/components/sidebar/SidebarContent.svelte.d.ts +9 -0
  104. package/dist/components/sidebar/SidebarFooter.svelte +23 -0
  105. package/dist/components/sidebar/SidebarFooter.svelte.d.ts +8 -0
  106. package/dist/components/sidebar/SidebarGroup.svelte +55 -0
  107. package/dist/components/sidebar/SidebarGroup.svelte.d.ts +11 -0
  108. package/dist/components/sidebar/SidebarHeader.svelte +23 -0
  109. package/dist/components/sidebar/SidebarHeader.svelte.d.ts +8 -0
  110. package/dist/components/sidebar/SidebarInset.svelte +25 -0
  111. package/dist/components/sidebar/SidebarInset.svelte.d.ts +9 -0
  112. package/dist/components/sidebar/SidebarMenu.svelte +27 -0
  113. package/dist/components/sidebar/SidebarMenu.svelte.d.ts +9 -0
  114. package/dist/components/sidebar/SidebarMenuItem.svelte +221 -0
  115. package/dist/components/sidebar/SidebarMenuItem.svelte.d.ts +23 -0
  116. package/dist/components/sidebar/SidebarProvider.svelte +62 -0
  117. package/dist/components/sidebar/SidebarProvider.svelte.d.ts +11 -0
  118. package/dist/components/sidebar/SidebarSeparator.svelte +5 -0
  119. package/dist/components/sidebar/SidebarSeparator.svelte.d.ts +18 -0
  120. package/dist/components/sidebar/SidebarTrigger.svelte +24 -0
  121. package/dist/components/sidebar/SidebarTrigger.svelte.d.ts +7 -0
  122. package/dist/components/sidebar/context.d.ts +15 -0
  123. package/dist/components/sidebar/context.js +2 -0
  124. package/dist/components/skeleton/Skeleton.svelte +30 -0
  125. package/dist/components/skeleton/Skeleton.svelte.d.ts +5 -0
  126. package/dist/components/spinner/Spinner.svelte +72 -0
  127. package/dist/components/spinner/Spinner.svelte.d.ts +9 -0
  128. package/dist/components/switch/Switch.svelte +88 -0
  129. package/dist/components/switch/Switch.svelte.d.ts +5 -0
  130. package/dist/components/table/Table.svelte +276 -0
  131. package/dist/components/table/Table.svelte.d.ts +60 -0
  132. package/dist/components/textarea/Textarea.svelte +57 -0
  133. package/dist/components/textarea/Textarea.svelte.d.ts +4 -0
  134. package/dist/components/time-picker/TimePicker.svelte +162 -0
  135. package/dist/components/time-picker/TimePicker.svelte.d.ts +11 -0
  136. package/dist/components/toaster/Toaster.svelte +151 -0
  137. package/dist/components/toaster/Toaster.svelte.d.ts +7 -0
  138. package/dist/components/toaster/toast.svelte.d.ts +28 -0
  139. package/dist/components/toaster/toast.svelte.js +22 -0
  140. package/dist/components/toggle/Toggle.svelte +31 -0
  141. package/dist/components/toggle/Toggle.svelte.d.ts +8 -0
  142. package/dist/components/tooltip/Tooltip.svelte +224 -0
  143. package/dist/components/tooltip/Tooltip.svelte.d.ts +27 -0
  144. package/dist/icons.d.ts +2 -0
  145. package/dist/icons.js +4 -0
  146. package/dist/index.d.ts +73 -0
  147. package/dist/index.js +66 -0
  148. package/dist/styles/tokens.css +50 -0
  149. package/package.json +88 -0
@@ -0,0 +1,247 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import type { LucideIcon } from '@lucide/svelte';
5
+ import Spinner from '../spinner/Spinner.svelte';
6
+
7
+ type Props = Omit<HTMLAttributes<HTMLElement>, 'children'> & {
8
+ /** Renders an <a> instead of a <button>. External (http) links open in a new tab. */
9
+ href?: string;
10
+ target?: string;
11
+ rel?: string;
12
+ type?: 'button' | 'submit' | 'reset';
13
+ disabled?: boolean;
14
+ /** Replaces the icon with a Spinner and blocks clicks. */
15
+ loading?: boolean;
16
+ /** `overlay` is a translucent, blurred, fully rounded button for use on top of images or media. */
17
+ variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'overlay';
18
+ size?: 'sm' | 'md' | 'lg';
19
+ /** Any Lucide icon (import from `svelte-ui/icons`). */
20
+ icon?: LucideIcon;
21
+ /** Accessible name. Required when the button has no label (icon-only). */
22
+ label?: string;
23
+ children?: Snippet;
24
+ };
25
+
26
+ let {
27
+ href,
28
+ target,
29
+ rel,
30
+ type = 'button',
31
+ disabled = false,
32
+ loading = false,
33
+ variant = 'primary',
34
+ size = 'md',
35
+ icon: Icon,
36
+ label,
37
+ class: className,
38
+ children,
39
+ ...rest
40
+ }: Props = $props();
41
+
42
+ let iconOnly = $derived(!children);
43
+ let resolvedTarget = $derived(target ?? (href?.startsWith('http') ? '_blank' : undefined));
44
+ let resolvedRel = $derived(rel ?? (resolvedTarget === '_blank' ? 'noopener' : undefined));
45
+ let classes = $derived([
46
+ 'button',
47
+ `button--${variant}`,
48
+ `button--${size}`,
49
+ {
50
+ 'button--icon-only': iconOnly,
51
+ 'button--no-icon': !Icon && !loading,
52
+ 'button--loading': loading
53
+ },
54
+ className
55
+ ]);
56
+ </script>
57
+
58
+ {#snippet content()}
59
+ {#if loading}
60
+ <Spinner class="button-spinner" aria-hidden="true" />
61
+ {:else if Icon}<Icon class="button-icon" aria-hidden="true" />{/if}
62
+ {#if children}<span class="button-label">{@render children()}</span>{/if}
63
+ {/snippet}
64
+
65
+ {#if href && !disabled && !loading}
66
+ <!-- href comes from the consumer, who resolves it; this library has no routes -->
67
+ <!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
68
+ <a {...rest} {href} target={resolvedTarget} rel={resolvedRel} aria-label={label} class={classes}>
69
+ {@render content()}
70
+ </a>
71
+ {:else}
72
+ <button
73
+ {...rest}
74
+ {type}
75
+ disabled={disabled || loading}
76
+ aria-busy={loading || undefined}
77
+ aria-label={label}
78
+ class={classes}
79
+ >
80
+ {@render content()}
81
+ </button>
82
+ {/if}
83
+
84
+ <style>
85
+ .button {
86
+ display: inline-flex;
87
+ align-items: center;
88
+ justify-content: center;
89
+ gap: 6px;
90
+ min-width: 0;
91
+ box-sizing: border-box;
92
+ border: none;
93
+ border-radius: 10px;
94
+ font-family: inherit;
95
+ font-size: 13px;
96
+ text-decoration: none;
97
+ outline: none;
98
+ cursor: pointer;
99
+ user-select: none;
100
+ transition:
101
+ background-color 200ms ease,
102
+ color 200ms ease,
103
+ opacity 200ms ease;
104
+ }
105
+
106
+ .button:disabled {
107
+ cursor: not-allowed;
108
+ opacity: 0.7;
109
+ }
110
+
111
+ .button--loading:disabled {
112
+ cursor: progress;
113
+ opacity: 1;
114
+ }
115
+
116
+ .button-label {
117
+ overflow: hidden;
118
+ min-width: 0;
119
+ white-space: nowrap;
120
+ text-overflow: ellipsis;
121
+ }
122
+
123
+ .button:focus-visible {
124
+ outline: 2px solid var(--color-accent);
125
+ outline-offset: 2px;
126
+ }
127
+
128
+ .button :global(.button-icon) {
129
+ width: 16px;
130
+ height: 16px;
131
+ flex-shrink: 0;
132
+ }
133
+
134
+ /* 2px smaller than the icon it replaces */
135
+ .button :global(.button-spinner) {
136
+ --spinner-size: 14px;
137
+ }
138
+
139
+ .button--sm :global(.button-spinner) {
140
+ --spinner-size: 12px;
141
+ }
142
+
143
+ /* Sizes */
144
+
145
+ .button--lg {
146
+ height: 36px;
147
+ padding: 0 20px 0 16px;
148
+ }
149
+
150
+ .button--md {
151
+ height: 32px;
152
+ padding: 0 15px 0 11px;
153
+ }
154
+
155
+ .button--sm {
156
+ height: 28px;
157
+ padding: 0 12px 0 9px;
158
+ gap: 5px;
159
+ border-radius: 8px;
160
+ font-size: 12px;
161
+ }
162
+
163
+ .button--sm :global(.button-icon) {
164
+ width: 14px;
165
+ height: 14px;
166
+ }
167
+
168
+ .button--no-icon.button--sm {
169
+ padding: 0 12px;
170
+ }
171
+
172
+ .button--no-icon.button--lg {
173
+ padding: 0 20px;
174
+ }
175
+
176
+ .button--no-icon.button--md {
177
+ padding: 0 16px;
178
+ }
179
+
180
+ /* Icon-only is square */
181
+ .button--icon-only.button--lg {
182
+ width: 36px;
183
+ padding: 0;
184
+ }
185
+
186
+ .button--icon-only.button--md {
187
+ width: 32px;
188
+ padding: 0;
189
+ }
190
+
191
+ .button--icon-only.button--sm {
192
+ width: 28px;
193
+ padding: 0;
194
+ }
195
+
196
+ /* Variants */
197
+
198
+ .button--primary {
199
+ background-color: var(--color-accent);
200
+ color: var(--color-accent-foreground);
201
+ }
202
+
203
+ .button--primary:hover:not(:disabled) {
204
+ background-color: var(--color-accent-hover);
205
+ }
206
+
207
+ .button--secondary {
208
+ background-color: var(--color-surface);
209
+ color: var(--color-text);
210
+ }
211
+
212
+ .button--secondary:hover:not(:disabled) {
213
+ background-color: var(--color-surface-hover);
214
+ }
215
+
216
+ .button--outline {
217
+ border: 1px solid var(--color-border-strong);
218
+ background-color: transparent;
219
+ color: var(--color-text);
220
+ }
221
+
222
+ .button--outline:hover:not(:disabled) {
223
+ background-color: var(--color-surface);
224
+ }
225
+
226
+ .button--ghost {
227
+ background-color: transparent;
228
+ color: var(--color-text);
229
+ }
230
+
231
+ .button--ghost:hover:not(:disabled) {
232
+ background-color: var(--color-surface);
233
+ }
234
+
235
+ /* Pill with a label, circle when icon-only */
236
+ .button--overlay {
237
+ border-radius: 999px;
238
+ background-color: color-mix(in srgb, var(--color-surface) 60%, transparent);
239
+ backdrop-filter: blur(8px);
240
+ -webkit-backdrop-filter: blur(8px);
241
+ color: var(--color-text);
242
+ }
243
+
244
+ .button--overlay:hover:not(:disabled) {
245
+ background-color: color-mix(in srgb, var(--color-surface) 75%, transparent);
246
+ }
247
+ </style>
@@ -0,0 +1,24 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { LucideIcon } from '@lucide/svelte';
4
+ type Props = Omit<HTMLAttributes<HTMLElement>, 'children'> & {
5
+ /** Renders an <a> instead of a <button>. External (http) links open in a new tab. */
6
+ href?: string;
7
+ target?: string;
8
+ rel?: string;
9
+ type?: 'button' | 'submit' | 'reset';
10
+ disabled?: boolean;
11
+ /** Replaces the icon with a Spinner and blocks clicks. */
12
+ loading?: boolean;
13
+ /** `overlay` is a translucent, blurred, fully rounded button for use on top of images or media. */
14
+ variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'overlay';
15
+ size?: 'sm' | 'md' | 'lg';
16
+ /** Any Lucide icon (import from `svelte-ui/icons`). */
17
+ icon?: LucideIcon;
18
+ /** Accessible name. Required when the button has no label (icon-only). */
19
+ label?: string;
20
+ children?: Snippet;
21
+ };
22
+ declare const Button: import("svelte").Component<Props, {}, "">;
23
+ type Button = ReturnType<typeof Button>;
24
+ export default Button;
@@ -0,0 +1,89 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+
5
+ type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
6
+ orientation?: 'horizontal' | 'vertical';
7
+ /** Accessible name for the group. */
8
+ label?: string;
9
+ /** Buttons, or ContextMenus with a Button trigger (split button). */
10
+ children: Snippet;
11
+ };
12
+
13
+ let { orientation = 'horizontal', label, class: className, children, ...rest }: Props = $props();
14
+ </script>
15
+
16
+ <div
17
+ {...rest}
18
+ role="group"
19
+ aria-label={label}
20
+ class={['button-group', `button-group--${orientation}`, className]}
21
+ >
22
+ {@render children()}
23
+ </div>
24
+
25
+ <style>
26
+ .button-group {
27
+ display: inline-flex;
28
+ gap: 1px;
29
+ width: fit-content;
30
+ }
31
+
32
+ .button-group--vertical {
33
+ flex-direction: column;
34
+ }
35
+
36
+ /* Keep the focus ring above neighbouring buttons */
37
+ .button-group > :global(*) {
38
+ position: relative;
39
+ }
40
+
41
+ .button-group > :global(:is(:focus-visible, :has(:focus-visible))) {
42
+ z-index: 1;
43
+ }
44
+
45
+ .button-group--vertical > :global(*),
46
+ .button-group--vertical > :global(* > .button) {
47
+ width: 100%;
48
+ }
49
+
50
+ /* Outline buttons share their borders instead of sitting 1px apart */
51
+ .button-group:has(> :global(.button--outline), > :global(* > .button--outline)) {
52
+ gap: 0;
53
+ }
54
+
55
+ .button-group--horizontal > :global(.button--outline:not(:first-child)),
56
+ .button-group--horizontal > :global(:not(:first-child):has(> .button--outline)) {
57
+ margin-inline-start: -1px;
58
+ }
59
+
60
+ .button-group--vertical > :global(.button--outline:not(:first-child)),
61
+ .button-group--vertical > :global(:not(:first-child):has(> .button--outline)) {
62
+ margin-block-start: -1px;
63
+ }
64
+
65
+ /* Square the inner corners; `* > .button` reaches a ContextMenu's trigger */
66
+ .button-group--horizontal > :global(:not(:first-child)),
67
+ .button-group--horizontal > :global(:not(:first-child) > .button) {
68
+ border-start-start-radius: 0;
69
+ border-end-start-radius: 0;
70
+ }
71
+
72
+ .button-group--horizontal > :global(:not(:last-child)),
73
+ .button-group--horizontal > :global(:not(:last-child) > .button) {
74
+ border-start-end-radius: 0;
75
+ border-end-end-radius: 0;
76
+ }
77
+
78
+ .button-group--vertical > :global(:not(:first-child)),
79
+ .button-group--vertical > :global(:not(:first-child) > .button) {
80
+ border-start-start-radius: 0;
81
+ border-start-end-radius: 0;
82
+ }
83
+
84
+ .button-group--vertical > :global(:not(:last-child)),
85
+ .button-group--vertical > :global(:not(:last-child) > .button) {
86
+ border-end-start-radius: 0;
87
+ border-end-end-radius: 0;
88
+ }
89
+ </style>
@@ -0,0 +1,12 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Props = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
4
+ orientation?: 'horizontal' | 'vertical';
5
+ /** Accessible name for the group. */
6
+ label?: string;
7
+ /** Buttons, or ContextMenus with a Button trigger (split button). */
8
+ children: Snippet;
9
+ };
10
+ declare const ButtonGroup: import("svelte").Component<Props, {}, "">;
11
+ type ButtonGroup = ReturnType<typeof ButtonGroup>;
12
+ export default ButtonGroup;