@nqmcreative/ui 0.2.3 → 0.4.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 (232) hide show
  1. package/README.md +209 -15
  2. package/cli/index.mjs +328 -112
  3. package/dist/core/color.d.ts +24 -0
  4. package/dist/core/color.js +39 -0
  5. package/dist/core/index.d.ts +8 -1
  6. package/dist/core/index.js +5 -1
  7. package/dist/core/locale.svelte.d.ts +8 -0
  8. package/dist/core/locale.svelte.js +14 -0
  9. package/dist/core/number.d.ts +22 -0
  10. package/dist/core/number.js +33 -0
  11. package/dist/core/pin.d.ts +23 -0
  12. package/dist/core/pin.js +38 -0
  13. package/dist/core/tags.d.ts +37 -0
  14. package/dist/core/tags.js +51 -0
  15. package/dist/core/time.d.ts +30 -0
  16. package/dist/core/time.js +78 -0
  17. package/dist/core/toast.svelte.d.ts +3 -0
  18. package/dist/styles/matte/AccordionItem.svelte +5 -0
  19. package/dist/styles/matte/AccordionItem.svelte.d.ts +2 -0
  20. package/dist/styles/matte/Avatar.svelte +15 -0
  21. package/dist/styles/matte/Avatar.svelte.d.ts +3 -0
  22. package/dist/styles/matte/Badge.svelte +5 -0
  23. package/dist/styles/matte/Badge.svelte.d.ts +2 -0
  24. package/dist/styles/matte/Breadcrumb.svelte +11 -4
  25. package/dist/styles/matte/Breadcrumb.svelte.d.ts +3 -0
  26. package/dist/styles/matte/Button.svelte +58 -7
  27. package/dist/styles/matte/Button.svelte.d.ts +14 -2
  28. package/dist/styles/matte/Card.svelte +6 -1
  29. package/dist/styles/matte/Card.svelte.d.ts +2 -0
  30. package/dist/styles/matte/CheckboxGroup.svelte +6 -0
  31. package/dist/styles/matte/CheckboxGroup.svelte.d.ts +2 -0
  32. package/dist/styles/matte/ColorInput.svelte +110 -0
  33. package/dist/styles/matte/ColorInput.svelte.d.ts +16 -0
  34. package/dist/styles/matte/Combobox.svelte +5 -0
  35. package/dist/styles/matte/Combobox.svelte.d.ts +3 -0
  36. package/dist/styles/matte/CommandPalette.svelte +6 -0
  37. package/dist/styles/matte/CommandPalette.svelte.d.ts +3 -0
  38. package/dist/styles/matte/CurrencyInput.svelte +108 -0
  39. package/dist/styles/matte/CurrencyInput.svelte.d.ts +26 -0
  40. package/dist/styles/matte/Drawer.svelte +5 -0
  41. package/dist/styles/matte/Drawer.svelte.d.ts +2 -0
  42. package/dist/styles/matte/FileInput.svelte +194 -0
  43. package/dist/styles/matte/FileInput.svelte.d.ts +32 -0
  44. package/dist/styles/matte/Footer.svelte +6 -2
  45. package/dist/styles/matte/Footer.svelte.d.ts +2 -0
  46. package/dist/styles/matte/InputAddon.svelte +36 -0
  47. package/dist/styles/matte/InputAddon.svelte.d.ts +13 -0
  48. package/dist/styles/matte/Link.svelte +9 -0
  49. package/dist/styles/matte/Link.svelte.d.ts +4 -0
  50. package/dist/styles/matte/MenuItem.svelte +2 -1
  51. package/dist/styles/matte/Modal.svelte +5 -0
  52. package/dist/styles/matte/Modal.svelte.d.ts +2 -0
  53. package/dist/styles/matte/MultiSelect.svelte +7 -1
  54. package/dist/styles/matte/MultiSelect.svelte.d.ts +3 -0
  55. package/dist/styles/matte/Navbar.svelte +18 -4
  56. package/dist/styles/matte/Navbar.svelte.d.ts +2 -0
  57. package/dist/styles/matte/PinInput.svelte +137 -0
  58. package/dist/styles/matte/PinInput.svelte.d.ts +25 -0
  59. package/dist/styles/matte/PricingCard.svelte +16 -8
  60. package/dist/styles/matte/PricingCard.svelte.d.ts +2 -0
  61. package/dist/styles/matte/RadioGroup.svelte +6 -0
  62. package/dist/styles/matte/RadioGroup.svelte.d.ts +2 -0
  63. package/dist/styles/matte/SearchInput.svelte +87 -0
  64. package/dist/styles/matte/SearchInput.svelte.d.ts +24 -0
  65. package/dist/styles/matte/SegmentedControl.svelte +16 -2
  66. package/dist/styles/matte/SegmentedControl.svelte.d.ts +5 -0
  67. package/dist/styles/matte/Sidebar.svelte +2 -1
  68. package/dist/styles/matte/Stat.svelte +8 -1
  69. package/dist/styles/matte/Stat.svelte.d.ts +3 -0
  70. package/dist/styles/matte/Steps.svelte +7 -0
  71. package/dist/styles/matte/Steps.svelte.d.ts +3 -0
  72. package/dist/styles/matte/Table.svelte +153 -97
  73. package/dist/styles/matte/Table.svelte.d.ts +12 -0
  74. package/dist/styles/matte/Tabs.svelte +5 -0
  75. package/dist/styles/matte/Tabs.svelte.d.ts +3 -0
  76. package/dist/styles/matte/TagsInput.svelte +173 -0
  77. package/dist/styles/matte/TagsInput.svelte.d.ts +29 -0
  78. package/dist/styles/matte/TimeInput.svelte +129 -0
  79. package/dist/styles/matte/TimeInput.svelte.d.ts +21 -0
  80. package/dist/styles/matte/Toaster.svelte +3 -0
  81. package/dist/styles/matte/icon.d.ts +21 -0
  82. package/dist/styles/matte/icon.js +21 -0
  83. package/dist/styles/matte/index.d.ts +8 -2
  84. package/dist/styles/matte/index.js +8 -2
  85. package/dist/styles/paper/AccordionItem.svelte +5 -0
  86. package/dist/styles/paper/AccordionItem.svelte.d.ts +2 -0
  87. package/dist/styles/paper/Avatar.svelte +15 -0
  88. package/dist/styles/paper/Avatar.svelte.d.ts +3 -0
  89. package/dist/styles/paper/Badge.svelte +5 -0
  90. package/dist/styles/paper/Badge.svelte.d.ts +2 -0
  91. package/dist/styles/paper/Breadcrumb.svelte +8 -4
  92. package/dist/styles/paper/Breadcrumb.svelte.d.ts +3 -0
  93. package/dist/styles/paper/Button.svelte +58 -7
  94. package/dist/styles/paper/Button.svelte.d.ts +14 -2
  95. package/dist/styles/paper/Card.svelte +6 -1
  96. package/dist/styles/paper/Card.svelte.d.ts +2 -0
  97. package/dist/styles/paper/CheckboxGroup.svelte +6 -0
  98. package/dist/styles/paper/CheckboxGroup.svelte.d.ts +2 -0
  99. package/dist/styles/paper/ColorInput.svelte +112 -0
  100. package/dist/styles/paper/ColorInput.svelte.d.ts +16 -0
  101. package/dist/styles/paper/Combobox.svelte +5 -0
  102. package/dist/styles/paper/Combobox.svelte.d.ts +3 -0
  103. package/dist/styles/paper/CommandPalette.svelte +6 -0
  104. package/dist/styles/paper/CommandPalette.svelte.d.ts +3 -0
  105. package/dist/styles/paper/CurrencyInput.svelte +108 -0
  106. package/dist/styles/paper/CurrencyInput.svelte.d.ts +26 -0
  107. package/dist/styles/paper/Drawer.svelte +5 -0
  108. package/dist/styles/paper/Drawer.svelte.d.ts +2 -0
  109. package/dist/styles/paper/FileInput.svelte +204 -0
  110. package/dist/styles/paper/FileInput.svelte.d.ts +32 -0
  111. package/dist/styles/paper/Footer.svelte +6 -2
  112. package/dist/styles/paper/Footer.svelte.d.ts +2 -0
  113. package/dist/styles/paper/InputAddon.svelte +36 -0
  114. package/dist/styles/paper/InputAddon.svelte.d.ts +13 -0
  115. package/dist/styles/paper/Link.svelte +9 -0
  116. package/dist/styles/paper/Link.svelte.d.ts +4 -0
  117. package/dist/styles/paper/MenuItem.svelte +2 -1
  118. package/dist/styles/paper/Modal.svelte +5 -0
  119. package/dist/styles/paper/Modal.svelte.d.ts +2 -0
  120. package/dist/styles/paper/MultiSelect.svelte +7 -1
  121. package/dist/styles/paper/MultiSelect.svelte.d.ts +3 -0
  122. package/dist/styles/paper/Navbar.svelte +18 -4
  123. package/dist/styles/paper/Navbar.svelte.d.ts +2 -0
  124. package/dist/styles/paper/PinInput.svelte +137 -0
  125. package/dist/styles/paper/PinInput.svelte.d.ts +25 -0
  126. package/dist/styles/paper/PricingCard.svelte +23 -15
  127. package/dist/styles/paper/PricingCard.svelte.d.ts +2 -0
  128. package/dist/styles/paper/RadioGroup.svelte +6 -0
  129. package/dist/styles/paper/RadioGroup.svelte.d.ts +2 -0
  130. package/dist/styles/paper/SearchInput.svelte +92 -0
  131. package/dist/styles/paper/SearchInput.svelte.d.ts +24 -0
  132. package/dist/styles/paper/SegmentedControl.svelte +16 -2
  133. package/dist/styles/paper/SegmentedControl.svelte.d.ts +5 -0
  134. package/dist/styles/paper/Sidebar.svelte +2 -1
  135. package/dist/styles/paper/Stat.svelte +8 -1
  136. package/dist/styles/paper/Stat.svelte.d.ts +3 -0
  137. package/dist/styles/paper/Steps.svelte +7 -0
  138. package/dist/styles/paper/Steps.svelte.d.ts +3 -0
  139. package/dist/styles/paper/Table.svelte +153 -97
  140. package/dist/styles/paper/Table.svelte.d.ts +12 -0
  141. package/dist/styles/paper/Tabs.svelte +5 -0
  142. package/dist/styles/paper/Tabs.svelte.d.ts +3 -0
  143. package/dist/styles/paper/TagsInput.svelte +178 -0
  144. package/dist/styles/paper/TagsInput.svelte.d.ts +29 -0
  145. package/dist/styles/paper/TimeInput.svelte +155 -0
  146. package/dist/styles/paper/TimeInput.svelte.d.ts +21 -0
  147. package/dist/styles/paper/Toaster.svelte +3 -0
  148. package/dist/styles/paper/icon.d.ts +21 -0
  149. package/dist/styles/paper/icon.js +21 -0
  150. package/dist/styles/paper/index.d.ts +8 -2
  151. package/dist/styles/paper/index.js +8 -2
  152. package/dist/styles/sprout/AccordionItem.svelte +5 -0
  153. package/dist/styles/sprout/AccordionItem.svelte.d.ts +2 -0
  154. package/dist/styles/sprout/Avatar.svelte +15 -0
  155. package/dist/styles/sprout/Avatar.svelte.d.ts +3 -0
  156. package/dist/styles/sprout/Badge.svelte +5 -0
  157. package/dist/styles/sprout/Badge.svelte.d.ts +2 -0
  158. package/dist/styles/sprout/Breadcrumb.svelte +8 -4
  159. package/dist/styles/sprout/Breadcrumb.svelte.d.ts +3 -0
  160. package/dist/styles/sprout/Button.svelte +58 -7
  161. package/dist/styles/sprout/Button.svelte.d.ts +14 -2
  162. package/dist/styles/sprout/Card.svelte +6 -1
  163. package/dist/styles/sprout/Card.svelte.d.ts +2 -0
  164. package/dist/styles/sprout/CheckboxGroup.svelte +6 -0
  165. package/dist/styles/sprout/CheckboxGroup.svelte.d.ts +2 -0
  166. package/dist/styles/sprout/ColorInput.svelte +112 -0
  167. package/dist/styles/sprout/ColorInput.svelte.d.ts +16 -0
  168. package/dist/styles/sprout/Combobox.svelte +5 -0
  169. package/dist/styles/sprout/Combobox.svelte.d.ts +3 -0
  170. package/dist/styles/sprout/CommandPalette.svelte +6 -0
  171. package/dist/styles/sprout/CommandPalette.svelte.d.ts +3 -0
  172. package/dist/styles/sprout/CurrencyInput.svelte +108 -0
  173. package/dist/styles/sprout/CurrencyInput.svelte.d.ts +26 -0
  174. package/dist/styles/sprout/Drawer.svelte +5 -0
  175. package/dist/styles/sprout/Drawer.svelte.d.ts +2 -0
  176. package/dist/styles/sprout/FileInput.svelte +205 -0
  177. package/dist/styles/sprout/FileInput.svelte.d.ts +32 -0
  178. package/dist/styles/sprout/Footer.svelte +6 -2
  179. package/dist/styles/sprout/Footer.svelte.d.ts +2 -0
  180. package/dist/styles/sprout/InputAddon.svelte +37 -0
  181. package/dist/styles/sprout/InputAddon.svelte.d.ts +13 -0
  182. package/dist/styles/sprout/Link.svelte +9 -0
  183. package/dist/styles/sprout/Link.svelte.d.ts +4 -0
  184. package/dist/styles/sprout/MenuItem.svelte +2 -1
  185. package/dist/styles/sprout/Modal.svelte +5 -0
  186. package/dist/styles/sprout/Modal.svelte.d.ts +2 -0
  187. package/dist/styles/sprout/MultiSelect.svelte +7 -1
  188. package/dist/styles/sprout/MultiSelect.svelte.d.ts +3 -0
  189. package/dist/styles/sprout/Navbar.svelte +18 -4
  190. package/dist/styles/sprout/Navbar.svelte.d.ts +2 -0
  191. package/dist/styles/sprout/PinInput.svelte +138 -0
  192. package/dist/styles/sprout/PinInput.svelte.d.ts +25 -0
  193. package/dist/styles/sprout/PricingCard.svelte +23 -15
  194. package/dist/styles/sprout/PricingCard.svelte.d.ts +2 -0
  195. package/dist/styles/sprout/RadioGroup.svelte +6 -0
  196. package/dist/styles/sprout/RadioGroup.svelte.d.ts +2 -0
  197. package/dist/styles/sprout/SearchInput.svelte +92 -0
  198. package/dist/styles/sprout/SearchInput.svelte.d.ts +24 -0
  199. package/dist/styles/sprout/SegmentedControl.svelte +16 -2
  200. package/dist/styles/sprout/SegmentedControl.svelte.d.ts +5 -0
  201. package/dist/styles/sprout/Sidebar.svelte +2 -1
  202. package/dist/styles/sprout/Stat.svelte +8 -1
  203. package/dist/styles/sprout/Stat.svelte.d.ts +3 -0
  204. package/dist/styles/sprout/Steps.svelte +7 -0
  205. package/dist/styles/sprout/Steps.svelte.d.ts +3 -0
  206. package/dist/styles/sprout/Table.svelte +153 -97
  207. package/dist/styles/sprout/Table.svelte.d.ts +12 -0
  208. package/dist/styles/sprout/Tabs.svelte +5 -0
  209. package/dist/styles/sprout/Tabs.svelte.d.ts +3 -0
  210. package/dist/styles/sprout/TagsInput.svelte +179 -0
  211. package/dist/styles/sprout/TagsInput.svelte.d.ts +29 -0
  212. package/dist/styles/sprout/TimeInput.svelte +155 -0
  213. package/dist/styles/sprout/TimeInput.svelte.d.ts +21 -0
  214. package/dist/styles/sprout/Toaster.svelte +3 -0
  215. package/dist/styles/sprout/icon.d.ts +21 -0
  216. package/dist/styles/sprout/icon.js +21 -0
  217. package/dist/styles/sprout/index.d.ts +8 -2
  218. package/dist/styles/sprout/index.js +8 -2
  219. package/package.json +98 -26
  220. package/registry.json +143 -35
  221. package/dist/styles/matte/NumberInput.svelte +0 -96
  222. package/dist/styles/matte/NumberInput.svelte.d.ts +0 -15
  223. package/dist/styles/matte/PasswordInput.svelte +0 -95
  224. package/dist/styles/matte/PasswordInput.svelte.d.ts +0 -12
  225. package/dist/styles/paper/NumberInput.svelte +0 -96
  226. package/dist/styles/paper/NumberInput.svelte.d.ts +0 -15
  227. package/dist/styles/paper/PasswordInput.svelte +0 -100
  228. package/dist/styles/paper/PasswordInput.svelte.d.ts +0 -12
  229. package/dist/styles/sprout/NumberInput.svelte +0 -97
  230. package/dist/styles/sprout/NumberInput.svelte.d.ts +0 -15
  231. package/dist/styles/sprout/PasswordInput.svelte +0 -101
  232. package/dist/styles/sprout/PasswordInput.svelte.d.ts +0 -12
package/registry.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nqmcreative/ui",
3
3
  "homepage": "https://github.com/mukhsamr/nqmcreative-ui",
4
- "count": 65,
4
+ "count": 71,
5
5
  "demoStyle": "matte",
6
6
  "styles": [
7
7
  {
@@ -190,40 +190,6 @@
190
190
  "uses": [],
191
191
  "modules": []
192
192
  },
193
- {
194
- "name": "PasswordInput",
195
- "slug": "password-input",
196
- "category": "forms",
197
- "description": "Password field with a visibility toggle and a strength meter.",
198
- "subpaths": {
199
- "matte": "@nqmcreative/ui/matte/password-input",
200
- "paper": "@nqmcreative/ui/paper/password-input",
201
- "sprout": "@nqmcreative/ui/sprout/password-input"
202
- },
203
- "uses": [],
204
- "modules": [
205
- "locale",
206
- "password",
207
- "tones"
208
- ]
209
- },
210
- {
211
- "name": "NumberInput",
212
- "slug": "number-input",
213
- "category": "forms",
214
- "description": "Number field with steppers, clamping and decimal handling.",
215
- "subpaths": {
216
- "matte": "@nqmcreative/ui/matte/number-input",
217
- "paper": "@nqmcreative/ui/paper/number-input",
218
- "sprout": "@nqmcreative/ui/sprout/number-input"
219
- },
220
- "uses": [],
221
- "modules": [
222
- "locale",
223
- "number",
224
- "tones"
225
- ]
226
- },
227
193
  {
228
194
  "name": "Slider",
229
195
  "slug": "slider",
@@ -302,6 +268,148 @@
302
268
  "uses": [],
303
269
  "modules": []
304
270
  },
271
+ {
272
+ "name": "InputAddon",
273
+ "slug": "input-addon",
274
+ "category": "forms",
275
+ "description": "Fixed label joined to an input inside an InputGroup.",
276
+ "subpaths": {
277
+ "matte": "@nqmcreative/ui/matte/input-addon",
278
+ "paper": "@nqmcreative/ui/paper/input-addon",
279
+ "sprout": "@nqmcreative/ui/sprout/input-addon"
280
+ },
281
+ "uses": [
282
+ "Input"
283
+ ],
284
+ "modules": []
285
+ },
286
+ {
287
+ "name": "SearchInput",
288
+ "slug": "search-input",
289
+ "category": "forms",
290
+ "description": "Search field with a clear button and a debounced callback.",
291
+ "subpaths": {
292
+ "matte": "@nqmcreative/ui/matte/search-input",
293
+ "paper": "@nqmcreative/ui/paper/search-input",
294
+ "sprout": "@nqmcreative/ui/sprout/search-input"
295
+ },
296
+ "uses": [
297
+ "Input"
298
+ ],
299
+ "modules": [
300
+ "locale",
301
+ "tones"
302
+ ]
303
+ },
304
+ {
305
+ "name": "PinInput",
306
+ "slug": "pin-input",
307
+ "category": "forms",
308
+ "description": "One box per character, with paste spreading and arrow keys.",
309
+ "subpaths": {
310
+ "matte": "@nqmcreative/ui/matte/pin-input",
311
+ "paper": "@nqmcreative/ui/paper/pin-input",
312
+ "sprout": "@nqmcreative/ui/sprout/pin-input"
313
+ },
314
+ "uses": [],
315
+ "modules": [
316
+ "locale",
317
+ "pin",
318
+ "tones"
319
+ ]
320
+ },
321
+ {
322
+ "name": "TagsInput",
323
+ "slug": "tags-input",
324
+ "category": "forms",
325
+ "description": "Free-text tokens committed on Enter, deduplicated and capped.",
326
+ "subpaths": {
327
+ "matte": "@nqmcreative/ui/matte/tags-input",
328
+ "paper": "@nqmcreative/ui/paper/tags-input",
329
+ "sprout": "@nqmcreative/ui/sprout/tags-input"
330
+ },
331
+ "uses": [],
332
+ "modules": [
333
+ "locale",
334
+ "tags",
335
+ "tones"
336
+ ]
337
+ },
338
+ {
339
+ "name": "CurrencyInput",
340
+ "slug": "currency-input",
341
+ "category": "forms",
342
+ "description": "Amount field that groups on blur and binds a number.",
343
+ "subpaths": {
344
+ "matte": "@nqmcreative/ui/matte/currency-input",
345
+ "paper": "@nqmcreative/ui/paper/currency-input",
346
+ "sprout": "@nqmcreative/ui/sprout/currency-input"
347
+ },
348
+ "uses": [
349
+ "Input"
350
+ ],
351
+ "modules": [
352
+ "number",
353
+ "tones"
354
+ ]
355
+ },
356
+ {
357
+ "name": "TimeInput",
358
+ "slug": "time-input",
359
+ "category": "forms",
360
+ "description": "HH:MM field with steppers, bounds and a minute step.",
361
+ "subpaths": {
362
+ "matte": "@nqmcreative/ui/matte/time-input",
363
+ "paper": "@nqmcreative/ui/paper/time-input",
364
+ "sprout": "@nqmcreative/ui/sprout/time-input"
365
+ },
366
+ "uses": [
367
+ "Input"
368
+ ],
369
+ "modules": [
370
+ "locale",
371
+ "time",
372
+ "tones"
373
+ ]
374
+ },
375
+ {
376
+ "name": "ColorInput",
377
+ "slug": "color-input",
378
+ "category": "forms",
379
+ "description": "Hex field paired with the native swatch and fixed choices.",
380
+ "subpaths": {
381
+ "matte": "@nqmcreative/ui/matte/color-input",
382
+ "paper": "@nqmcreative/ui/paper/color-input",
383
+ "sprout": "@nqmcreative/ui/sprout/color-input"
384
+ },
385
+ "uses": [
386
+ "Input"
387
+ ],
388
+ "modules": [
389
+ "color",
390
+ "locale",
391
+ "tones"
392
+ ]
393
+ },
394
+ {
395
+ "name": "FileInput",
396
+ "slug": "file-input",
397
+ "category": "forms",
398
+ "description": "One-line file picker with type, size and count validation.",
399
+ "subpaths": {
400
+ "matte": "@nqmcreative/ui/matte/file-input",
401
+ "paper": "@nqmcreative/ui/paper/file-input",
402
+ "sprout": "@nqmcreative/ui/sprout/file-input"
403
+ },
404
+ "uses": [
405
+ "Input"
406
+ ],
407
+ "modules": [
408
+ "files",
409
+ "locale",
410
+ "tones"
411
+ ]
412
+ },
305
413
  {
306
414
  "name": "Combobox",
307
415
  "slug": "combobox",
@@ -1,96 +0,0 @@
1
- <script lang="ts">
2
- import type { HTMLInputAttributes } from 'svelte/elements';
3
- import { toneFocusWithinBorder, type Tone } from '../../core/tones.js';
4
- import { useLocale } from '../../core/locale.svelte.js';
5
- import { clampToStep } from '../../core/number.js';
6
-
7
- interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
8
- value?: number;
9
- min?: number;
10
- max?: number;
11
- step?: number;
12
- tone?: Tone;
13
- invalid?: boolean;
14
- /** Short unit rendered inside the field, e.g. `'px'` or `'%'`. */
15
- unit?: string;
16
- }
17
-
18
- let {
19
- value = $bindable(0),
20
- min = -Infinity,
21
- max = Infinity,
22
- step = 1,
23
- tone = 'brand',
24
- invalid = false,
25
- unit,
26
- disabled = false,
27
- class: className = '',
28
- ...rest
29
- }: Props = $props();
30
-
31
- const t = useLocale();
32
-
33
- const clamp = (next: number) => clampToStep(next, min, max, step);
34
-
35
- function nudge(direction: 1 | -1) {
36
- value = clamp(value + direction * step);
37
- }
38
-
39
- function onKeydown(event: KeyboardEvent) {
40
- if (event.key === 'ArrowUp') {
41
- event.preventDefault();
42
- nudge(1);
43
- } else if (event.key === 'ArrowDown') {
44
- event.preventDefault();
45
- nudge(-1);
46
- }
47
- }
48
-
49
- const stepper =
50
- 'flex size-8 shrink-0 items-center justify-center text-text-secondary transition-colors duration-150 hover:bg-bg-inset hover:text-text disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current';
51
- </script>
52
-
53
- <span
54
- class="inline-flex w-full items-center border bg-bg pr-1 pl-3.5 transition-colors duration-150 ease-brand-out
55
- {invalid ? 'border-danger' : `border-hairline ${toneFocusWithinBorder[tone]}`}
56
- {disabled ? 'pointer-events-none opacity-50' : ''} {className}"
57
- >
58
- <input
59
- type="number"
60
- {min}
61
- {max}
62
- {step}
63
- {disabled}
64
- {value}
65
- oninput={(event) => (value = clamp(event.currentTarget.valueAsNumber))}
66
- onkeydown={onKeydown}
67
- aria-invalid={invalid ? 'true' : undefined}
68
- class="h-10 w-full min-w-0 [appearance:textfield] bg-transparent font-sans text-[15px] text-text tabular-nums placeholder:text-text-muted focus:outline-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
69
- {...rest}
70
- />
71
- {#if unit}
72
- <span class="shrink-0 px-2 font-mono text-xs text-text-muted">{unit}</span>
73
- {/if}
74
- <button
75
- type="button"
76
- class={stepper}
77
- onclick={() => nudge(-1)}
78
- disabled={disabled || value <= min}
79
- aria-label={t.current.decrease}
80
- >
81
- <svg class="size-3.5" viewBox="0 0 14 14" fill="none" aria-hidden="true">
82
- <path d="M2.5 7h9" stroke="currentColor" stroke-width="1.5" />
83
- </svg>
84
- </button>
85
- <button
86
- type="button"
87
- class={stepper}
88
- onclick={() => nudge(1)}
89
- disabled={disabled || value >= max}
90
- aria-label={t.current.increase}
91
- >
92
- <svg class="size-3.5" viewBox="0 0 14 14" fill="none" aria-hidden="true">
93
- <path d="M7 2.5v9M2.5 7h9" stroke="currentColor" stroke-width="1.5" />
94
- </svg>
95
- </button>
96
- </span>
@@ -1,15 +0,0 @@
1
- import type { HTMLInputAttributes } from 'svelte/elements';
2
- import { type Tone } from '../../core/tones.js';
3
- interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
4
- value?: number;
5
- min?: number;
6
- max?: number;
7
- step?: number;
8
- tone?: Tone;
9
- invalid?: boolean;
10
- /** Short unit rendered inside the field, e.g. `'px'` or `'%'`. */
11
- unit?: string;
12
- }
13
- declare const NumberInput: import("svelte").Component<Props, {}, "value">;
14
- type NumberInput = ReturnType<typeof NumberInput>;
15
- export default NumberInput;
@@ -1,95 +0,0 @@
1
- <script lang="ts">
2
- import type { HTMLInputAttributes } from 'svelte/elements';
3
- import { toneFocusWithinBorder, type Tone } from '../../core/tones.js';
4
- import { useLocale } from '../../core/locale.svelte.js';
5
- import { passwordScore } from '../../core/password.js';
6
-
7
- interface Props extends Omit<HTMLInputAttributes, 'size' | 'type'> {
8
- value?: string;
9
- tone?: Tone;
10
- invalid?: boolean;
11
- /** Draws a four-segment strength meter under the field. */
12
- strength?: boolean;
13
- }
14
-
15
- let {
16
- value = $bindable(''),
17
- tone = 'brand',
18
- invalid = false,
19
- strength = false,
20
- disabled = false,
21
- class: className = '',
22
- ...rest
23
- }: Props = $props();
24
-
25
- const t = useLocale();
26
-
27
- let visible = $state(false);
28
-
29
- const score = $derived(passwordScore(value));
30
-
31
- const bars = ['bg-danger', 'bg-danger', 'bg-warning', 'bg-info', 'bg-success'];
32
- const texts = ['text-danger', 'text-danger', 'text-warning', 'text-info', 'text-success'];
33
- </script>
34
-
35
- <div class="flex w-full flex-col gap-2">
36
- <span
37
- class="inline-flex w-full items-center gap-2 border bg-bg pr-2 pl-3.5 transition-colors duration-150 ease-brand-out
38
- {invalid ? 'border-danger' : `border-hairline ${toneFocusWithinBorder[tone]}`}
39
- {disabled ? 'pointer-events-none opacity-50' : ''} {className}"
40
- >
41
- <input
42
- bind:value
43
- {disabled}
44
- type={visible ? 'text' : 'password'}
45
- aria-invalid={invalid ? 'true' : undefined}
46
- class="h-10 w-full min-w-0 bg-transparent font-sans text-[15px] text-text placeholder:text-text-muted focus:outline-none"
47
- {...rest}
48
- />
49
- <button
50
- type="button"
51
- onclick={() => (visible = !visible)}
52
- aria-label={visible ? t.current.hidePassword : t.current.showPassword}
53
- aria-pressed={visible}
54
- class="shrink-0 p-2 text-text-muted transition-colors duration-150 hover:text-text focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current"
55
- >
56
- {#if visible}
57
- <svg class="size-4" viewBox="0 0 20 20" fill="none" aria-hidden="true">
58
- <path
59
- d="M2.5 10S5.5 4.5 10 4.5 17.5 10 17.5 10 14.5 15.5 10 15.5 2.5 10 2.5 10Z"
60
- stroke="currentColor"
61
- stroke-width="1.4"
62
- />
63
- <circle cx="10" cy="10" r="2.4" stroke="currentColor" stroke-width="1.4" />
64
- <path d="m3.5 16.5 13-13" stroke="currentColor" stroke-width="1.4" />
65
- </svg>
66
- {:else}
67
- <svg class="size-4" viewBox="0 0 20 20" fill="none" aria-hidden="true">
68
- <path
69
- d="M2.5 10S5.5 4.5 10 4.5 17.5 10 17.5 10 14.5 15.5 10 15.5 2.5 10 2.5 10Z"
70
- stroke="currentColor"
71
- stroke-width="1.4"
72
- />
73
- <circle cx="10" cy="10" r="2.4" stroke="currentColor" stroke-width="1.4" />
74
- </svg>
75
- {/if}
76
- </button>
77
- </span>
78
-
79
- {#if strength}
80
- <div class="flex items-center gap-3">
81
- <div class="flex flex-1 gap-1" aria-hidden="true">
82
- {#each [0, 1, 2, 3] as segment (segment)}
83
- <span
84
- class="h-1 flex-1 transition-colors duration-200 {segment < score
85
- ? bars[score]
86
- : 'bg-bg-inset'}"
87
- ></span>
88
- {/each}
89
- </div>
90
- <span class="font-mono text-xs {value ? texts[score] : 'text-text-muted'}">
91
- {value ? t.current.passwordStrength[score] : '—'}
92
- </span>
93
- </div>
94
- {/if}
95
- </div>
@@ -1,12 +0,0 @@
1
- import type { HTMLInputAttributes } from 'svelte/elements';
2
- import { type Tone } from '../../core/tones.js';
3
- interface Props extends Omit<HTMLInputAttributes, 'size' | 'type'> {
4
- value?: string;
5
- tone?: Tone;
6
- invalid?: boolean;
7
- /** Draws a four-segment strength meter under the field. */
8
- strength?: boolean;
9
- }
10
- declare const PasswordInput: import("svelte").Component<Props, {}, "value">;
11
- type PasswordInput = ReturnType<typeof PasswordInput>;
12
- export default PasswordInput;
@@ -1,96 +0,0 @@
1
- <script lang="ts">
2
- import type { HTMLInputAttributes } from 'svelte/elements';
3
- import { toneFocusWithinBorder, type Tone } from '../../core/tones.js';
4
- import { useLocale } from '../../core/locale.svelte.js';
5
- import { clampToStep } from '../../core/number.js';
6
-
7
- interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
8
- value?: number;
9
- min?: number;
10
- max?: number;
11
- step?: number;
12
- tone?: Tone;
13
- invalid?: boolean;
14
- /** Short unit rendered inside the field, e.g. `'px'` or `'%'`. */
15
- unit?: string;
16
- }
17
-
18
- let {
19
- value = $bindable(0),
20
- min = -Infinity,
21
- max = Infinity,
22
- step = 1,
23
- tone = 'brand',
24
- invalid = false,
25
- unit,
26
- disabled = false,
27
- class: className = '',
28
- ...rest
29
- }: Props = $props();
30
-
31
- const t = useLocale();
32
-
33
- const clamp = (next: number) => clampToStep(next, min, max, step);
34
-
35
- function nudge(direction: 1 | -1) {
36
- value = clamp(value + direction * step);
37
- }
38
-
39
- function onKeydown(event: KeyboardEvent) {
40
- if (event.key === 'ArrowUp') {
41
- event.preventDefault();
42
- nudge(1);
43
- } else if (event.key === 'ArrowDown') {
44
- event.preventDefault();
45
- nudge(-1);
46
- }
47
- }
48
-
49
- const stepper =
50
- 'flex size-7 shrink-0 items-center justify-center rounded text-text-secondary transition-colors duration-150 hover:bg-bg-inset hover:text-text disabled:pointer-events-none disabled:opacity-30 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current';
51
- </script>
52
-
53
- <span
54
- class="inline-flex w-full items-center rounded-md border bg-bg pr-1 pl-3 shadow-xs transition-colors duration-150 ease-brand-out
55
- {invalid ? 'border-danger' : `border-hairline-strong ${toneFocusWithinBorder[tone]}`}
56
- {disabled ? 'pointer-events-none opacity-50' : ''} {className}"
57
- >
58
- <input
59
- type="number"
60
- {min}
61
- {max}
62
- {step}
63
- {disabled}
64
- {value}
65
- oninput={(event) => (value = clamp(event.currentTarget.valueAsNumber))}
66
- onkeydown={onKeydown}
67
- aria-invalid={invalid ? 'true' : undefined}
68
- class="h-10 w-full min-w-0 [appearance:textfield] bg-transparent font-sans text-sm text-text tabular-nums placeholder:text-text-muted focus:outline-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
69
- {...rest}
70
- />
71
- {#if unit}
72
- <span class="shrink-0 px-1.5 text-xs text-text-muted">{unit}</span>
73
- {/if}
74
- <button
75
- type="button"
76
- class={stepper}
77
- onclick={() => nudge(-1)}
78
- disabled={disabled || value <= min}
79
- aria-label={t.current.decrease}
80
- >
81
- <svg class="size-3.5" viewBox="0 0 14 14" fill="none" aria-hidden="true">
82
- <path d="M2.5 7h9" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" />
83
- </svg>
84
- </button>
85
- <button
86
- type="button"
87
- class={stepper}
88
- onclick={() => nudge(1)}
89
- disabled={disabled || value >= max}
90
- aria-label={t.current.increase}
91
- >
92
- <svg class="size-3.5" viewBox="0 0 14 14" fill="none" aria-hidden="true">
93
- <path d="M7 2.5v9M2.5 7h9" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" />
94
- </svg>
95
- </button>
96
- </span>
@@ -1,15 +0,0 @@
1
- import type { HTMLInputAttributes } from 'svelte/elements';
2
- import { type Tone } from '../../core/tones.js';
3
- interface Props extends Omit<HTMLInputAttributes, 'size' | 'type' | 'value' | 'min' | 'max'> {
4
- value?: number;
5
- min?: number;
6
- max?: number;
7
- step?: number;
8
- tone?: Tone;
9
- invalid?: boolean;
10
- /** Short unit rendered inside the field, e.g. `'px'` or `'%'`. */
11
- unit?: string;
12
- }
13
- declare const NumberInput: import("svelte").Component<Props, {}, "value">;
14
- type NumberInput = ReturnType<typeof NumberInput>;
15
- export default NumberInput;
@@ -1,100 +0,0 @@
1
- <script lang="ts">
2
- import type { HTMLInputAttributes } from 'svelte/elements';
3
- import { toneFocusWithinBorder, type Tone } from '../../core/tones.js';
4
- import { useLocale } from '../../core/locale.svelte.js';
5
- import { passwordScore } from '../../core/password.js';
6
-
7
- interface Props extends Omit<HTMLInputAttributes, 'size' | 'type'> {
8
- value?: string;
9
- tone?: Tone;
10
- invalid?: boolean;
11
- /** Draws a four-segment strength meter under the field. */
12
- strength?: boolean;
13
- }
14
-
15
- let {
16
- value = $bindable(''),
17
- tone = 'brand',
18
- invalid = false,
19
- strength = false,
20
- disabled = false,
21
- class: className = '',
22
- ...rest
23
- }: Props = $props();
24
-
25
- const t = useLocale();
26
-
27
- let visible = $state(false);
28
-
29
- const score = $derived(passwordScore(value));
30
-
31
- const bars = ['bg-danger', 'bg-danger', 'bg-warning', 'bg-info', 'bg-success'];
32
- const texts = ['text-danger', 'text-danger', 'text-warning', 'text-info', 'text-success'];
33
- </script>
34
-
35
- <div class="flex w-full flex-col gap-2">
36
- <span
37
- class="inline-flex w-full items-center gap-2 rounded-md border bg-bg pr-1 pl-3 shadow-xs transition-colors duration-150 ease-brand-out
38
- {invalid ? 'border-danger' : `border-hairline-strong ${toneFocusWithinBorder[tone]}`}
39
- {disabled ? 'pointer-events-none opacity-50' : ''} {className}"
40
- >
41
- <input
42
- bind:value
43
- {disabled}
44
- type={visible ? 'text' : 'password'}
45
- aria-invalid={invalid ? 'true' : undefined}
46
- class="h-10 w-full min-w-0 bg-transparent font-sans text-sm text-text placeholder:text-text-muted focus:outline-none"
47
- {...rest}
48
- />
49
- <button
50
- type="button"
51
- onclick={() => (visible = !visible)}
52
- aria-label={visible ? t.current.hidePassword : t.current.showPassword}
53
- aria-pressed={visible}
54
- class="shrink-0 rounded p-1.5 text-text-muted transition-colors duration-150 hover:bg-bg-inset hover:text-text focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current"
55
- >
56
- {#if visible}
57
- <svg class="size-4" viewBox="0 0 20 20" fill="none" aria-hidden="true">
58
- <path
59
- d="M2.5 10S5.5 4.5 10 4.5 17.5 10 17.5 10 14.5 15.5 10 15.5 2.5 10 2.5 10Z"
60
- stroke="currentColor"
61
- stroke-width="1.4"
62
- />
63
- <circle cx="10" cy="10" r="2.4" stroke="currentColor" stroke-width="1.4" />
64
- <path
65
- d="m3.5 16.5 13-13"
66
- stroke="currentColor"
67
- stroke-width="1.4"
68
- stroke-linecap="round"
69
- />
70
- </svg>
71
- {:else}
72
- <svg class="size-4" viewBox="0 0 20 20" fill="none" aria-hidden="true">
73
- <path
74
- d="M2.5 10S5.5 4.5 10 4.5 17.5 10 17.5 10 14.5 15.5 10 15.5 2.5 10 2.5 10Z"
75
- stroke="currentColor"
76
- stroke-width="1.4"
77
- />
78
- <circle cx="10" cy="10" r="2.4" stroke="currentColor" stroke-width="1.4" />
79
- </svg>
80
- {/if}
81
- </button>
82
- </span>
83
-
84
- {#if strength}
85
- <div class="flex items-center gap-3">
86
- <div class="flex flex-1 gap-1" aria-hidden="true">
87
- {#each [0, 1, 2, 3] as segment (segment)}
88
- <span
89
- class="h-1 flex-1 rounded-full transition-colors duration-200 {segment < score
90
- ? bars[score]
91
- : 'bg-bg-inset'}"
92
- ></span>
93
- {/each}
94
- </div>
95
- <span class="text-xs font-medium {value ? texts[score] : 'text-text-muted'}">
96
- {value ? t.current.passwordStrength[score] : '—'}
97
- </span>
98
- </div>
99
- {/if}
100
- </div>
@@ -1,12 +0,0 @@
1
- import type { HTMLInputAttributes } from 'svelte/elements';
2
- import { type Tone } from '../../core/tones.js';
3
- interface Props extends Omit<HTMLInputAttributes, 'size' | 'type'> {
4
- value?: string;
5
- tone?: Tone;
6
- invalid?: boolean;
7
- /** Draws a four-segment strength meter under the field. */
8
- strength?: boolean;
9
- }
10
- declare const PasswordInput: import("svelte").Component<Props, {}, "value">;
11
- type PasswordInput = ReturnType<typeof PasswordInput>;
12
- export default PasswordInput;