@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
- {#each options as { value, label }, index}
103
- <label
104
- class={labelClasses}
105
- class:disabled={isDisabled || disabledOptions.includes(value) || undefined}
106
- >
107
- <input
108
- class={inputClasses}
109
- id="{id}-{name}-{index}"
110
- {type}
111
- {name}
112
- {value}
113
- disabled={isDisabled || disabledOptions.includes(value)}
114
- checked={checkedOptions.includes(value)}
115
- onchange={onChange}
116
- {...restProps}
117
- />
118
- <span class={labelSpanClasses} aria-hidden="true"></span>
119
- <span class={labelCopyClasses}>{label}</span>
120
- </label>
121
- {/each}
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
- * These radio and checkbox customizations are an amalgamation of various resources I've
128
- * found on the internets; from Heydon Pickering's radio article (and his Inclusive Components
129
- * book), to Sara Soueidan, Scott O'Hara, MDO, and Adrian Roselli's research on the matter
130
- * of inclusive hiding and custom radio/checkbox inputs.
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
- so we add a multiplyer to even those out initially */
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
- * Consumer styles <legend> themselves, and can opt to use the .screenreader-only from
332
- * utilities.css if they're design requires it.
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
- to style the custom radio / checkbox. Note it does NOT target the input
349
- itself. */
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
- 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";
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
- interface Props {
9
- action: string;
10
- schema: Array<Field>;
11
- }
11
+ interface FormButton{
12
+ label: string;
13
+ type: "submit" | "reset" | "button";
14
+ click?: () => void;
15
+ }
12
16
 
13
- let { action, schema }: Props = $props();
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
- <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>
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 "./form.js";
2
- interface Props {
3
- action: string;
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
- declare const Form: import("svelte").Component<Props, {}, "">;
10
+ buttonPosition: Placement;
11
+ buttonsContainer: string;
12
+ }>, {}, "">;
7
13
  type Form = ReturnType<typeof Form>;
8
14
  export default Form;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@functionalcms/svelte-components",
3
- "version": "4.10.27",
3
+ "version": "4.10.29",
4
4
  "watch": {
5
5
  "build": {
6
6
  "patterns": [