@onsvisual/svelte-components 1.0.53 → 1.0.55

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.
@@ -38,6 +38,11 @@
38
38
  * @type {object[]}
39
39
  */
40
40
  export let options = [];
41
+ /**
42
+ * The width of the <input> in characters or a valid css width string (eg. "100px")
43
+ * @type {number|string|null}
44
+ */
45
+ export let width = 20;
41
46
  /**
42
47
  * Optional: Set an additional CSS class for the component
43
48
  * @type {string|null}
@@ -52,7 +57,10 @@
52
57
  <select
53
58
  {id}
54
59
  {name}
55
- class="ons-input ons-input--select"
60
+ class="ons-input ons-input--select {Number.isInteger(width)
61
+ ? `ons-input--w-${width}`
62
+ : ''}"
63
+ style:width={typeof width === "string" ? width : null}
56
64
  bind:value
57
65
  on:change={(e) => dispatch("change", e)}
58
66
  >
@@ -64,3 +72,9 @@
64
72
  {/each}
65
73
  </select>
66
74
  </div>
75
+
76
+ <style>
77
+ .ons-input--select {
78
+ width: 100%;
79
+ }
80
+ </style>
@@ -4,6 +4,7 @@
4
4
  export default class Dropdown extends SvelteComponentTyped<{
5
5
  cls?: string | null | undefined;
6
6
  id?: string | null | undefined;
7
+ width?: string | number | null | undefined;
7
8
  label?: string | null | undefined;
8
9
  name?: string | null | undefined;
9
10
  value?: object | null | undefined;
@@ -24,6 +25,7 @@ declare const __propDef: {
24
25
  props: {
25
26
  cls?: string | null | undefined;
26
27
  id?: string | null | undefined;
28
+ width?: string | number | null | undefined;
27
29
  label?: string | null | undefined;
28
30
  name?: string | null | undefined;
29
31
  value?: object | null | undefined;
@@ -35,14 +35,14 @@
35
35
  export let description = null;
36
36
  /**
37
37
  * The maximum number of characters that can be entered (optional)
38
- * @type {number}
38
+ * @type {number|null}
39
39
  */
40
40
  export let charLimit = null;
41
41
  /**
42
- * The width of the &lt;input&gt; in characters
43
- * @type {number}
42
+ * The width of the &lt;input&gt; in characters or a valid css width string (eg. "100px")
43
+ * @type {number|string|null}
44
44
  */
45
- export let width = null;
45
+ export let width = 20;
46
46
  /**
47
47
  * An optional prefix (eg. £) to appear on the left of the input
48
48
  * @type {string|null}
@@ -116,6 +116,7 @@
116
116
  class="ons-input ons-input--text ons-input-type__input {Number.isInteger(width)
117
117
  ? `ons-input--w-${width}`
118
118
  : ''}"
119
+ style:width={typeof width === "string" ? width : null}
119
120
  class:ons-input--error={error}
120
121
  aria-labelledby="{id} {id}-unit"
121
122
  aria-describedby={description ? `${id}-description-hint` : null}
@@ -142,6 +143,7 @@
142
143
  class="ons-input ons-input--text ons-input-type__input {Number.isInteger(width)
143
144
  ? `ons-input--w-${width}`
144
145
  : ''}"
146
+ style:width={typeof width === "string" ? width : null}
145
147
  class:ons-input--error={error}
146
148
  aria-describedby={description ? `${id}-description-hint` : null}
147
149
  {disabled}
@@ -149,3 +151,9 @@
149
151
  />
150
152
  {/if}
151
153
  </div>
154
+
155
+ <style>
156
+ .ons-input--text {
157
+ width: 100%;
158
+ }
159
+ </style>
@@ -4,7 +4,7 @@
4
4
  export default class Input extends SvelteComponentTyped<{
5
5
  cls?: string | null | undefined;
6
6
  id?: string | null | undefined;
7
- width?: number | undefined;
7
+ width?: string | number | null | undefined;
8
8
  label?: string | null | undefined;
9
9
  pattern?: string | null | undefined;
10
10
  name?: string | null | undefined;
@@ -14,7 +14,7 @@ export default class Input extends SvelteComponentTyped<{
14
14
  description?: string | null | undefined;
15
15
  disabled?: boolean | undefined;
16
16
  hideLabel?: boolean | undefined;
17
- charLimit?: number | undefined;
17
+ charLimit?: number | null | undefined;
18
18
  prefix?: string | null | undefined;
19
19
  suffix?: string | null | undefined;
20
20
  unitLabel?: string | undefined;
@@ -32,7 +32,7 @@ declare const __propDef: {
32
32
  props: {
33
33
  cls?: string | null | undefined;
34
34
  id?: string | null | undefined;
35
- width?: number | undefined;
35
+ width?: string | number | null | undefined;
36
36
  label?: string | null | undefined;
37
37
  pattern?: string | null | undefined;
38
38
  name?: string | null | undefined;
@@ -42,7 +42,7 @@ declare const __propDef: {
42
42
  description?: string | null | undefined;
43
43
  disabled?: boolean | undefined;
44
44
  hideLabel?: boolean | undefined;
45
- charLimit?: number | undefined;
45
+ charLimit?: number | null | undefined;
46
46
  prefix?: string | null | undefined;
47
47
  suffix?: string | null | undefined;
48
48
  unitLabel?: string | undefined;
@@ -1,7 +1,7 @@
1
1
  <script>
2
2
  // @ts-nocheck
3
-
4
3
  import { onMount, createEventDispatcher } from "svelte";
4
+ import accessibleAutocomplete from "accessible-autocomplete";
5
5
  import Dropdown from "../Dropdown/Dropdown.svelte";
6
6
  import Input from "../Input/Input.svelte";
7
7
 
@@ -10,9 +10,8 @@
10
10
  const chevron = (opts) =>
11
11
  `<svg class="${opts?.className}" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 11.75 7.7" width="18" style="z-index:1"><path fill="currentColor" d="m1.37.15 4.5 5.1 4.5-5.1a.37.37 0 0 1 .6 0l.7.7a.45.45 0 0 1 0 .5l-5.5 6.2a.37.37 0 0 1-.6 0l-5.5-6.1a.64.64 0 0 1 0-.6l.7-.7a.64.64 0 0 1 .6 0Z"></path></svg>`;
12
12
 
13
+ let mounted = false;
13
14
  let inputElement;
14
- let scriptLoaded;
15
- let accessibleAutocomplete;
16
15
  let hideMenu = false;
17
16
 
18
17
  /**
@@ -98,12 +97,6 @@
98
97
  );
99
98
  populateResults(filteredResults);
100
99
  };
101
- /**
102
- * Optional: Override the default CDN URL for the accessible-autocomplete script
103
- * @type {string}
104
- */
105
- export let scriptUrl =
106
- "https://cdn.ons.gov.uk/vendor/accessible-autocomplete/3.0.1/accessible-autocomplete.min.js";
107
100
  /**
108
101
  * Call this function externally to clear the input
109
102
  * @type {function}
@@ -167,13 +160,6 @@
167
160
  if (!e.target.value) select(null);
168
161
  }
169
162
 
170
- function handleScriptLoad() {
171
- if (!scriptLoaded && window?.accessibleAutocomplete) {
172
- accessibleAutocomplete = window.accessibleAutocomplete;
173
- scriptLoaded = true;
174
- }
175
- }
176
-
177
163
  function initAutocomplete(element) {
178
164
  accessibleAutocomplete({
179
165
  element,
@@ -209,24 +195,20 @@
209
195
  }
210
196
  $: bindInputValue(value);
211
197
 
212
- onMount(handleScriptLoad);
198
+ onMount(() => mounted = true);
213
199
  </script>
214
200
 
215
- <svelte:head>
216
- <script src={scriptUrl} on:load={handleScriptLoad}></script>
217
- </svelte:head>
218
-
219
- {#if renderFallback && !scriptLoaded}
201
+ {#if renderFallback && !mounted}
220
202
  {#if mode === "search"}
221
- <Input {id} {name} {label} {hideLabel} value={value?.[labelKey]} />
203
+ <Input {id} {name} {label} {hideLabel} value={value?.[labelKey]} width={null}/>
222
204
  {:else}
223
- <Dropdown {id} {name} {options} {label} {hideLabel} {placeholder} {value} />
205
+ <Dropdown {id} {name} {options} {label} {hideLabel} {placeholder} {value} width={null} />
224
206
  {/if}
225
207
  {:else}
226
208
  <div class="ons-field {cls}">
227
209
  {#if label}<label for={id} class="ons-label" class:ons-u-vh={hideLabel}>{label}</label>{/if}
228
210
  <div class="ons-autocomplete-wrapper">
229
- {#if scriptLoaded}
211
+ {#if mounted}
230
212
  <div
231
213
  id="{id}-container"
232
214
  class="ons-autocomplete"
@@ -18,7 +18,6 @@ export default class Select extends SvelteComponentTyped<{
18
18
  renderFallback?: boolean | undefined;
19
19
  minLength?: number | undefined;
20
20
  loadOptions?: Function | undefined;
21
- scriptUrl?: string | undefined;
22
21
  clearInput?: Function | undefined;
23
22
  }, {
24
23
  clear: CustomEvent<any>;
@@ -49,7 +48,6 @@ declare const __propDef: {
49
48
  renderFallback?: boolean | undefined;
50
49
  minLength?: number | undefined;
51
50
  loadOptions?: Function | undefined;
52
- scriptUrl?: string | undefined;
53
51
  clearInput?: Function | undefined;
54
52
  };
55
53
  events: {
@@ -1,6 +1,4 @@
1
1
  <script>
2
- import { onMount, onDestroy } from "svelte";
3
-
4
2
  /**
5
3
  * Bind to this variable to monitor whether the component has entered the viewport (boolean true/false).
6
4
  * @type {boolean}
@@ -17,34 +15,31 @@
17
15
  */
18
16
  export let rootMargin = 200;
19
17
 
20
- let el, observer;
21
-
22
18
  const callback = (entries, observer) => {
23
19
  entries.forEach((entry) => {
20
+ console.log(entry);
24
21
  let intersecting = entry.isIntersecting;
25
22
  if (!entered && intersecting) {
26
- observer.unobserve(el);
23
+ observer.unobserve(entry.target);
27
24
  entered = true;
28
25
  }
29
26
  });
30
27
  };
31
28
 
32
- onMount(() => {
29
+ function initObserver(el) {
33
30
  let options = { root: document, rootMargin: `${rootMargin}px` };
34
31
 
35
- observer = new IntersectionObserver(callback, options);
32
+ const observer = new IntersectionObserver(callback, options);
36
33
  observer.observe(el);
37
- });
38
34
 
39
- onDestroy(() => {
40
- if (el && observer) {
41
- observer.unobserve(el);
42
- }
43
- });
35
+ return {
36
+ destroy: () => observer?.unobserve?.(el)
37
+ };
38
+ }
44
39
  </script>
45
40
 
46
41
  {#if entered}
47
42
  <slot />
48
43
  {:else}
49
- <div bind:this={el} style:height="{+initialHeight || 100}px"></div>
44
+ <div use:initObserver style:height="{+initialHeight || 100}px"></div>
50
45
  {/if}
@@ -1,6 +1,6 @@
1
- A wrapper component that uses IntersectionObserver to allow the elements it contains to be lazy loaded, ie. to be initialised/mounted only when they enter the viewport (or come close to it).
1
+ A wrapper component that uses IntersectionObserver to allow the Svelte components or HTML elements it contains to be lazy loaded, ie. to be added to the page (or DOM) only when they enter the viewport.
2
2
 
3
- Optionally, you can use the **initialHeight** to set a placeholder height in pixels (default 400), and you can use **rootMargin** to set how many pixels from the viewport you want lazy loading to kick in (default 200).
3
+ Optionally, you can use the **initialHeight** to set a placeholder height in pixels (default 400), and you can use **rootMargin** to set how many pixels before the viewport you want lazy loading to kick in (default 200).
4
4
 
5
5
  <!-- prettier-ignore -->
6
6
  ```html
@@ -1,5 +1,5 @@
1
1
  <script>
2
- import { onMount, onDestroy, createEventDispatcher } from "svelte";
2
+ import { createEventDispatcher } from "svelte";
3
3
 
4
4
  const dispatch = createEventDispatcher();
5
5
 
@@ -14,8 +14,6 @@
14
14
  */
15
15
  export let rootMargin = 0;
16
16
 
17
- let el, observer;
18
-
19
17
  const callback = (entries) => {
20
18
  entries.forEach((entry) => {
21
19
  let intersecting = entry.isIntersecting;
@@ -30,16 +28,18 @@
30
28
  });
31
29
  };
32
30
 
33
- onMount(() => {
31
+ function initObserver(el) {
34
32
  let options = { root: document, rootMargin: `${rootMargin}px` };
35
33
 
36
- observer = new IntersectionObserver(callback, options);
34
+ const observer = new IntersectionObserver(callback, options);
37
35
  observer.observe(el);
38
- });
39
36
 
40
- onDestroy(() => observer?.unobserve?.(el));
37
+ return {
38
+ destroy: () => observer?.unobserve?.(el)
39
+ };
40
+ }
41
41
  </script>
42
42
 
43
- <div bind:this={el}>
43
+ <div use:initObserver>
44
44
  <slot />
45
45
  </div>
@@ -4,16 +4,21 @@ This component can be useful for triggering actions such as lazy loading of data
4
4
 
5
5
  This component has **enter** and **exit** events, triggered when it enters or leaves the viewport. It also has a **visible** binding which has a value of **true** when it is within the viewport.
6
6
 
7
+ In this demo, you can open your browser's developer console (**F12**) to see the logs for elements entering and existing the viewport.
8
+
7
9
  <!-- prettier-ignore -->
8
10
  ```html
9
11
  <script>
10
12
  import { Observe } from "@onsvisual/svelte-components";
11
13
 
14
+ let visible;
15
+
12
16
  const colors = ["yellow", "green", "blue", "purple", "red", "orange"];
13
17
  </script>
14
18
 
15
19
  {#each colors as color}
16
20
  <Observe
21
+ bind:visible
17
22
  on:enter={() => console.log(`${color} entered`)}
18
23
  on:exit={() => console.log(`${color} exited`)}>
19
24
  <div class="section" style:background={color} style:height="400px"/>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onsvisual/svelte-components",
3
- "version": "1.0.53",
3
+ "version": "1.0.55",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "npm run build:package && npm run build:docs",
@@ -62,6 +62,7 @@
62
62
  "@types/node": "^20",
63
63
  "@vitest/browser": "3.2.3",
64
64
  "@vitest/coverage-v8": "3.2.3",
65
+ "accessible-autocomplete": "^3.0.1",
65
66
  "csso": "^5.0.5",
66
67
  "eslint": "^9.18.0",
67
68
  "eslint-config-prettier": "^10.0.1",
@@ -86,4 +87,4 @@
86
87
  "keywords": [
87
88
  "svelte"
88
89
  ]
89
- }
90
+ }