noph-ui 0.19.1 → 0.20.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.
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import Ripple from '../ripple/Ripple.svelte'
|
|
3
3
|
import Tooltip from '../tooltip/Tooltip.svelte'
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
HTMLAnchorAttributes,
|
|
6
|
+
HTMLButtonAttributes,
|
|
7
|
+
MouseEventHandler,
|
|
8
|
+
} from 'svelte/elements'
|
|
5
9
|
import type { ButtonProps } from './types.ts'
|
|
6
10
|
import CircularProgress from '../progress/CircularProgress.svelte'
|
|
7
11
|
|
|
@@ -16,6 +20,11 @@
|
|
|
16
20
|
loading = false,
|
|
17
21
|
keepTooltipOnClick,
|
|
18
22
|
loadingAriaLabel,
|
|
23
|
+
size = 's',
|
|
24
|
+
shape = 'round',
|
|
25
|
+
toggle = false,
|
|
26
|
+
selected = $bindable(false),
|
|
27
|
+
onclick,
|
|
19
28
|
...attributes
|
|
20
29
|
}: ButtonProps = $props()
|
|
21
30
|
|
|
@@ -38,21 +47,21 @@
|
|
|
38
47
|
<CircularProgress aria-label={loadingAriaLabel} indeterminate />
|
|
39
48
|
</div>
|
|
40
49
|
{/if}
|
|
41
|
-
|
|
42
|
-
|
|
50
|
+
{#if start}
|
|
51
|
+
<div class="button-icon">
|
|
43
52
|
{@render start()}
|
|
44
|
-
|
|
45
|
-
|
|
53
|
+
</div>
|
|
54
|
+
{/if}
|
|
46
55
|
{#if children}
|
|
47
56
|
<div class="children-wrapper">
|
|
48
57
|
{@render children()}
|
|
49
58
|
</div>
|
|
50
59
|
{/if}
|
|
51
|
-
|
|
52
|
-
|
|
60
|
+
{#if end}
|
|
61
|
+
<div class="button-icon">
|
|
53
62
|
{@render end()}
|
|
54
|
-
|
|
55
|
-
|
|
63
|
+
</div>
|
|
64
|
+
{/if}
|
|
56
65
|
{/snippet}
|
|
57
66
|
|
|
58
67
|
{#if isButton(attributes) || disabled || loading}
|
|
@@ -61,9 +70,20 @@
|
|
|
61
70
|
aria-describedby={title ? uid : attributes['aria-describedby']}
|
|
62
71
|
aria-label={title || attributes['aria-label']}
|
|
63
72
|
disabled={disabled || loading}
|
|
73
|
+
aria-pressed={selected}
|
|
64
74
|
bind:this={element}
|
|
75
|
+
onclick={(event) => {
|
|
76
|
+
if (toggle) {
|
|
77
|
+
selected = !selected
|
|
78
|
+
}
|
|
79
|
+
;(onclick as MouseEventHandler<HTMLButtonElement>)?.(event)
|
|
80
|
+
}}
|
|
65
81
|
class={[
|
|
66
82
|
'np-button',
|
|
83
|
+
size,
|
|
84
|
+
selected ? 'square' : shape,
|
|
85
|
+
toggle ? 'toggle' : '',
|
|
86
|
+
selected ? 'selected' : '',
|
|
67
87
|
loading ? 'np-loading' : '',
|
|
68
88
|
disabled || loading ? `${variant}-disabled disabled` : `${variant} enabled`,
|
|
69
89
|
attributes.class,
|
|
@@ -77,7 +97,7 @@
|
|
|
77
97
|
aria-describedby={title ? uid : attributes['aria-describedby']}
|
|
78
98
|
aria-label={title || attributes['aria-label']}
|
|
79
99
|
bind:this={element}
|
|
80
|
-
class={['np-button', 'enabled', variant, attributes.class]}
|
|
100
|
+
class={['np-button', size, selected ? 'square' : 'round', 'enabled', variant, attributes.class]}
|
|
81
101
|
>
|
|
82
102
|
{@render content()}
|
|
83
103
|
</a>
|
|
@@ -95,7 +115,6 @@
|
|
|
95
115
|
text-wrap: nowrap;
|
|
96
116
|
}
|
|
97
117
|
.circular-progress {
|
|
98
|
-
--np-circular-progress-size: calc(var(--button-height) * 0.75);
|
|
99
118
|
--np-circular-progress-color: color-mix(in srgb, var(--np-color-on-surface) 38%, transparent);
|
|
100
119
|
position: absolute;
|
|
101
120
|
top: 50%;
|
|
@@ -121,11 +140,95 @@
|
|
|
121
140
|
overflow: hidden;
|
|
122
141
|
font-weight: 500;
|
|
123
142
|
text-decoration: none;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
143
|
+
transition:
|
|
144
|
+
background-color 150ms linear,
|
|
145
|
+
border-radius 150ms ease-in-out,
|
|
146
|
+
box-shadow 150ms linear;
|
|
147
|
+
}
|
|
148
|
+
.xs {
|
|
149
|
+
font-size: 0.875rem;
|
|
150
|
+
height: 2rem;
|
|
151
|
+
padding-inline: var(--np-button-padding, 0.75rem);
|
|
152
|
+
gap: var(--np-button-gap, 0.25rem);
|
|
153
|
+
--_icon-size: var(--np-button-icon-size, 1.25rem);
|
|
154
|
+
--np-circular-progress-size: 1.75rem;
|
|
155
|
+
}
|
|
156
|
+
.xs.round {
|
|
157
|
+
border-radius: 1rem;
|
|
158
|
+
}
|
|
159
|
+
.xs.square {
|
|
160
|
+
border-radius: var(--np-button-shape, 0.75rem);
|
|
161
|
+
}
|
|
162
|
+
.xs:active {
|
|
163
|
+
border-radius: 0.5rem;
|
|
164
|
+
}
|
|
165
|
+
.s {
|
|
166
|
+
font-size: 0.875rem;
|
|
167
|
+
height: 2.5rem;
|
|
168
|
+
padding-inline: var(--np-button-padding, 1rem);
|
|
169
|
+
gap: var(--np-button-gap, 0.5rem);
|
|
170
|
+
--_icon-size: var(--np-button-icon-size, 1.25rem);
|
|
171
|
+
--np-circular-progress-size: 2rem;
|
|
172
|
+
}
|
|
173
|
+
.s.round {
|
|
174
|
+
border-radius: 1.25rem;
|
|
175
|
+
}
|
|
176
|
+
.s.square {
|
|
177
|
+
border-radius: var(--np-button-shape, 0.75rem);
|
|
178
|
+
}
|
|
179
|
+
.s:active {
|
|
180
|
+
border-radius: 0.5rem;
|
|
181
|
+
}
|
|
182
|
+
.m {
|
|
183
|
+
font-size: 1rem;
|
|
184
|
+
height: 3.5rem;
|
|
185
|
+
padding-inline: var(--np-button-padding, 1.5rem);
|
|
186
|
+
gap: var(--np-button-gap, 0.5rem);
|
|
187
|
+
--_icon-size: var(--np-button-icon-size, 1.5rem);
|
|
188
|
+
--np-circular-progress-size: 3rem;
|
|
189
|
+
}
|
|
190
|
+
.m.round {
|
|
191
|
+
border-radius: 1.75rem;
|
|
192
|
+
}
|
|
193
|
+
.m.square {
|
|
194
|
+
border-radius: var(--np-button-shape, 1rem);
|
|
195
|
+
}
|
|
196
|
+
.m:active {
|
|
197
|
+
border-radius: 0.75rem;
|
|
198
|
+
}
|
|
199
|
+
.l {
|
|
200
|
+
font-size: 1.5rem;
|
|
201
|
+
height: 6rem;
|
|
202
|
+
padding-inline: var(--np-button-padding, 3rem);
|
|
203
|
+
gap: var(--np-button-gap, 0.75rem);
|
|
204
|
+
--_icon-size: var(--np-button-icon-size, 2rem);
|
|
205
|
+
--np-circular-progress-size: 5rem;
|
|
206
|
+
}
|
|
207
|
+
.l.round {
|
|
208
|
+
border-radius: 3rem;
|
|
209
|
+
}
|
|
210
|
+
.l.square {
|
|
211
|
+
border-radius: var(--np-button-shape, 1.75rem);
|
|
212
|
+
}
|
|
213
|
+
.l:active {
|
|
214
|
+
border-radius: 1rem;
|
|
215
|
+
}
|
|
216
|
+
.xl {
|
|
217
|
+
font-size: 2rem;
|
|
218
|
+
height: 8.5rem;
|
|
219
|
+
padding-inline: var(--np-button-padding, 4rem);
|
|
220
|
+
gap: var(--np-button-gap, 1rem);
|
|
221
|
+
--_icon-size: var(--np-button-icon-size, 2.5rem);
|
|
222
|
+
--np-circular-progress-size: 7rem;
|
|
223
|
+
}
|
|
224
|
+
.xl.round {
|
|
225
|
+
border-radius: 4.25rem;
|
|
226
|
+
}
|
|
227
|
+
.xl.square {
|
|
228
|
+
border-radius: var(--np-button-shape, 1.75rem);
|
|
229
|
+
}
|
|
230
|
+
.xl:active {
|
|
231
|
+
border-radius: 1rem;
|
|
129
232
|
}
|
|
130
233
|
.disabled {
|
|
131
234
|
pointer-events: none;
|
|
@@ -136,32 +239,11 @@
|
|
|
136
239
|
.elevated-disabled {
|
|
137
240
|
background-color: color-mix(in srgb, var(--np-color-on-surface) 12%, transparent);
|
|
138
241
|
}
|
|
139
|
-
.filled-disabled {
|
|
140
|
-
--button-height: var(--np-filled-button-container-height, 2.5rem);
|
|
141
|
-
border-radius: var(--np-filled-button-container-shape, var(--np-shape-corner-full));
|
|
142
|
-
}
|
|
143
|
-
.tonal-disabled {
|
|
144
|
-
--button-height: var(--np-tonal-button-container-height, 2.5rem);
|
|
145
|
-
border-radius: var(--np-tonal-button-container-shape, var(--np-shape-corner-full));
|
|
146
|
-
}
|
|
147
|
-
.elevated-disabled {
|
|
148
|
-
--button-height: var(--np-elevated-button-container-height, 2.5rem);
|
|
149
|
-
border-radius: var(--np-elevated-button-container-shape, var(--np-shape-corner-full));
|
|
150
|
-
}
|
|
151
242
|
.outlined-disabled {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
.text-disabled {
|
|
158
|
-
--button-height: var(--np-text-button-container-height, 2.5rem);
|
|
159
|
-
border-radius: var(--np-text-button-container-shape, var(--np-shape-corner-full));
|
|
160
|
-
padding-left: calc((var(--button-height) - 1.5rem) / 2);
|
|
161
|
-
padding-right: calc((var(--button-height) - 1.5rem) / 2);
|
|
162
|
-
}
|
|
163
|
-
.enabled {
|
|
164
|
-
transition: background-color 0.3s ease;
|
|
243
|
+
outline-style: solid;
|
|
244
|
+
outline-color: color-mix(in srgb, var(--np-color-on-surface) 12%, transparent);
|
|
245
|
+
outline-width: 1px;
|
|
246
|
+
outline-offset: -1px;
|
|
165
247
|
}
|
|
166
248
|
.enabled:focus-visible {
|
|
167
249
|
outline-style: solid;
|
|
@@ -182,25 +264,24 @@
|
|
|
182
264
|
}
|
|
183
265
|
}
|
|
184
266
|
.text {
|
|
185
|
-
--button-height: var(--np-text-button-container-height, 2.5rem);
|
|
186
267
|
--np-ripple-hover-color: var(--np-text-button-label-text-color, var(--np-color-primary));
|
|
187
268
|
--np-ripple-pressed-color: var(--np-text-button-label-text-color, var(--np-color-primary));
|
|
188
269
|
color: var(--np-text-button-label-text-color, var(--np-color-primary));
|
|
189
|
-
border-radius: var(--np-text-button-container-shape, var(--np-shape-corner-full));
|
|
190
|
-
padding-left: calc((var(--button-height) - 1.5rem) / 2);
|
|
191
|
-
padding-right: calc((var(--button-height) - 1.5rem) / 2);
|
|
192
270
|
}
|
|
193
271
|
.filled {
|
|
194
|
-
--button-height: var(--np-filled-button-container-height, 2.5rem);
|
|
195
272
|
--np-ripple-hover-opacity: 0.12;
|
|
196
273
|
--np-ripple-hover-color: var(--np-color-surface);
|
|
197
274
|
--np-ripple-pressed-color: var(--np-color-surface);
|
|
198
|
-
transition:
|
|
199
|
-
background-color 150ms linear,
|
|
200
|
-
box-shadow 150ms linear;
|
|
201
275
|
color: var(--np-filled-button-label-text-color, var(--np-color-on-primary));
|
|
202
276
|
background-color: var(--np-filled-button-container-color, var(--np-color-primary));
|
|
203
|
-
|
|
277
|
+
}
|
|
278
|
+
.filled.toggle {
|
|
279
|
+
background-color: var(--np-color-surface-container);
|
|
280
|
+
color: var(--np-color-on-surface-variant);
|
|
281
|
+
}
|
|
282
|
+
.filled.selected {
|
|
283
|
+
background-color: var(--np-color-primary);
|
|
284
|
+
color: var(--np-color-on-primary);
|
|
204
285
|
}
|
|
205
286
|
@media (hover: hover) {
|
|
206
287
|
.filled:hover {
|
|
@@ -216,15 +297,14 @@
|
|
|
216
297
|
}
|
|
217
298
|
|
|
218
299
|
.tonal {
|
|
219
|
-
transition:
|
|
220
|
-
background-color 150ms linear,
|
|
221
|
-
box-shadow 150ms linear;
|
|
222
|
-
--button-height: var(--np-tonal-button-container-height, 2.5rem);
|
|
223
300
|
--np-ripple-hover-color: var(--np-tonal-button-label-text-color, var(--np-color-primary));
|
|
224
301
|
--np-ripple-pressed-color: var(--np-tonal-button-label-text-color, var(--np-color-primary));
|
|
225
302
|
color: var(--np-tonal-button-label-text-color, var(--np-color-on-secondary-container));
|
|
226
303
|
background-color: var(--np-tonal-button-container-color, var(--np-color-secondary-container));
|
|
227
|
-
|
|
304
|
+
}
|
|
305
|
+
.tonal.selected {
|
|
306
|
+
background-color: var(--np-color-secondary);
|
|
307
|
+
color: var(--np-color-on-secondary);
|
|
228
308
|
}
|
|
229
309
|
|
|
230
310
|
@media (hover: hover) {
|
|
@@ -241,10 +321,6 @@
|
|
|
241
321
|
}
|
|
242
322
|
|
|
243
323
|
.elevated {
|
|
244
|
-
transition:
|
|
245
|
-
background-color 150ms linear,
|
|
246
|
-
box-shadow 150ms linear;
|
|
247
|
-
--button-height: var(--np-elevated-button-container-height, 2.5rem);
|
|
248
324
|
--np-ripple-hover-color: var(--np-elevated-button-label-text-color, var(--np-color-primary));
|
|
249
325
|
--np-ripple-pressed-color: var(--np-elevated-button-label-text-color, var(--np-color-primary));
|
|
250
326
|
color: var(--np-elevated-button-label-text-color, var(--np-color-primary));
|
|
@@ -253,7 +329,10 @@
|
|
|
253
329
|
var(--np-color-surface-container-low)
|
|
254
330
|
);
|
|
255
331
|
box-shadow: var(--np-elevation-1);
|
|
256
|
-
|
|
332
|
+
}
|
|
333
|
+
.elevated.selected {
|
|
334
|
+
background-color: var(--np-color-primary);
|
|
335
|
+
color: var(--np-color-on-primary);
|
|
257
336
|
}
|
|
258
337
|
|
|
259
338
|
@media (hover: hover) {
|
|
@@ -266,13 +345,19 @@
|
|
|
266
345
|
}
|
|
267
346
|
.outlined {
|
|
268
347
|
background-color: var(--np-outlined-button-container-color, transparent);
|
|
269
|
-
|
|
270
|
-
|
|
348
|
+
outline-style: solid;
|
|
349
|
+
outline-color: var(--np-outlined-button-outline-color, var(--np-color-outline));
|
|
350
|
+
outline-width: 1px;
|
|
351
|
+
outline-offset: -1px;
|
|
271
352
|
--np-ripple-hover-color: var(--np-outlined-button-label-text-color, var(--np-color-primary));
|
|
272
353
|
--np-ripple-pressed-color: var(--np-outlined-button-label-text-color, var(--np-color-primary));
|
|
273
354
|
color: var(--np-outlined-button-label-text-color, var(--np-color-primary));
|
|
274
|
-
|
|
275
|
-
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.outlined.selected {
|
|
358
|
+
background-color: var(--np-color-inverse-surface);
|
|
359
|
+
color: var(--np-color-inverse-on-surface);
|
|
360
|
+
outline-style: none;
|
|
276
361
|
}
|
|
277
362
|
.button-icon {
|
|
278
363
|
display: inline-flex;
|
|
@@ -281,7 +366,6 @@
|
|
|
281
366
|
}
|
|
282
367
|
|
|
283
368
|
:global(.np-button .button-icon) {
|
|
284
|
-
--_icon-size: var(--np-button-icon-size, calc((var(--button-height) - 0.375rem) / 2));
|
|
285
369
|
--_icon-color: var(--np-button-icon-color, inherit);
|
|
286
370
|
}
|
|
287
371
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { ButtonProps } from './types.ts';
|
|
2
|
-
declare const Button: import("svelte").Component<ButtonProps, {}, "element">;
|
|
2
|
+
declare const Button: import("svelte").Component<ButtonProps, {}, "element" | "selected">;
|
|
3
3
|
type Button = ReturnType<typeof Button>;
|
|
4
4
|
export default Button;
|
package/dist/button/types.d.ts
CHANGED
|
@@ -9,6 +9,10 @@ interface ButtonButtonProps extends HTMLButtonAttributes {
|
|
|
9
9
|
loading?: boolean;
|
|
10
10
|
loadingAriaLabel?: string;
|
|
11
11
|
keepTooltipOnClick?: boolean;
|
|
12
|
+
size?: 'xs' | 's' | 'm' | 'l' | 'xl';
|
|
13
|
+
toggle?: boolean;
|
|
14
|
+
shape?: 'round' | 'square';
|
|
15
|
+
selected?: boolean;
|
|
12
16
|
}
|
|
13
17
|
interface ButtonAnchorProps extends HTMLAnchorAttributes {
|
|
14
18
|
variant?: 'text' | 'filled' | 'outlined' | 'elevated' | 'tonal';
|
|
@@ -19,6 +23,10 @@ interface ButtonAnchorProps extends HTMLAnchorAttributes {
|
|
|
19
23
|
disabled?: boolean;
|
|
20
24
|
loading?: boolean;
|
|
21
25
|
loadingAriaLabel?: string;
|
|
26
|
+
size?: 'xs' | 's' | 'm' | 'l' | 'xl';
|
|
27
|
+
toggle?: boolean;
|
|
28
|
+
shape?: 'round' | 'square';
|
|
29
|
+
selected?: boolean;
|
|
22
30
|
}
|
|
23
31
|
interface IconButtonButtonProps extends HTMLButtonAttributes {
|
|
24
32
|
variant?: 'text' | 'filled' | 'outlined' | 'tonal';
|
|
@@ -13,18 +13,17 @@
|
|
|
13
13
|
</script>
|
|
14
14
|
|
|
15
15
|
<Button
|
|
16
|
+
size="xs"
|
|
17
|
+
shape="square"
|
|
16
18
|
--np-elevated-button-container-shape="var(--np-assist-chip-container-shape, var(--np-shape-corner-small))"
|
|
17
19
|
--np-outlined-button-container-shape="var(--np-assist-chip-container-shape, var(--np-shape-corner-small))"
|
|
18
20
|
--np-elevated-button-label-text-color="var(--np-assist-chip-label-text-color, var(--np-color-on-surface-variant))"
|
|
19
21
|
--np-outlined-button-label-text-color="var(--np-assist-chip-label-text-color, var(--np-color-on-surface-variant))"
|
|
20
22
|
--np-outlined-button-outline-color="var(--np-assist-chip-outline-color, var(--np-color-outline-variant))"
|
|
21
|
-
--np-elevated-button-container-height="2rem"
|
|
22
|
-
--np-outlined-button-container-height="2rem"
|
|
23
|
-
--np-button-label-text-font-size="0.875rem"
|
|
24
23
|
--np-button-icon-size="1.125rem"
|
|
25
|
-
--np-button-padding
|
|
26
|
-
--np-button-padding-right="0.5rem"
|
|
24
|
+
--np-button-padding="0.5rem 1rem"
|
|
27
25
|
--np-button-gap="0.5rem"
|
|
26
|
+
--np-button-shape="0.5rem"
|
|
28
27
|
--np-button-icon-color="var(--np-color-primary)"
|
|
29
28
|
--np-outlined-button-container-color="var(--np-color-surface-container-low)"
|
|
30
29
|
bind:element
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "noph-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"homepage": "https://noph.dev",
|
|
6
6
|
"repository": {
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"svelte 5",
|
|
16
16
|
"material",
|
|
17
17
|
"material 3",
|
|
18
|
+
"expressive",
|
|
18
19
|
"material you",
|
|
19
20
|
"material expressive",
|
|
20
21
|
"m3",
|