@functionalcms/svelte-components 4.10.27 → 4.10.29
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,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { cn } from '../../utils.js';
|
|
3
|
+
import { Orientation } from '../Styling.js';
|
|
3
4
|
import type { ChoiceInputOption, ChoiceInputSize, ChoiceInputType, HtmlParts } from './utils.js';
|
|
4
5
|
|
|
5
6
|
interface Props {
|
|
@@ -15,6 +16,7 @@
|
|
|
15
16
|
label: string;
|
|
16
17
|
size: ChoiceInputSize;
|
|
17
18
|
checked: string[];
|
|
19
|
+
orientation: Orientation;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
let {
|
|
@@ -36,6 +38,7 @@
|
|
|
36
38
|
size = '',
|
|
37
39
|
// Provides bind:checked capabilities that consumer can use
|
|
38
40
|
checked = $bindable([]),
|
|
41
|
+
orientation = Orientation.DynamicRow,
|
|
39
42
|
...restProps
|
|
40
43
|
}: Partial<Props & HtmlParts> = $props();
|
|
41
44
|
|
|
@@ -99,36 +102,38 @@
|
|
|
99
102
|
<div class="w-100">
|
|
100
103
|
<fieldset class={fieldsetClasses}>
|
|
101
104
|
<legend class={legendClasses}>{label}</legend>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
105
|
+
<div class="flex {orientation}">
|
|
106
|
+
{#each options as { value, label }, index}
|
|
107
|
+
<label
|
|
108
|
+
class={labelClasses}
|
|
109
|
+
class:disabled={isDisabled || disabledOptions.includes(value) || undefined}
|
|
110
|
+
>
|
|
111
|
+
<input
|
|
112
|
+
class={inputClasses}
|
|
113
|
+
id="{id}-{name}-{index}"
|
|
114
|
+
{type}
|
|
115
|
+
{name}
|
|
116
|
+
{value}
|
|
117
|
+
disabled={isDisabled || disabledOptions.includes(value)}
|
|
118
|
+
checked={checkedOptions.includes(value)}
|
|
119
|
+
onchange={onChange}
|
|
120
|
+
{...restProps}
|
|
121
|
+
/>
|
|
122
|
+
<span class={labelSpanClasses} aria-hidden="true"></span>
|
|
123
|
+
<span class={labelCopyClasses}>{label}</span>
|
|
124
|
+
</label>
|
|
125
|
+
{/each}
|
|
126
|
+
</div>
|
|
122
127
|
</fieldset>
|
|
123
128
|
</div>
|
|
124
129
|
|
|
125
130
|
<style>
|
|
126
131
|
/**
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
+
* These radio and checkbox customizations are an amalgamation of various resources I've
|
|
133
|
+
* found on the internets; from Heydon Pickering's radio article (and his Inclusive Components
|
|
134
|
+
* book), to Sara Soueidan, Scott O'Hara, MDO, and Adrian Roselli's research on the matter
|
|
135
|
+
* of inclusive hiding and custom radio/checkbox inputs.
|
|
136
|
+
*/
|
|
132
137
|
.checkbox-group,
|
|
133
138
|
.radio-group {
|
|
134
139
|
--width-28: calc(7 * var(--fluid-4)); /* 1.75rem/28px */
|
|
@@ -152,7 +157,7 @@
|
|
|
152
157
|
}
|
|
153
158
|
|
|
154
159
|
/* Hiding technique from https://www.sarasoueidan.com/blog/inclusively-hiding-and-styling-checkboxes-and-radio-buttons/
|
|
155
|
-
|
|
160
|
+
*/
|
|
156
161
|
.checkbox,
|
|
157
162
|
.radio {
|
|
158
163
|
position: absolute;
|
|
@@ -238,7 +243,7 @@
|
|
|
238
243
|
}
|
|
239
244
|
|
|
240
245
|
/* Since we build up the radio size outwardly, it's naturally larger then the checkboxes
|
|
241
|
-
|
|
246
|
+
so we add a multiplyer to even those out initially */
|
|
242
247
|
.checkbox-label::before {
|
|
243
248
|
border: 2px solid var(--agnostic-checkbox-border-color, var(--agnostic-gray-light));
|
|
244
249
|
width: var(--fluid-16);
|
|
@@ -328,9 +333,9 @@
|
|
|
328
333
|
}
|
|
329
334
|
|
|
330
335
|
/**
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
336
|
+
* Consumer styles <legend> themselves, and can opt to use the .screenreader-only from
|
|
337
|
+
* utilities.css if they're design requires it.
|
|
338
|
+
*/
|
|
334
339
|
.checkbox-group-hidden,
|
|
335
340
|
.radio-group-hidden {
|
|
336
341
|
border: 0;
|
|
@@ -345,8 +350,8 @@
|
|
|
345
350
|
}
|
|
346
351
|
|
|
347
352
|
/* Targets both the label container and the span label that is used
|
|
348
|
-
|
|
349
|
-
|
|
353
|
+
to style the custom radio / checkbox. Note it does NOT target the input
|
|
354
|
+
itself. */
|
|
350
355
|
.checkbox[disabled] ~ .checkbox-label-copy,
|
|
351
356
|
.radio[disabled] ~ .radio-label-copy,
|
|
352
357
|
.checkbox-label-wrap[class='disabled'],
|
|
@@ -374,4 +379,40 @@
|
|
|
374
379
|
outline-offset: -2px;
|
|
375
380
|
}
|
|
376
381
|
}
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
.field-help,
|
|
385
|
+
.field-help-large,
|
|
386
|
+
.field-help-small,
|
|
387
|
+
.field-error,
|
|
388
|
+
.field-error-large,
|
|
389
|
+
.field-error-small,
|
|
390
|
+
.label-skin,
|
|
391
|
+
.label,
|
|
392
|
+
.input-addon-container,
|
|
393
|
+
.input-small,
|
|
394
|
+
.input-large,
|
|
395
|
+
.input-skin,
|
|
396
|
+
.input-underlined,
|
|
397
|
+
.input-underlined-bg,
|
|
398
|
+
.input {
|
|
399
|
+
color: var(--font-color, var(--dark));
|
|
400
|
+
font-family: var(--font-family-body);
|
|
401
|
+
font-weight: var(--font-weight, 300);
|
|
402
|
+
font-size: var(--font-size, 1rem);
|
|
403
|
+
line-height: var(--line-height, var(--fluid-20, 1.25rem));
|
|
404
|
+
width: 100%;
|
|
405
|
+
max-width: 100%;
|
|
406
|
+
}
|
|
407
|
+
.label {
|
|
408
|
+
display: inline-block;
|
|
409
|
+
|
|
410
|
+
/* Provided --input-vertical-pad isn't overriden we'll get 20px
|
|
411
|
+
label w/a 6px margin then a 38px input = 64 which is on the 8pt grid */
|
|
412
|
+
margin-block-start: 0;
|
|
413
|
+
margin-inline-start: 0;
|
|
414
|
+
margin-inline-end: 0;
|
|
415
|
+
margin-block-end: var(--input-label-pad, 0.375rem);
|
|
416
|
+
vertical-align: initial;
|
|
417
|
+
}
|
|
377
418
|
</style>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Orientation } from '../Styling.js';
|
|
1
2
|
import type { ChoiceInputOption, ChoiceInputSize, ChoiceInputType, HtmlParts } from './utils.js';
|
|
2
3
|
declare const ChoiceInput: import("svelte").Component<Partial<{
|
|
3
4
|
isSkinned: boolean;
|
|
@@ -12,6 +13,7 @@ declare const ChoiceInput: import("svelte").Component<Partial<{
|
|
|
12
13
|
label: string;
|
|
13
14
|
size: ChoiceInputSize;
|
|
14
15
|
checked: string[];
|
|
16
|
+
orientation: Orientation;
|
|
15
17
|
} & HtmlParts>, {}, "checked">;
|
|
16
18
|
type ChoiceInput = ReturnType<typeof ChoiceInput>;
|
|
17
19
|
export default ChoiceInput;
|
|
@@ -1,48 +1,82 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
import ChoiceInput from
|
|
4
|
-
import Input from
|
|
5
|
-
import Select from
|
|
6
|
-
import Switch from
|
|
2
|
+
import { mapEntiresToOptions, type Field } from './form.js';
|
|
3
|
+
import ChoiceInput from './ChoiceInput.svelte';
|
|
4
|
+
import Input from './Input.svelte';
|
|
5
|
+
import Select from './Select.svelte';
|
|
6
|
+
import Switch from './Switch.svelte';
|
|
7
|
+
import { Placement } from '../Styling.ts';
|
|
8
|
+
import { addTransactionSupport } from 'ioredis/built/transaction.js';
|
|
9
|
+
import Button from './Button.svelte';
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
interface FormButton{
|
|
12
|
+
label: string;
|
|
13
|
+
type: "submit" | "reset" | "button";
|
|
14
|
+
click?: () => void;
|
|
15
|
+
}
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
interface Props {
|
|
18
|
+
actions: Array<FormButton>;
|
|
19
|
+
schema: Array<Field>;
|
|
20
|
+
buttonPosition: Placement;
|
|
21
|
+
buttonsContainer: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let {
|
|
25
|
+
actions = [],
|
|
26
|
+
schema,
|
|
27
|
+
buttonsContainer = '',
|
|
28
|
+
buttonPosition = Placement.Bottom
|
|
29
|
+
}: Partial<Props> = $props();
|
|
14
30
|
</script>
|
|
15
31
|
|
|
32
|
+
{#snippet buttons()}
|
|
33
|
+
<div class={buttonsContainer}>
|
|
34
|
+
{#each actions as action}
|
|
35
|
+
<Button type={action.type} click={action.click}>{action.label}</Button>
|
|
36
|
+
{/each}
|
|
37
|
+
</div>
|
|
38
|
+
{/snippet}
|
|
39
|
+
|
|
16
40
|
<form method="POST" {action}>
|
|
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
|
-
|
|
41
|
+
<fieldset>
|
|
42
|
+
{#if buttonPosition === Placement.Top}
|
|
43
|
+
{@render buttons()}
|
|
44
|
+
{/if}
|
|
45
|
+
|
|
46
|
+
<div>
|
|
47
|
+
{#each schema as field}
|
|
48
|
+
{#if field.type === 'boolean'}
|
|
49
|
+
<Switch name={field.name} id={field.name} label={field.name} />
|
|
50
|
+
{:else if field.type === 'enum' && field.meta.type === 'select'}
|
|
51
|
+
<Select
|
|
52
|
+
name={field.name}
|
|
53
|
+
id={field.name}
|
|
54
|
+
label={field.name}
|
|
55
|
+
options={mapEntiresToOptions(field)}
|
|
56
|
+
singleSelected="LOW"
|
|
57
|
+
/>
|
|
58
|
+
{:else if field.type === 'enum'}
|
|
59
|
+
<ChoiceInput
|
|
60
|
+
name={field.name}
|
|
61
|
+
id={field.name}
|
|
62
|
+
label={field.name}
|
|
63
|
+
type={field.meta.type}
|
|
64
|
+
options={mapEntiresToOptions(field)}
|
|
65
|
+
/>
|
|
66
|
+
{:else if field.type === 'string' || field.type === 'number'}
|
|
67
|
+
<Input
|
|
68
|
+
name={field.name}
|
|
69
|
+
id={field.name}
|
|
70
|
+
label={field.name}
|
|
71
|
+
type={field.meta.type}
|
|
72
|
+
isRequired={field.isRequired}
|
|
73
|
+
/>
|
|
74
|
+
{/if}
|
|
75
|
+
{/each}
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
{#if buttonPosition !== Placement.Top}
|
|
79
|
+
{@render buttons()}
|
|
80
|
+
{/if}
|
|
81
|
+
</fieldset>
|
|
48
82
|
</form>
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
import { type Field } from
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { type Field } from './form.js';
|
|
2
|
+
import { Placement } from '../Styling.ts';
|
|
3
|
+
declare const Form: import("svelte").Component<Partial<{
|
|
4
|
+
actions: Array<{
|
|
5
|
+
label: string;
|
|
6
|
+
type: "submit" | "reset" | "button";
|
|
7
|
+
click?: () => void;
|
|
8
|
+
}>;
|
|
4
9
|
schema: Array<Field>;
|
|
5
|
-
|
|
6
|
-
|
|
10
|
+
buttonPosition: Placement;
|
|
11
|
+
buttonsContainer: string;
|
|
12
|
+
}>, {}, "">;
|
|
7
13
|
type Form = ReturnType<typeof Form>;
|
|
8
14
|
export default Form;
|