@soleil-se/config-svelte 1.20.1 → 1.22.0

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/CHANGELOG.md CHANGED
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.22.0] - 2024-02-13
9
+
10
+ - More lenient `@sitevision/api` peer dependency range.
11
+ - Try to use `window.sv.getValues()` if available since `window._getValues()` is deprecated.
12
+
13
+ ## [1.21.0] - 2023-10-13
14
+
15
+ - Add `legendVisuallyHidden` prop for [RadioGroup](./components/RadioGroup) and [CheckboxGroup](./components/CheckboxGroup).
16
+ - Add `class` prop for [Panel](./components/Panel).
17
+ - Add `removable` prop for [CustomSelector](./components/CustomSelector).
18
+
8
19
  ## [1.20.1] - 2023-09-25
9
20
 
10
21
  - Fix element containting title in [Modal](./components/Modal).
@@ -9,26 +9,28 @@
9
9
  export let name;
10
10
  export let options;
11
11
  export let legend;
12
+ export let legendVisuallyHidden = false;
12
13
  export let disabled = false;
13
14
  export let show = true;
14
15
  export let value = [];
15
16
  value = name ? values[name] || value : value;
16
17
 
17
-
18
18
  let className = '';
19
19
  export { className as class };
20
20
 
21
- $: isChecked = (option) => value.includes(option.value || option);
21
+ function isChecked(option) {
22
+ return value.includes(option.value || option);
23
+ }
22
24
 
23
- $: isDisabled = (option) => {
25
+ function isDisabled(option) {
24
26
  if (Array.isArray(disabled)) return disabled.includes(option.value || option);
25
27
  return disabled;
26
- };
28
+ }
27
29
 
28
- const onChange = () => {
30
+ function onChange() {
29
31
  dispatch('input', value);
30
32
  dispatch('change', value);
31
- };
33
+ }
32
34
  </script>
33
35
 
34
36
  <!--
@@ -39,29 +41,30 @@
39
41
  -->
40
42
 
41
43
  <fieldset class="form-group {className}" class:hidden={!show}>
42
- <legend>{legend}</legend>
44
+ <legend class:sr-only={legendVisuallyHidden}>{legend}</legend>
43
45
  {#each options as option, index}
44
46
  <input
45
47
  id={`${id}_${index}`}
46
- bind:group={value}
47
- class="sr-only"
48
- value={option.value || option}
49
48
  {name}
49
+ class="sr-only"
50
+ disabled={isDisabled(option, disabled)}
50
51
  type="checkbox"
51
- disabled={isDisabled(option)}
52
+ value={option.value || option}
53
+ bind:group={value}
52
54
  on:change={onChange}
53
55
  />
54
56
  <label
55
- for={`${id}_${index}`}
56
57
  class="checkbox-inline"
57
- class:disabled={isDisabled(option)}
58
- class:checked={isChecked(option)}
58
+ class:checked={isChecked(option, value)}
59
+ class:disabled={isDisabled(option, disabled)}
60
+ for={`${id}_${index}`}
59
61
  >
60
62
  {option.label || option}
61
63
  </label>
62
64
  {/each}
63
65
  </fieldset>
64
66
 
67
+ <!-- eslint-disable -->
65
68
  <style lang="scss">
66
69
  fieldset {
67
70
  margin-top: 0;
@@ -13,6 +13,8 @@ export let name;
13
13
  export let options;
14
14
  // Fieldset legend
15
15
  export let legend;
16
+ // If legend should be hidden visually
17
+ export let legendVisuallyHidden = false;
16
18
  // Disable input, or provide an array of disabled options: ['value1'].
17
19
  export let disabled = false;
18
20
  // Show and hide compoment without re-rendering.
@@ -1,5 +1,6 @@
1
1
  <script>
2
- import { createEventDispatcher, onMount } from 'svelte';
2
+ import { createEventDispatcher, onMount, tick } from 'svelte';
3
+
3
4
  import { generateId, addGeneratedIds } from '../../utils';
4
5
  import { resizer } from '../../actions';
5
6
  import i18n from './i18n';
@@ -32,64 +33,65 @@
32
33
  let dragDisabled = disabled;
33
34
  let addModalOpen = false;
34
35
 
35
- const onAddOpen = () => {
36
+ function onAddOpen() {
36
37
  addModalOpen = true;
37
- };
38
+ }
38
39
 
39
- const onAddClose = () => {
40
+ function onAddClose() {
40
41
  addModalOpen = false;
41
- };
42
+ }
42
43
 
43
- const updateItems = () => {
44
+ async function updateItems() {
45
+ await tick();
44
46
  items = value.map((id) => ({
45
47
  id,
46
48
  name: document.querySelector(`#modal_${id} input`)?.value || id,
47
49
  }));
48
- };
50
+ }
49
51
 
50
- const onChange = () => {
52
+ function onChange() {
51
53
  value = items.map((item) => item.id);
52
54
  dispatch('input', value);
53
55
  dispatch('change', value);
54
- };
56
+ }
55
57
 
56
- const onAddSave = ({ detail }) => {
58
+ function onAddSave({ detail }) {
57
59
  items = items.concat(detail);
58
60
  modals = modals.concat(detail.id);
59
61
  onChange();
60
- };
62
+ }
61
63
 
62
- const onEdit = ({ detail }) => {
64
+ function onEdit({ detail }) {
63
65
  editId = detail;
64
- };
66
+ }
65
67
 
66
- const onRemove = ({ detail }) => {
68
+ function onRemove({ detail }) {
67
69
  items = items.filter((item) => item.id !== detail);
68
70
  modals = modals.filter((id) => id !== detail);
69
71
  onChange();
70
- };
72
+ }
71
73
 
72
- const onEditSave = () => {
74
+ function onEditSave() {
73
75
  editId = undefined;
74
76
  updateItems();
75
77
  onChange();
76
- };
78
+ }
77
79
 
78
- const onEditClose = () => {
80
+ function onEditClose() {
79
81
  editId = undefined;
80
- };
82
+ }
81
83
 
82
- const tempDisableDrag = () => {
84
+ function tempDisableDrag() {
83
85
  dragDisabled = true;
84
86
  setTimeout(() => {
85
87
  dragDisabled = disabled;
86
88
  }, 300);
87
- };
89
+ }
88
90
 
89
- const onFinalize = ({ detail }) => {
91
+ function onFinalize({ detail }) {
90
92
  items = detail;
91
93
  onChange();
92
- };
94
+ }
93
95
 
94
96
  onMount(updateItems);
95
97
  </script>
@@ -112,12 +114,12 @@
112
114
  </AddModal>
113
115
 
114
116
  <div class="form-group" class:hidden={!show}>
115
- <label for={domId} class="control-label {required ? 'control-label--required' : ''}">
117
+ <label class="control-label {required ? 'control-label--required' : ''}" for={domId}>
116
118
  {label}
117
119
  </label>
118
120
  <div class="list-component">
119
121
  <div class="list-component__list-wrapper ui-resizable">
120
- <Sortable {items} {dragDisabled} on:finalize={onFinalize} let:item>
122
+ <Sortable {dragDisabled} {items} on:finalize={onFinalize} let:item>
121
123
  <SortableItem
122
124
  {...item}
123
125
  {disabled}
@@ -127,9 +129,9 @@
127
129
  on:click={tempDisableDrag}
128
130
  />
129
131
  </Sortable>
130
- <div use:resizer class="ui-resizable-handle ui-resizable-s" />
132
+ <div class="ui-resizable-handle ui-resizable-s" use:resizer />
131
133
  </div>
132
- <button class="list-component__add-item btn btn-link" on:click={onAddOpen} {disabled}>
134
+ <button class="list-component__add-item btn btn-link" {disabled} on:click={onAddOpen}>
133
135
  <i class="glyphicons plus" aria-hidden="true" />
134
136
  {i18n('add')}
135
137
  </button>
@@ -139,7 +141,7 @@
139
141
  {/if}
140
142
  </div>
141
143
 
142
- <DataHolder {domId} {name} {value} {required} />
144
+ <DataHolder {name} {domId} {required} {value} />
143
145
  </div>
144
146
 
145
147
  <style lang="scss">
@@ -12,6 +12,7 @@
12
12
  export let placeholder = i18n('placeholder');
13
13
  export let options = [];
14
14
  export let searchable = false;
15
+ export let removable = true;
15
16
  export let required = false;
16
17
  export let disabled = false;
17
18
  export let multiple = false;
@@ -19,6 +20,7 @@
19
20
 
20
21
  export let value = multiple ? [] : '';
21
22
 
23
+ value = !removable && !multiple ? value || options[0]?.value || options[0] || '' : value;
22
24
  value = name ? values[name]?.value ?? values[name] ?? value : value;
23
25
  value = Array.isArray(value) ? value.map((v) => v.value ?? v) : value;
24
26
 
@@ -45,7 +47,7 @@
45
47
  .select2({
46
48
  placeholder,
47
49
  width: '100%',
48
- allowClear: true,
50
+ allowClear: removable,
49
51
  minimumResultsForSearch: searchable ? 0 : Infinity,
50
52
  templateResult: template,
51
53
  formatResult: template,
@@ -72,19 +74,19 @@
72
74
  <div class="form-group {className}" class:hidden={!show}>
73
75
  {#if $$slots.option}
74
76
  {#each options as option}
75
- <span hidden data-option="{id}_{option.value ?? option}">
77
+ <span data-option="{id}_{option.value ?? option}" hidden>
76
78
  <slot name="option" {option} />
77
79
  </span>
78
80
  {/each}
79
81
  {/if}
80
- <label for={id} class="control-label {required ? 'control-label--required' : ''}">{label}</label>
82
+ <label class="control-label {required ? 'control-label--required' : ''}" for={id}>{label}</label>
81
83
  <select
82
84
  bind:this={element}
83
85
  {id}
84
- {required}
86
+ name={!multiple ? name : undefined}
85
87
  {disabled}
86
88
  {multiple}
87
- name={!multiple ? name : undefined}
89
+ {required}
88
90
  >
89
91
  <option />
90
92
  {#each options as option}
@@ -95,7 +97,7 @@
95
97
  </select>
96
98
  <slot />
97
99
  {#if multiple}
98
- <select {name} {value} multiple hidden>
100
+ <select {name} hidden multiple {value}>
99
101
  {#each options as option}
100
102
  <option value={option.value ?? option} />
101
103
  {/each}
@@ -2,7 +2,7 @@
2
2
 
3
3
  Wrapper component for Sitevision [Custom selector](https://developer.sitevision.se/docs/webapps/webapps-2/configuration/sitevision-components#h-Customselectorsince91).
4
4
 
5
- ![CustomSelector](../../images/CustomSelector.png)
5
+ ![CustomSelector](../../images/CustomSelector_single.png)
6
6
  ![CustomSelectorMultiple](../../images/CustomSelector_multiple.png)
7
7
 
8
8
  ## Props
@@ -14,6 +14,7 @@ export let name = undefined;
14
14
  export let placeholder;
15
15
  export let options = [];
16
16
  export let searchable = false;
17
+ export let removable = true;
17
18
  export let required = false;
18
19
  export let disabled = false;
19
20
  export let multiple = false;
@@ -42,8 +42,8 @@
42
42
  });
43
43
 
44
44
  /*
45
- * The sv:loaded event is only triggered on initial load, if the component rerenders check if any
46
- * children are present and set value of select element.
45
+ * The sv:loaded event is only triggered on initial load, if the component rerenders check
46
+ * if any children are present and set value of select element.
47
47
  */
48
48
  if (el?.childElementCount > 0) {
49
49
  setValue(el);
@@ -58,16 +58,16 @@
58
58
  [README](https://docs.soleilit.se/03.packages/@soleil&svelte-config/components/DropdownSelector/)
59
59
  -->
60
60
 
61
- <div class="form-group {className}" {hidden} class:hidden={!show}>
62
- <label for={id} class="control-label {required ? 'control-label--required' : ''}">{label}</label>
61
+ <div class="form-group {className}" class:hidden={!show} {hidden}>
62
+ <label class="control-label {required ? 'control-label--required' : ''}" for={id}>{label}</label>
63
63
  <select
64
64
  {id}
65
65
  {name}
66
- {required}
67
- {disabled}
68
66
  data-component={component}
69
67
  data-removable
70
68
  data-types={selectable}
69
+ {disabled}
70
+ {required}
71
71
  />
72
72
  <slot />
73
73
  </div>
@@ -4,6 +4,10 @@
4
4
  export let heading = i18n('settings');
5
5
  export let required = false;
6
6
  export let show = true;
7
+
8
+ let className = '';
9
+ /** @type {string} */
10
+ export { className as class };
7
11
  </script>
8
12
 
9
13
  <!--
@@ -13,8 +17,8 @@
13
17
  [README](https://docs.soleilit.se/03.packages/@soleil&svelte-config/components/Panel/)
14
18
  -->
15
19
 
16
- <div class="panel panel-default" class:hidden={!show}>
17
- <input class="sr-only" type="text" tabindex="-1" />
20
+ <div class="panel panel-default {className}" class:hidden={!show}>
21
+ <input class="sr-only" tabindex="-1" type="text" />
18
22
  <div class="panel-heading">
19
23
  <h1 class="panel-title {required && 'panel-title--required'}">{heading}</h1>
20
24
  </div>
@@ -23,7 +27,7 @@
23
27
  </div>
24
28
  </div>
25
29
 
26
- <style lang="scss" global>
30
+ <style global lang="scss">
27
31
  html {
28
32
  position: fixed;
29
33
  overflow: hidden;
@@ -9,20 +9,24 @@
9
9
  export let name;
10
10
  export let options = [];
11
11
  export let legend;
12
+ export let label;
13
+ export let legendVisuallyHidden = false;
12
14
  export let disabled = false;
13
15
  export let show = true;
14
16
  export let value = options[0]?.value ?? options[0] ?? '';
15
17
  value = name ? values[name] ?? value : value;
16
18
 
17
- $: isDisabled = (option) => {
19
+ $: legend = legend || label;
20
+
21
+ function isDisabled(option) {
18
22
  if (Array.isArray(disabled)) return disabled.includes(option.value || option);
19
23
  return disabled;
20
- };
24
+ }
21
25
 
22
- const onChange = () => {
26
+ function onChange() {
23
27
  dispatch('input', value);
24
28
  dispatch('change', value);
25
- };
29
+ }
26
30
  </script>
27
31
 
28
32
  <!--
@@ -33,19 +37,23 @@
33
37
  -->
34
38
 
35
39
  <fieldset class="form-group" class:hidden={!show}>
36
- <legend>{legend}</legend>
40
+ <legend class:sr-only={legendVisuallyHidden}>{legend}</legend>
37
41
  {#each options as option, index}
38
42
  <input
39
43
  id={`${id}_${index}`}
40
44
  class="sr-only"
41
45
  checked={option.value || option}
42
- disabled={isDisabled(option)}
46
+ disabled={isDisabled(option, disabled)}
43
47
  type="radio"
44
48
  value={option.value || option}
45
49
  bind:group={value}
46
50
  on:change={onChange}
47
51
  />
48
- <label class="radio-inline" class:disabled={isDisabled(option)} for={`${id}_${index}`}>
52
+ <label
53
+ class="radio-inline"
54
+ class:disabled={isDisabled(option, disabled)}
55
+ for={`${id}_${index}`}
56
+ >
49
57
  {option.label || option}
50
58
  </label>
51
59
  {/each}
@@ -12,6 +12,8 @@ export let name;
12
12
  export let options;
13
13
  // Fieldset legend.
14
14
  export let legend;
15
+ // If legend should be hidden visually
16
+ export let legendVisuallyHidden = false;
15
17
  // If field is disabled, can be boolean to disable all options, or an array of disabled option values; ['value1'].
16
18
  export let disabled = false;
17
19
  // Show and hide compoment without re-rendering.
@@ -20,7 +20,7 @@ export default function createConfigApp(App) {
20
20
 
21
21
  window.getValues = () => {
22
22
  // eslint-disable-next-line no-underscore-dangle
23
- const values = window._getValues();
23
+ const values = window?.sv?.getValues() || window?._getValues();
24
24
  return {
25
25
  ...values,
26
26
  __lastEditTimestamp: new Date().getTime(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soleil-se/config-svelte",
3
- "version": "1.20.1",
3
+ "version": "1.22.0",
4
4
  "main": "./index.js",
5
5
  "module": "./index.js",
6
6
  "svelte": "./index.js",
@@ -12,22 +12,22 @@
12
12
  "svelte": "^3.46.0 || ^4.0.0"
13
13
  },
14
14
  "devDependencies": {
15
- "@soleil-se/eslint-config": "^5.1.0",
16
- "@soleil-se/stylelint-config": "^3.0.0",
17
- "eslint": "^8.43.0",
15
+ "@soleil-se/eslint-config": "^5.1.1",
16
+ "@soleil-se/stylelint-config": "^3.1.1",
17
+ "eslint": "^8.51.0",
18
18
  "eslint-config-airbnb-base": "^15.0.0",
19
- "eslint-config-prettier": "^8.8.0",
20
- "eslint-plugin-import": "^2.27.5",
21
- "eslint-plugin-svelte": "^2.31.1",
22
- "stylelint": "^15.9.0",
23
- "svelte": "^4.0.0",
19
+ "eslint-config-prettier": "^9.0.0",
20
+ "eslint-plugin-import": "^2.28.1",
21
+ "eslint-plugin-svelte": "^2.34.0",
22
+ "stylelint": "^15.10.3",
23
+ "svelte": "^4.2.1",
24
24
  "svelte-preprocess": "^5.0.4"
25
25
  },
26
26
  "dependencies": {
27
27
  "@soleil-se/config-validate": "^1.1.2",
28
28
  "a11y-dialog": "7.5.2",
29
29
  "focus-visible": "^5.2.0",
30
- "svelte-dnd-action": "^0.9.22"
30
+ "svelte-dnd-action": "^0.9.31"
31
31
  },
32
32
  "homepage": "https://docs.soleil.se/packages/config-svelte",
33
33
  "description": "A collection of Svelte components and utilities for WebApp, RESTApp and Widget configurations.",