@functionalcms/svelte-components 4.10.24 → 4.10.25
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/form/Button.svelte +0 -1
- package/dist/components/form/Form.svelte +38 -90
- package/dist/components/form/Form.svelte.d.ts +3 -2
- package/dist/components/form/Select.svelte +35 -1
- package/dist/components/form/form.d.ts +7 -6
- package/dist/components/form/form.js +22 -1
- package/dist/components/menu/CollapsibleMenu.svelte +1 -4
- package/package.json +1 -1
|
@@ -1,100 +1,48 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { mapEntiresToOptions, type Field } from "./form.js";
|
|
2
3
|
import ChoiceInput from "./ChoiceInput.svelte";
|
|
3
|
-
import type { Field, Validation } from "./form.js";
|
|
4
4
|
import Input from "./Input.svelte";
|
|
5
5
|
import Select from "./Select.svelte";
|
|
6
6
|
import Switch from "./Switch.svelte";
|
|
7
7
|
|
|
8
|
+
interface Props {
|
|
9
|
+
action: string;
|
|
10
|
+
schema: Array<Field>;
|
|
11
|
+
}
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
schema: Validation;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
let { schema }: Props = $props();
|
|
14
|
-
|
|
15
|
-
const fields = Object.keys(schema.shape).map((key) => ({
|
|
16
|
-
name: key,
|
|
17
|
-
type:
|
|
18
|
-
schema.shape[key].def.type == 'optional'
|
|
19
|
-
? schema.shape[key].def.innerType._def.type
|
|
20
|
-
: schema.shape[key].def.type,
|
|
21
|
-
subType: schema.shape[key].def.format,
|
|
22
|
-
meta: { ...schema.shape[key].meta() },
|
|
23
|
-
entries: schema.shape[key]._def.innerType
|
|
24
|
-
? schema.shape[key]._def.innerType._def.entries
|
|
25
|
-
: schema.shape[key]._def.entries,
|
|
26
|
-
field: schema.shape[key]
|
|
27
|
-
}));
|
|
28
|
-
|
|
29
|
-
function getFieldType(field: Field) {
|
|
30
|
-
if (field.type === 'number') {
|
|
31
|
-
return 'number';
|
|
32
|
-
}
|
|
33
|
-
if (field.meta.multiline) {
|
|
34
|
-
return 'textarea';
|
|
35
|
-
}
|
|
36
|
-
if (field.meta.secure) {
|
|
37
|
-
return 'password';
|
|
38
|
-
}
|
|
39
|
-
switch (field.subType) {
|
|
40
|
-
case 'email':
|
|
41
|
-
return 'email';
|
|
42
|
-
case 'url':
|
|
43
|
-
return 'url';
|
|
44
|
-
case 'tel':
|
|
45
|
-
return 'tel';
|
|
46
|
-
case 'password':
|
|
47
|
-
return 'password';
|
|
48
|
-
case 'email':
|
|
49
|
-
return 'email';
|
|
50
|
-
}
|
|
51
|
-
return 'string';
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function mapEntiresToOptions(field: Field) {
|
|
55
|
-
if (field.entries) {
|
|
56
|
-
let result = Object.keys(field.entries).map((key) => ({
|
|
57
|
-
label: key,
|
|
58
|
-
value: field.entries[key]
|
|
59
|
-
}));
|
|
60
|
-
return result;
|
|
61
|
-
} else {
|
|
62
|
-
return [];
|
|
63
|
-
}
|
|
64
|
-
}
|
|
13
|
+
let { action, schema }: Props = $props();
|
|
65
14
|
</script>
|
|
66
15
|
|
|
67
|
-
<form method="POST">
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
</fieldset>
|
|
16
|
+
<form method="POST" {action}>
|
|
17
|
+
<fieldset>
|
|
18
|
+
{#each schema as field}
|
|
19
|
+
{#if field.type === "boolean"}
|
|
20
|
+
<Switch name={field.name} id={field.name} label={field.name} />
|
|
21
|
+
{:else if field.type === "enum" && field.meta.type === "select"}
|
|
22
|
+
<Select
|
|
23
|
+
name={field.name}
|
|
24
|
+
id={field.name}
|
|
25
|
+
label={field.name}
|
|
26
|
+
options={mapEntiresToOptions(field)}
|
|
27
|
+
singleSelected="LOW"
|
|
28
|
+
/>
|
|
29
|
+
{:else if field.type === "enum"}
|
|
30
|
+
<ChoiceInput
|
|
31
|
+
name={field.name}
|
|
32
|
+
id={field.name}
|
|
33
|
+
label={field.name}
|
|
34
|
+
type={field.meta.type}
|
|
35
|
+
options={mapEntiresToOptions(field)}
|
|
36
|
+
/>
|
|
37
|
+
{:else if field.type === "string" || field.type === "number"}
|
|
38
|
+
<Input
|
|
39
|
+
name={field.name}
|
|
40
|
+
id={field.name}
|
|
41
|
+
label={field.name}
|
|
42
|
+
type={field.meta.type}
|
|
43
|
+
isRequired={field.isRequired}
|
|
44
|
+
/>
|
|
45
|
+
{/if}
|
|
46
|
+
{/each}
|
|
47
|
+
</fieldset>
|
|
100
48
|
</form>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Field } from "./form.js";
|
|
2
2
|
interface Props {
|
|
3
|
-
|
|
3
|
+
action: string;
|
|
4
|
+
schema: Array<Field>;
|
|
4
5
|
}
|
|
5
6
|
declare const Form: import("svelte").Component<Props, {}, "">;
|
|
6
7
|
type Form = ReturnType<typeof Form>;
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
</script>
|
|
48
48
|
|
|
49
49
|
<div class="w-100">
|
|
50
|
-
<label for={id}> {label} </label>
|
|
50
|
+
<label class="label" for={id}> {label} </label>
|
|
51
51
|
{#if isMultiple}
|
|
52
52
|
<select
|
|
53
53
|
{id}
|
|
@@ -160,4 +160,38 @@
|
|
|
160
160
|
padding-left: var(--fluid-16);
|
|
161
161
|
font-size: var(--fluid-18);
|
|
162
162
|
}
|
|
163
|
+
.field-help,
|
|
164
|
+
.field-help-large,
|
|
165
|
+
.field-help-small,
|
|
166
|
+
.field-error,
|
|
167
|
+
.field-error-large,
|
|
168
|
+
.field-error-small,
|
|
169
|
+
.label-skin,
|
|
170
|
+
.label,
|
|
171
|
+
.input-addon-container,
|
|
172
|
+
.input-small,
|
|
173
|
+
.input-large,
|
|
174
|
+
.input-skin,
|
|
175
|
+
.input-underlined,
|
|
176
|
+
.input-underlined-bg,
|
|
177
|
+
.input {
|
|
178
|
+
color: var(--font-color, var(--dark));
|
|
179
|
+
font-family: var(--font-family-body);
|
|
180
|
+
font-weight: var(--font-weight, 300);
|
|
181
|
+
font-size: var(--font-size, 1rem);
|
|
182
|
+
line-height: var(--line-height, var(--fluid-20, 1.25rem));
|
|
183
|
+
width: 100%;
|
|
184
|
+
max-width: 100%;
|
|
185
|
+
}
|
|
186
|
+
.label {
|
|
187
|
+
display: inline-block;
|
|
188
|
+
|
|
189
|
+
/* Provided --input-vertical-pad isn't overriden we'll get 20px
|
|
190
|
+
label w/a 6px margin then a 38px input = 64 which is on the 8pt grid */
|
|
191
|
+
margin-block-start: 0;
|
|
192
|
+
margin-inline-start: 0;
|
|
193
|
+
margin-inline-end: 0;
|
|
194
|
+
margin-block-end: var(--input-label-pad, 0.375rem);
|
|
195
|
+
vertical-align: initial;
|
|
196
|
+
}
|
|
163
197
|
</style>
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
export interface Field {
|
|
2
2
|
name: string;
|
|
3
3
|
type: string;
|
|
4
|
-
|
|
4
|
+
entries: Array<string>;
|
|
5
5
|
meta: any;
|
|
6
|
-
|
|
7
|
-
field: any;
|
|
8
|
-
}
|
|
9
|
-
export interface Validation {
|
|
10
|
-
shape: any;
|
|
6
|
+
isRequired: boolean;
|
|
11
7
|
}
|
|
8
|
+
export declare function serialize(schema: any): Array<Field>;
|
|
9
|
+
export declare function mapEntiresToOptions(field: Field): {
|
|
10
|
+
label: string;
|
|
11
|
+
value: string;
|
|
12
|
+
}[];
|
|
@@ -1 +1,22 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export function serialize(schema) {
|
|
2
|
+
const keys = schema._nodes.reverse();
|
|
3
|
+
const fields = keys.map((key) => {
|
|
4
|
+
const field = schema.fields[key];
|
|
5
|
+
const hasEntries = field._whitelist.size > 0;
|
|
6
|
+
const isOptional = field.spec.optional ?? true;
|
|
7
|
+
return {
|
|
8
|
+
name: key,
|
|
9
|
+
type: hasEntries ? "enum" : field.type,
|
|
10
|
+
entries: hasEntries ? [...field._whitelist] : [],
|
|
11
|
+
meta: field.spec.meta ?? {},
|
|
12
|
+
isRequired: !isOptional,
|
|
13
|
+
};
|
|
14
|
+
});
|
|
15
|
+
return fields;
|
|
16
|
+
}
|
|
17
|
+
export function mapEntiresToOptions(field) {
|
|
18
|
+
return (field?.entries?.map((entry) => ({
|
|
19
|
+
label: entry,
|
|
20
|
+
value: entry,
|
|
21
|
+
})) ?? []);
|
|
22
|
+
}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { HeaderNavigationItem
|
|
3
|
-
import { afterNavigate } from '$app/navigation';
|
|
2
|
+
import { HeaderNavigationItem } from './types.js';
|
|
4
3
|
import { cn } from '../../utils.js';
|
|
5
4
|
import { Placement } from '../Styling.js';
|
|
6
5
|
import Button from '../form/Button.svelte';
|
|
7
|
-
import Drawer from '../presentation/Drawer.svelte';
|
|
8
|
-
import ListMenu from './ListMenu.svelte';
|
|
9
6
|
import type { Snippet } from 'svelte';
|
|
10
7
|
|
|
11
8
|
interface Css {
|