@primer/view-components 0.35.1-rc.84c8404f → 0.35.2-rc.4013086b

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,7 @@
1
1
  import { IncludeFragmentElement } from '@github/include-fragment-element';
2
2
  import type { AnchorAlignment, AnchorSide } from '@primer/behaviors';
3
+ import type { LiveRegionElement } from '@primer/live-region-element';
4
+ import '@primer/live-region-element';
3
5
  import '@oddbird/popover-polyfill';
4
6
  type SelectVariant = 'none' | 'single' | 'multiple' | null;
5
7
  type SelectedItem = {
@@ -16,11 +18,11 @@ export declare class SelectPanelElement extends HTMLElement {
16
18
  filterInputTextField: HTMLInputElement;
17
19
  remoteInput: HTMLElement;
18
20
  list: HTMLElement;
19
- ariaLiveContainer: HTMLElement;
20
21
  noResults: HTMLElement;
21
22
  fragmentErrorElement: HTMLElement;
22
23
  bannerErrorElement: HTMLElement;
23
24
  bodySpinner: HTMLElement;
25
+ liveRegion: LiveRegionElement;
24
26
  filterFn?: FilterFn;
25
27
  get open(): boolean;
26
28
  get selectVariant(): SelectVariant;
@@ -18,8 +18,8 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
18
18
  var _SelectPanelElement_instances, _SelectPanelElement_dialogIntersectionObserver, _SelectPanelElement_abortController, _SelectPanelElement_originalLabel, _SelectPanelElement_inputName, _SelectPanelElement_selectedItems, _SelectPanelElement_loadingDelayTimeoutId, _SelectPanelElement_loadingAnnouncementTimeoutId, _SelectPanelElement_hasLoadedData, _SelectPanelElement_waitForCondition, _SelectPanelElement_softDisableItems, _SelectPanelElement_updateTabIndices, _SelectPanelElement_potentiallyDisallowActivation, _SelectPanelElement_isAnchorActivationViaSpace, _SelectPanelElement_isActivation, _SelectPanelElement_checkSelectedItems, _SelectPanelElement_addSelectedItem, _SelectPanelElement_removeSelectedItem, _SelectPanelElement_setTextFieldLoadingSpinnerTimer, _SelectPanelElement_handleIncludeFragmentEvent, _SelectPanelElement_toggleIncludeFragmentElements, _SelectPanelElement_handleRemoteInputEvent, _SelectPanelElement_defaultFilterFn, _SelectPanelElement_handleSearchFieldEvent, _SelectPanelElement_updateItemVisibility, _SelectPanelElement_inErrorState, _SelectPanelElement_setErrorState, _SelectPanelElement_clearErrorState, _SelectPanelElement_maybeAnnounce, _SelectPanelElement_fetchStrategy_get, _SelectPanelElement_filterInputTextFieldElement_get, _SelectPanelElement_performFilteringLocally, _SelectPanelElement_handleInvokerActivated, _SelectPanelElement_handleDialogItemActivated, _SelectPanelElement_handleItemActivated, _SelectPanelElement_setDynamicLabel, _SelectPanelElement_updateInput, _SelectPanelElement_firstItem_get, _SelectPanelElement_hideItem, _SelectPanelElement_showItem, _SelectPanelElement_getItemContent;
19
19
  import { getAnchoredPosition } from '@primer/behaviors';
20
20
  import { controller, target } from '@github/catalyst';
21
- import { announceFromElement, announce } from '../aria_live';
22
21
  import { IncludeFragmentElement } from '@github/include-fragment-element';
22
+ import '@primer/live-region-element';
23
23
  import '@oddbird/popover-polyfill';
24
24
  const validSelectors = ['[role="option"]'];
25
25
  const menuItemSelectors = validSelectors.join(',');
@@ -255,10 +255,12 @@ let SelectPanelElement = class SelectPanelElement extends HTMLElement {
255
255
  this.dialog.removeAttribute('data-ready');
256
256
  this.invokerElement?.setAttribute('aria-expanded', 'false');
257
257
  // When we close the dialog, clear the filter input
258
- const fireSearchEvent = this.filterInputTextField.value.length > 0;
259
- this.filterInputTextField.value = '';
260
- if (fireSearchEvent) {
261
- this.filterInputTextField.dispatchEvent(new Event('input'));
258
+ if (this.filterInputTextField) {
259
+ const fireSearchEvent = this.filterInputTextField.value.length > 0;
260
+ this.filterInputTextField.value = '';
261
+ if (fireSearchEvent) {
262
+ this.filterInputTextField.dispatchEvent(new Event('input'));
263
+ }
262
264
  }
263
265
  this.dispatchEvent(new CustomEvent('panelClosed', {
264
266
  detail: { panel: this },
@@ -523,7 +525,7 @@ _SelectPanelElement_setTextFieldLoadingSpinnerTimer = function _SelectPanelEleme
523
525
  if (__classPrivateFieldGet(this, _SelectPanelElement_loadingAnnouncementTimeoutId, "f"))
524
526
  clearTimeout(__classPrivateFieldGet(this, _SelectPanelElement_loadingAnnouncementTimeoutId, "f"));
525
527
  __classPrivateFieldSet(this, _SelectPanelElement_loadingAnnouncementTimeoutId, setTimeout(() => {
526
- announce('Loading', { element: this.ariaLiveContainer });
528
+ this.liveRegion.announce('Loading');
527
529
  }, 2000), "f");
528
530
  __classPrivateFieldSet(this, _SelectPanelElement_loadingDelayTimeoutId, setTimeout(() => {
529
531
  __classPrivateFieldGet(this, _SelectPanelElement_instances, "a", _SelectPanelElement_filterInputTextFieldElement_get)?.showLeadingSpinner();
@@ -549,7 +551,7 @@ _SelectPanelElement_handleIncludeFragmentEvent = function _SelectPanelElement_ha
549
551
  const errorElement = this.fragmentErrorElement;
550
552
  // check if the errorElement is visible in the dom
551
553
  if (errorElement && !errorElement.hasAttribute('hidden')) {
552
- announceFromElement(errorElement, { element: this.ariaLiveContainer, assertive: true });
554
+ this.liveRegion.announceFromElement(errorElement, { politeness: 'assertive' });
553
555
  return;
554
556
  }
555
557
  break;
@@ -736,7 +738,7 @@ _SelectPanelElement_setErrorState = function _SelectPanelElement_setErrorState(t
736
738
  }
737
739
  // check if the errorElement is visible in the dom
738
740
  if (errorElement && !errorElement.hasAttribute('hidden')) {
739
- announceFromElement(errorElement, { element: this.ariaLiveContainer, assertive: true });
741
+ this.liveRegion.announceFromElement(errorElement, { politeness: 'assertive' });
740
742
  return;
741
743
  }
742
744
  };
@@ -746,17 +748,15 @@ _SelectPanelElement_clearErrorState = function _SelectPanelElement_clearErrorSta
746
748
  };
747
749
  _SelectPanelElement_maybeAnnounce = function _SelectPanelElement_maybeAnnounce() {
748
750
  if (this.open && this.list) {
749
- const items = this.items;
751
+ const items = this.visibleItems;
750
752
  if (items.length > 0) {
751
753
  const instructions = 'tab for results';
752
- announce(`${items.length} result${items.length === 1 ? '' : 's'} ${instructions}`, {
753
- element: this.ariaLiveContainer,
754
- });
754
+ this.liveRegion.announce(`${items.length} result${items.length === 1 ? '' : 's'} ${instructions}`);
755
755
  }
756
756
  else {
757
757
  const noResultsEl = this.noResults;
758
758
  if (noResultsEl) {
759
- announceFromElement(noResultsEl, { element: this.ariaLiveContainer });
759
+ this.liveRegion.announceFromElement(noResultsEl);
760
760
  }
761
761
  }
762
762
  }
@@ -974,9 +974,6 @@ __decorate([
974
974
  __decorate([
975
975
  target
976
976
  ], SelectPanelElement.prototype, "list", void 0);
977
- __decorate([
978
- target
979
- ], SelectPanelElement.prototype, "ariaLiveContainer", void 0);
980
977
  __decorate([
981
978
  target
982
979
  ], SelectPanelElement.prototype, "noResults", void 0);
@@ -989,6 +986,9 @@ __decorate([
989
986
  __decorate([
990
987
  target
991
988
  ], SelectPanelElement.prototype, "bodySpinner", void 0);
989
+ __decorate([
990
+ target
991
+ ], SelectPanelElement.prototype, "liveRegion", void 0);
992
992
  SelectPanelElement = __decorate([
993
993
  controller
994
994
  ], SelectPanelElement);
@@ -7,7 +7,6 @@ import './anchored_position';
7
7
  import './dialog_helper';
8
8
  import './focus_group';
9
9
  import './scrollable_region';
10
- import './aria_live';
11
10
  import './shared_events';
12
11
  import './alpha/modal_dialog';
13
12
  import './beta/nav_list';
@@ -7,7 +7,6 @@ import './anchored_position';
7
7
  import './dialog_helper';
8
8
  import './focus_group';
9
9
  import './scrollable_region';
10
- import './aria_live';
11
10
  import './shared_events';
12
11
  import './alpha/modal_dialog';
13
12
  import './beta/nav_list';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primer/view-components",
3
- "version": "0.35.1-rc.84c8404f",
3
+ "version": "0.35.2-rc.4013086b",
4
4
  "description": "ViewComponents for the Primer Design System",
5
5
  "main": "app/assets/javascripts/primer_view_components.js",
6
6
  "module": "app/components/primer/primer.js",
@@ -53,9 +53,13 @@
53
53
  "@github/relative-time-element": "^4.0.0",
54
54
  "@github/remote-input-element": "^0.4.0",
55
55
  "@github/tab-container-element": "^3.1.2",
56
+ "@primer/live-region-element": "^0.7.1",
56
57
  "@oddbird/popover-polyfill": "^0.4.0",
57
58
  "@primer/behaviors": "^1.3.4"
58
59
  },
60
+ "peerDependencies": {
61
+ "@primer/primitives": "9.x || 10.x"
62
+ },
59
63
  "devDependencies": {
60
64
  "@changesets/changelog-github": "^0.5.0",
61
65
  "@changesets/cli": "^2.24.1",
@@ -65,7 +69,6 @@
65
69
  "@github/prettier-config": "0.0.6",
66
70
  "@playwright/test": "^1.35.1",
67
71
  "@primer/css": "21.5.0",
68
- "@primer/primitives": "^9.0.2",
69
72
  "@primer/stylelint-config": "^13.1.1",
70
73
  "@rollup/plugin-node-resolve": "^15.2.3",
71
74
  "@rollup/plugin-typescript": "^8.3.3",
@@ -1,8 +0,0 @@
1
- export declare function announceFromElement(el: HTMLElement, options?: {
2
- assertive?: boolean;
3
- element?: HTMLElement;
4
- }): void;
5
- export declare function announce(message: string, options?: {
6
- assertive?: boolean;
7
- element?: HTMLElement;
8
- }): void;
@@ -1,8 +0,0 @@
1
- export declare function announceFromElement(el: HTMLElement, options?: {
2
- assertive?: boolean;
3
- element?: HTMLElement;
4
- }): void;
5
- export declare function announce(message: string, options?: {
6
- assertive?: boolean;
7
- element?: HTMLElement;
8
- }): void;
@@ -1,38 +0,0 @@
1
- const safeDocument = typeof document === 'undefined' ? undefined : document;
2
- // Announce an element's text to the screen reader.
3
- export function announceFromElement(el, options) {
4
- announce(getTextContent(el), options);
5
- }
6
- // Announce message update to screen reader.
7
- // Note: Use caution when using this function while a dialog is active.
8
- // If the message is updated while the dialog is open, the screen reader may not announce the live region.
9
- export function announce(message, options) {
10
- const { assertive, element } = options ?? {};
11
- setContainerContent(message, assertive, element);
12
- }
13
- // Set aria-live container to message.
14
- function setContainerContent(message, assertive, element) {
15
- const getQuerySelector = () => {
16
- return assertive ? '#js-global-screen-reader-notice-assertive' : '#js-global-screen-reader-notice';
17
- };
18
- const container = element ?? safeDocument?.querySelector(getQuerySelector());
19
- if (!container)
20
- return;
21
- if (container.textContent === message) {
22
- /* This is a hack due to the way the aria live API works.
23
- A screen reader will not read a live region again
24
- if the text is the same. Adding a space character tells
25
- the browser that the live region has updated,
26
- which will cause it to read again, but with no audible difference. */
27
- container.textContent = `${message}\u00A0`;
28
- }
29
- else {
30
- container.textContent = message;
31
- }
32
- }
33
- // Gets the trimmed text content of an element.
34
- function getTextContent(el) {
35
- // innerText does not contain hidden text
36
- /* eslint-disable-next-line github/no-innerText */
37
- return (el.getAttribute('aria-label') || el.innerText || '').trim();
38
- }