@dorsk/tsumikit 0.2.15 → 0.2.16

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.
@@ -2,13 +2,14 @@
2
2
  // File-picker button. A real <input type="file"> visually hidden inside a
3
3
  // <label> styled as a button — so it's keyboard-focusable and works with zero
4
4
  // JS to open the dialog. Emits the chosen files via `onfiles`. Dependency-free.
5
- import Icon, { isIconName } from '../atoms/Icon.svelte';
5
+ import Icon from '../atoms/Icon.svelte';
6
6
  import type { IconName } from '../atoms/Icon.svelte';
7
7
 
8
8
  let {
9
9
  onfiles,
10
10
  label = 'Choose file',
11
- icon = '📎',
11
+ icon,
12
+ emoji = '📎',
12
13
  iconOnly = false,
13
14
  accept,
14
15
  multiple = false,
@@ -19,9 +20,12 @@
19
20
  }: {
20
21
  onfiles: (files: File[]) => void;
21
22
  label?: string;
22
- /** A registered glyph name (rendered as SVG) or any string such as an
23
- * emoji (rendered as text). Defaults to the 📎 paperclip emoji. */
24
- icon?: IconName | (string & {});
23
+ /** A registered glyph name (rendered as SVG). Use `emoji` for an
24
+ * off-registry glyph. */
25
+ icon?: IconName;
26
+ /** Off-registry glyph such as an emoji, rendered as text as-is. Defaults to
27
+ * the 📎 paperclip emoji; ignored when `icon` is set. */
28
+ emoji?: string;
25
29
  /** Hide the label visually, showing only the icon. The label is kept for
26
30
  * assistive tech (and used as the accessible name). */
27
31
  iconOnly?: boolean;
@@ -61,10 +65,10 @@
61
65
  {disabled}
62
66
  onchange={onchange}
63
67
  />
64
- {#if isIconName(icon)}
68
+ {#if icon}
65
69
  <Icon name={icon} />
66
- {:else}
67
- <span class="emoji" aria-hidden="true">{icon}</span>
70
+ {:else if emoji}
71
+ <span class="emoji" aria-hidden="true">{emoji}</span>
68
72
  {/if}
69
73
  <span class:sr-only={iconOnly}>{label}</span>
70
74
  </label>
@@ -2,9 +2,12 @@ import type { IconName } from '../atoms/Icon.svelte';
2
2
  type $$ComponentProps = {
3
3
  onfiles: (files: File[]) => void;
4
4
  label?: string;
5
- /** A registered glyph name (rendered as SVG) or any string such as an
6
- * emoji (rendered as text). Defaults to the 📎 paperclip emoji. */
7
- icon?: IconName | (string & {});
5
+ /** A registered glyph name (rendered as SVG). Use `emoji` for an
6
+ * off-registry glyph. */
7
+ icon?: IconName;
8
+ /** Off-registry glyph such as an emoji, rendered as text as-is. Defaults to
9
+ * the 📎 paperclip emoji; ignored when `icon` is set. */
10
+ emoji?: string;
8
11
  /** Hide the label visually, showing only the icon. The label is kept for
9
12
  * assistive tech (and used as the accessible name). */
10
13
  iconOnly?: boolean;
@@ -6,8 +6,11 @@
6
6
  import type { IconName } from '../atoms/Icon.svelte';
7
7
 
8
8
  type IconButtonProps = HTMLButtonAttributes & {
9
- /** Named glyph from the registry. Omit when supplying `children`. */
9
+ /** Named glyph from the registry (rendered as SVG). */
10
10
  icon?: IconName;
11
+ /** Off-registry glyph such as an emoji, rendered as text as-is. Use instead
12
+ * of `icon` when the glyph isn't in the registry. */
13
+ emoji?: string;
11
14
  /** Raw SVG markup (24×24 viewBox) — overrides `icon`. Pass a
12
15
  * lucide-svelte component's contents to render any off-registry icon. */
13
16
  children?: Snippet;
@@ -32,6 +35,7 @@
32
35
 
33
36
  let {
34
37
  icon,
38
+ emoji,
35
39
  children,
36
40
  label,
37
41
  title = label,
@@ -50,7 +54,7 @@
50
54
  </script>
51
55
 
52
56
  <!-- Composition: the icon-only button is a Button (canonical control styling)
53
- in its icon variant, wrapping an Icon. -->
57
+ in its icon variant, wrapping an Icon (or a text emoji glyph). -->
54
58
  <Button
55
59
  {...rest}
56
60
  {variant}
@@ -68,7 +72,21 @@
68
72
  >
69
73
  {#if children}
70
74
  <Icon {size}>{@render children()}</Icon>
71
- {:else}
75
+ {:else if emoji}
76
+ <span class="emoji" style="font-size: {size * 1.35}px" aria-hidden="true">{emoji}</span>
77
+ {:else if icon}
72
78
  <Icon name={icon} {size} />
73
79
  {/if}
74
80
  </Button>
81
+
82
+ <style>
83
+ /* Off-registry glyph (emoji) rendered as text rather than an SVG. Sized off the
84
+ `size` prop (×1.35, since an emoji reads small next to an SVG glyph of the
85
+ same px) and centered so it shares the button's tap target. */
86
+ .emoji {
87
+ display: inline-flex;
88
+ align-items: center;
89
+ justify-content: center;
90
+ line-height: 1;
91
+ }
92
+ </style>
@@ -2,8 +2,11 @@ import type { Snippet } from 'svelte';
2
2
  import type { HTMLButtonAttributes } from 'svelte/elements';
3
3
  import type { IconName } from '../atoms/Icon.svelte';
4
4
  type IconButtonProps = HTMLButtonAttributes & {
5
- /** Named glyph from the registry. Omit when supplying `children`. */
5
+ /** Named glyph from the registry (rendered as SVG). */
6
6
  icon?: IconName;
7
+ /** Off-registry glyph such as an emoji, rendered as text as-is. Use instead
8
+ * of `icon` when the glyph isn't in the registry. */
9
+ emoji?: string;
7
10
  /** Raw SVG markup (24×24 viewBox) — overrides `icon`. Pass a
8
11
  * lucide-svelte component's contents to render any off-registry icon. */
9
12
  children?: Snippet;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dorsk/tsumikit",
3
- "version": "0.2.15",
3
+ "version": "0.2.16",
4
4
  "description": "Minimal, dependency-free Svelte 5 + pure-CSS UI kit. Token-driven atoms, molecules & layouts with theming out of the box.",
5
5
  "type": "module",
6
6
  "license": "MIT",