@communitiesuk/svelte-component-library 0.1.19-beta.3 → 0.1.19-beta.34

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.
Files changed (52) hide show
  1. package/README.md +7 -0
  2. package/dist/components/content/Tag.svelte +32 -0
  3. package/dist/components/content/Tag.svelte.d.ts +13 -0
  4. package/dist/components/data-vis/Histogram.svelte +287 -0
  5. package/dist/components/data-vis/Histogram.svelte.d.ts +75 -0
  6. package/dist/components/data-vis/axis/Axis.svelte +217 -34
  7. package/dist/components/data-vis/axis/Axis.svelte.d.ts +38 -30
  8. package/dist/components/data-vis/axis/Ticks.svelte +142 -78
  9. package/dist/components/data-vis/axis/Ticks.svelte.d.ts +28 -31
  10. package/dist/components/data-vis/line-chart/LineChart.svelte +51 -21
  11. package/dist/components/data-vis/line-chart/LineChart.svelte.d.ts +14 -6
  12. package/dist/components/data-vis/line-chart/ValueLabel.svelte +2 -1
  13. package/dist/components/data-vis/line-chart/ValueLabel.svelte.d.ts +2 -0
  14. package/dist/components/data-vis/position-chart/PositionChart.svelte +279 -122
  15. package/dist/components/data-vis/position-chart/PositionChart.svelte.d.ts +37 -5
  16. package/dist/components/data-vis/position-chart/PositionChartAxis.svelte +59 -48
  17. package/dist/components/data-vis/position-chart/PositionChartAxis.svelte.d.ts +4 -4
  18. package/dist/components/data-vis/table/Table.svelte +145 -95
  19. package/dist/components/data-vis/table/Table.svelte.d.ts +4 -4
  20. package/dist/components/layout/Footer.svelte +9 -0
  21. package/dist/components/layout/Footer.svelte.d.ts +1 -0
  22. package/dist/components/layout/PhaseBanner.svelte +10 -1
  23. package/dist/components/layout/PhaseBanner.svelte.d.ts +1 -0
  24. package/dist/components/layout/ServiceNavigation.svelte +19 -1
  25. package/dist/components/layout/ServiceNavigation.svelte.d.ts +2 -0
  26. package/dist/components/ui/Accordion.svelte +212 -66
  27. package/dist/components/ui/Accordion.svelte.d.ts +2 -0
  28. package/dist/components/ui/BasicMultiSelect.svelte +716 -0
  29. package/dist/components/ui/BasicMultiSelect.svelte.d.ts +18 -0
  30. package/dist/components/ui/Button.svelte +220 -104
  31. package/dist/components/ui/Button.svelte.d.ts +4 -0
  32. package/dist/components/ui/Card.svelte +48 -60
  33. package/dist/components/ui/Card.svelte.d.ts +26 -12
  34. package/dist/components/ui/CardHeader.svelte +46 -0
  35. package/dist/components/ui/CardHeader.svelte.d.ts +21 -0
  36. package/dist/components/ui/ChartExporter.svelte +142 -0
  37. package/dist/components/ui/ChartExporter.svelte.d.ts +16 -0
  38. package/dist/components/ui/CheckBox.svelte +1 -0
  39. package/dist/components/ui/Details.svelte +47 -8
  40. package/dist/components/ui/Details.svelte.d.ts +8 -10
  41. package/dist/components/ui/Masthead.svelte +44 -6
  42. package/dist/components/ui/Masthead.svelte.d.ts +6 -0
  43. package/dist/components/ui/RelatedContent.svelte +4 -1
  44. package/dist/components/ui/RelatedContent.svelte.d.ts +1 -0
  45. package/dist/components/ui/SearchAutocomplete.svelte +69 -44
  46. package/dist/components/ui/SearchAutocomplete.svelte.d.ts +1 -0
  47. package/dist/components/ui/Select.svelte +18 -7
  48. package/dist/components/ui/Tabs.svelte +192 -18
  49. package/dist/components/ui/Tabs.svelte.d.ts +1 -0
  50. package/dist/index.d.ts +5 -0
  51. package/dist/index.js +5 -0
  52. package/package.json +4 -1
@@ -225,20 +225,31 @@
225
225
 
226
226
  <style>
227
227
  .select-row {
228
- display: grid;
229
- grid-template-columns: 1fr auto;
230
- align-items: stretch;
231
- -moz-column-gap: 0;
232
- column-gap: 0;
228
+ display: flex;
229
+ flex-wrap: wrap;
230
+ align-items: flex-end;
231
+ gap: 0.5rem;
232
+ width: 100%;
233
233
  }
234
234
 
235
235
  .select-cell {
236
+ flex: 0 1 auto;
236
237
  min-width: 0;
238
+ max-width: 100%;
237
239
  }
238
240
 
239
241
  .select-addon {
240
242
  display: flex;
241
- align-items: stretch; /* match .choices container height */
242
- max-height: 46px;
243
+ align-items: stretch;
244
+ flex: 0 0 auto;
245
+ }
246
+
247
+ .govuk-select {
248
+ max-width: 100%;
249
+ min-width: 0;
250
+ padding-right: 2rem;
251
+ overflow: hidden;
252
+ white-space: nowrap;
253
+ text-overflow: ellipsis;
243
254
  }
244
255
  </style>
@@ -19,12 +19,14 @@
19
19
  idPrefix = "tab",
20
20
  selectedTabId = $bindable(),
21
21
  autoAddHeadings = true,
22
+ forceTabBehavior = false,
22
23
  } = $props<{
23
24
  title?: string;
24
25
  tabs: TabItem[];
25
26
  idPrefix?: string;
26
27
  selectedTabId?: string | null;
27
28
  autoAddHeadings?: boolean;
29
+ forceTabBehavior?: boolean;
28
30
  }>();
29
31
 
30
32
  // Component state variables
@@ -32,6 +34,9 @@
32
34
  let isSupported = $state(false);
33
35
  let isMobile = $state(false);
34
36
 
37
+ // Derived value: use mobile behavior only if isMobile is true AND forceTabBehavior is false
38
+ let useMobileBehavior = $derived(isMobile && !forceTabBehavior);
39
+
35
40
  // DOM element references for programmatic focus
36
41
  let tabElements: { [key: string]: HTMLAnchorElement } = {};
37
42
 
@@ -56,7 +61,7 @@
56
61
  }
57
62
 
58
63
  // Update URL hash on non-mobile views
59
- if (!isMobile) {
64
+ if (!useMobileBehavior) {
60
65
  // Use history.replaceState to update the displayed URL hash without causing scroll/navigation.
61
66
  const currentUrl = window.location.href;
62
67
  const hashIndex = currentUrl.indexOf("#");
@@ -67,10 +72,12 @@
67
72
  }
68
73
  }
69
74
 
75
+ //$inspect(isSupported, "isSupported");
76
+
70
77
  // Handle keyboard navigation
71
78
  function handleKeydown(event: KeyboardEvent, currentIndex: number): void {
72
79
  // Skip navigation on mobile or if component isn't ready
73
- if (isMobile || !isSupported || !isInitialized) return;
80
+ if (useMobileBehavior || !isSupported || !isInitialized) return;
74
81
 
75
82
  // Initialize to null, indicating no valid navigation key pressed yet.
76
83
  // Will be updated to a valid index (0+) if ArrowLeft/Right is pressed.
@@ -107,7 +114,7 @@
107
114
  // Handle tab click
108
115
  function handleTabClick(event: MouseEvent, tabId: string): void {
109
116
  // On mobile or without JS support, let default browser behavior happen
110
- if (isMobile || !isSupported) return;
117
+ if (useMobileBehavior || !isSupported) return;
111
118
  event.preventDefault();
112
119
  selectTab(tabId);
113
120
  }
@@ -115,7 +122,7 @@
115
122
  // Handle hash change
116
123
  function handleHashChange(): void {
117
124
  // Skip on mobile or when not properly initialized
118
- if (isMobile || !isSupported || !isInitialized) return;
125
+ if (useMobileBehavior || !isSupported || !isInitialized) return;
119
126
 
120
127
  const hash = window.location.hash.substring(1);
121
128
  if (hash && tabs.some((tab) => tab.id === hash)) {
@@ -225,32 +232,45 @@
225
232
  });
226
233
  </script>
227
234
 
228
- <div class="govuk-tabs" data-module="govuk-tabs">
235
+ <div
236
+ class="govuk-tabs"
237
+ data-module="govuk-tabs"
238
+ data-force-desktop={forceTabBehavior || null}
239
+ >
229
240
  <h2 class="govuk-tabs__title">
230
241
  {title}
231
242
  </h2>
232
243
 
233
244
  <ul
234
245
  class="govuk-tabs__list"
235
- role={isSupported && !isMobile ? "tablist" : null}
246
+ role={isSupported && !useMobileBehavior ? "tablist" : null}
236
247
  >
237
248
  {#each tabs as tab, index}
238
249
  {@const isSelected = selectedTabId === tab.id}
239
250
  {#key tab.id}
240
251
  <li
241
252
  class="govuk-tabs__list-item"
242
- class:govuk-tabs__list-item--selected={isSelected && !isMobile}
243
- role={isSupported && !isMobile ? "presentation" : null}
253
+ class:govuk-tabs__list-item--selected={isSelected &&
254
+ !useMobileBehavior}
255
+ role={isSupported && !useMobileBehavior ? "presentation" : null}
244
256
  >
245
257
  <!-- svelte-ignore binding_property_non_reactive -->
246
258
  <a
247
259
  class="govuk-tabs__tab"
248
260
  href={"#" + tab.id}
249
- id={isSupported && !isMobile ? `${idPrefix}_${tab.id}` : null}
250
- role={isSupported && !isMobile ? "tab" : null}
251
- aria-controls={isSupported && !isMobile ? tab.id : null}
252
- aria-selected={isSupported && !isMobile ? isSelected : null}
253
- tabindex={isSupported && !isMobile ? (isSelected ? 0 : -1) : null}
261
+ id={isSupported && !useMobileBehavior
262
+ ? `${idPrefix}_${tab.id}`
263
+ : null}
264
+ role={isSupported && !useMobileBehavior ? "tab" : null}
265
+ aria-controls={isSupported && !useMobileBehavior ? tab.id : null}
266
+ aria-selected={isSupported && !useMobileBehavior
267
+ ? isSelected
268
+ : null}
269
+ tabindex={isSupported && !useMobileBehavior
270
+ ? isSelected
271
+ ? 0
272
+ : -1
273
+ : null}
254
274
  onclick={(e) => handleTabClick(e, tab.id)}
255
275
  onkeydown={(e) => handleKeydown(e, index)}
256
276
  bind:this={tabElements[tab.id]}
@@ -266,13 +286,15 @@
266
286
  {@const isSelected = selectedTabId === tab.id}
267
287
  <div
268
288
  class="govuk-tabs__panel"
269
- class:govuk-tabs__panel--hidden={!isSelected && isSupported && !isMobile}
289
+ class:govuk-tabs__panel--hidden={!isSelected &&
290
+ isSupported &&
291
+ !useMobileBehavior}
270
292
  id={tab.id}
271
- role={isSupported && !isMobile ? "tabpanel" : null}
272
- aria-labelledby={isSupported && !isMobile
293
+ role={isSupported && !useMobileBehavior ? "tabpanel" : null}
294
+ aria-labelledby={isSupported && !useMobileBehavior
273
295
  ? `${idPrefix}_${tab.id}`
274
296
  : null}
275
- hidden={!isSelected && isSupported && !isMobile}
297
+ hidden={!isSelected && isSupported && !useMobileBehavior}
276
298
  >
277
299
  {#if autoAddHeadings}
278
300
  <h2 class="govuk-heading-l">{tab.label}</h2>
@@ -287,7 +309,8 @@
287
309
  {:else if tab.content satisfies Snippet}
288
310
  {@render tab.content()}
289
311
  {:else if tab.content}
290
- <svelte:component this={tab.content} />
312
+ {@const Component = tab.content}
313
+ <Component />
291
314
  {/if}
292
315
  </div>
293
316
  {/each}
@@ -303,4 +326,155 @@
303
326
  .govuk-tabs__panel--hidden {
304
327
  display: none;
305
328
  }
329
+
330
+ /*
331
+ * Force desktop tab appearance when forceTabBehavior is enabled
332
+ * These styles are copied verbatim from GOV.UK Frontend's desktop (40.0625em+) styles
333
+ * but applied at mobile breakpoints when data-force-desktop attribute is present
334
+ */
335
+ @media (max-width: 40.0624em) {
336
+ :global(.govuk-frontend-supported)
337
+ .govuk-tabs[data-force-desktop]
338
+ .govuk-tabs__list {
339
+ margin-bottom: 0;
340
+ border-bottom: 1px solid #b1b4b6;
341
+ }
342
+
343
+ :global(.govuk-frontend-supported)
344
+ .govuk-tabs[data-force-desktop]
345
+ .govuk-tabs__list:after {
346
+ content: "";
347
+ display: block;
348
+ clear: both;
349
+ }
350
+
351
+ :global(.govuk-frontend-supported)
352
+ .govuk-tabs[data-force-desktop]
353
+ .govuk-tabs__title {
354
+ display: none;
355
+ }
356
+
357
+ :global(.govuk-frontend-supported)
358
+ .govuk-tabs[data-force-desktop]
359
+ .govuk-tabs__list-item {
360
+ position: relative;
361
+ margin-right: 5px;
362
+ margin-bottom: 0;
363
+ margin-left: 0;
364
+ padding: 10px 20px;
365
+ float: left;
366
+ background-color: #f3f2f1;
367
+ text-align: center;
368
+ }
369
+
370
+ :global(.govuk-frontend-supported)
371
+ .govuk-tabs[data-force-desktop]
372
+ .govuk-tabs__list-item:before {
373
+ content: none;
374
+ }
375
+
376
+ :global(.govuk-frontend-supported)
377
+ .govuk-tabs[data-force-desktop]
378
+ .govuk-tabs__list-item--selected {
379
+ position: relative;
380
+ margin-top: -5px;
381
+ margin-bottom: -1px;
382
+ padding: 14px 19px 16px;
383
+ border: 1px solid #b1b4b6;
384
+ border-bottom: 0;
385
+ background-color: #fff;
386
+ }
387
+
388
+ :global(.govuk-frontend-supported)
389
+ .govuk-tabs[data-force-desktop]
390
+ .govuk-tabs__list-item--selected
391
+ .govuk-tabs__tab {
392
+ text-decoration: none;
393
+ }
394
+
395
+ :global(.govuk-frontend-supported)
396
+ .govuk-tabs[data-force-desktop]
397
+ .govuk-tabs__tab {
398
+ margin-bottom: 0;
399
+ }
400
+
401
+ :global(.govuk-frontend-supported)
402
+ .govuk-tabs[data-force-desktop]
403
+ .govuk-tabs__tab:link,
404
+ :global(.govuk-frontend-supported)
405
+ .govuk-tabs[data-force-desktop]
406
+ .govuk-tabs__tab:visited {
407
+ color: #0b0c0c;
408
+ }
409
+
410
+ @media print {
411
+ :global(.govuk-frontend-supported)
412
+ .govuk-tabs[data-force-desktop]
413
+ .govuk-tabs__tab:link,
414
+ :global(.govuk-frontend-supported)
415
+ .govuk-tabs[data-force-desktop]
416
+ .govuk-tabs__tab:visited {
417
+ color: #000;
418
+ }
419
+ }
420
+
421
+ :global(.govuk-frontend-supported)
422
+ .govuk-tabs[data-force-desktop]
423
+ .govuk-tabs__tab:hover {
424
+ color: rgba(11, 12, 12, 0.99);
425
+ }
426
+
427
+ :global(.govuk-frontend-supported)
428
+ .govuk-tabs[data-force-desktop]
429
+ .govuk-tabs__tab:active,
430
+ :global(.govuk-frontend-supported)
431
+ .govuk-tabs[data-force-desktop]
432
+ .govuk-tabs__tab:focus {
433
+ color: #0b0c0c;
434
+ }
435
+
436
+ @media print {
437
+ :global(.govuk-frontend-supported)
438
+ .govuk-tabs[data-force-desktop]
439
+ .govuk-tabs__tab:active,
440
+ :global(.govuk-frontend-supported)
441
+ .govuk-tabs[data-force-desktop]
442
+ .govuk-tabs__tab:focus {
443
+ color: #000;
444
+ }
445
+ }
446
+
447
+ :global(.govuk-frontend-supported)
448
+ .govuk-tabs[data-force-desktop]
449
+ .govuk-tabs__tab:after {
450
+ content: "";
451
+ position: absolute;
452
+ top: 0;
453
+ right: 0;
454
+ bottom: 0;
455
+ left: 0;
456
+ }
457
+
458
+ :global(.govuk-frontend-supported)
459
+ .govuk-tabs[data-force-desktop]
460
+ .govuk-tabs__panel {
461
+ margin-bottom: 0;
462
+ padding: 30px 20px;
463
+ border: 1px solid #b1b4b6;
464
+ border-top: 0;
465
+ }
466
+
467
+ :global(.govuk-frontend-supported)
468
+ .govuk-tabs[data-force-desktop]
469
+ .govuk-tabs__panel
470
+ > :last-child {
471
+ margin-bottom: 0;
472
+ }
473
+
474
+ :global(.govuk-frontend-supported)
475
+ .govuk-tabs[data-force-desktop]
476
+ .govuk-tabs__panel--hidden {
477
+ display: none;
478
+ }
479
+ }
306
480
  </style>
@@ -12,6 +12,7 @@ type $$ComponentProps = {
12
12
  idPrefix?: string;
13
13
  selectedTabId?: string | null;
14
14
  autoAddHeadings?: boolean;
15
+ forceTabBehavior?: boolean;
15
16
  };
16
17
  declare const Tabs: import("svelte").Component<$$ComponentProps, {}, "selectedTabId">;
17
18
  type Tabs = ReturnType<typeof Tabs>;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import "./main.css";
2
2
  export { default as InsetText } from './components/content/InsetText.svelte';
3
+ export { default as Tag } from './components/content/Tag.svelte';
3
4
  export { default as WarningText } from './components/content/WarningText.svelte';
5
+ export { default as Histogram } from './components/data-vis/Histogram.svelte';
4
6
  export { default as Axis } from './components/data-vis/axis/Axis.svelte';
5
7
  export { default as Ticks } from './components/data-vis/axis/Ticks.svelte';
6
8
  export { default as Line } from './components/data-vis/line-chart/Line.svelte';
@@ -28,8 +30,11 @@ export { default as MobileNav } from './components/layout/service-navigation-nes
28
30
  export { default as ServiceNavigationNestedMobile } from './components/layout/service-navigation-nested-mobile/ServiceNavigationNestedMobile.svelte';
29
31
  export { default as SideNav } from './components/layout/service-navigation-nested-mobile/SideNav.svelte';
30
32
  export { default as Accordion } from './components/ui/Accordion.svelte';
33
+ export { default as BasicMultiSelect } from './components/ui/BasicMultiSelect.svelte';
31
34
  export { default as Button } from './components/ui/Button.svelte';
32
35
  export { default as Card } from './components/ui/Card.svelte';
36
+ export { default as CardHeader } from './components/ui/CardHeader.svelte';
37
+ export { default as ChartExporter } from './components/ui/ChartExporter.svelte';
33
38
  export { default as CheckBox } from './components/ui/CheckBox.svelte';
34
39
  export { default as ContentsList } from './components/ui/ContentsList.svelte';
35
40
  export { default as CookieBanner } from './components/ui/CookieBanner.svelte';
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  // this file is auto-generated — do not edit by hand
2
2
  import "./main.css";
3
3
  export { default as InsetText } from './components/content/InsetText.svelte';
4
+ export { default as Tag } from './components/content/Tag.svelte';
4
5
  export { default as WarningText } from './components/content/WarningText.svelte';
6
+ export { default as Histogram } from './components/data-vis/Histogram.svelte';
5
7
  export { default as Axis } from './components/data-vis/axis/Axis.svelte';
6
8
  export { default as Ticks } from './components/data-vis/axis/Ticks.svelte';
7
9
  export { default as Line } from './components/data-vis/line-chart/Line.svelte';
@@ -29,8 +31,11 @@ export { default as MobileNav } from './components/layout/service-navigation-nes
29
31
  export { default as ServiceNavigationNestedMobile } from './components/layout/service-navigation-nested-mobile/ServiceNavigationNestedMobile.svelte';
30
32
  export { default as SideNav } from './components/layout/service-navigation-nested-mobile/SideNav.svelte';
31
33
  export { default as Accordion } from './components/ui/Accordion.svelte';
34
+ export { default as BasicMultiSelect } from './components/ui/BasicMultiSelect.svelte';
32
35
  export { default as Button } from './components/ui/Button.svelte';
33
36
  export { default as Card } from './components/ui/Card.svelte';
37
+ export { default as CardHeader } from './components/ui/CardHeader.svelte';
38
+ export { default as ChartExporter } from './components/ui/ChartExporter.svelte';
34
39
  export { default as CheckBox } from './components/ui/CheckBox.svelte';
35
40
  export { default as ContentsList } from './components/ui/ContentsList.svelte';
36
41
  export { default as CookieBanner } from './components/ui/CookieBanner.svelte';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@communitiesuk/svelte-component-library",
3
- "version": "0.1.19-beta.3",
3
+ "version": "0.1.19-beta.34",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/communitiesuk/mhclg_svelte_component_library.git"
@@ -101,13 +101,16 @@
101
101
  "@types/dompurify": "^3.0.5",
102
102
  "accessible-autocomplete": "^3.0.1",
103
103
  "choices.js": "^11.1.0",
104
+ "chroma-js": "^3.2.0",
104
105
  "csv-parser": "^3.0.0",
105
106
  "d3": "^7.9.0",
107
+ "d3-array": "^3.2.4",
106
108
  "decimal.js": "^10.5.0",
107
109
  "dompurify": "^3.2.5",
108
110
  "flowbite-svelte-icons": "^2.0.3",
109
111
  "gh-pages": "^6.3.0",
110
112
  "govuk-frontend": "^5.11.1",
113
+ "html-to-image": "^1.11.13",
111
114
  "labelplacer": "^0.0.0",
112
115
  "leaflet": "^1.9.4",
113
116
  "mapbox-gl": "^1.13.3",