noph-ui 0.18.3 → 0.18.4
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/chip/ChipSet.svelte
CHANGED
|
@@ -1,20 +1,35 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import { setContext } from 'svelte'
|
|
3
|
+
import type { ChipSetContext, ChipSetProps } from './types.ts'
|
|
3
4
|
|
|
4
5
|
let { children, ...attributes }: ChipSetProps = $props()
|
|
6
|
+
let chipSet: ChipSetContext = $state({
|
|
7
|
+
chips: [],
|
|
8
|
+
})
|
|
9
|
+
setContext('chipSet', chipSet)
|
|
5
10
|
</script>
|
|
6
11
|
|
|
7
12
|
{#if children}
|
|
8
|
-
<div
|
|
13
|
+
<div
|
|
14
|
+
class={['np-chip-set', chipSet.chips.length > 0 && 'np-chip-set-has-chips', attributes.class]}
|
|
15
|
+
style={attributes.style}
|
|
16
|
+
role="toolbar"
|
|
17
|
+
>
|
|
9
18
|
{@render children()}
|
|
10
19
|
</div>
|
|
11
20
|
{/if}
|
|
12
21
|
|
|
13
22
|
<style>
|
|
23
|
+
.np-chip-set-has-chips {
|
|
24
|
+
margin-right: 0.5rem;
|
|
25
|
+
padding-block: 2px;
|
|
26
|
+
padding-right: 2px;
|
|
27
|
+
}
|
|
14
28
|
.np-chip-set {
|
|
15
29
|
display: flex;
|
|
16
30
|
flex-wrap: wrap;
|
|
17
31
|
gap: 0.5rem;
|
|
32
|
+
overflow: auto;
|
|
18
33
|
align-items: center;
|
|
19
34
|
min-width: 0;
|
|
20
35
|
}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
import CheckIcon from '../icons/CheckIcon.svelte'
|
|
4
4
|
import CloseIcon from '../icons/CloseIcon.svelte'
|
|
5
5
|
import Ripple from '../ripple/Ripple.svelte'
|
|
6
|
-
import
|
|
6
|
+
import { getContext, onMount } from 'svelte'
|
|
7
|
+
import type { ChipSetContext, FilterChipProps } from './types.ts'
|
|
7
8
|
|
|
8
9
|
let {
|
|
9
10
|
selected = $bindable(),
|
|
@@ -23,6 +24,17 @@
|
|
|
23
24
|
}: FilterChipProps = $props()
|
|
24
25
|
|
|
25
26
|
let chipLabel: HTMLLabelElement | undefined = $state()
|
|
27
|
+
let chipSet: ChipSetContext = getContext('chipSet')
|
|
28
|
+
|
|
29
|
+
onMount(() => {
|
|
30
|
+
chipSet.chips.push({ label: label, name: name, value: value })
|
|
31
|
+
return () => {
|
|
32
|
+
const index = chipSet.chips.findIndex((chip) => chip.value === value)
|
|
33
|
+
if (index !== -1) {
|
|
34
|
+
chipSet.chips.splice(index, 1)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
})
|
|
26
38
|
|
|
27
39
|
$effect(() => {
|
|
28
40
|
if (group && value) {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import IconButton from '../button/IconButton.svelte'
|
|
3
3
|
import CloseIcon from '../icons/CloseIcon.svelte'
|
|
4
4
|
import Ripple from '../ripple/Ripple.svelte'
|
|
5
|
-
import { onMount } from 'svelte'
|
|
6
|
-
import type { InputChipProps } from './types.ts'
|
|
5
|
+
import { getContext, onMount } from 'svelte'
|
|
6
|
+
import type { ChipSetContext, InputChipProps } from './types.ts'
|
|
7
7
|
|
|
8
8
|
let {
|
|
9
9
|
selected = $bindable(),
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
let chipLabel: HTMLDivElement | undefined = $state()
|
|
22
22
|
let visible = $state(false)
|
|
23
|
+
let chipSet: ChipSetContext = getContext('chipSet')
|
|
23
24
|
|
|
24
25
|
onMount(() => {
|
|
25
26
|
const observer = new IntersectionObserver((entries) => {
|
|
@@ -34,8 +35,15 @@
|
|
|
34
35
|
if (element) {
|
|
35
36
|
observer.observe(element)
|
|
36
37
|
}
|
|
38
|
+
chipSet.chips.push({ label: label, name: name, value: value })
|
|
37
39
|
|
|
38
|
-
return () =>
|
|
40
|
+
return () => {
|
|
41
|
+
observer.disconnect()
|
|
42
|
+
const index = chipSet.chips.findIndex((chip) => chip.value === value)
|
|
43
|
+
if (index !== -1) {
|
|
44
|
+
chipSet.chips.splice(index, 1)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
39
47
|
})
|
|
40
48
|
</script>
|
|
41
49
|
|
package/dist/chip/types.d.ts
CHANGED
|
@@ -46,4 +46,11 @@ export interface InputChipProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
46
46
|
currentTarget: EventTarget & HTMLButtonElement;
|
|
47
47
|
}) => void;
|
|
48
48
|
}
|
|
49
|
+
export interface ChipSetContext {
|
|
50
|
+
chips: {
|
|
51
|
+
label: string;
|
|
52
|
+
name: string | undefined;
|
|
53
|
+
value: string | number | undefined;
|
|
54
|
+
}[];
|
|
55
|
+
}
|
|
49
56
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { isFirstInvalidControlInForm } from './report-validity.js'
|
|
3
|
-
import type { FocusEventHandler } from 'svelte/elements'
|
|
3
|
+
import type { FocusEventHandler, EventHandler } from 'svelte/elements'
|
|
4
4
|
import type { TextFieldProps } from './types.ts'
|
|
5
5
|
|
|
6
6
|
let {
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
reportValidity = $bindable(),
|
|
23
23
|
checkValidity = $bindable(),
|
|
24
24
|
children,
|
|
25
|
+
oninput,
|
|
26
|
+
oninvalid,
|
|
25
27
|
onfocus,
|
|
26
28
|
onblur,
|
|
27
29
|
focused = $bindable(false),
|
|
@@ -65,15 +67,22 @@
|
|
|
65
67
|
value = ''
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
const
|
|
70
|
+
const onInputEvent = (
|
|
71
|
+
event: Event & {
|
|
72
|
+
currentTarget: (EventTarget & HTMLInputElement) | HTMLTextAreaElement
|
|
73
|
+
},
|
|
74
|
+
) => {
|
|
69
75
|
doValidity = true
|
|
76
|
+
;(oninput as EventHandler)?.(event)
|
|
70
77
|
}
|
|
71
78
|
|
|
72
|
-
const
|
|
73
|
-
event
|
|
74
|
-
const { currentTarget } = event as Event & {
|
|
79
|
+
const onInvalidEvent = (
|
|
80
|
+
event: Event & {
|
|
75
81
|
currentTarget: HTMLInputElement | HTMLTextAreaElement
|
|
76
|
-
}
|
|
82
|
+
},
|
|
83
|
+
) => {
|
|
84
|
+
event.preventDefault()
|
|
85
|
+
const { currentTarget } = event
|
|
77
86
|
errorRaw = true
|
|
78
87
|
if (errorText === '') {
|
|
79
88
|
errorTextRaw = currentTarget.validationMessage
|
|
@@ -81,34 +90,43 @@
|
|
|
81
90
|
if (focusOnInvalid && isFirstInvalidControlInForm(currentTarget.form, currentTarget)) {
|
|
82
91
|
currentTarget.focus()
|
|
83
92
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
;(oninvalid as EventHandler)?.(event)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const onFocusEvent = (
|
|
97
|
+
event: FocusEvent & {
|
|
98
|
+
currentTarget: EventTarget & (HTMLInputElement | HTMLTextAreaElement)
|
|
99
|
+
},
|
|
100
|
+
) => {
|
|
101
|
+
focused = true
|
|
102
|
+
;(onfocus as FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>)?.(event)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const onBlurEvent = (
|
|
106
|
+
event: FocusEvent & {
|
|
107
|
+
currentTarget: EventTarget & (HTMLInputElement | HTMLTextAreaElement)
|
|
108
|
+
},
|
|
109
|
+
) => {
|
|
110
|
+
focused = false
|
|
111
|
+
if (doValidity) {
|
|
112
|
+
focusOnInvalid = false
|
|
113
|
+
if (checkValidity()) {
|
|
114
|
+
errorRaw = error
|
|
115
|
+
errorTextRaw = errorText
|
|
95
116
|
}
|
|
96
|
-
}
|
|
117
|
+
} else {
|
|
118
|
+
focusOnInvalid = true
|
|
119
|
+
}
|
|
120
|
+
;(onblur as FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>)?.(event)
|
|
97
121
|
}
|
|
98
122
|
|
|
99
123
|
$effect(() => {
|
|
100
124
|
if (inputElement) {
|
|
101
125
|
inputElement.form?.addEventListener('reset', onReset)
|
|
102
|
-
inputElement.addEventListener('input', onInput)
|
|
103
|
-
inputElement.addEventListener('invalid', onInvalid)
|
|
104
|
-
inputElement.addEventListener('blur', onBlur)
|
|
105
126
|
}
|
|
106
127
|
return () => {
|
|
107
128
|
if (inputElement) {
|
|
108
|
-
inputElement.removeEventListener('reset', onReset)
|
|
109
|
-
inputElement.removeEventListener('input', onInput)
|
|
110
|
-
inputElement.removeEventListener('invalid', onInvalid)
|
|
111
|
-
inputElement.removeEventListener('blur', onBlur)
|
|
129
|
+
inputElement.form?.removeEventListener('reset', onReset)
|
|
112
130
|
}
|
|
113
131
|
}
|
|
114
132
|
})
|
|
@@ -192,14 +210,10 @@
|
|
|
192
210
|
<textarea
|
|
193
211
|
aria-label={label}
|
|
194
212
|
{...attributes}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
199
|
-
onblur={(event) => {
|
|
200
|
-
focused = false
|
|
201
|
-
;(onblur as FocusEventHandler<HTMLTextAreaElement>)?.(event)
|
|
202
|
-
}}
|
|
213
|
+
oninput={onInputEvent}
|
|
214
|
+
oninvalid={onInvalidEvent}
|
|
215
|
+
onfocus={onFocusEvent}
|
|
216
|
+
onblur={onBlurEvent}
|
|
203
217
|
bind:value
|
|
204
218
|
bind:this={inputElement}
|
|
205
219
|
class="input"
|
|
@@ -218,14 +232,10 @@
|
|
|
218
232
|
{...attributes}
|
|
219
233
|
bind:value
|
|
220
234
|
bind:this={inputElement}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
onblur={(event) => {
|
|
226
|
-
focused = false
|
|
227
|
-
;(onblur as FocusEventHandler<HTMLInputElement>)?.(event)
|
|
228
|
-
}}
|
|
235
|
+
oninput={onInputEvent}
|
|
236
|
+
oninvalid={onInvalidEvent}
|
|
237
|
+
onfocus={onFocusEvent}
|
|
238
|
+
onblur={onBlurEvent}
|
|
229
239
|
class="input"
|
|
230
240
|
aria-invalid={errorRaw}
|
|
231
241
|
/>
|
|
@@ -514,7 +524,6 @@
|
|
|
514
524
|
}
|
|
515
525
|
:global(.content .input-wrapper .np-chip-set) {
|
|
516
526
|
margin-top: calc(var(--top-space, 1.5rem) - 4px);
|
|
517
|
-
margin-right: 0.5rem;
|
|
518
527
|
}
|
|
519
528
|
|
|
520
529
|
.prefix {
|