From 71ae832aa7d9320039575f6fef2b1daac21e1645 Mon Sep 17 00:00:00 2001 From: Stefan Dietz Date: Wed, 15 Nov 2023 17:16:50 +0100 Subject: [PATCH 1/5] Add initial new ariaCurrent state implementation with ariaCurrentService (still WIP) --- packages/components/src/components.d.ts | 20 +-------- .../src/components/link-button/component.tsx | 1 - .../src/components/link/ariaCurrentService.ts | 27 ++++++++++++ .../src/components/link/component.tsx | 43 +++++-------------- .../components/src/components/link/shadow.tsx | 7 --- .../components/src/components/link/types.ts | 3 +- packages/components/src/index.ts | 1 + .../src/types/props/aria-current.ts | 25 ----------- packages/samples/react/src/App.tsx | 2 + 9 files changed, 43 insertions(+), 86 deletions(-) create mode 100644 packages/components/src/components/link/ariaCurrentService.ts diff --git a/packages/components/src/components.d.ts b/packages/components/src/components.d.ts index 4f8976848e..30d61fa5f5 100644 --- a/packages/components/src/components.d.ts +++ b/packages/components/src/components.d.ts @@ -43,9 +43,9 @@ import { W3CInputValue } from "./types/w3c"; import { InputTextType } from "./types/input/control/text"; import { DownloadPropType } from "./types/props/download"; import { HrefPropType } from "./types/props/href"; -import { AriaCurrentPropType } from "./types/props/aria-current"; import { LinkOnCallbacksPropType } from "./types/props/link-on-callbacks"; import { LinkTargetPropType } from "./types/props/link-target"; +import { AriaCurrentPropType } from "./types/props/aria-current"; import { ListStyleType } from "./components/link-group/types"; import { LinkProps } from "./components/link/types"; import { Bundesamt, Bundesanstalt, Bundesministerium } from "./enums/bund"; @@ -99,9 +99,9 @@ export { W3CInputValue } from "./types/w3c"; export { InputTextType } from "./types/input/control/text"; export { DownloadPropType } from "./types/props/download"; export { HrefPropType } from "./types/props/href"; -export { AriaCurrentPropType } from "./types/props/aria-current"; export { LinkOnCallbacksPropType } from "./types/props/link-on-callbacks"; export { LinkTargetPropType } from "./types/props/link-target"; +export { AriaCurrentPropType } from "./types/props/aria-current"; export { ListStyleType } from "./components/link-group/types"; export { LinkProps } from "./components/link/types"; export { Bundesamt, Bundesanstalt, Bundesministerium } from "./enums/bund"; @@ -1757,10 +1757,6 @@ export namespace Components { * Defines the visible or semantic label of the component (e.g. aria-label, label, headline, caption, summary, etc.). Set to `false` to enable the expert slot. */ "_label"?: LabelWithExpertSlotPropType; - /** - * Listen on an aria-current event with this value. If the value matches the current value and the href is the same as the current url, the aria-current attribute will be set to current value. - */ - "_listenAriaCurrent"?: AriaCurrentPropType; /** * Defines the callback functions for links. */ @@ -1893,10 +1889,6 @@ export namespace Components { * Defines the visible or semantic label of the component (e.g. aria-label, label, headline, caption, summary, etc.). Set to `false` to enable the expert slot. */ "_label"?: LabelWithExpertSlotPropType; - /** - * Listen on an aria-current event with this value. If the value matches the current value and the href is the same as the current url, the aria-current attribute will be set to current value. - */ - "_listenAriaCurrent"?: AriaCurrentPropType; /** * Defines the callback functions for links. */ @@ -4551,10 +4543,6 @@ declare namespace LocalJSX { * Defines the visible or semantic label of the component (e.g. aria-label, label, headline, caption, summary, etc.). Set to `false` to enable the expert slot. */ "_label"?: LabelWithExpertSlotPropType; - /** - * Listen on an aria-current event with this value. If the value matches the current value and the href is the same as the current url, the aria-current attribute will be set to current value. - */ - "_listenAriaCurrent"?: AriaCurrentPropType; /** * Defines the callback functions for links. */ @@ -4687,10 +4675,6 @@ declare namespace LocalJSX { * Defines the visible or semantic label of the component (e.g. aria-label, label, headline, caption, summary, etc.). Set to `false` to enable the expert slot. */ "_label"?: LabelWithExpertSlotPropType; - /** - * Listen on an aria-current event with this value. If the value matches the current value and the href is the same as the current url, the aria-current attribute will be set to current value. - */ - "_listenAriaCurrent"?: AriaCurrentPropType; /** * Defines the callback functions for links. */ diff --git a/packages/components/src/components/link-button/component.tsx b/packages/components/src/components/link-button/component.tsx index 44ac156832..a47ae6c750 100644 --- a/packages/components/src/components/link-button/component.tsx +++ b/packages/components/src/components/link-button/component.tsx @@ -46,7 +46,6 @@ export class KolLinkButton implements Props { _href={this._href} _icons={this._icons} _label={this._label} - _listenAriaCurrent={this._listenAriaCurrent} _on={this._on} _role="button" _tabIndex={this._tabIndex} diff --git a/packages/components/src/components/link/ariaCurrentService.ts b/packages/components/src/components/link/ariaCurrentService.ts new file mode 100644 index 0000000000..403fde1d12 --- /dev/null +++ b/packages/components/src/components/link/ariaCurrentService.ts @@ -0,0 +1,27 @@ +type LocationChangeCallback = (location: string) => void; +export type UnsubscribeFunction = () => void; + +let currentLocation: string | undefined; +const subscribers: Array = []; + +export const setCurrentLocation = (location: string) => { + currentLocation = location; + subscribers.forEach((subscriber) => { + subscriber(location); + }); +}; + +export const onLocationChange = (callback: LocationChangeCallback, eager = true): UnsubscribeFunction => { + if (eager && typeof currentLocation === 'string') { + callback(currentLocation); + } + subscribers.push(callback); + + // unsubscribe function + return () => { + const index = subscribers.indexOf(callback); + if (index >= 0) { + subscribers.splice(index, 1); + } + }; +}; diff --git a/packages/components/src/components/link/component.tsx b/packages/components/src/components/link/component.tsx index 998cbbc55a..7ed65a710b 100644 --- a/packages/components/src/components/link/component.tsx +++ b/packages/components/src/components/link/component.tsx @@ -4,7 +4,6 @@ import { translate } from '../../i18n'; import { Stringified } from '../../types/common'; import { KoliBriIconsProp } from '../../types/icons'; import { AlternativeButtonLinkRolePropType, validateAlternativeButtonLinkRole } from '../../types/props/alternative-button-link-role'; -import { AriaCurrentPropType, validateAriaCurrent, validateListenAriaCurrent } from '../../types/props/aria-current'; import { DownloadPropType, validateDownload } from '../../types/props/download'; import { HrefPropType, validateHref } from '../../types/props/href'; import { validateIcons } from '../../types/props/icons'; @@ -12,14 +11,15 @@ import { LabelWithExpertSlotPropType, validateLabelWithExpertSlot } from '../../ import { LinkOnCallbacksPropType, validateLinkCallbacks } from '../../types/props/link-on-callbacks'; import { LinkTargetPropType, validateLinkTarget } from '../../types/props/link-target'; import { TooltipAlignPropType, validateTooltipAlign } from '../../types/props/tooltip-align'; -import { devHint, devWarning } from '../../utils/a11y.tipps'; -import { ariaCurrentSubject, setEventTarget, watchString } from '../../utils/prop.validators'; +import { devHint } from '../../utils/a11y.tipps'; +import { setEventTarget, watchString } from '../../utils/prop.validators'; import { propagateFocus, showExpertSlot } from '../../utils/reuse'; import { validateTabIndex } from '../../utils/validators/tab-index'; import { States as LinkStates } from '../link/types'; import { API } from './types'; import { validateHideLabel } from '../../types/props/hide-label'; import { AccessKeyPropType, validateAccessKey } from '../../types/props/access-key'; +import { onLocationChange, UnsubscribeFunction } from './ariaCurrentService'; /** * @internal @@ -31,6 +31,7 @@ import { AccessKeyPropType, validateAccessKey } from '../../types/props/access-k export class KolLinkWc implements API { @Element() private readonly host?: HTMLKolLinkWcElement; private ref?: HTMLAnchorElement; + private unsubscribeOnLocationChange?: UnsubscribeFunction; private readonly catchRef = (ref?: HTMLAnchorElement) => { this.ref = ref; @@ -160,11 +161,6 @@ export class KolLinkWc implements API { */ @Prop() public _label?: LabelWithExpertSlotPropType; - /** - * Listen on an aria-current event with this value. If the value matches the current value and the href is the same as the current url, the aria-current attribute will be set to current value. - */ - @Prop() public _listenAriaCurrent?: AriaCurrentPropType; - /** * Defines the callback functions for links. */ @@ -205,10 +201,6 @@ export class KolLinkWc implements API { validateAccessKey(this, value); } - private validateAriaCurrent(value?: AriaCurrentPropType): void { - validateAriaCurrent(this, value); - } - @Watch('_download') public validateDownload(value?: DownloadPropType): void { validateDownload(this, value); @@ -234,11 +226,6 @@ export class KolLinkWc implements API { validateLabelWithExpertSlot(this, value); } - @Watch('_listenAriaCurrent') - public validateListenAriaCurrent(value?: AriaCurrentPropType): void { - validateListenAriaCurrent(this, value); - } - @Watch('_on') public validateOn(value?: LinkOnCallbacksPropType): void { validateLinkCallbacks(this, value); @@ -276,30 +263,20 @@ export class KolLinkWc implements API { this.validateHref(this._href); this.validateIcons(this._icons); this.validateLabel(this._label); - this.validateListenAriaCurrent(this._listenAriaCurrent); this.validateOn(this._on); this.validateRole(this._role); this.validateTabIndex(this._tabIndex); this.validateTarget(this._target); this.validateTargetDescription(this._targetDescription); this.validateTooltipAlign(this._tooltipAlign); + this.unsubscribeOnLocationChange = onLocationChange((location) => { + this.state._ariaCurrent = location === this.state._href ? 'page' : undefined; + }); } - private unsubscribeAriaCurrentSubject = ariaCurrentSubject.subscribe((event) => { - try { - if (this.state._listenAriaCurrent && this.state._listenAriaCurrent === event.ariaCurrent) { - if (this.state._href === event.href) { - this.validateAriaCurrent(event.ariaCurrent); - } else { - this.validateAriaCurrent(false); - } - } - } catch (e) { - devWarning(`The aria-current event is not valid.`); - } - }); - public disconnectedCallback(): void { - this.unsubscribeAriaCurrentSubject.unsubscribe(); + if (this.unsubscribeOnLocationChange) { + this.unsubscribeOnLocationChange(); + } } } diff --git a/packages/components/src/components/link/shadow.tsx b/packages/components/src/components/link/shadow.tsx index b383f1382e..bf10ed2f8e 100644 --- a/packages/components/src/components/link/shadow.tsx +++ b/packages/components/src/components/link/shadow.tsx @@ -3,7 +3,6 @@ import { Component, Element, h, Host, JSX, Prop } from '@stencil/core'; import { Stringified } from '../../types/common'; import { KoliBriIconsProp } from '../../types/icons'; import { AlternativeButtonLinkRolePropType } from '../../types/props/alternative-button-link-role'; -import { AriaCurrentPropType } from '../../types/props/aria-current'; import { DownloadPropType } from '../../types/props/download'; import { HrefPropType } from '../../types/props/href'; import { LabelWithExpertSlotPropType } from '../../types/props/label'; @@ -39,7 +38,6 @@ export class KolLink implements LinkProps { _href={this._href} _icons={this._icons} _label={this._label} - _listenAriaCurrent={this._listenAriaCurrent} _on={this._on} _role={this._role} _tabIndex={this._tabIndex} @@ -89,11 +87,6 @@ export class KolLink implements LinkProps { */ @Prop() public _label?: LabelWithExpertSlotPropType; - /** - * Listen on an aria-current event with this value. If the value matches the current value and the href is the same as the current url, the aria-current attribute will be set to current value. - */ - @Prop() public _listenAriaCurrent?: AriaCurrentPropType; - /** * Defines the callback functions for links. */ diff --git a/packages/components/src/components/link/types.ts b/packages/components/src/components/link/types.ts index 9f032a6a25..c252b044da 100644 --- a/packages/components/src/components/link/types.ts +++ b/packages/components/src/components/link/types.ts @@ -1,6 +1,6 @@ import { Generic } from '@a11y-ui/core'; import { PropAlternativeButtonLinkRole } from '../../types/props/alternative-button-link-role'; -import { PropAriaCurrent, PropListenAriaCurrent } from '../../types/props/aria-current'; +import { PropAriaCurrent } from '../../types/props/aria-current'; import { PropDownload } from '../../types/props/download'; import { PropHref } from '../../types/props/href'; import { PropIcons } from '../../types/props/icons'; @@ -28,7 +28,6 @@ export type OptionalProps = { PropLabelWithExpertSlot & PropLinkOnCallbacks & PropLinkTarget & - PropListenAriaCurrent & PropTooltipAlign; export type LinkProps = Generic.Element.Members; diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index a828b978d7..a0b63ef986 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -1,3 +1,4 @@ +export { setCurrentLocation } from './components/link/ariaCurrentService'; export * from './components.d'; export { register } from './core'; export * from './enums/bund'; diff --git a/packages/components/src/types/props/aria-current.ts b/packages/components/src/types/props/aria-current.ts index 6f23dfc19c..e8e3e8c8fb 100644 --- a/packages/components/src/types/props/aria-current.ts +++ b/packages/components/src/types/props/aria-current.ts @@ -1,7 +1,3 @@ -import { Generic } from '@a11y-ui/core'; - -import { watchValidator } from '../../utils/prop.validators'; - /* types */ /** * Marks the element as the selected in a group of related elements. Can be one of the following: `date` | `location` | `page` | `step` | `time` | `true`. @@ -14,24 +10,3 @@ export type PropAriaCurrent = { // only used for state ariaCurrent: AriaCurrentPropType; }; - -export type PropListenAriaCurrent = { - listenAriaCurrent: AriaCurrentPropType; -}; - -/* validator */ -const validate = (component: Generic.Element.Component, propName: string, value?: AriaCurrentPropType): void => { - watchValidator( - component, - propName, - (value?) => (typeof value === 'string' || typeof value === 'boolean') && ariaCurrentPropTypeOptions.includes(value), - new Set([`String {${ariaCurrentPropTypeOptions.filter((option) => typeof option === 'string').join(', ')}`, 'true', 'false']), - value - ); -}; -export const validateAriaCurrent = (component: Generic.Element.Component, value?: AriaCurrentPropType): void => { - validate(component, '_ariaCurrent', value); -}; -export const validateListenAriaCurrent = (component: Generic.Element.Component, value?: AriaCurrentPropType): void => { - validate(component, '_listenAriaCurrent', value); -}; diff --git a/packages/samples/react/src/App.tsx b/packages/samples/react/src/App.tsx index fed9699379..463ff66938 100644 --- a/packages/samples/react/src/App.tsx +++ b/packages/samples/react/src/App.tsx @@ -11,6 +11,7 @@ import { getTheme, getThemeName, setStorage, setTheme } from './shares/store'; import { Sidebar } from './components/Sidebar'; import { useLocation } from 'react-router'; import { HideMenusContext } from './shares/HideMenusContext'; +import { setCurrentLocation } from '@public-ui/components'; setStorage(localStorage); @@ -107,6 +108,7 @@ export const App: FC = () => { const hideMenus = searchParams.has('hideMenus'); setTheme(theme as Theme); // set for `getTheme` usages within the application + setCurrentLocation('#' + routerLocation.pathname); document.title = `KoliBri-Handout - ${getThemeName(getTheme())} | v${PackageJson.version}`; document.body.setAttribute('class', theme); From a1fa715b1899e80af2dd64a659111638c2b02ad0 Mon Sep 17 00:00:00 2001 From: Stefan Dietz Date: Thu, 16 Nov 2023 10:59:42 +0100 Subject: [PATCH 2/5] Implement ariaCurrentValue prop --- packages/components/src/components.d.ts | 44 +++++++++++-------- .../src/components/link-button/component.tsx | 13 +++--- .../src/components/link/component.tsx | 15 ++++++- .../components/src/components/link/shadow.tsx | 7 +++ .../src/components/link/test/html.mock.ts | 1 + .../components/src/components/link/types.ts | 7 +-- .../src/components/nav/component.tsx | 19 -------- .../components/src/components/nav/types.ts | 3 -- .../src/types/props/aria-current-value.ts | 29 ++++++++++++ .../src/types/props/aria-current.ts | 12 ----- .../components/src/utils/prop.validators.ts | 8 ---- .../react/src/components/link/basic.tsx | 4 +- 12 files changed, 89 insertions(+), 73 deletions(-) create mode 100644 packages/components/src/types/props/aria-current-value.ts delete mode 100644 packages/components/src/types/props/aria-current.ts diff --git a/packages/components/src/components.d.ts b/packages/components/src/components.d.ts index 30d61fa5f5..564d4232a0 100644 --- a/packages/components/src/components.d.ts +++ b/packages/components/src/components.d.ts @@ -41,11 +41,11 @@ import { OptionsPropType, OptionsWithOptgroupPropType } from "./types/props/opti import { Orientation } from "./types/orientation"; import { W3CInputValue } from "./types/w3c"; import { InputTextType } from "./types/input/control/text"; +import { AriaCurrentValuePropType } from "./types/props/aria-current-value"; import { DownloadPropType } from "./types/props/download"; import { HrefPropType } from "./types/props/href"; import { LinkOnCallbacksPropType } from "./types/props/link-on-callbacks"; import { LinkTargetPropType } from "./types/props/link-target"; -import { AriaCurrentPropType } from "./types/props/aria-current"; import { ListStyleType } from "./components/link-group/types"; import { LinkProps } from "./components/link/types"; import { Bundesamt, Bundesanstalt, Bundesministerium } from "./enums/bund"; @@ -97,11 +97,11 @@ export { OptionsPropType, OptionsWithOptgroupPropType } from "./types/props/opti export { Orientation } from "./types/orientation"; export { W3CInputValue } from "./types/w3c"; export { InputTextType } from "./types/input/control/text"; +export { AriaCurrentValuePropType } from "./types/props/aria-current-value"; export { DownloadPropType } from "./types/props/download"; export { HrefPropType } from "./types/props/href"; export { LinkOnCallbacksPropType } from "./types/props/link-on-callbacks"; export { LinkTargetPropType } from "./types/props/link-target"; -export { AriaCurrentPropType } from "./types/props/aria-current"; export { ListStyleType } from "./components/link-group/types"; export { LinkProps } from "./components/link/types"; export { Bundesamt, Bundesanstalt, Bundesministerium } from "./enums/bund"; @@ -1736,6 +1736,10 @@ export namespace Components { * Defines the elements access key. */ "_accessKey"?: AccessKeyPropType; + /** + * Defines the value for the aria-current attribute. + */ + "_ariaCurrentValue"?: AriaCurrentValuePropType; /** * Tells the browser that the link contains a file. Optionally sets the filename. */ @@ -1787,6 +1791,10 @@ export namespace Components { * Defines the elements access key. */ "_accessKey"?: AccessKeyPropType; + /** + * Defines the value for the aria-current attribute. + */ + "_ariaCurrentValue"?: AriaCurrentValuePropType; /** * Defines the custom class attribute if _variant="custom" is set. */ @@ -1812,10 +1820,6 @@ export namespace Components { * Defines the visible or semantic label of the component (e.g. aria-label, label, headline, caption, summary, etc.). Set to `false` to enable the expert slot. */ "_label": LabelWithExpertSlotPropType; - /** - * Listen on an aria-current event with this value. If the value matches the current value and the href is the same as the current url, the aria-current attribute will be set to current value. - */ - "_listenAriaCurrent"?: AriaCurrentPropType; /** * Defines the callback functions for links. */ @@ -1868,6 +1872,10 @@ export namespace Components { * Defines the elements access key. */ "_accessKey"?: AccessKeyPropType; + /** + * Defines the value for the aria-current attribute. + */ + "_ariaCurrentValue"?: AriaCurrentValuePropType; /** * Tells the browser that the link contains a file. Optionally sets the filename. */ @@ -1939,10 +1947,6 @@ export namespace Components { "_width"?: string; } interface KolNav { - /** - * Defines the value of aria-current to be used with the current context within the navigation. - */ - "_ariaCurrentValue": AriaCurrentPropType; /** * Defines if navigation nodes can be collapsed or not. Enabled by default. * @TODO : Change type back to `CollapsiblePropType` after Stencil#4663 has been resolved. @@ -4522,6 +4526,10 @@ declare namespace LocalJSX { * Defines the elements access key. */ "_accessKey"?: AccessKeyPropType; + /** + * Defines the value for the aria-current attribute. + */ + "_ariaCurrentValue"?: AriaCurrentValuePropType; /** * Tells the browser that the link contains a file. Optionally sets the filename. */ @@ -4573,6 +4581,10 @@ declare namespace LocalJSX { * Defines the elements access key. */ "_accessKey"?: AccessKeyPropType; + /** + * Defines the value for the aria-current attribute. + */ + "_ariaCurrentValue"?: AriaCurrentValuePropType; /** * Defines the custom class attribute if _variant="custom" is set. */ @@ -4598,10 +4610,6 @@ declare namespace LocalJSX { * Defines the visible or semantic label of the component (e.g. aria-label, label, headline, caption, summary, etc.). Set to `false` to enable the expert slot. */ "_label": LabelWithExpertSlotPropType; - /** - * Listen on an aria-current event with this value. If the value matches the current value and the href is the same as the current url, the aria-current attribute will be set to current value. - */ - "_listenAriaCurrent"?: AriaCurrentPropType; /** * Defines the callback functions for links. */ @@ -4654,6 +4662,10 @@ declare namespace LocalJSX { * Defines the elements access key. */ "_accessKey"?: AccessKeyPropType; + /** + * Defines the value for the aria-current attribute. + */ + "_ariaCurrentValue"?: AriaCurrentValuePropType; /** * Tells the browser that the link contains a file. Optionally sets the filename. */ @@ -4725,10 +4737,6 @@ declare namespace LocalJSX { "_width"?: string; } interface KolNav { - /** - * Defines the value of aria-current to be used with the current context within the navigation. - */ - "_ariaCurrentValue"?: AriaCurrentPropType; /** * Defines if navigation nodes can be collapsed or not. Enabled by default. * @TODO : Change type back to `CollapsiblePropType` after Stencil#4663 has been resolved. diff --git a/packages/components/src/components/link-button/component.tsx b/packages/components/src/components/link-button/component.tsx index a47ae6c750..79cc47f987 100644 --- a/packages/components/src/components/link-button/component.tsx +++ b/packages/components/src/components/link-button/component.tsx @@ -2,7 +2,6 @@ import { Component, Element, h, Host, JSX, Prop } from '@stencil/core'; import { translate } from '../../i18n'; import { AlternativeButtonLinkRolePropType } from '../../types/props/alternative-button-link-role'; -import { AriaCurrentPropType } from '../../types/props/aria-current'; import { ButtonVariantPropType } from '../../types/props/button-variant'; import { CustomClassPropType } from '../../types/props/custom-class'; import { DownloadPropType } from '../../types/props/download'; @@ -15,6 +14,7 @@ import { TooltipAlignPropType } from '../../types/props/tooltip-align'; import { propagateFocus } from '../../utils/reuse'; import { Props } from './types'; import { AccessKeyPropType } from '../../types/props/access-key'; +import { AriaCurrentValuePropType } from '../../types/props/aria-current-value'; @Component({ tag: 'kol-link-button', @@ -41,6 +41,7 @@ export class KolLinkButton implements Props { [this._customClass as string]: this._variant === 'custom' && typeof this._customClass === 'string' && this._customClass.length > 0, }} _accessKey={this._accessKey} + _ariaCurrentValue={this._ariaCurrentValue} _download={this._download} _hideLabel={this._hideLabel} _href={this._href} @@ -64,6 +65,11 @@ export class KolLinkButton implements Props { */ @Prop() public _accessKey?: AccessKeyPropType; + /** + * Defines the value for the aria-current attribute. + */ + @Prop() public _ariaCurrentValue?: AriaCurrentValuePropType; + /** * Defines the custom class attribute if _variant="custom" is set. */ @@ -96,11 +102,6 @@ export class KolLinkButton implements Props { */ @Prop() public _label!: LabelWithExpertSlotPropType; - /** - * Listen on an aria-current event with this value. If the value matches the current value and the href is the same as the current url, the aria-current attribute will be set to current value. - */ - @Prop() public _listenAriaCurrent?: AriaCurrentPropType; - /** * Defines the callback functions for links. */ diff --git a/packages/components/src/components/link/component.tsx b/packages/components/src/components/link/component.tsx index 7ed65a710b..ddc164cba5 100644 --- a/packages/components/src/components/link/component.tsx +++ b/packages/components/src/components/link/component.tsx @@ -20,6 +20,7 @@ import { API } from './types'; import { validateHideLabel } from '../../types/props/hide-label'; import { AccessKeyPropType, validateAccessKey } from '../../types/props/access-key'; import { onLocationChange, UnsubscribeFunction } from './ariaCurrentService'; +import { AriaCurrentValuePropType, validateAriaCurrentValue } from '../../types/props/aria-current-value'; /** * @internal @@ -134,6 +135,11 @@ export class KolLinkWc implements API { */ @Prop() public _accessKey?: AccessKeyPropType; + /** + * Defines the value for the aria-current attribute. + */ + @Prop() public _ariaCurrentValue?: AriaCurrentValuePropType; + /** * Tells the browser that the link contains a file. Optionally sets the filename. */ @@ -194,6 +200,7 @@ export class KolLinkWc implements API { @State() public state: LinkStates = { _href: '…', // ⚠ required _icons: {}, // ⚠ required + _ariaCurrentValue: 'page', // ⚠ required }; @Watch('_accessKey') @@ -201,6 +208,11 @@ export class KolLinkWc implements API { validateAccessKey(this, value); } + @Watch('_ariaCurrentValue') + public validateAriaCurrentValue(value?: AriaCurrentValuePropType): void { + validateAriaCurrentValue(this, value); + } + @Watch('_download') public validateDownload(value?: DownloadPropType): void { validateDownload(this, value); @@ -258,6 +270,7 @@ export class KolLinkWc implements API { public componentWillLoad(): void { this.validateAccessKey(this._accessKey); + this.validateAriaCurrentValue(this._ariaCurrentValue); this.validateDownload(this._download); this.validateHideLabel(this._hideLabel); this.validateHref(this._href); @@ -270,7 +283,7 @@ export class KolLinkWc implements API { this.validateTargetDescription(this._targetDescription); this.validateTooltipAlign(this._tooltipAlign); this.unsubscribeOnLocationChange = onLocationChange((location) => { - this.state._ariaCurrent = location === this.state._href ? 'page' : undefined; + this.state._ariaCurrent = location === this.state._href ? this.state._ariaCurrentValue : undefined; }); } diff --git a/packages/components/src/components/link/shadow.tsx b/packages/components/src/components/link/shadow.tsx index bf10ed2f8e..b2e5383e77 100644 --- a/packages/components/src/components/link/shadow.tsx +++ b/packages/components/src/components/link/shadow.tsx @@ -12,6 +12,7 @@ import { TooltipAlignPropType } from '../../types/props/tooltip-align'; import { propagateFocus } from '../../utils/reuse'; import { LinkProps } from './types'; import { AccessKeyPropType } from '../../types/props/access-key'; +import { AriaCurrentValuePropType } from '../../types/props/aria-current-value'; @Component({ tag: 'kol-link', @@ -33,6 +34,7 @@ export class KolLink implements LinkProps { { _icons: {}, _tooltipAlign: 'right', _targetDescription: 'Der Link wird in einem neuen Tab geöffnet.', + _ariaCurrentValue: 'page', }, props ); diff --git a/packages/components/src/components/link/types.ts b/packages/components/src/components/link/types.ts index c252b044da..64f397ab99 100644 --- a/packages/components/src/components/link/types.ts +++ b/packages/components/src/components/link/types.ts @@ -1,6 +1,6 @@ import { Generic } from '@a11y-ui/core'; import { PropAlternativeButtonLinkRole } from '../../types/props/alternative-button-link-role'; -import { PropAriaCurrent } from '../../types/props/aria-current'; +import { PropAriaCurrentValue } from '../../types/props/aria-current-value'; import { PropDownload } from '../../types/props/download'; import { PropHref } from '../../types/props/href'; import { PropIcons } from '../../types/props/icons'; @@ -21,6 +21,7 @@ export type OptionalProps = { targetDescription: string; tabIndex: number; } & PropAccessKey & + PropAriaCurrentValue & PropAlternativeButtonLinkRole & PropDownload & PropHideLabel & @@ -31,8 +32,8 @@ export type OptionalProps = { PropTooltipAlign; export type LinkProps = Generic.Element.Members; -type RequiredStates = PropIcons & PropHref; -type OptionalStates = PropAriaCurrent & Omit & PropLabelWithExpertSlot; +type RequiredStates = PropAriaCurrentValue & PropIcons & PropHref; +type OptionalStates = { ariaCurrent: string } & Omit; export type States = Generic.Element.Members; export type API = Generic.Element.ComponentApi; diff --git a/packages/components/src/components/nav/component.tsx b/packages/components/src/components/nav/component.tsx index 03d6710d90..13f5e59a77 100644 --- a/packages/components/src/components/nav/component.tsx +++ b/packages/components/src/components/nav/component.tsx @@ -4,7 +4,6 @@ import { translate } from '../../i18n'; import { ButtonOrLinkOrTextWithChildrenProps, ButtonWithChildrenProps } from '../../types/button-link-text'; import { Stringified } from '../../types/common'; import { Orientation } from '../../types/orientation'; -import { AriaCurrentPropType } from '../../types/props/aria-current'; import { CollapsiblePropType, validateCollapsible } from '../../types/props/collapsible'; import { validateHasCompactButton } from '../../types/props/has-compact-button'; import { HideLabelPropType, validateHideLabel } from '../../types/props/hide-label'; @@ -181,11 +180,6 @@ export class KolNav implements API { ); } - /** - * Defines the value of aria-current to be used with the current context within the navigation. - */ - @Prop() public _ariaCurrentValue: AriaCurrentPropType = false; - /** * Defines if navigation nodes can be collapsed or not. Enabled by default. * @TODO: Change type back to `CollapsiblePropType` after Stencil#4663 has been resolved. @@ -220,7 +214,6 @@ export class KolNav implements API { @Prop() public _orientation?: Orientation = 'vertical'; @State() public state: States = { - _ariaCurrentValue: false, _collapsible: true, _hasCompactButton: false, _hideLabel: false, @@ -229,17 +222,6 @@ export class KolNav implements API { _orientation: 'vertical', }; - @Watch('_ariaCurrentValue') - public validateAriaCurrentValue(value?: AriaCurrentPropType): void { - watchValidator( - this, - '_ariaCurrentValue', - (value) => value === true || value === 'date' || value === 'location' || value === 'page' || value === 'step' || value === 'time', - new Set(['boolean', 'String {data, location, page, step, time}']), - value - ); - } - @Watch('_collapsible') public validateCollapsible(value?: CollapsiblePropType): void { validateCollapsible(this, value); @@ -286,7 +268,6 @@ export class KolNav implements API { } public componentWillLoad(): void { - this.validateAriaCurrentValue(this._ariaCurrentValue); this.validateCollapsible(this._collapsible); this.validateHideLabel(this._hideLabel); this.validateHasCompactButton(this._hasCompactButton); diff --git a/packages/components/src/components/nav/types.ts b/packages/components/src/components/nav/types.ts index 7f5eb91ccc..8a29aa988e 100644 --- a/packages/components/src/components/nav/types.ts +++ b/packages/components/src/components/nav/types.ts @@ -3,7 +3,6 @@ import { Generic } from '@a11y-ui/core'; import { ButtonOrLinkOrTextWithChildrenProps } from '../../types/button-link-text'; import { Stringified } from '../../types/common'; import { Orientation } from '../../types/orientation'; -import { AriaCurrentPropType } from '../../types/props/aria-current'; import { PropCollapsible } from '../../types/props/collapsible'; import { PropHasCompactButton } from '../../types/props/has-compact-button'; import { PropHideLabel } from '../../types/props/hide-label'; @@ -13,7 +12,6 @@ type RequiredProps = { links: Stringified; } & PropLabel; type OptionalProps = { - ariaCurrentValue: AriaCurrentPropType; orientation: Orientation; } & PropCollapsible & PropHasCompactButton & @@ -21,7 +19,6 @@ type OptionalProps = { // type Props = Generic.Element.Members; type RequiredStates = { - ariaCurrentValue: AriaCurrentPropType; links: ButtonOrLinkOrTextWithChildrenProps[]; orientation: Orientation; } & PropCollapsible & diff --git a/packages/components/src/types/props/aria-current-value.ts b/packages/components/src/types/props/aria-current-value.ts new file mode 100644 index 0000000000..eb98f678f7 --- /dev/null +++ b/packages/components/src/types/props/aria-current-value.ts @@ -0,0 +1,29 @@ +/* types */ +import { Generic } from '@a11y-ui/core'; +import { watchValidator } from '../../utils/prop.validators'; + +/** + * Defines the value for the aria-current attribute. + * @see https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current + * @see https://www.aditus.io/aria/aria-current/ + */ +const ariaCurrentValuePropTypeOptions = ['date', 'location', 'page', 'step', 'time', 'true', 'false'] as const; +export type AriaCurrentValuePropType = (typeof ariaCurrentValuePropTypeOptions)[number]; + +export type PropAriaCurrentValue = { + ariaCurrentValue: AriaCurrentValuePropType; +}; + +/* validator */ +export const validateAriaCurrentValue = (component: Generic.Element.Component, value?: AriaCurrentValuePropType): void => { + watchValidator( + component, + `_ariaCurrentValue`, + (value) => typeof value === 'string' && ariaCurrentValuePropTypeOptions.includes(value), + new Set([`AriaCurrentValue {${ariaCurrentValuePropTypeOptions.join(', ')}`]), + value, + { + defaultValue: 'page', + } + ); +}; diff --git a/packages/components/src/types/props/aria-current.ts b/packages/components/src/types/props/aria-current.ts deleted file mode 100644 index e8e3e8c8fb..0000000000 --- a/packages/components/src/types/props/aria-current.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* types */ -/** - * Marks the element as the selected in a group of related elements. Can be one of the following: `date` | `location` | `page` | `step` | `time` | `true`. - * (https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current) - */ -const ariaCurrentPropTypeOptions = ['date', 'location', 'page', 'step', 'time', true, false] as const; -export type AriaCurrentPropType = (typeof ariaCurrentPropTypeOptions)[number]; - -export type PropAriaCurrent = { - // only used for state - ariaCurrent: AriaCurrentPropType; -}; diff --git a/packages/components/src/utils/prop.validators.ts b/packages/components/src/utils/prop.validators.ts index d29580b513..0e6db1989e 100644 --- a/packages/components/src/utils/prop.validators.ts +++ b/packages/components/src/utils/prop.validators.ts @@ -1,14 +1,11 @@ import { querySelectorAll } from 'query-selector-all-shadow-root'; import { querySelector } from 'query-selector-shadow-root'; import rgba from 'rgba-convert'; -import { Subject } from 'rxjs'; import { hex, score } from 'wcag-contrast'; import { Generic, patchTheme, patchThemeTag } from '@a11y-ui/core'; import { Stringified } from '../types/common'; -import { AriaCurrentPropType } from '../types/props/aria-current'; -import { PropHref } from '../types/props/href'; import { StencilUnknown } from '../types/unknown'; import { devHint } from './a11y.tipps'; import { getDocument, getExperimentalMode, Log } from './dev.utils'; @@ -479,11 +476,6 @@ export class KoliBriUtils { } } -type AriaCurrentEventType = { - ariaCurrent: AriaCurrentPropType; -} & PropHref; -export const ariaCurrentSubject = new Subject(); - export class KoliBriDevHelper { public static readonly patchTheme = patchTheme; public static readonly patchThemeTag = patchThemeTag; diff --git a/packages/samples/react/src/components/link/basic.tsx b/packages/samples/react/src/components/link/basic.tsx index 0b1b49f1cb..412b4d2fba 100644 --- a/packages/samples/react/src/components/link/basic.tsx +++ b/packages/samples/react/src/components/link/basic.tsx @@ -1,8 +1,6 @@ -import React from 'react'; +import React, { FC } from 'react'; import { KolLink } from '@public-ui/react'; -import { FC } from 'react'; - export const LinkBasic: FC = () => (
From f672f58714031ddb71fcae6779f90ec2a890c7eb Mon Sep 17 00:00:00 2001 From: Stefan Dietz Date: Thu, 16 Nov 2023 11:18:07 +0100 Subject: [PATCH 3/5] Remove rxjs dependency --- packages/components/package.json | 1 - pnpm-lock.yaml | 120 ++++++++++++++++--------------- 2 files changed, 64 insertions(+), 57 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 8ac3b2cdd0..22a00d72a1 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -116,7 +116,6 @@ "query-selector-shadow-root": "0.0.3", "rgba-convert": "0.3.0", "rimraf": "3.0.2", - "rxjs": "7.8.1", "stencil-awesome-test": "1.0.6", "terser": "5.24.0", "tslib": "2.6.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a694f1e184..776ad048c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -589,10 +589,10 @@ importers: version: 7.33.2(eslint@8.53.0) jest: specifier: 26.6.3 - version: 26.6.3(ts-node@10.9.1) + version: 26.6.3 jest-cli: specifier: 26.6.3 - version: 26.6.3(ts-node@10.9.1) + version: 26.6.3 lighthouse: specifier: 11.3.0 version: 11.3.0 @@ -623,9 +623,6 @@ importers: rimraf: specifier: 3.0.2 version: 3.0.2 - rxjs: - specifier: 7.8.1 - version: 7.8.1 stencil-awesome-test: specifier: 1.0.6 version: 1.0.6(@stencil/core@4.7.1) @@ -1832,7 +1829,7 @@ packages: '@babel/traverse': 7.22.11 '@babel/types': 7.23.0 convert-source-map: 1.9.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -1901,7 +1898,7 @@ packages: '@babel/traverse': 7.23.2 '@babel/types': 7.23.0 convert-source-map: 2.0.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -2084,7 +2081,7 @@ packages: '@babel/core': 7.22.11 '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 lodash.debounce: 4.0.8 resolve: 1.22.6 transitivePeerDependencies: @@ -5177,7 +5174,7 @@ packages: '@babel/helper-split-export-declaration': 7.22.6 '@babel/parser': 7.23.0 '@babel/types': 7.23.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -5195,7 +5192,7 @@ packages: '@babel/helper-split-export-declaration': 7.22.6 '@babel/parser': 7.23.0 '@babel/types': 7.23.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -6237,7 +6234,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 espree: 9.6.1 globals: 13.21.0 ignore: 5.2.4 @@ -6312,7 +6309,7 @@ packages: engines: {node: '>=10.10.0'} dependencies: '@humanwhocodes/object-schema': 2.0.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -6367,7 +6364,7 @@ packages: slash: 3.0.0 dev: true - /@jest/core@26.6.3(ts-node@10.9.1): + /@jest/core@26.6.3: resolution: {integrity: sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==} engines: {node: '>= 10.14.2'} dependencies: @@ -6382,14 +6379,14 @@ packages: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 26.6.2 - jest-config: 26.6.3(ts-node@10.9.1) + jest-config: 26.6.3 jest-haste-map: 26.6.2 jest-message-util: 26.6.2 jest-regex-util: 26.0.0 jest-resolve: 26.6.2 jest-resolve-dependencies: 26.6.3 - jest-runner: 26.6.3(ts-node@10.9.1) - jest-runtime: 26.6.3(ts-node@10.9.1) + jest-runner: 26.6.3 + jest-runtime: 26.6.3 jest-snapshot: 26.6.2 jest-util: 26.6.2 jest-validate: 26.6.2 @@ -6498,15 +6495,15 @@ packages: collect-v8-coverage: 1.0.2 dev: true - /@jest/test-sequencer@26.6.3(ts-node@10.9.1): + /@jest/test-sequencer@26.6.3: resolution: {integrity: sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==} engines: {node: '>= 10.14.2'} dependencies: '@jest/test-result': 26.6.2 graceful-fs: 4.2.11 jest-haste-map: 26.6.2 - jest-runner: 26.6.3(ts-node@10.9.1) - jest-runtime: 26.6.3(ts-node@10.9.1) + jest-runner: 26.6.3 + jest-runtime: 26.6.3 transitivePeerDependencies: - bufferutil - canvas @@ -7482,7 +7479,7 @@ packages: engines: {node: '>=16.3.0'} hasBin: true dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 extract-zip: 2.0.1 progress: 2.0.3 proxy-agent: 6.3.1 @@ -8479,7 +8476,7 @@ packages: '@typescript-eslint/type-utils': 6.10.0(eslint@8.53.0)(typescript@5.2.2) '@typescript-eslint/utils': 6.10.0(eslint@8.53.0)(typescript@5.2.2) '@typescript-eslint/visitor-keys': 6.10.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 eslint: 8.53.0 graphemer: 1.4.0 ignore: 5.2.4 @@ -8574,7 +8571,7 @@ packages: '@typescript-eslint/types': 6.10.0 '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.2.2) '@typescript-eslint/visitor-keys': 6.10.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 eslint: 8.53.0 typescript: 5.2.2 transitivePeerDependencies: @@ -8676,7 +8673,7 @@ packages: dependencies: '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.2.2) '@typescript-eslint/utils': 6.10.0(eslint@8.53.0)(typescript@5.2.2) - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 eslint: 8.53.0 ts-api-utils: 1.0.2(typescript@5.2.2) typescript: 5.2.2 @@ -8770,7 +8767,7 @@ packages: dependencies: '@typescript-eslint/types': 6.10.0 '@typescript-eslint/visitor-keys': 6.10.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 @@ -9356,7 +9353,7 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 transitivePeerDependencies: - supports-color @@ -9364,7 +9361,7 @@ packages: resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} engines: {node: '>= 14'} dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 transitivePeerDependencies: - supports-color dev: true @@ -11679,6 +11676,17 @@ packages: ms: 2.1.2 supports-color: 8.1.1 + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + /debug@4.3.4(supports-color@8.1.1): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -12649,7 +12657,7 @@ packages: '@es-joy/jsdoccomment': 0.40.1 are-docs-informative: 0.0.2 comment-parser: 1.4.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 escape-string-regexp: 4.0.0 eslint: 8.53.0 esquery: 1.5.0 @@ -12865,7 +12873,7 @@ packages: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -13188,7 +13196,7 @@ packages: engines: {node: '>= 10.17.0'} hasBin: true dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -13782,7 +13790,7 @@ packages: dependencies: basic-ftp: 5.0.3 data-uri-to-buffer: 5.0.1 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 fs-extra: 8.1.0 transitivePeerDependencies: - supports-color @@ -14410,7 +14418,7 @@ packages: dependencies: '@tootallnate/once': 1.1.2 agent-base: 6.0.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 transitivePeerDependencies: - supports-color dev: true @@ -14430,7 +14438,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 transitivePeerDependencies: - supports-color dev: true @@ -14476,7 +14484,7 @@ packages: engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 transitivePeerDependencies: - supports-color @@ -14485,7 +14493,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 transitivePeerDependencies: - supports-color dev: true @@ -15283,7 +15291,7 @@ packages: resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} engines: {node: '>=10'} dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 istanbul-lib-coverage: 3.2.0 source-map: 0.6.1 transitivePeerDependencies: @@ -15347,12 +15355,12 @@ packages: throat: 5.0.0 dev: true - /jest-cli@26.6.3(ts-node@10.9.1): + /jest-cli@26.6.3: resolution: {integrity: sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==} engines: {node: '>= 10.14.2'} hasBin: true dependencies: - '@jest/core': 26.6.3(ts-node@10.9.1) + '@jest/core': 26.6.3 '@jest/test-result': 26.6.2 '@jest/types': 26.6.2 chalk: 4.1.2 @@ -15360,7 +15368,7 @@ packages: graceful-fs: 4.2.11 import-local: 3.1.0 is-ci: 2.0.0 - jest-config: 26.6.3(ts-node@10.9.1) + jest-config: 26.6.3 jest-util: 26.6.2 jest-validate: 26.6.2 prompts: 2.4.2 @@ -15373,7 +15381,7 @@ packages: - utf-8-validate dev: true - /jest-config@26.6.3(ts-node@10.9.1): + /jest-config@26.6.3: resolution: {integrity: sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==} engines: {node: '>= 10.14.2'} peerDependencies: @@ -15383,7 +15391,7 @@ packages: optional: true dependencies: '@babel/core': 7.23.2 - '@jest/test-sequencer': 26.6.3(ts-node@10.9.1) + '@jest/test-sequencer': 26.6.3 '@jest/types': 26.6.2 babel-jest: 26.6.3(@babel/core@7.23.2) chalk: 4.1.2 @@ -15393,14 +15401,13 @@ packages: jest-environment-jsdom: 26.6.2 jest-environment-node: 26.6.2 jest-get-type: 26.3.0 - jest-jasmine2: 26.6.3(ts-node@10.9.1) + jest-jasmine2: 26.6.3 jest-regex-util: 26.0.0 jest-resolve: 26.6.2 jest-util: 26.6.2 jest-validate: 26.6.2 micromatch: 4.0.5 pretty-format: 26.6.2 - ts-node: 10.9.1(@types/node@20.7.2)(typescript@5.2.2) transitivePeerDependencies: - bufferutil - canvas @@ -15509,7 +15516,7 @@ packages: - supports-color dev: true - /jest-jasmine2@26.6.3(ts-node@10.9.1): + /jest-jasmine2@26.6.3: resolution: {integrity: sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==} engines: {node: '>= 10.14.2'} dependencies: @@ -15526,7 +15533,7 @@ packages: jest-each: 26.6.2 jest-matcher-utils: 26.6.2 jest-message-util: 26.6.2 - jest-runtime: 26.6.3(ts-node@10.9.1) + jest-runtime: 26.6.3 jest-snapshot: 26.6.2 jest-util: 26.6.2 pretty-format: 26.6.2 @@ -15622,7 +15629,7 @@ packages: slash: 3.0.0 dev: true - /jest-runner@26.6.3(ts-node@10.9.1): + /jest-runner@26.6.3: resolution: {integrity: sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==} engines: {node: '>= 10.14.2'} dependencies: @@ -15635,13 +15642,13 @@ packages: emittery: 0.7.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 26.6.3(ts-node@10.9.1) + jest-config: 26.6.3 jest-docblock: 26.0.0 jest-haste-map: 26.6.2 jest-leak-detector: 26.6.2 jest-message-util: 26.6.2 jest-resolve: 26.6.2 - jest-runtime: 26.6.3(ts-node@10.9.1) + jest-runtime: 26.6.3 jest-util: 26.6.2 jest-worker: 26.6.2 source-map-support: 0.5.21 @@ -15654,7 +15661,7 @@ packages: - utf-8-validate dev: true - /jest-runtime@26.6.3(ts-node@10.9.1): + /jest-runtime@26.6.3: resolution: {integrity: sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==} engines: {node: '>= 10.14.2'} hasBin: true @@ -15674,7 +15681,7 @@ packages: exit: 0.1.2 glob: 7.2.3 graceful-fs: 4.2.11 - jest-config: 26.6.3(ts-node@10.9.1) + jest-config: 26.6.3 jest-haste-map: 26.6.2 jest-message-util: 26.6.2 jest-mock: 26.6.2 @@ -15780,14 +15787,14 @@ packages: merge-stream: 2.0.0 supports-color: 8.1.1 - /jest@26.6.3(ts-node@10.9.1): + /jest@26.6.3: resolution: {integrity: sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==} engines: {node: '>= 10.14.2'} hasBin: true dependencies: - '@jest/core': 26.6.3(ts-node@10.9.1) + '@jest/core': 26.6.3 import-local: 3.1.0 - jest-cli: 26.6.3(ts-node@10.9.1) + jest-cli: 26.6.3 transitivePeerDependencies: - bufferutil - canvas @@ -18550,7 +18557,7 @@ packages: dependencies: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 get-uri: 6.0.1 http-proxy-agent: 7.0.0 https-proxy-agent: 7.0.2 @@ -19458,7 +19465,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 http-proxy-agent: 7.0.0 https-proxy-agent: 7.0.2 lru-cache: 7.18.3 @@ -19608,7 +19615,7 @@ packages: '@puppeteer/browsers': 1.8.0 chromium-bidi: 0.4.33(devtools-protocol@0.0.1203626) cross-fetch: 4.0.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 devtools-protocol: 0.0.1203626 ws: 8.14.2 transitivePeerDependencies: @@ -20842,7 +20849,7 @@ packages: engines: {node: '>= 14'} dependencies: agent-base: 7.1.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 socks: 2.7.1 transitivePeerDependencies: - supports-color @@ -22471,6 +22478,7 @@ packages: /uuid@8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true + requiresBuild: true /uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} From a044be8a98341aed4f97f0a33932a036e0403b0b Mon Sep 17 00:00:00 2001 From: Stefan Dietz Date: Thu, 16 Nov 2023 11:28:11 +0100 Subject: [PATCH 4/5] Add documentation --- MIGRATION.md | 3 ++- packages/components/src/components/link/readme.md | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index ca193a4785..57ad68e392 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -166,7 +166,7 @@ kol-input-text: kol-link: - prop `_ariaControls` removed -- prop `_ariaCurrent` removed (use `_listenAriaCurrent` instead) +- prop `_ariaCurrent` removed (Use ariaCurrentService instead) - prop `_ariaExpanded` removed - prop `_ariaLabel` removed - prop `_ariaSelected` removed @@ -209,6 +209,7 @@ kol-modal: kol-nav: +- prop `_ariaCurrentValue` removed - prop `_ariaLabel` removed (use `_label` instead) - prop `_compact` removed (use `_hideLabel` instead) - prop `_hasCompactButton` removed diff --git a/packages/components/src/components/link/readme.md b/packages/components/src/components/link/readme.md index 79253b12f6..7165b472fe 100644 --- a/packages/components/src/components/link/readme.md +++ b/packages/components/src/components/link/readme.md @@ -46,6 +46,20 @@ Eingabe von Leerzeichen eingefügt werden. Zusätzliche Leerzeichen vergrößern facilis, amet ducimus minus quae corporis eligendi cum distinctio. Fugit, repellendus.

+## `aria-current` Service + +Damit die Link-Komponente automatisch ein [`aria-current`-Tag](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current) +setzen kann, muss ihr über den ariaCurrent-Service mitgeteilt werden, welche Seite gerade aktiv ist: + +```typescript +import { setCurrentLocation } from '@public-ui/components'; + +/* Bei jedem Seitenwechsel aufrufen: */ +setCurrentLocation('/path/to/page'); +``` + +Der übergebene Location-String muss dabei exakt dem `href`-Attributs des Links entsprechen. + From 53c765f04a2ac60d9d90e230bb960ba8787c1b2c Mon Sep 17 00:00:00 2001 From: Stefan Dietz Date: Thu, 16 Nov 2023 11:31:24 +0100 Subject: [PATCH 5/5] Separate setCurrentLocation into hook --- packages/samples/react/src/App.tsx | 4 ++-- packages/samples/react/src/hooks/useSetCurrentLocation.ts | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 packages/samples/react/src/hooks/useSetCurrentLocation.ts diff --git a/packages/samples/react/src/App.tsx b/packages/samples/react/src/App.tsx index 463ff66938..607acee1aa 100644 --- a/packages/samples/react/src/App.tsx +++ b/packages/samples/react/src/App.tsx @@ -11,7 +11,7 @@ import { getTheme, getThemeName, setStorage, setTheme } from './shares/store'; import { Sidebar } from './components/Sidebar'; import { useLocation } from 'react-router'; import { HideMenusContext } from './shares/HideMenusContext'; -import { setCurrentLocation } from '@public-ui/components'; +import { useSetCurrentLocation } from './hooks/useSetCurrentLocation'; setStorage(localStorage); @@ -108,7 +108,7 @@ export const App: FC = () => { const hideMenus = searchParams.has('hideMenus'); setTheme(theme as Theme); // set for `getTheme` usages within the application - setCurrentLocation('#' + routerLocation.pathname); + useSetCurrentLocation(); document.title = `KoliBri-Handout - ${getThemeName(getTheme())} | v${PackageJson.version}`; document.body.setAttribute('class', theme); diff --git a/packages/samples/react/src/hooks/useSetCurrentLocation.ts b/packages/samples/react/src/hooks/useSetCurrentLocation.ts new file mode 100644 index 0000000000..7ea2b8350f --- /dev/null +++ b/packages/samples/react/src/hooks/useSetCurrentLocation.ts @@ -0,0 +1,7 @@ +import { setCurrentLocation } from '@public-ui/components'; +import { useLocation } from 'react-router'; + +export const useSetCurrentLocation = () => { + const routerLocation = useLocation(); + setCurrentLocation('#' + routerLocation.pathname); +};