noph-ui 0.24.19 → 0.25.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/dist/checkbox/Checkbox.svelte +36 -49
- package/dist/radio/Radio.svelte +70 -72
- package/package.json +1 -1
|
@@ -8,21 +8,22 @@
|
|
|
8
8
|
element = $bindable(),
|
|
9
9
|
group = $bindable(),
|
|
10
10
|
style,
|
|
11
|
+
value,
|
|
11
12
|
...attributes
|
|
12
13
|
}: CheckboxProps = $props()
|
|
13
14
|
|
|
14
15
|
$effect(() => {
|
|
15
|
-
if (group &&
|
|
16
|
-
checked = group.includes(
|
|
16
|
+
if (group && value) {
|
|
17
|
+
checked = group.includes(value)
|
|
17
18
|
}
|
|
18
19
|
})
|
|
19
20
|
|
|
20
21
|
$effect(() => {
|
|
21
|
-
if (
|
|
22
|
-
const index = group.indexOf(
|
|
22
|
+
if (value && group) {
|
|
23
|
+
const index = group.indexOf(value)
|
|
23
24
|
if (checked) {
|
|
24
25
|
if (index < 0) {
|
|
25
|
-
group?.push(
|
|
26
|
+
group?.push(value)
|
|
26
27
|
group = group
|
|
27
28
|
}
|
|
28
29
|
} else {
|
|
@@ -36,59 +37,48 @@
|
|
|
36
37
|
let inputEl: HTMLInputElement | undefined = $state()
|
|
37
38
|
</script>
|
|
38
39
|
|
|
39
|
-
<div {style} class={['np-
|
|
40
|
-
<div class="np-
|
|
41
|
-
|
|
42
|
-
{
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
</label>
|
|
55
|
-
|
|
56
|
-
<div class="np-outline"></div>
|
|
57
|
-
<div class="np-background"></div>
|
|
58
|
-
<svg class="np-icon" viewBox="0 0 18 18" aria-hidden="true">
|
|
59
|
-
<rect class="mark short" />
|
|
60
|
-
<rect class="mark long" />
|
|
61
|
-
</svg>
|
|
40
|
+
<div {style} class={['np-container', attributes.class]} bind:this={element}>
|
|
41
|
+
<div class="np-input-wrapper">
|
|
42
|
+
{#if !attributes.disabled}
|
|
43
|
+
<Ripple forElement={inputEl} />
|
|
44
|
+
{/if}
|
|
45
|
+
<input
|
|
46
|
+
{...attributes}
|
|
47
|
+
{value}
|
|
48
|
+
class="np-input"
|
|
49
|
+
type="checkbox"
|
|
50
|
+
bind:indeterminate
|
|
51
|
+
bind:checked
|
|
52
|
+
bind:this={inputEl}
|
|
53
|
+
aria-checked={indeterminate ? 'mixed' : undefined}
|
|
54
|
+
/>
|
|
62
55
|
</div>
|
|
56
|
+
<div class="np-outline"></div>
|
|
57
|
+
<div class="np-background"></div>
|
|
58
|
+
<svg class="np-icon" viewBox="0 0 18 18" aria-hidden="true">
|
|
59
|
+
<rect class="mark short" />
|
|
60
|
+
<rect class="mark long" />
|
|
61
|
+
</svg>
|
|
63
62
|
</div>
|
|
64
63
|
|
|
65
64
|
<style>
|
|
66
|
-
.np-
|
|
67
|
-
border-
|
|
68
|
-
border-start-end-radius: var(--np-checkbox-container-shape, 2px);
|
|
69
|
-
border-end-end-radius: var(--np-checkbox-container-shape, 2px);
|
|
70
|
-
border-end-start-radius: var(--np-checkbox-container-shape, 2px);
|
|
65
|
+
.np-container {
|
|
66
|
+
border-radius: var(--np-checkbox-container-shape, 2px);
|
|
71
67
|
display: inline-flex;
|
|
68
|
+
place-content: center;
|
|
69
|
+
place-items: center;
|
|
70
|
+
position: relative;
|
|
72
71
|
height: 18px;
|
|
73
72
|
position: relative;
|
|
74
73
|
vertical-align: top;
|
|
75
74
|
width: 18px;
|
|
76
|
-
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
77
75
|
cursor: pointer;
|
|
76
|
+
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
78
77
|
margin: var(--np-checkbox-margin, max(0px, (48px - 18px)/2));
|
|
79
78
|
}
|
|
80
|
-
.np-
|
|
79
|
+
.np-container:has(input:disabled) {
|
|
81
80
|
cursor: default;
|
|
82
81
|
}
|
|
83
|
-
.np-container {
|
|
84
|
-
border-radius: inherit;
|
|
85
|
-
display: flex;
|
|
86
|
-
height: 100%;
|
|
87
|
-
place-content: center;
|
|
88
|
-
place-items: center;
|
|
89
|
-
position: relative;
|
|
90
|
-
width: 100%;
|
|
91
|
-
}
|
|
92
82
|
.np-input {
|
|
93
83
|
height: 48px;
|
|
94
84
|
width: 48px;
|
|
@@ -144,11 +134,8 @@
|
|
|
144
134
|
border-width: 2px;
|
|
145
135
|
box-sizing: border-box;
|
|
146
136
|
}
|
|
147
|
-
:
|
|
148
|
-
|
|
149
|
-
border-width: 2px;
|
|
150
|
-
}
|
|
151
|
-
:where(:focus-within) .np-outline {
|
|
137
|
+
.np-container:focus-within .np-outline,
|
|
138
|
+
.np-container:hover .np-outline {
|
|
152
139
|
border-color: var(--np-color-on-surface);
|
|
153
140
|
border-width: 2px;
|
|
154
141
|
}
|
package/dist/radio/Radio.svelte
CHANGED
|
@@ -15,41 +15,39 @@
|
|
|
15
15
|
const uid = $props.id()
|
|
16
16
|
</script>
|
|
17
17
|
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
{
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
</div>
|
|
52
|
-
</label>
|
|
18
|
+
<div {style} class={['np-container', attributes.class]} bind:this={element}>
|
|
19
|
+
{#if !attributes.disabled}
|
|
20
|
+
<Ripple forElement={inputEl} class="np-radio-ripple" />
|
|
21
|
+
{/if}
|
|
22
|
+
<svg class="np-radio-icon" viewBox="0 0 20 20">
|
|
23
|
+
<mask id="{uid}-mask">
|
|
24
|
+
<rect width="100%" height="100%" fill="white" />
|
|
25
|
+
<circle cx="10" cy="10" r="8" fill="black" />
|
|
26
|
+
</mask>
|
|
27
|
+
<circle class="outer circle" cx="10" cy="10" r="10" mask="url(#{uid}-mask)" />
|
|
28
|
+
<circle class="inner circle" cx="10" cy="10" r="5" />
|
|
29
|
+
</svg>
|
|
30
|
+
{#if group !== undefined}
|
|
31
|
+
<input
|
|
32
|
+
{...attributes}
|
|
33
|
+
bind:this={inputEl}
|
|
34
|
+
type="radio"
|
|
35
|
+
class="np-input"
|
|
36
|
+
{checked}
|
|
37
|
+
{defaultChecked}
|
|
38
|
+
bind:group
|
|
39
|
+
/>
|
|
40
|
+
{:else}
|
|
41
|
+
<input
|
|
42
|
+
{...attributes}
|
|
43
|
+
bind:this={inputEl}
|
|
44
|
+
type="radio"
|
|
45
|
+
class="np-input"
|
|
46
|
+
{checked}
|
|
47
|
+
{defaultChecked}
|
|
48
|
+
/>
|
|
49
|
+
{/if}
|
|
50
|
+
</div>
|
|
53
51
|
|
|
54
52
|
<style>
|
|
55
53
|
:global(.np-radio-ripple) {
|
|
@@ -57,6 +55,7 @@
|
|
|
57
55
|
inset: unset !important;
|
|
58
56
|
width: 40px;
|
|
59
57
|
}
|
|
58
|
+
|
|
60
59
|
.np-input {
|
|
61
60
|
opacity: 0;
|
|
62
61
|
margin: 0;
|
|
@@ -65,71 +64,51 @@
|
|
|
65
64
|
height: 48px;
|
|
66
65
|
width: 48px;
|
|
67
66
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
|
|
68
|
+
.np-container {
|
|
69
|
+
margin: max(0px, (40px - var(--np-radio-icon-size, 20px))/2);
|
|
71
70
|
display: inline-flex;
|
|
72
71
|
vertical-align: top;
|
|
72
|
+
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
73
|
+
border-radius: var(--np-shape-corner-full);
|
|
74
|
+
place-content: center;
|
|
75
|
+
place-items: center;
|
|
76
|
+
position: relative;
|
|
73
77
|
width: var(--np-radio-icon-size, 20px);
|
|
74
78
|
height: var(--np-radio-icon-size, 20px);
|
|
75
79
|
cursor: pointer;
|
|
76
|
-
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
77
|
-
outline: none;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.np-host:has(input:focus-visible) .np-container {
|
|
81
|
-
outline-style: solid;
|
|
82
|
-
outline-color: var(--np-color-secondary);
|
|
83
|
-
outline-width: 3px;
|
|
84
|
-
outline-offset: 12px;
|
|
85
|
-
border-radius: 50%;
|
|
86
|
-
animation: focusAnimation 0.3s ease forwards;
|
|
87
|
-
}
|
|
88
|
-
@keyframes focusAnimation {
|
|
89
|
-
0% {
|
|
90
|
-
outline-width: 3px;
|
|
91
|
-
}
|
|
92
|
-
50% {
|
|
93
|
-
outline-width: 6px;
|
|
94
|
-
}
|
|
95
|
-
100% {
|
|
96
|
-
outline-width: 3px;
|
|
97
|
-
}
|
|
98
80
|
}
|
|
99
81
|
|
|
100
|
-
.np-
|
|
82
|
+
.np-container:has(input:disabled) {
|
|
101
83
|
cursor: default;
|
|
102
84
|
}
|
|
103
85
|
|
|
104
|
-
.np-container {
|
|
105
|
-
display: flex;
|
|
106
|
-
height: 100%;
|
|
107
|
-
border-radius: var(--np-shape-corner-full);
|
|
108
|
-
place-content: center;
|
|
109
|
-
place-items: center;
|
|
110
|
-
width: 100%;
|
|
111
|
-
}
|
|
112
86
|
.np-radio-icon {
|
|
113
87
|
fill: var(--np-radio-icon-color, var(--np-color-on-surface-variant));
|
|
114
88
|
inset: 0px;
|
|
115
89
|
position: absolute;
|
|
116
90
|
}
|
|
117
|
-
|
|
91
|
+
|
|
92
|
+
.np-container:has(input:checked) .np-radio-icon {
|
|
118
93
|
fill: var(--np-radio-selected-icon-color, var(--np-color-primary));
|
|
119
94
|
}
|
|
120
|
-
|
|
95
|
+
|
|
96
|
+
.np-container:has(input:disabled) .np-radio-icon {
|
|
121
97
|
fill: var(--np-color-on-surface);
|
|
122
98
|
opacity: 0.38;
|
|
123
99
|
}
|
|
100
|
+
|
|
124
101
|
.inner.circle {
|
|
125
102
|
opacity: 0;
|
|
126
103
|
transform-origin: center center;
|
|
127
104
|
transition: opacity 50ms linear;
|
|
128
105
|
}
|
|
129
|
-
|
|
106
|
+
|
|
107
|
+
.np-container:has(input:checked) .inner.circle {
|
|
130
108
|
animation: 300ms cubic-bezier(0.05, 0.7, 0.1, 1) 0s 1 normal none running inner-circle-grow;
|
|
131
109
|
opacity: 1;
|
|
132
110
|
}
|
|
111
|
+
|
|
133
112
|
@keyframes inner-circle-grow {
|
|
134
113
|
from {
|
|
135
114
|
transform: scale(0);
|
|
@@ -138,4 +117,23 @@
|
|
|
138
117
|
transform: scale(1);
|
|
139
118
|
}
|
|
140
119
|
}
|
|
120
|
+
|
|
121
|
+
.np-container:has(input:focus-visible) {
|
|
122
|
+
outline-style: solid;
|
|
123
|
+
outline-color: var(--np-color-secondary);
|
|
124
|
+
outline-width: 3px;
|
|
125
|
+
outline-offset: 2px;
|
|
126
|
+
animation: focusAnimation 0.3s ease forwards;
|
|
127
|
+
}
|
|
128
|
+
@keyframes focusAnimation {
|
|
129
|
+
0% {
|
|
130
|
+
outline-width: 3px;
|
|
131
|
+
}
|
|
132
|
+
50% {
|
|
133
|
+
outline-width: 6px;
|
|
134
|
+
}
|
|
135
|
+
100% {
|
|
136
|
+
outline-width: 3px;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
141
139
|
</style>
|