nsw-design-system 3.22.6 → 3.22.7

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.
@@ -48,6 +48,7 @@ declare class Carousel extends SwipeContent {
48
48
  flexSupported: boolean;
49
49
  transitionSupported: boolean;
50
50
  cssPropertiesSupported: boolean;
51
+ uid: string | undefined;
51
52
  initCarouselLayout(): void;
52
53
  carouselCreateContainer(): void;
53
54
  setItemsWidth(bool: any): void;
@@ -15,6 +15,7 @@ declare class ColorSwatches {
15
15
  init(): void;
16
16
  paletteSelect: any;
17
17
  createPaletteSelector(): any;
18
+ paletteLabel: HTMLLabelElement | undefined;
18
19
  createColorSwatches(): HTMLUListElement;
19
20
  addEventListeners(): void;
20
21
  updateSelectedSwatch(selectedSwatch: any): void;
package/dist/js/main.js CHANGED
@@ -555,6 +555,13 @@
555
555
  }
556
556
  init() {
557
557
  if (!this.items) return;
558
+ if (!this.uid) {
559
+ if (this.element && this.element.id && !document.getElementById(`${this.element.id}__list`)) {
560
+ this.uid = `${this.element.id}__list`;
561
+ } else {
562
+ this.uid = uniqueId('nsw-carousel__list');
563
+ }
564
+ }
558
565
  this.initCarouselLayout();
559
566
  this.setItemsWidth(true);
560
567
  this.insertBefore(this.visibItemsNb);
@@ -574,6 +581,11 @@
574
581
  element.setAttribute('aria-label', `${index + 1} of ${itemsArray.length}`);
575
582
  element.setAttribute('data-index', index);
576
583
  });
584
+
585
+ // Ensure the list element has a unique id for a11y bindings
586
+ if (this.list && !this.list.id) {
587
+ this.list.id = this.uid;
588
+ }
577
589
  this.carouselCreateContainer();
578
590
  const itemStyle = this.items && window.getComputedStyle(this.items[0]);
579
591
  const containerStyle = this.listWrapper && window.getComputedStyle(this.listWrapper);
@@ -636,6 +648,12 @@
636
648
  this.carouselInitNavigationEvents();
637
649
  }
638
650
  if (this.controls.length > 0) {
651
+ // Bind controls to the actual list id to satisfy aria-controls validity
652
+ if (this.list) {
653
+ this.controls.forEach(btn => {
654
+ btn.setAttribute('aria-controls', this.uid);
655
+ });
656
+ }
639
657
  this.controls[0].addEventListener('click', event => {
640
658
  event.preventDefault();
641
659
  this.showPrevItems();
@@ -3042,9 +3060,8 @@
3042
3060
  function getAxisLength(axis) {
3043
3061
  return axis === 'y' ? 'height' : 'width';
3044
3062
  }
3045
- const yAxisSides = /*#__PURE__*/new Set(['top', 'bottom']);
3046
3063
  function getSideAxis(placement) {
3047
- return yAxisSides.has(getSide(placement)) ? 'y' : 'x';
3064
+ return ['top', 'bottom'].includes(getSide(placement)) ? 'y' : 'x';
3048
3065
  }
3049
3066
  function getAlignmentAxis(placement) {
3050
3067
  return getOppositeAxis(getSideAxis(placement));
@@ -3069,19 +3086,19 @@
3069
3086
  function getOppositeAlignmentPlacement(placement) {
3070
3087
  return placement.replace(/start|end/g, alignment => oppositeAlignmentMap[alignment]);
3071
3088
  }
3072
- const lrPlacement = ['left', 'right'];
3073
- const rlPlacement = ['right', 'left'];
3074
- const tbPlacement = ['top', 'bottom'];
3075
- const btPlacement = ['bottom', 'top'];
3076
3089
  function getSideList(side, isStart, rtl) {
3090
+ const lr = ['left', 'right'];
3091
+ const rl = ['right', 'left'];
3092
+ const tb = ['top', 'bottom'];
3093
+ const bt = ['bottom', 'top'];
3077
3094
  switch (side) {
3078
3095
  case 'top':
3079
3096
  case 'bottom':
3080
- if (rtl) return isStart ? rlPlacement : lrPlacement;
3081
- return isStart ? lrPlacement : rlPlacement;
3097
+ if (rtl) return isStart ? rl : lr;
3098
+ return isStart ? lr : rl;
3082
3099
  case 'left':
3083
3100
  case 'right':
3084
- return isStart ? tbPlacement : btPlacement;
3101
+ return isStart ? tb : bt;
3085
3102
  default:
3086
3103
  return [];
3087
3104
  }
@@ -3501,22 +3518,16 @@
3501
3518
  const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;
3502
3519
  const nextPlacement = placements[nextIndex];
3503
3520
  if (nextPlacement) {
3504
- const ignoreCrossAxisOverflow = checkCrossAxis === 'alignment' ? initialSideAxis !== getSideAxis(nextPlacement) : false;
3505
- if (!ignoreCrossAxisOverflow ||
3506
- // We leave the current main axis only if every placement on that axis
3507
- // overflows the main axis.
3508
- overflowsData.every(d => d.overflows[0] > 0 && getSideAxis(d.placement) === initialSideAxis)) {
3509
- // Try next placement and re-run the lifecycle.
3510
- return {
3511
- data: {
3512
- index: nextIndex,
3513
- overflows: overflowsData
3514
- },
3515
- reset: {
3516
- placement: nextPlacement
3517
- }
3518
- };
3519
- }
3521
+ // Try next placement and re-run the lifecycle.
3522
+ return {
3523
+ data: {
3524
+ index: nextIndex,
3525
+ overflows: overflowsData
3526
+ },
3527
+ reset: {
3528
+ placement: nextPlacement
3529
+ }
3530
+ };
3520
3531
  }
3521
3532
 
3522
3533
  // First, find the candidates that fit on the mainAxis side of overflow,
@@ -3562,8 +3573,6 @@
3562
3573
  };
3563
3574
  };
3564
3575
 
3565
- const originSides = /*#__PURE__*/new Set(['left', 'top']);
3566
-
3567
3576
  // For type backwards-compatibility, the `OffsetOptions` type was also
3568
3577
  // Derivable.
3569
3578
 
@@ -3577,7 +3586,7 @@
3577
3586
  const side = getSide(placement);
3578
3587
  const alignment = getAlignment(placement);
3579
3588
  const isVertical = getSideAxis(placement) === 'y';
3580
- const mainAxisMulti = originSides.has(side) ? -1 : 1;
3589
+ const mainAxisMulti = ['left', 'top'].includes(side) ? -1 : 1;
3581
3590
  const crossAxisMulti = rtl && isVertical ? -1 : 1;
3582
3591
  const rawValue = evaluate(options, state);
3583
3592
 
@@ -3777,7 +3786,7 @@
3777
3786
  if (checkCrossAxis) {
3778
3787
  var _middlewareData$offse, _middlewareData$offse2;
3779
3788
  const len = mainAxis === 'y' ? 'width' : 'height';
3780
- const isOriginSide = originSides.has(getSide(placement));
3789
+ const isOriginSide = ['top', 'left'].includes(getSide(placement));
3781
3790
  const limitMin = rects.reference[crossAxis] - rects.floating[len] + (isOriginSide ? ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse[crossAxis]) || 0 : 0) + (isOriginSide ? 0 : computedOffset.crossAxis);
3782
3791
  const limitMax = rects.reference[crossAxis] + rects.reference[len] + (isOriginSide ? 0 : ((_middlewareData$offse2 = middlewareData.offset) == null ? void 0 : _middlewareData$offse2[crossAxis]) || 0) - (isOriginSide ? computedOffset.crossAxis : 0);
3783
3792
  if (crossAxisCoord < limitMin) {
@@ -3838,7 +3847,6 @@
3838
3847
  }
3839
3848
  return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;
3840
3849
  }
3841
- const invalidOverflowDisplayValues = /*#__PURE__*/new Set(['inline', 'contents']);
3842
3850
  function isOverflowElement(element) {
3843
3851
  const {
3844
3852
  overflow,
@@ -3846,32 +3854,27 @@
3846
3854
  overflowY,
3847
3855
  display
3848
3856
  } = getComputedStyle$1(element);
3849
- return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !invalidOverflowDisplayValues.has(display);
3857
+ return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && !['inline', 'contents'].includes(display);
3850
3858
  }
3851
- const tableElements = /*#__PURE__*/new Set(['table', 'td', 'th']);
3852
3859
  function isTableElement(element) {
3853
- return tableElements.has(getNodeName(element));
3860
+ return ['table', 'td', 'th'].includes(getNodeName(element));
3854
3861
  }
3855
- const topLayerSelectors = [':popover-open', ':modal'];
3856
3862
  function isTopLayer(element) {
3857
- return topLayerSelectors.some(selector => {
3863
+ return [':popover-open', ':modal'].some(selector => {
3858
3864
  try {
3859
3865
  return element.matches(selector);
3860
- } catch (_e) {
3866
+ } catch (e) {
3861
3867
  return false;
3862
3868
  }
3863
3869
  });
3864
3870
  }
3865
- const transformProperties = ['transform', 'translate', 'scale', 'rotate', 'perspective'];
3866
- const willChangeValues = ['transform', 'translate', 'scale', 'rotate', 'perspective', 'filter'];
3867
- const containValues = ['paint', 'layout', 'strict', 'content'];
3868
3871
  function isContainingBlock(elementOrCss) {
3869
3872
  const webkit = isWebKit();
3870
3873
  const css = isElement(elementOrCss) ? getComputedStyle$1(elementOrCss) : elementOrCss;
3871
3874
 
3872
3875
  // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
3873
3876
  // https://drafts.csswg.org/css-transforms-2/#individual-transforms
3874
- return transformProperties.some(value => css[value] ? css[value] !== 'none' : false) || (css.containerType ? css.containerType !== 'normal' : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== 'none' : false) || !webkit && (css.filter ? css.filter !== 'none' : false) || willChangeValues.some(value => (css.willChange || '').includes(value)) || containValues.some(value => (css.contain || '').includes(value));
3877
+ return ['transform', 'translate', 'scale', 'rotate', 'perspective'].some(value => css[value] ? css[value] !== 'none' : false) || (css.containerType ? css.containerType !== 'normal' : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== 'none' : false) || !webkit && (css.filter ? css.filter !== 'none' : false) || ['transform', 'translate', 'scale', 'rotate', 'perspective', 'filter'].some(value => (css.willChange || '').includes(value)) || ['paint', 'layout', 'strict', 'content'].some(value => (css.contain || '').includes(value));
3875
3878
  }
3876
3879
  function getContainingBlock(element) {
3877
3880
  let currentNode = getParentNode(element);
@@ -3889,9 +3892,8 @@
3889
3892
  if (typeof CSS === 'undefined' || !CSS.supports) return false;
3890
3893
  return CSS.supports('-webkit-backdrop-filter', 'none');
3891
3894
  }
3892
- const lastTraversableNodeNames = /*#__PURE__*/new Set(['html', 'body', '#document']);
3893
3895
  function isLastTraversableNode(node) {
3894
- return lastTraversableNodeNames.has(getNodeName(node));
3896
+ return ['html', 'body', '#document'].includes(getNodeName(node));
3895
3897
  }
3896
3898
  function getComputedStyle$1(element) {
3897
3899
  return getWindow(element).getComputedStyle(element);
@@ -4196,7 +4198,6 @@
4196
4198
  };
4197
4199
  }
4198
4200
 
4199
- const absoluteOrFixed = /*#__PURE__*/new Set(['absolute', 'fixed']);
4200
4201
  // Returns the inner client rect, subtracting scrollbars if present.
4201
4202
  function getInnerBoundingClientRect(element, strategy) {
4202
4203
  const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');
@@ -4261,7 +4262,7 @@
4261
4262
  if (!currentNodeIsContaining && computedStyle.position === 'fixed') {
4262
4263
  currentContainingBlockComputedStyle = null;
4263
4264
  }
4264
- const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && absoluteOrFixed.has(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
4265
+ const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && ['absolute', 'fixed'].includes(currentContainingBlockComputedStyle.position) || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);
4265
4266
  if (shouldDropCurrentNode) {
4266
4267
  // Drop non-containing blocks.
4267
4268
  result = result.filter(ancestor => ancestor !== currentNode);
@@ -4324,12 +4325,6 @@
4324
4325
  scrollTop: 0
4325
4326
  };
4326
4327
  const offsets = createCoords(0);
4327
-
4328
- // If the <body> scrollbar appears on the left (e.g. RTL systems). Use
4329
- // Firefox with layout.scrollbar.side = 3 in about:config to test this.
4330
- function setLeftRTLScrollbarOffset() {
4331
- offsets.x = getWindowScrollBarX(documentElement);
4332
- }
4333
4328
  if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
4334
4329
  if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {
4335
4330
  scroll = getNodeScroll(offsetParent);
@@ -4339,12 +4334,11 @@
4339
4334
  offsets.x = offsetRect.x + offsetParent.clientLeft;
4340
4335
  offsets.y = offsetRect.y + offsetParent.clientTop;
4341
4336
  } else if (documentElement) {
4342
- setLeftRTLScrollbarOffset();
4337
+ // If the <body> scrollbar appears on the left (e.g. RTL systems). Use
4338
+ // Firefox with layout.scrollbar.side = 3 in about:config to test this.
4339
+ offsets.x = getWindowScrollBarX(documentElement);
4343
4340
  }
4344
4341
  }
4345
- if (isFixed && !isOffsetParentAnElement && documentElement) {
4346
- setLeftRTLScrollbarOffset();
4347
- }
4348
4342
  const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);
4349
4343
  const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;
4350
4344
  const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nsw-design-system",
3
- "version": "3.22.6",
3
+ "version": "3.22.7",
4
4
  "description": "Design system for Digital NSW",
5
5
  "main": "dist/js/main.js",
6
6
  "types": "dist/js/main.d.ts",
@@ -40,7 +40,9 @@
40
40
  "release:patch": "npm run bump:patch && npm run starterkit:build && npm run changelog:build",
41
41
  "release-local:major": "npm run bump:major && redrun starterkit:build surge changelog:build commit git-tag -s && npm publish",
42
42
  "release-local:minor": "npm run bump:minor && redrun starterkit:build surge changelog:build commit git-tag -s && npm publish",
43
- "release-local:patch": "npm run bump:patch && redrun starterkit:build surge changelog:build commit git-tag -s && npm publish"
43
+ "release-local:patch": "npm run bump:patch && redrun starterkit:build surge changelog:build commit git-tag -s && npm publish",
44
+ "test:a11y": "node a11y-test.js",
45
+ "test:a11y-local": "DISABLE_PROXY=true BASE_URL=http://localhost:3000 FULL_SWEEP=true node a11y-test.js"
44
46
  },
45
47
  "keywords": [
46
48
  "design system"
@@ -59,6 +61,7 @@
59
61
  "@rollup/plugin-node-resolve": "^15.0.2",
60
62
  "auto-changelog": "^2.4.0",
61
63
  "autoprefixer": "^9.7.5",
64
+ "axe-core": "^4.10.2",
62
65
  "browser-sync": "^3.0.2",
63
66
  "cssnano": "^6.0.0",
64
67
  "del": "^5.1.0",
@@ -96,6 +99,7 @@
96
99
  "metalsmith-in-place": "^4.4.1",
97
100
  "metalsmith-layouts": "^2.3.1",
98
101
  "metalsmith-register-helpers": "^0.4.1",
102
+ "playwright": "^1.50.0",
99
103
  "postcss-normalize": "^10.0.1",
100
104
  "redrun": "^10.0.2",
101
105
  "rollup": "^3.20.6",
@@ -1,4 +1,5 @@
1
1
  import SwipeContent from './swipe-content'
2
+ import { uniqueId } from '../../global/scripts/helpers/utilities'
2
3
 
3
4
  /* eslint-disable max-len */
4
5
  class Carousel extends SwipeContent {
@@ -59,6 +60,14 @@ class Carousel extends SwipeContent {
59
60
  init() {
60
61
  if (!this.items) return
61
62
 
63
+ if (!this.uid) {
64
+ if (this.element && this.element.id && !document.getElementById(`${this.element.id}__list`)) {
65
+ this.uid = `${this.element.id}__list`
66
+ } else {
67
+ this.uid = uniqueId('nsw-carousel__list')
68
+ }
69
+ }
70
+
62
71
  this.initCarouselLayout()
63
72
  this.setItemsWidth(true)
64
73
  this.insertBefore(this.visibItemsNb)
@@ -81,6 +90,11 @@ class Carousel extends SwipeContent {
81
90
  element.setAttribute('data-index', index)
82
91
  })
83
92
 
93
+ // Ensure the list element has a unique id for a11y bindings
94
+ if (this.list && !this.list.id) {
95
+ this.list.id = this.uid
96
+ }
97
+
84
98
  this.carouselCreateContainer()
85
99
 
86
100
  const itemStyle = this.items && window.getComputedStyle(this.items[0])
@@ -161,6 +175,12 @@ class Carousel extends SwipeContent {
161
175
  }
162
176
 
163
177
  if (this.controls.length > 0) {
178
+ // Bind controls to the actual list id to satisfy aria-controls validity
179
+ if (this.list) {
180
+ this.controls.forEach((btn) => {
181
+ btn.setAttribute('aria-controls', this.uid)
182
+ })
183
+ }
164
184
  this.controls[0].addEventListener('click', (event) => {
165
185
  event.preventDefault()
166
186
  this.showPrevItems()