lutra 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 (153) hide show
  1. package/README.md +29 -0
  2. package/dist/Data/Stat.svelte +89 -0
  3. package/dist/Data/Stat.svelte.d.ts +33 -0
  4. package/dist/DataTable/DataTable.svelte +36 -0
  5. package/dist/DataTable/DataTable.svelte.d.ts +19 -0
  6. package/dist/DataTable/DataTableColumn.svelte +20 -0
  7. package/dist/DataTable/DataTableColumn.svelte.d.ts +18 -0
  8. package/dist/DataTable/DataTableRow.svelte +28 -0
  9. package/dist/DataTable/DataTableRow.svelte.d.ts +18 -0
  10. package/dist/Display/Avatar.svelte +61 -0
  11. package/dist/Display/Avatar.svelte.d.ts +18 -0
  12. package/dist/Display/Badge.svelte +93 -0
  13. package/dist/Display/Badge.svelte.d.ts +30 -0
  14. package/dist/Display/Callout.svelte +105 -0
  15. package/dist/Display/Callout.svelte.d.ts +34 -0
  16. package/dist/Display/Code.svelte +195 -0
  17. package/dist/Display/Code.svelte.d.ts +29 -0
  18. package/dist/Display/ContextTip.svelte +23 -0
  19. package/dist/Display/ContextTip.svelte.d.ts +17 -0
  20. package/dist/Display/Details.svelte +49 -0
  21. package/dist/Display/Details.svelte.d.ts +26 -0
  22. package/dist/Display/Hero.svelte +50 -0
  23. package/dist/Display/Hero.svelte.d.ts +25 -0
  24. package/dist/Display/Icon.svelte +35 -0
  25. package/dist/Display/Icon.svelte.d.ts +18 -0
  26. package/dist/Display/IconButton.svelte +85 -0
  27. package/dist/Display/IconButton.svelte.d.ts +28 -0
  28. package/dist/Display/Indicator.svelte +352 -0
  29. package/dist/Display/Indicator.svelte.d.ts +22 -0
  30. package/dist/Display/Popup.svelte +111 -0
  31. package/dist/Display/Popup.svelte.d.ts +26 -0
  32. package/dist/Display/Tag.svelte +90 -0
  33. package/dist/Display/Tag.svelte.d.ts +31 -0
  34. package/dist/Display/Tooltip.svelte +96 -0
  35. package/dist/Display/Tooltip.svelte.d.ts +22 -0
  36. package/dist/Form/Button.svelte +34 -0
  37. package/dist/Form/Button.svelte.d.ts +24 -0
  38. package/dist/Form/FieldActions.svelte +25 -0
  39. package/dist/Form/FieldActions.svelte.d.ts +17 -0
  40. package/dist/Form/FieldContainer.svelte +31 -0
  41. package/dist/Form/FieldContainer.svelte.d.ts +18 -0
  42. package/dist/Form/FieldContent.svelte +78 -0
  43. package/dist/Form/FieldContent.svelte.d.ts +32 -0
  44. package/dist/Form/FieldSection.svelte +97 -0
  45. package/dist/Form/FieldSection.svelte.d.ts +23 -0
  46. package/dist/Form/Fieldset.svelte +63 -0
  47. package/dist/Form/Fieldset.svelte.d.ts +32 -0
  48. package/dist/Form/Form.svelte +19 -0
  49. package/dist/Form/Form.svelte.d.ts +18 -0
  50. package/dist/Form/Input.svelte +266 -0
  51. package/dist/Form/Input.svelte.d.ts +113 -0
  52. package/dist/Form/InputLength.svelte +32 -0
  53. package/dist/Form/InputLength.svelte.d.ts +19 -0
  54. package/dist/Form/Label.svelte +26 -0
  55. package/dist/Form/Label.svelte.d.ts +25 -0
  56. package/dist/Form/Select.svelte +24 -0
  57. package/dist/Form/Select.svelte.d.ts +28 -0
  58. package/dist/Form/form.d.ts +34 -0
  59. package/dist/Form/form.js +31 -0
  60. package/dist/Form/types.d.ts +4 -0
  61. package/dist/Form/types.js +1 -0
  62. package/dist/Grid/Column.svelte +11 -0
  63. package/dist/Grid/Column.svelte.d.ts +17 -0
  64. package/dist/Grid/Grid.svelte +19 -0
  65. package/dist/Grid/Grid.svelte.d.ts +18 -0
  66. package/dist/Grid/Row.svelte +44 -0
  67. package/dist/Grid/Row.svelte.d.ts +19 -0
  68. package/dist/Icons/Alert.svelte +3 -0
  69. package/dist/Icons/Alert.svelte.d.ts +23 -0
  70. package/dist/Icons/Copy.svelte +3 -0
  71. package/dist/Icons/Copy.svelte.d.ts +23 -0
  72. package/dist/Icons/Done.svelte +3 -0
  73. package/dist/Icons/Done.svelte.d.ts +23 -0
  74. package/dist/Icons/Error.svelte +3 -0
  75. package/dist/Icons/Error.svelte.d.ts +23 -0
  76. package/dist/Icons/Help.svelte +3 -0
  77. package/dist/Icons/Help.svelte.d.ts +23 -0
  78. package/dist/Icons/Hide.svelte +3 -0
  79. package/dist/Icons/Hide.svelte.d.ts +23 -0
  80. package/dist/Icons/Info.svelte +3 -0
  81. package/dist/Icons/Info.svelte.d.ts +23 -0
  82. package/dist/Icons/Link.svelte +3 -0
  83. package/dist/Icons/Link.svelte.d.ts +23 -0
  84. package/dist/Icons/Show.svelte +3 -0
  85. package/dist/Icons/Show.svelte.d.ts +23 -0
  86. package/dist/Icons/Success.svelte +3 -0
  87. package/dist/Icons/Success.svelte.d.ts +23 -0
  88. package/dist/Icons/Warning.svelte +3 -0
  89. package/dist/Icons/Warning.svelte.d.ts +23 -0
  90. package/dist/Layout/Layout.svelte +43 -0
  91. package/dist/Layout/Layout.svelte.d.ts +21 -0
  92. package/dist/Layout/LayoutFooter.svelte +21 -0
  93. package/dist/Layout/LayoutFooter.svelte.d.ts +17 -0
  94. package/dist/Layout/LayoutGrid.svelte +51 -0
  95. package/dist/Layout/LayoutGrid.svelte.d.ts +30 -0
  96. package/dist/Layout/LayoutHeader.svelte +94 -0
  97. package/dist/Layout/LayoutHeader.svelte.d.ts +38 -0
  98. package/dist/Layout/LayoutTypes.svelte.d.ts +15 -0
  99. package/dist/Layout/LayoutTypes.svelte.js +9 -0
  100. package/dist/Layout/PageContent.svelte +89 -0
  101. package/dist/Layout/PageContent.svelte.d.ts +23 -0
  102. package/dist/Layout/Theme.svelte +215 -0
  103. package/dist/Layout/Theme.svelte.d.ts +18 -0
  104. package/dist/Layout/UIContent.svelte +15 -0
  105. package/dist/Layout/UIContent.svelte.d.ts +17 -0
  106. package/dist/Navigation/Breadcrumb.svelte +82 -0
  107. package/dist/Navigation/Breadcrumb.svelte.d.ts +29 -0
  108. package/dist/Navigation/Menu.svelte +180 -0
  109. package/dist/Navigation/Menu.svelte.d.ts +18 -0
  110. package/dist/Navigation/MenuTypes.svelte.d.ts +37 -0
  111. package/dist/Navigation/MenuTypes.svelte.js +1 -0
  112. package/dist/Navigation/TabbedContent.svelte +43 -0
  113. package/dist/Navigation/TabbedContent.svelte.d.ts +22 -0
  114. package/dist/Navigation/Tabs.svelte +118 -0
  115. package/dist/Navigation/Tabs.svelte.d.ts +24 -0
  116. package/dist/Pages/LoginPage.svelte +32 -0
  117. package/dist/Pages/LoginPage.svelte.d.ts +14 -0
  118. package/dist/Typography/Clamp.svelte +25 -0
  119. package/dist/Typography/Clamp.svelte.d.ts +23 -0
  120. package/dist/Typography/H.svelte +51 -0
  121. package/dist/Typography/H.svelte.d.ts +25 -0
  122. package/dist/Typography/H1.svelte +14 -0
  123. package/dist/Typography/H1.svelte.d.ts +23 -0
  124. package/dist/Typography/H2.svelte +13 -0
  125. package/dist/Typography/H2.svelte.d.ts +23 -0
  126. package/dist/Typography/H3.svelte +13 -0
  127. package/dist/Typography/H3.svelte.d.ts +23 -0
  128. package/dist/Typography/H4.svelte +13 -0
  129. package/dist/Typography/H4.svelte.d.ts +23 -0
  130. package/dist/Typography/H5.svelte +13 -0
  131. package/dist/Typography/H5.svelte.d.ts +23 -0
  132. package/dist/Typography/H6.svelte +13 -0
  133. package/dist/Typography/H6.svelte.d.ts +23 -0
  134. package/dist/Typography/P.svelte +32 -0
  135. package/dist/Typography/P.svelte.d.ts +23 -0
  136. package/dist/index.d.ts +1 -0
  137. package/dist/index.js +2 -0
  138. package/dist/style.css +787 -0
  139. package/dist/utils/attr.d.ts +5 -0
  140. package/dist/utils/attr.js +21 -0
  141. package/dist/utils/color.d.ts +51 -0
  142. package/dist/utils/color.js +97 -0
  143. package/dist/utils/defaults.d.ts +4 -0
  144. package/dist/utils/defaults.js +1 -0
  145. package/dist/utils/hooks.server.d.ts +2 -0
  146. package/dist/utils/hooks.server.js +16 -0
  147. package/dist/utils/id.d.ts +1 -0
  148. package/dist/utils/id.js +3 -0
  149. package/dist/utils/isSnippet.d.ts +5 -0
  150. package/dist/utils/isSnippet.js +6 -0
  151. package/dist/utils/transitions.d.ts +29 -0
  152. package/dist/utils/transitions.js +66 -0
  153. package/package.json +58 -0
@@ -0,0 +1,352 @@
1
+ <script>import { isStatusColor, StatusColors } from "../utils/color.js";
2
+ let {
3
+ color = "default",
4
+ motion,
5
+ label
6
+ } = $props();
7
+ let isSet = $derived(isStatusColor(color));
8
+ let _label = $derived(isSet ? StatusColors[color] : label ? label : "status");
9
+ </script>
10
+
11
+ <span role="status" aria-label="{_label}" class="Indicator {color} {motion}" style="--bgColor: {isSet ? 'var(--status-'+color+')' : color};" />
12
+
13
+ <style>
14
+ .Indicator {
15
+ --isize: var(--size, 0.75em);
16
+ --icount: var(--animation-iteration-count, infinite);
17
+ --bwidth: min(3px, calc(var(--isize) * 0.15));
18
+ display: inline-block;
19
+ position: relative;
20
+ vertical-align: middle;
21
+ margin-inline: var(--margin-inline, 0 calc(var(--isize) * 0.75));
22
+ background: var(--bgColor);
23
+ block-size: var(--isize);
24
+ inline-size: var(--isize);
25
+ border-radius: 50%;
26
+ mask-size: 0% 0%;
27
+ --dur: clamp(0.5s, var(--animation-duration, 1.2s), 3s);
28
+ transition: all calc(var(--dur) / 2), width 0s, height 0s, margin 0s;
29
+ margin-block-start: -2px;
30
+ animation-name: none;
31
+ animation-duration: var(--dur);
32
+ animation-iteration-count: var(--icount);
33
+ border-width: var(--bwidth);
34
+ border-style: solid;
35
+ border-color: transparent;
36
+ box-sizing: border-box;
37
+ }
38
+ .Indicator::after,
39
+ .Indicator::before {
40
+ box-sizing: border-box;
41
+ content: "";
42
+ position: absolute;
43
+ top: 0%;
44
+ left: 0;
45
+ width: 100%;
46
+ height: 100%;
47
+ border-radius: 50%;
48
+ border-width: var(--bwidth);
49
+ border-style: solid;
50
+ border-color: transparent;
51
+ animation-name: none;
52
+ animation-duration: var(--dur);
53
+ animation-iteration-count: var(--icount);
54
+ }
55
+
56
+ /**
57
+ * Tunnel
58
+ */
59
+
60
+ .Indicator.tunnel {
61
+ background: transparent;
62
+ border-color: var(--bgColor);
63
+ }
64
+ .Indicator.tunnel::after,
65
+ .Indicator.tunnel::before {
66
+ animation-name: tunnel;
67
+ animation-timing-function: ease-in;
68
+ border-width: calc(var(--bwidth) * 2);
69
+ animation-duration: calc(var(--dur) * 2);
70
+ }
71
+ .Indicator.tunnel::before {
72
+ animation-delay: calc(-1 * var(--dur) * 0.95);
73
+ }
74
+ @keyframes tunnel {
75
+ 0% {
76
+ border-color: var(--bgColor);
77
+ transform: scale(0.1);
78
+ opacity: 0;
79
+ }
80
+ 10% {
81
+ opacity: 1;
82
+ }
83
+ 75% {
84
+ opacity: 1;
85
+ }
86
+ 100% {
87
+ transform: scale(1.5);
88
+ opacity: 0;
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Blink
94
+ */
95
+
96
+ .Indicator.blink {
97
+ animation-name: blink;
98
+ animation-timing-function: ease-in-out;
99
+ }
100
+ @keyframes blink {
101
+ 0% {
102
+ opacity: 1;
103
+ transform: scale(1);
104
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.15) var(--bgColor));
105
+ }
106
+ 25% {
107
+ opacity: 0.5;
108
+ transform: scale(0.95);
109
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.1) transparent);
110
+ }
111
+ 50% {
112
+ opacity: 0.5;
113
+ transform: scale(0.95);
114
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.1) transparent);
115
+ }
116
+ 75% {
117
+ opacity: 1;
118
+ transform: scale(1);
119
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.15) var(--bgColor));
120
+ }
121
+ 100% {
122
+ opacity: 1;
123
+ transform: scale(1);
124
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.15) var(--bgColor));
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Bulge
130
+ */
131
+
132
+ .Indicator.bulge {
133
+ animation-name: bulge;
134
+ animation-timing-function: ease-in-out;
135
+ }
136
+ @keyframes bulge {
137
+ 0% {
138
+ transform: scale(0.85);
139
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.05) var(--bgColor)) brightness(1) saturate(1);
140
+ }
141
+ 50% {
142
+ transform: scale(1);
143
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.1) var(--bgColor)) brightness(1.15) saturate(1.15);
144
+ }
145
+ 100% {
146
+ transform: scale(0.85);
147
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.05) var(--bgColor)) brightness(1) saturate(1);
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Highlight
153
+ */
154
+
155
+ .Indicator.highlight {
156
+ animation-name: hilite2;
157
+ animation-timing-function:cubic-bezier(0.445, 0.05, 0.55, 0.95);
158
+ border-width: 0;
159
+ }
160
+
161
+ @keyframes hilite2 {
162
+ 0% {
163
+ filter: brightness(1) saturate(1) drop-shadow(0 0 calc(var(--isize) * 0.1) var(--bgColor));
164
+ }
165
+ 35% {
166
+ filter: brightness(1) saturate(1) drop-shadow(0 0 calc(var(--isize) * 0.1) var(--bgColor));
167
+ }
168
+ 50% {
169
+ filter: brightness(1.05) saturate(1.05) drop-shadow(0 0 calc(var(--isize) * 0.05) var(--bgColor));
170
+ }
171
+ 65% {
172
+ filter: brightness(1) saturate(1) drop-shadow(0 0 calc(var(--isize) * 0.1) var(--bgColor));
173
+ }
174
+ 100% {
175
+ filter: brightness(1) saturate(1) drop-shadow(0 0 calc(var(--isize) * 0.1) var(--bgColor));
176
+ }
177
+ }
178
+
179
+ .Indicator.highlight::before {
180
+ border-width: 0;
181
+ }
182
+
183
+ .Indicator.highlight::after {
184
+ background: linear-gradient(45deg, transparent, transparent, rgba(255,255,255,0.75), transparent, transparent);
185
+ animation-name: hilite;
186
+ animation-timing-function: linear;
187
+ mix-blend-mode: luminosity;
188
+ border-width: 0;
189
+ filter: blur(calc(var(--isize) * 0.12));
190
+ background-size: 500% 120%;
191
+ }
192
+ @keyframes hilite {
193
+ 0% {
194
+ background-position: 100% center;
195
+ }
196
+ 100% {
197
+ background-position: 0 center;
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Spin
203
+ */
204
+
205
+ .Indicator.spin {
206
+ background: transparent;
207
+ --mask: radial-gradient(circle, rgba(0, 0, 0, 0) 20%, rgba(0, 0, 0, 0) 45%, black 50%, black 100%);
208
+ -webkit-mask-image: var(--mask);
209
+ mask-image: var(--mask);
210
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.05) var(--bgColor));
211
+ }
212
+ .Indicator.spin::after,
213
+ .Indicator.spin::before {
214
+ animation-name: spin;
215
+ background: none;
216
+ animation-timing-function: linear;
217
+ mask-mode: luminance;
218
+ background-origin: border-box;
219
+ background-clip: border-box;
220
+ }
221
+ .Indicator.spin::before {
222
+ animation-timing-function:cubic-bezier(0.445, 0.05, 0.55, 0.95);
223
+ animation-delay: calc(-1 * var(--dur) * 0.85);
224
+ animation-name: spin2;
225
+ }
226
+ @keyframes spin {
227
+ 0% {
228
+ background-image: conic-gradient(from 0deg, transparent, transparent 73%, var(--bgColor) 73%, var(--bgColor) 100%);
229
+ transform: rotate(0deg) scale(1.2);
230
+ }
231
+ 100% {
232
+ background-image: conic-gradient(from 0deg, transparent, transparent 73%, var(--bgColor) 73%, var(--bgColor) 100%);
233
+ transform: rotate(360deg) scale(1.2);
234
+ }
235
+ }
236
+ @keyframes spin2 {
237
+ 0% {
238
+ background-image: conic-gradient(from 0deg, transparent, transparent 50%, var(--bgColor) 75%, var(--bgColor) 100%);
239
+ transform: rotate(0deg) scale(1.2);
240
+ }
241
+ 100% {
242
+ background-image: conic-gradient(from 0deg, transparent, transparent 50%, var(--bgColor) 75%, var(--bgColor) 100%);
243
+ transform: rotate(360deg) scale(1.2);
244
+ }
245
+ }
246
+
247
+ /**
248
+ * Pulse
249
+ */
250
+
251
+ .Indicator.pulse {
252
+ animation-name: pulse;
253
+ animation-timing-function: cubic-bezier(0.445, 0.05, 0.55, 0.95);
254
+ }
255
+ @keyframes pulse {
256
+ 0% {
257
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.03) var(--bgColor));
258
+ transform: scale(0.85);
259
+ }
260
+ 25% {
261
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.01) var(--bgColor)) brightness(1) saturate(1);
262
+ transform: scale(1);
263
+ }
264
+ 50% {
265
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.03) var(--bgColor)) brightness(1.25) saturate(1.25);
266
+ transform: scale(1);
267
+ }
268
+ 75% {
269
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.1) var(--bgColor)) brightness(1.25) saturate(1.25);
270
+ }
271
+ 100% {
272
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.03) var(--bgColor)) brightness(1) saturate(1);
273
+ transform: scale(0.85);
274
+ }
275
+ }
276
+ .Indicator.pulse::after {
277
+ border-color: var(--bgColor);
278
+ border-width: calc(var(--bwidth) * 0.75);
279
+ animation-name: task;
280
+ animation-timing-function: ease-out;
281
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.025) var(--bgColor));
282
+ }
283
+ @keyframes task {
284
+ 0% {
285
+ transform: scale(.5);
286
+ opacity: 1;
287
+ filter: blur(calc(var(--isize) * 0.05)) saturate(1);
288
+ }
289
+ 75% {
290
+ opacity: 0.25;
291
+ filter: blur(calc(var(--isize) * 0.01)) saturate(1);
292
+ }
293
+ 100% {
294
+ transform: scale(2.75);
295
+ opacity: 0;
296
+ filter: blur(0) saturate(0.5);
297
+ }
298
+ }
299
+
300
+ /**
301
+ * Typing
302
+ */
303
+
304
+ .Indicator.typing {
305
+ --mask-image: radial-gradient(ellipse, black, black 65%, transparent 70%, transparent 100%);
306
+ mask-image: var(--mask-image);
307
+ -webkit-mask-image: var(--mask-image);
308
+ mask-size: 100% 100%;
309
+ width: calc(var(--isize) * 1.5);
310
+ background: transparent;
311
+ border-radius: 0;
312
+ position: relative;
313
+ }
314
+ .Indicator.typing::before,
315
+ .Indicator.typing::after {
316
+ animation-name: typing;
317
+ background: var(--bgColor);
318
+ width: calc(var(--isize) * 0.5);
319
+ height: calc(var(--isize) * 0.5);
320
+ top: 50%;
321
+ left: calc(50% - var(--isize) * 0.25);
322
+ animation-timing-function: ease-in;
323
+ animation-direction: reverse;
324
+ }
325
+ .Indicator.typing::before,
326
+ .Indicator.recording::before {
327
+ animation-delay: calc(-1 * var(--dur) * 0.5);
328
+ }
329
+ @keyframes typing {
330
+ 0% {
331
+ transform: translateX(-100%) translateY(-50%) scale(0.25);
332
+ opacity: 0;
333
+ }
334
+ 25% {
335
+ transform: translateX(-50%) translateY(-50%) scale(1);
336
+ opacity: 1;
337
+ }
338
+ 50% {
339
+ transform: translateX(0) translateY(-50%) scale(1);
340
+ filter: drop-shadow(0 0 calc(var(--isize) * 0.01) var(--bgColor));
341
+ }
342
+ 75% {
343
+ transform: translateX(50%) translateY(-50%) scale(1);
344
+ opacity: 1;
345
+ }
346
+ 100% {
347
+ transform: translateX(100%) translateY(-50%) scale(0.25);
348
+ opacity: 0;
349
+ }
350
+ }
351
+
352
+ </style>
@@ -0,0 +1,22 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import { type StatusColorOrString } from "../utils/color.js";
3
+ declare const __propDef: {
4
+ props: {
5
+ /** The color of the tag. Select from default status colors or provide a CSS Color value. */
6
+ color?: StatusColorOrString | undefined;
7
+ /** Possible motion to apply to the indicator. */
8
+ motion?: "highlight" | "pulse" | "spin" | "blink" | "bulge" | "tunnel" | "typing" | undefined;
9
+ /** ARIA label to use when a custom color is applied */
10
+ label?: string | undefined;
11
+ };
12
+ events: {
13
+ [evt: string]: CustomEvent<any>;
14
+ };
15
+ slots: {};
16
+ };
17
+ export type IndicatorProps = typeof __propDef.props;
18
+ export type IndicatorEvents = typeof __propDef.events;
19
+ export type IndicatorSlots = typeof __propDef.slots;
20
+ export default class Indicator extends SvelteComponent<IndicatorProps, IndicatorEvents, IndicatorSlots> {
21
+ }
22
+ export {};
@@ -0,0 +1,111 @@
1
+ <script>import UiContent from "../Layout/UIContent.svelte";
2
+ import { slidefade } from "../utils/transitions.js";
3
+ import { attr } from "../utils/attr.js";
4
+ let {
5
+ content,
6
+ trigger,
7
+ hover = false,
8
+ shape = "rounded"
9
+ } = $props();
10
+ const id = `po-${Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)}`;
11
+ let isOpen = $state(false);
12
+ function closePopup() {
13
+ isOpen = false;
14
+ }
15
+ function togglePopup() {
16
+ isOpen = !isOpen;
17
+ }
18
+ function clickElsewhere(e) {
19
+ if (isOpen && e.target instanceof HTMLElement && !e.target.closest(".Popup")) {
20
+ closePopup();
21
+ }
22
+ }
23
+ let timeoutAmount = 250;
24
+ let timeout;
25
+ function mouseenterTrigger() {
26
+ if (timeout) {
27
+ clearTimeout(timeout);
28
+ }
29
+ if (!isOpen) {
30
+ isOpen = true;
31
+ }
32
+ }
33
+ function mouseleave(e) {
34
+ timeout = setTimeout(closePopup, timeoutAmount);
35
+ }
36
+ function mouseoverContent() {
37
+ if (timeout) {
38
+ clearTimeout(timeout);
39
+ }
40
+ }
41
+ let attrs = $derived.by(() => {
42
+ return attr({
43
+ "aria-haspopup": "dialog",
44
+ "aria-expanded": isOpen,
45
+ "aria-controls": id,
46
+ onclick: !hover ? togglePopup : void 0,
47
+ onmouseenter: hover ? mouseenterTrigger : void 0,
48
+ onmouseleave: hover ? mouseleave : void 0,
49
+ onfocusin: hover ? mouseenterTrigger : void 0,
50
+ onblur: hover ? mouseleave : void 0
51
+ });
52
+ });
53
+ </script>
54
+
55
+ <svelte:window on:click={clickElsewhere} />
56
+
57
+ <div class="Popup" class:hover>
58
+ <div class="Trigger">
59
+ {@render trigger(attrs)}
60
+ </div>
61
+ {#if isOpen}
62
+ <UiContent>
63
+ <div
64
+ {id}
65
+ class="PopupContainer"
66
+ transition:slidefade={{duration: 100}}
67
+ role="dialog"
68
+ onmouseover={hover ? mouseoverContent : undefined}
69
+ onfocus={hover ? mouseoverContent : undefined}
70
+ onfocusin={hover ? mouseoverContent : undefined}
71
+ onmouseout={hover ? mouseleave : undefined}
72
+ onblur={hover ? mouseleave : undefined}
73
+ onfocusout={hover ? mouseleave : undefined}
74
+ >
75
+ <div class="PopupContent {shape}">
76
+ {@render content(closePopup)}
77
+ </div>
78
+ </div>
79
+ </UiContent>
80
+ {/if}
81
+ </div>
82
+
83
+ <style>
84
+ .Popup, .Trigger {
85
+ position: relative;
86
+ display: inline-block;
87
+ }
88
+ .PopupContainer {
89
+ position: absolute;
90
+ padding-top: 0.5rem;
91
+ }
92
+ .Popup.hover .PopupContainer {
93
+ padding: var(--safe-zone, 1rem);
94
+ left: calc(-1 * var(--safe-zone, 1rem));
95
+ top: calc(100% + -0.5 * var(--safe-zone, 1rem));
96
+ }
97
+ .PopupContent {
98
+ background: var(--bg, var(--bg-app));
99
+ border: var(--border);
100
+ box-shadow: var(--shadow);
101
+ z-index: 10000;
102
+ padding: var(--content-padding, 1rem);
103
+ opacity: 1;
104
+ border-radius: var(--border-radius);
105
+ box-shadow: 0 0.25rem 2rem 0 var(--shadow);
106
+ left: 0;
107
+ }
108
+ .PopupContent.rounded {
109
+ border-radius: var(--border-radius);
110
+ }
111
+ </style>
@@ -0,0 +1,26 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { Snippet } from "svelte";
3
+ declare const __propDef: {
4
+ props: {
5
+ /** The content of the popup */
6
+ content: Snippet<[close: () => void]>;
7
+ /** Snippet containing the trigger element */
8
+ trigger: (this: void, attrs: (node: Element) => void) => typeof import("svelte").SnippetReturn & {
9
+ _: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
10
+ };
11
+ /** Triggers the popup on hover (and keyboard focus) instead of click */
12
+ hover?: boolean | undefined;
13
+ /** The shape of the popup */
14
+ shape?: "rounded" | "sharp" | undefined;
15
+ };
16
+ events: {
17
+ [evt: string]: CustomEvent<any>;
18
+ };
19
+ slots: {};
20
+ };
21
+ export type PopupProps = typeof __propDef.props;
22
+ export type PopupEvents = typeof __propDef.events;
23
+ export type PopupSlots = typeof __propDef.slots;
24
+ export default class Popup extends SvelteComponent<PopupProps, PopupEvents, PopupSlots> {
25
+ }
26
+ export {};
@@ -0,0 +1,90 @@
1
+ <script>import { isStatusColor } from "../utils/color.js";
2
+ let {
3
+ code,
4
+ color = "default",
5
+ shape = "pill",
6
+ onclick,
7
+ href,
8
+ target,
9
+ children
10
+ } = $props();
11
+ let isSet = $derived(color ? isStatusColor(color) : true);
12
+ </script>
13
+
14
+ {#snippet content()}
15
+ <em>
16
+ {@render children()}
17
+ </em>
18
+ {/snippet}
19
+
20
+ {#if href}
21
+ <a {href} {target} class:code class="Tag Link {shape}" style="--bgColor: {!isSet ? color : 'var(--status-'+color+')'};" onclick={onclick}>
22
+ {@render content()}
23
+ </a>
24
+ {:else if onclick}
25
+ <button class:code class="Tag {shape}" style="--bgColor: {!isSet ? color : 'var(--status-'+color+')'};" onclick={onclick}>
26
+ {@render content()}
27
+ </button>
28
+ {:else}
29
+ <span class:code class="Tag {shape}" style="--bgColor: {!isSet ? color : 'var(--status-'+color+')'};">
30
+ {@render content()}
31
+ </span>
32
+ {/if}
33
+
34
+ <style>
35
+ .Tag {
36
+ display: inline-flex;
37
+ padding: var(--padding, 0.25em 0.65em);
38
+ font-weight: var(--font-weight, 600);
39
+ --bgColor2: var(--bgColor);
40
+ background: var(--bgColor);
41
+ border-radius: var(--border-radius);
42
+ font-size: var(--font-size, 1em);
43
+ vertical-align: var(--vertical-align, baseline);
44
+ border: 1px solid color-mix(in srgb, var(--bgColor) 95%, var(--mix-target, black) 5%);
45
+ }
46
+ .Tag.rectangle {
47
+ border-radius: 0;
48
+ }
49
+ .Tag.pill {
50
+ border-radius: 99999px;
51
+ }
52
+ .Tag.code {
53
+ font-family: var(--font-family-mono);
54
+ padding: var(--padding, 0.15em 0.35em);
55
+ font-size: 1em;
56
+ line-height: 1em;
57
+ background: var(--bg, var(--bg-subtle));
58
+ color: var(--text);
59
+ border: var(--border, var(--border-subtle));
60
+ }
61
+ em {
62
+ opacity: 0.75;
63
+ font-style: normal;
64
+ color: var(--bgColor2);
65
+ filter: url(#bwFilter);
66
+ mix-blend-mode: luminosity;
67
+ left: 50%;
68
+ position: relative;
69
+ display: block;
70
+ transform: translateX(-50%);
71
+ }
72
+ a:hover, button:hover {
73
+ --bgColor2: color-mix(in srgb, var(--bgColor) 87%, white 13%);
74
+ background-color: var(--bgColor2);
75
+ cursor: pointer;
76
+ }
77
+ @media (prefers-contrast: more) {
78
+ .Tag {
79
+ border: 1px solid color-mix(in srgb, var(--bgColor) 50%, var(--mix-target, black) 50%);
80
+ }
81
+ em {
82
+ opacity: 0.99;
83
+ }
84
+ }
85
+ @media (prefers-contrast: less) {
86
+ em {
87
+ opacity: 0.65;
88
+ }
89
+ }
90
+ </style>
@@ -0,0 +1,31 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { Snippet } from "svelte";
3
+ import type { StatusColorOrString } from '../utils/color.js';
4
+ declare const __propDef: {
5
+ props: {
6
+ /** Use a mono-spaced font for the tag. */
7
+ code?: boolean | undefined;
8
+ /** The color of the tag. */
9
+ color?: StatusColorOrString | undefined;
10
+ /** The shape of the tag. */
11
+ shape?: "rounded" | "pill" | "rectangle" | undefined;
12
+ /** A function to run when the tag is clicked. */
13
+ onclick?: ((event: MouseEvent) => void) | undefined;
14
+ /** A URL to link to. */
15
+ href?: string | undefined;
16
+ /** The target of the link. */
17
+ target?: string | undefined;
18
+ /** The content of the tag. */
19
+ children: Snippet;
20
+ };
21
+ events: {
22
+ [evt: string]: CustomEvent<any>;
23
+ };
24
+ slots: {};
25
+ };
26
+ export type TagProps = typeof __propDef.props;
27
+ export type TagEvents = typeof __propDef.events;
28
+ export type TagSlots = typeof __propDef.slots;
29
+ export default class Tag extends SvelteComponent<TagProps, TagEvents, TagSlots> {
30
+ }
31
+ export {};