@signal9/era-ui 30.2.0 → 30.2.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.
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [30.2.1](https://github.com/sig-nine/era-ui/compare/v30.2.0...v30.2.1) (2026-08-16)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* **select:** the multi-value chips no longer nest a button in the trigger ([c7ff9a2](https://github.com/sig-nine/era-ui/commit/c7ff9a27469b4f5ef2059e4616af38c2bdede8f7))
|
|
6
|
+
|
|
1
7
|
## [30.2.0](https://github.com/sig-nine/era-ui/compare/v30.1.4...v30.2.0) (2026-08-16)
|
|
2
8
|
|
|
3
9
|
### Features
|
package/dist/ui/chip/chip.svelte
CHANGED
|
@@ -61,13 +61,14 @@
|
|
|
61
61
|
import type { Snippet } from 'svelte';
|
|
62
62
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
63
63
|
import { cn } from '../../utils/index.js';
|
|
64
|
-
import { Button } from '../button';
|
|
64
|
+
import { Button, buttonVariants } from '../button';
|
|
65
65
|
import X from '@lucide/svelte/icons/x';
|
|
66
66
|
|
|
67
67
|
let {
|
|
68
68
|
ref = $bindable(null),
|
|
69
69
|
size = 'chip',
|
|
70
70
|
ondismiss,
|
|
71
|
+
dismissAs = 'button',
|
|
71
72
|
lead,
|
|
72
73
|
children,
|
|
73
74
|
class: className,
|
|
@@ -78,6 +79,27 @@
|
|
|
78
79
|
* that nests inside an md container (a select trigger, a button). */
|
|
79
80
|
size?: 'chip' | 'pill';
|
|
80
81
|
ondismiss?: () => void;
|
|
82
|
+
/**
|
|
83
|
+
* What the dismiss control RENDERS AS. `button` (the default) is right
|
|
84
|
+
* for a free-standing chip. Use `span` when the chip lives inside
|
|
85
|
+
* another control.
|
|
86
|
+
*
|
|
87
|
+
* A <button> inside a <button> is not merely bad manners: it is invalid,
|
|
88
|
+
* and the HTML parser repairs it by CLOSING the outer control before the
|
|
89
|
+
* inner one. So the server's markup and the client's DOM disagree, Svelte
|
|
90
|
+
* discards the page's hydration and re-renders from scratch, and the
|
|
91
|
+
* chips briefly sit outside the trigger they belong to. era's own
|
|
92
|
+
* multi-select shipped exactly that (a Chip with `ondismiss` inside
|
|
93
|
+
* Select.Trigger) and logged node_invalid_placement_ssr on every load.
|
|
94
|
+
*
|
|
95
|
+
* `span` also drops the control from the accessibility tree rather than
|
|
96
|
+
* announcing a button inside a button — which is the honest description
|
|
97
|
+
* of what it is there: a pointer shortcut. The accessible way to remove
|
|
98
|
+
* a selection is the listbox itself, which is unaffected. Keyboard focus
|
|
99
|
+
* order is unchanged, because a nested button was never reachable in a
|
|
100
|
+
* sensible order anyway.
|
|
101
|
+
*/
|
|
102
|
+
dismissAs?: 'button' | 'span';
|
|
81
103
|
/** Icon rendered BEFORE the label, outside it. Use this rather than putting
|
|
82
104
|
* an icon in `children`: the label then gets its own box, which is the only
|
|
83
105
|
* place era's ink centring can reach. */
|
|
@@ -112,16 +134,36 @@
|
|
|
112
134
|
In the sm chip it nests; in the xxs chip the same button is the flush
|
|
113
135
|
end-cap, so only its OUTER corners round — squaring the inner pair is
|
|
114
136
|
what reads as "segment of this pill" rather than "pill on a pill". -->
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
137
|
+
{#if dismissAs === 'span'}
|
|
138
|
+
<!-- Same classes, no <button> — see the `dismissAs` prop. era-interactive
|
|
139
|
+
is in buttonVariants' base, so the focus/disabled recipe comes with
|
|
140
|
+
it; what a span cannot inherit is the pointer cursor a button gets
|
|
141
|
+
for free. -->
|
|
142
|
+
<span
|
|
143
|
+
aria-hidden="true"
|
|
144
|
+
class={cn(
|
|
145
|
+
buttonVariants({ icon: true, size: 'pill', tone: 'destructive' }),
|
|
146
|
+
'cursor-pointer',
|
|
147
|
+
size === 'pill' && 'rounded-l-none'
|
|
148
|
+
)}
|
|
149
|
+
onclick={ondismiss}
|
|
150
|
+
onpointerdown={(e: PointerEvent) => e.stopPropagation()}
|
|
151
|
+
onpointerup={(e: PointerEvent) => e.stopPropagation()}
|
|
152
|
+
>
|
|
153
|
+
<X />
|
|
154
|
+
</span>
|
|
155
|
+
{:else}
|
|
156
|
+
<Button
|
|
157
|
+
icon
|
|
158
|
+
size="pill"
|
|
159
|
+
tone="destructive"
|
|
160
|
+
class={size === 'pill' ? 'rounded-l-none' : undefined}
|
|
161
|
+
onclick={ondismiss}
|
|
162
|
+
onpointerdown={(e: PointerEvent) => e.stopPropagation()}
|
|
163
|
+
onpointerup={(e: PointerEvent) => e.stopPropagation()}
|
|
164
|
+
>
|
|
165
|
+
<X />
|
|
166
|
+
</Button>
|
|
167
|
+
{/if}
|
|
126
168
|
{/if}
|
|
127
169
|
</div>
|
|
@@ -34,6 +34,27 @@ type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
|
|
|
34
34
|
* that nests inside an md container (a select trigger, a button). */
|
|
35
35
|
size?: 'chip' | 'pill';
|
|
36
36
|
ondismiss?: () => void;
|
|
37
|
+
/**
|
|
38
|
+
* What the dismiss control RENDERS AS. `button` (the default) is right
|
|
39
|
+
* for a free-standing chip. Use `span` when the chip lives inside
|
|
40
|
+
* another control.
|
|
41
|
+
*
|
|
42
|
+
* A <button> inside a <button> is not merely bad manners: it is invalid,
|
|
43
|
+
* and the HTML parser repairs it by CLOSING the outer control before the
|
|
44
|
+
* inner one. So the server's markup and the client's DOM disagree, Svelte
|
|
45
|
+
* discards the page's hydration and re-renders from scratch, and the
|
|
46
|
+
* chips briefly sit outside the trigger they belong to. era's own
|
|
47
|
+
* multi-select shipped exactly that (a Chip with `ondismiss` inside
|
|
48
|
+
* Select.Trigger) and logged node_invalid_placement_ssr on every load.
|
|
49
|
+
*
|
|
50
|
+
* `span` also drops the control from the accessibility tree rather than
|
|
51
|
+
* announcing a button inside a button — which is the honest description
|
|
52
|
+
* of what it is there: a pointer shortcut. The accessible way to remove
|
|
53
|
+
* a selection is the listbox itself, which is unaffected. Keyboard focus
|
|
54
|
+
* order is unchanged, because a nested button was never reachable in a
|
|
55
|
+
* sensible order anyway.
|
|
56
|
+
*/
|
|
57
|
+
dismissAs?: 'button' | 'span';
|
|
37
58
|
/** Icon rendered BEFORE the label, outside it. Use this rather than putting
|
|
38
59
|
* an icon in `children`: the label then gets its own box, which is the only
|
|
39
60
|
* place era's ink centring can reach. */
|