@joyautomation/salt 0.1.4 → 0.1.5
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/components/forms/Form.svelte +101 -12
- package/dist/components/forms/Form.svelte.d.ts +2 -0
- package/dist/components/forms/Input.svelte +16 -2
- package/dist/components/forms/Input.svelte.d.ts +1 -0
- package/dist/components/forms/Select.svelte +16 -3
- package/dist/components/forms/Select.svelte.d.ts +1 -0
- package/dist/components/forms/Switch.svelte +8 -4
- package/dist/components/forms/Switch.svelte.d.ts +1 -0
- package/package.json +1 -1
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
groups: propGroups,
|
|
12
12
|
action,
|
|
13
13
|
buttonText = 'Submit',
|
|
14
|
+
resetButtonText = 'Reset',
|
|
15
|
+
showReset = true,
|
|
14
16
|
onsubmitstart,
|
|
15
17
|
onsubmitend
|
|
16
18
|
}: {
|
|
@@ -18,12 +20,15 @@
|
|
|
18
20
|
groups?: FormGroup[]
|
|
19
21
|
action: string
|
|
20
22
|
buttonText?: string
|
|
23
|
+
resetButtonText?: string
|
|
24
|
+
showReset?: boolean
|
|
21
25
|
onsubmitstart?: () => void
|
|
22
26
|
onsubmitend?: () => void
|
|
23
27
|
} = $props()
|
|
24
28
|
|
|
25
29
|
let groups = $state(propGroups ?? [{ rows: propInputs ?? [] }])
|
|
26
30
|
let submitting = $state(false)
|
|
31
|
+
let defaultValues: Map<string, string> = $state(new Map())
|
|
27
32
|
|
|
28
33
|
$effect(() => {
|
|
29
34
|
groups = propGroups ?? [{ rows: propInputs ?? [] }]
|
|
@@ -31,6 +36,19 @@
|
|
|
31
36
|
|
|
32
37
|
const allInputs = $derived(groups.flatMap((g) => g.rows))
|
|
33
38
|
|
|
39
|
+
// Capture defaults on first render
|
|
40
|
+
$effect(() => {
|
|
41
|
+
if (defaultValues.size === 0) {
|
|
42
|
+
const defaults = new Map<string, string>()
|
|
43
|
+
for (const row of allInputs) {
|
|
44
|
+
for (const input of row) {
|
|
45
|
+
defaults.set(input.id, input.value)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
defaultValues = defaults
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
34
52
|
const valid = $derived(
|
|
35
53
|
allInputs.every((row) =>
|
|
36
54
|
row.every((input) => {
|
|
@@ -40,6 +58,39 @@
|
|
|
40
58
|
})
|
|
41
59
|
)
|
|
42
60
|
)
|
|
61
|
+
|
|
62
|
+
const hasChanges = $derived(
|
|
63
|
+
allInputs.some((row) =>
|
|
64
|
+
row.some((input) => {
|
|
65
|
+
return defaultValues.get(input.id) !== input.value
|
|
66
|
+
})
|
|
67
|
+
)
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
function isChanged(inputId: string, value: string): boolean {
|
|
71
|
+
return defaultValues.has(inputId) && defaultValues.get(inputId) !== value
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function reset() {
|
|
75
|
+
for (const row of allInputs) {
|
|
76
|
+
for (const input of row) {
|
|
77
|
+
const def = defaultValues.get(input.id)
|
|
78
|
+
if (def !== undefined) {
|
|
79
|
+
input.value = def
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function updateDefaults() {
|
|
86
|
+
const defaults = new Map<string, string>()
|
|
87
|
+
for (const row of allInputs) {
|
|
88
|
+
for (const input of row) {
|
|
89
|
+
defaults.set(input.id, input.value)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
defaultValues = defaults
|
|
93
|
+
}
|
|
43
94
|
</script>
|
|
44
95
|
|
|
45
96
|
<form
|
|
@@ -51,6 +102,7 @@
|
|
|
51
102
|
onsubmitstart?.()
|
|
52
103
|
return async ({ update }) => {
|
|
53
104
|
submitting = false
|
|
105
|
+
updateDefaults()
|
|
54
106
|
onsubmitend?.()
|
|
55
107
|
update({ reset: false })
|
|
56
108
|
}
|
|
@@ -71,11 +123,22 @@
|
|
|
71
123
|
bind:value={input.value}
|
|
72
124
|
inputs={allInputs}
|
|
73
125
|
options={input.options || []}
|
|
126
|
+
changed={isChanged(input.id, input.value)}
|
|
74
127
|
/>
|
|
75
128
|
{:else if input.type === 'checkbox'}
|
|
76
|
-
<Switch
|
|
129
|
+
<Switch
|
|
130
|
+
{...input}
|
|
131
|
+
bind:value={input.value}
|
|
132
|
+
inputs={allInputs}
|
|
133
|
+
changed={isChanged(input.id, input.value)}
|
|
134
|
+
/>
|
|
77
135
|
{:else}
|
|
78
|
-
<Input
|
|
136
|
+
<Input
|
|
137
|
+
{...input}
|
|
138
|
+
bind:value={input.value}
|
|
139
|
+
inputs={allInputs}
|
|
140
|
+
changed={isChanged(input.id, input.value)}
|
|
141
|
+
/>
|
|
79
142
|
{/if}
|
|
80
143
|
</div>
|
|
81
144
|
{/each}
|
|
@@ -83,17 +146,24 @@
|
|
|
83
146
|
{/each}
|
|
84
147
|
</fieldset>
|
|
85
148
|
{/each}
|
|
86
|
-
<
|
|
87
|
-
{
|
|
88
|
-
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
149
|
+
<div class="form__actions">
|
|
150
|
+
<button class="button--primary" disabled={!valid || submitting}>
|
|
151
|
+
{#if submitting}
|
|
152
|
+
<div class="form__spinner-container" transition:slide>
|
|
153
|
+
<span class="form__spinner"></span>
|
|
154
|
+
</div>
|
|
155
|
+
{:else}
|
|
156
|
+
<div transition:slide>
|
|
157
|
+
{buttonText}
|
|
158
|
+
</div>
|
|
159
|
+
{/if}
|
|
160
|
+
</button>
|
|
161
|
+
{#if showReset && hasChanges}
|
|
162
|
+
<button type="button" class="button--secondary form__reset" onclick={reset} transition:slide>
|
|
163
|
+
{resetButtonText}
|
|
164
|
+
</button>
|
|
95
165
|
{/if}
|
|
96
|
-
</
|
|
166
|
+
</div>
|
|
97
167
|
</form>
|
|
98
168
|
|
|
99
169
|
<style>.form {
|
|
@@ -125,6 +195,25 @@
|
|
|
125
195
|
flex-grow: 1;
|
|
126
196
|
}
|
|
127
197
|
|
|
198
|
+
.form__actions {
|
|
199
|
+
display: flex;
|
|
200
|
+
align-items: center;
|
|
201
|
+
gap: calc(var(--spacing-unit) * 2);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.form__reset {
|
|
205
|
+
background: transparent;
|
|
206
|
+
border: 1px solid var(--theme-neutral-400);
|
|
207
|
+
color: var(--theme-text);
|
|
208
|
+
padding: calc(var(--spacing-unit) * 1.5) calc(var(--spacing-unit) * 3);
|
|
209
|
+
border-radius: var(--rounded-sm);
|
|
210
|
+
cursor: pointer;
|
|
211
|
+
font-size: var(--text-sm);
|
|
212
|
+
}
|
|
213
|
+
.form__reset:hover {
|
|
214
|
+
background: var(--theme-neutral-200);
|
|
215
|
+
}
|
|
216
|
+
|
|
128
217
|
.form__spinner-container {
|
|
129
218
|
display: flex;
|
|
130
219
|
justify-content: center;
|
|
@@ -12,8 +12,14 @@
|
|
|
12
12
|
validations,
|
|
13
13
|
inputs,
|
|
14
14
|
touched = false,
|
|
15
|
+
changed = false,
|
|
15
16
|
onblur = () => {}
|
|
16
|
-
}: InputProps & {
|
|
17
|
+
}: InputProps & {
|
|
18
|
+
inputs?: FormInputs
|
|
19
|
+
touched?: boolean
|
|
20
|
+
changed?: boolean
|
|
21
|
+
onblur?: () => void
|
|
22
|
+
} = $props()
|
|
17
23
|
const validationResult = $derived(
|
|
18
24
|
validations.find(([validation]) => {
|
|
19
25
|
return validation(value, inputs ?? [])
|
|
@@ -21,7 +27,11 @@
|
|
|
21
27
|
)
|
|
22
28
|
</script>
|
|
23
29
|
|
|
24
|
-
<div
|
|
30
|
+
<div
|
|
31
|
+
class="input"
|
|
32
|
+
class:input--invalid={touched && validationResult != null}
|
|
33
|
+
class:input--changed={changed}
|
|
34
|
+
>
|
|
25
35
|
{#if label != null}
|
|
26
36
|
<label for={id}>{label}</label>
|
|
27
37
|
{/if}
|
|
@@ -72,6 +82,10 @@
|
|
|
72
82
|
font-family: inherit;
|
|
73
83
|
}
|
|
74
84
|
|
|
85
|
+
.input--changed > input, .input--changed > textarea {
|
|
86
|
+
border-left: solid 3px var(--theme-primary);
|
|
87
|
+
}
|
|
88
|
+
|
|
75
89
|
.input--invalid > input, .input--invalid > textarea {
|
|
76
90
|
border: solid 1px var(--theme-error-400, var(--red-400));
|
|
77
91
|
}</style>
|
|
@@ -2,6 +2,7 @@ import type { FormInputs, InputProps } from './types.js';
|
|
|
2
2
|
type $$ComponentProps = InputProps & {
|
|
3
3
|
inputs?: FormInputs;
|
|
4
4
|
touched?: boolean;
|
|
5
|
+
changed?: boolean;
|
|
5
6
|
onblur?: () => void;
|
|
6
7
|
};
|
|
7
8
|
declare const Input: import("svelte").Component<$$ComponentProps, {}, "value">;
|
|
@@ -9,8 +9,13 @@
|
|
|
9
9
|
value = $bindable(''),
|
|
10
10
|
validations,
|
|
11
11
|
inputs,
|
|
12
|
-
options
|
|
13
|
-
|
|
12
|
+
options,
|
|
13
|
+
changed = false
|
|
14
|
+
}: InputProps & {
|
|
15
|
+
inputs?: FormInputs
|
|
16
|
+
options: { value: string; label: string }[]
|
|
17
|
+
changed?: boolean
|
|
18
|
+
} = $props()
|
|
14
19
|
const validationResult = $derived(
|
|
15
20
|
validations.find(([validation]) => {
|
|
16
21
|
return validation(value, inputs ?? [])
|
|
@@ -18,7 +23,11 @@
|
|
|
18
23
|
)
|
|
19
24
|
</script>
|
|
20
25
|
|
|
21
|
-
<div
|
|
26
|
+
<div
|
|
27
|
+
class="select-field"
|
|
28
|
+
class:select-field--invalid={validationResult != null}
|
|
29
|
+
class:select-field--changed={changed}
|
|
30
|
+
>
|
|
22
31
|
{#if label != null}
|
|
23
32
|
<label for={id}>{label}</label>
|
|
24
33
|
{/if}
|
|
@@ -64,6 +73,10 @@
|
|
|
64
73
|
border-color: var(--theme-primary);
|
|
65
74
|
}
|
|
66
75
|
|
|
76
|
+
.select-field--changed > select {
|
|
77
|
+
border-left: solid 3px var(--theme-primary);
|
|
78
|
+
}
|
|
79
|
+
|
|
67
80
|
.select-field--invalid > select {
|
|
68
81
|
border: solid 1px var(--theme-error-400, var(--red-400));
|
|
69
82
|
}</style>
|
|
@@ -6,9 +6,8 @@
|
|
|
6
6
|
name,
|
|
7
7
|
label,
|
|
8
8
|
value = $bindable('false'),
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}: InputProps & { inputs?: FormInputs } = $props()
|
|
9
|
+
changed = false
|
|
10
|
+
}: InputProps & { inputs?: FormInputs; changed?: boolean } = $props()
|
|
12
11
|
|
|
13
12
|
const checked = $derived(value === 'true')
|
|
14
13
|
|
|
@@ -24,7 +23,7 @@
|
|
|
24
23
|
}
|
|
25
24
|
</script>
|
|
26
25
|
|
|
27
|
-
<div class="switch-field">
|
|
26
|
+
<div class="switch-field" class:switch-field--changed={changed}>
|
|
28
27
|
{#if label != null}
|
|
29
28
|
<label for={id}>{label}</label>
|
|
30
29
|
{/if}
|
|
@@ -57,6 +56,11 @@
|
|
|
57
56
|
text-transform: capitalize;
|
|
58
57
|
}
|
|
59
58
|
|
|
59
|
+
.switch-field--changed {
|
|
60
|
+
padding-left: calc(var(--spacing-unit) * 1.5);
|
|
61
|
+
border-left: solid 3px var(--theme-primary);
|
|
62
|
+
}
|
|
63
|
+
|
|
60
64
|
.switch {
|
|
61
65
|
position: relative;
|
|
62
66
|
display: inline-block;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { FormInputs, InputProps } from './types.js';
|
|
2
2
|
type $$ComponentProps = InputProps & {
|
|
3
3
|
inputs?: FormInputs;
|
|
4
|
+
changed?: boolean;
|
|
4
5
|
};
|
|
5
6
|
declare const Switch: import("svelte").Component<$$ComponentProps, {}, "value">;
|
|
6
7
|
type Switch = ReturnType<typeof Switch>;
|