Skip to content

Commit

Permalink
Fix screen reader content for external links (#5815)
Browse files Browse the repository at this point in the history
  • Loading branch information
deleonio authored Dec 21, 2023
2 parents 5abdb7d + 018011a commit 59b8053
Show file tree
Hide file tree
Showing 11 changed files with 33 additions and 77 deletions.
24 changes: 0 additions & 24 deletions packages/components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1795,10 +1795,6 @@ export namespace Components {
* Defines where to open the link.
*/
"_target"?: LinkTargetPropType;
/**
* Defines the description to use when the link is going to be opened in another application.
*/
"_targetDescription"?: string;
/**
* Defines where to show the Tooltip preferably: top, right, bottom or left.
*/
Expand Down Expand Up @@ -1854,10 +1850,6 @@ export namespace Components {
* Defines where to open the link.
*/
"_target"?: LinkTargetPropType;
/**
* Defines the description to use when the link is going to be opened in another application.
*/
"_targetDescription"?: string;
/**
* Defines where to show the Tooltip preferably: top, right, bottom or left.
*/
Expand Down Expand Up @@ -1931,10 +1923,6 @@ export namespace Components {
* Defines where to open the link.
*/
"_target"?: LinkTargetPropType;
/**
* Defines the description to use when the link is going to be opened in another application.
*/
"_targetDescription"?: string;
/**
* Defines where to show the Tooltip preferably: top, right, bottom or left.
*/
Expand Down Expand Up @@ -4595,10 +4583,6 @@ declare namespace LocalJSX {
* Defines where to open the link.
*/
"_target"?: LinkTargetPropType;
/**
* Defines the description to use when the link is going to be opened in another application.
*/
"_targetDescription"?: string;
/**
* Defines where to show the Tooltip preferably: top, right, bottom or left.
*/
Expand Down Expand Up @@ -4654,10 +4638,6 @@ declare namespace LocalJSX {
* Defines where to open the link.
*/
"_target"?: LinkTargetPropType;
/**
* Defines the description to use when the link is going to be opened in another application.
*/
"_targetDescription"?: string;
/**
* Defines where to show the Tooltip preferably: top, right, bottom or left.
*/
Expand Down Expand Up @@ -4731,10 +4711,6 @@ declare namespace LocalJSX {
* Defines where to open the link.
*/
"_target"?: LinkTargetPropType;
/**
* Defines the description to use when the link is going to be opened in another application.
*/
"_targetDescription"?: string;
/**
* Defines where to show the Tooltip preferably: top, right, bottom or left.
*/
Expand Down
8 changes: 0 additions & 8 deletions packages/components/src/components/link-button/component.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { Component, Element, h, Host, JSX, Prop } from '@stencil/core';

import { translate } from '../../i18n';
import { AlternativeButtonLinkRolePropType } from '../../types/props/alternative-button-link-role';
import { ButtonVariantPropType } from '../../types/props/button-variant';
import { CustomClassPropType } from '../../types/props/custom-class';
Expand Down Expand Up @@ -51,7 +49,6 @@ export class KolLinkButton implements Props {
_role="button"
_tabIndex={this._tabIndex}
_target={this._target}
_targetDescription={this._targetDescription}
_tooltipAlign={this._tooltipAlign}
>
<slot name="expert" slot="expert"></slot>
Expand Down Expand Up @@ -122,11 +119,6 @@ export class KolLinkButton implements Props {
*/
@Prop() public _target?: LinkTargetPropType;

/**
* Defines the description to use when the link is going to be opened in another application.
*/
@Prop() public _targetDescription?: string = translate('kol-open-link-in-tab');

/**
* Defines where to show the Tooltip preferably: top, right, bottom or left.
*/
Expand Down
28 changes: 13 additions & 15 deletions packages/components/src/components/link/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { LinkOnCallbacksPropType, validateLinkCallbacks } from '../../types/prop
import { LinkTargetPropType, validateLinkTarget } from '../../types/props/link-target';
import { TooltipAlignPropType, validateTooltipAlign } from '../../types/props/tooltip-align';
import { devHint } from '../../utils/a11y.tipps';
import { setEventTarget, watchString } from '../../utils/prop.validators';
import { setEventTarget } from '../../utils/prop.validators';
import { propagateFocus, showExpertSlot } from '../../utils/reuse';
import { validateTabIndex } from '../../utils/validators/tab-index';
import { States as LinkStates } from '../link/types';
Expand Down Expand Up @@ -78,7 +78,7 @@ export class KolLinkWc implements API {
};

if (this.state._hideLabel === true && !this.state._label) {
devHint(`[KolLink] Es muss ein Aria-Label gesetzt werden _hide-label gesetzt ist.`);
devHint(`[KolLink] Es muss ein Aria-Label gesetzt werden, wenn _hide-label gesetzt ist.`);
}
return { isExternal, tagAttrs };
};
Expand All @@ -93,7 +93,9 @@ export class KolLinkWc implements API {
{...tagAttrs}
accessKey={this.state._accessKey}
aria-current={this.state._ariaCurrent}
aria-label={this.state._hideLabel && typeof this.state._label === 'string' ? this.state._label : undefined}
aria-label={
this.state._hideLabel && typeof this.state._label === 'string' ? `${this.state._label} (${translate('kol-open-link-in-tab')})` : undefined
}
class={{
'external-link': isExternal,
'hide-label': this.state._hideLabel === true,
Expand All @@ -113,7 +115,14 @@ export class KolLinkWc implements API {
>
<slot name="expert" slot="expert"></slot>
</kol-span-wc>
{isExternal && <kol-icon class="external-link-icon" _label={this.state._targetDescription as string} _icons={'codicon codicon-link-external'} />}
{isExternal && (
<kol-icon
class="external-link-icon"
_label={translate('kol-open-link-in-tab')}
_icons={'codicon codicon-link-external'}
aria-hidden={this.state._hideLabel}
/>
)}
</a>
<kol-tooltip-wc
/**
Expand Down Expand Up @@ -187,11 +196,6 @@ export class KolLinkWc implements API {
*/
@Prop() public _target?: LinkTargetPropType;

/**
* Defines the description to use when the link is going to be opened in another application.
*/
@Prop() public _targetDescription?: string = translate('kol-open-link-in-tab');

/**
* Defines where to show the Tooltip preferably: top, right, bottom or left.
*/
Expand Down Expand Up @@ -258,11 +262,6 @@ export class KolLinkWc implements API {
validateLinkTarget(this, value);
}

@Watch('_targetDescription')
public validateTargetDescription(value?: string): void {
watchString(this, '_targetDescription', value);
}

@Watch('_tooltipAlign')
public validateTooltipAlign(value?: TooltipAlignPropType): void {
validateTooltipAlign(this, value);
Expand All @@ -280,7 +279,6 @@ export class KolLinkWc implements API {
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 ? this.state._ariaCurrentValue : undefined;
Expand Down
30 changes: 15 additions & 15 deletions packages/components/src/components/link/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,21 @@ Der übergebene Location-String muss dabei exakt dem `href`-Attributs des Links

## Properties

| Property | Attribute | Description | Type | Default |
| -------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- | ---------------------------------------------- |
| `_accessKey` | `_access-key` | Defines the elements access key. | `string \| undefined` | `undefined` |
| `_ariaCurrentValue` | `_aria-current-value` | Defines the value for the aria-current attribute. | `"date" \| "false" \| "location" \| "page" \| "step" \| "time" \| "true" \| undefined` | `undefined` |
| `_download` | `_download` | Tells the browser that the link contains a file. Optionally sets the filename. | `string \| undefined` | `undefined` |
| `_hideLabel` | `_hide-label` | Hides the caption by default and displays the caption text with a tooltip when the interactive element is focused or the mouse is over it. | `boolean \| undefined` | `false` |
| `_href` _(required)_ | `_href` | Sets the target URI of the link or citation source. | `string` | `undefined` |
| `_icons` | `_icons` | Defines the icon classnames (e.g. `_icons="fa-solid fa-user"`). | `KoliBriHorizontalIcons & KoliBriVerticalIcons \| string \| undefined` | `undefined` |
| `_label` | `_label` | 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. | `string \| undefined` | `undefined` |
| `_on` | -- | Defines the callback functions for links. | `undefined \| { onClick?: EventValueOrEventCallback<Event, string> \| undefined; }` | `undefined` |
| `_role` | `_role` | Defines the role of the components primary element. | `"button" \| "link" \| "tab" \| undefined` | `undefined` |
| `_tabIndex` | `_tab-index` | Defines which tab-index the primary element of the component has. (https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) | `number \| undefined` | `undefined` |
| `_target` | `_target` | Defines where to open the link. | `string \| undefined` | `undefined` |
| `_targetDescription` | `_target-description` | Defines the description to use when the link is going to be opened in another application. | `string \| undefined` | `'Der Link wird in einem neuen Tab geöffnet.'` |
| `_tooltipAlign` | `_tooltip-align` | Defines where to show the Tooltip preferably: top, right, bottom or left. | `"bottom" \| "left" \| "right" \| "top" \| undefined` | `'right'` |
| Property | Attribute | Description | Type | Default |
| -------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- | ----------------------------------- |
| `_accessKey` | `_access-key` | Defines the elements access key. | `string \| undefined` | `undefined` |
| `_ariaCurrentValue` | `_aria-current-value` | Defines the value for the aria-current attribute. | `"date" \| "false" \| "location" \| "page" \| "step" \| "time" \| "true" \| undefined` | `undefined` |
| `_download` | `_download` | Tells the browser that the link contains a file. Optionally sets the filename. | `string \| undefined` | `undefined` |
| `_hideLabel` | `_hide-label` | Hides the caption by default and displays the caption text with a tooltip when the interactive element is focused or the mouse is over it. | `boolean \| undefined` | `false` |
| `_href` _(required)_ | `_href` | Sets the target URI of the link or citation source. | `string` | `undefined` |
| `_icons` | `_icons` | Defines the icon classnames (e.g. `_icons="fa-solid fa-user"`). | `KoliBriHorizontalIcons & KoliBriVerticalIcons \| string \| undefined` | `undefined` |
| `_label` | `_label` | 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. | `string \| undefined` | `undefined` |
| `_on` | -- | Defines the callback functions for links. | `undefined \| { onClick?: EventValueOrEventCallback<Event, string> \| undefined; }` | `undefined` |
| `_role` | `_role` | Defines the role of the components primary element. | `"button" \| "link" \| "tab" \| undefined` | `undefined` |
| `_tabIndex` | `_tab-index` | Defines which tab-index the primary element of the component has. (https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) | `number \| undefined` | `undefined` |
| `_target` | `_target` | Defines where to open the link. | `string \| undefined` | `undefined` |
| `_targetDescription` | `_target-description` | Defines the description to use when the link is going to be opened in another application. | `string` | `translate('kol-open-link-in-tab')` |
| `_tooltipAlign` | `_tooltip-align` | Defines where to show the Tooltip preferably: top, right, bottom or left. | `"bottom" \| "left" \| "right" \| "top" \| undefined` | `'right'` |

## Dependencies

Expand Down
6 changes: 0 additions & 6 deletions packages/components/src/components/link/shadow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export class KolLink implements LinkProps {
_role={this._role}
_tabIndex={this._tabIndex}
_target={this._target}
_targetDescription={this._targetDescription}
_tooltipAlign={this._tooltipAlign}
>
{/*
Expand Down Expand Up @@ -114,11 +113,6 @@ export class KolLink implements LinkProps {
*/
@Prop() public _target?: LinkTargetPropType;

/**
* Defines the description to use when the link is going to be opened in another application.
*/
@Prop() public _targetDescription?: string = 'Der Link wird in einem neuen Tab geöffnet.';

/**
* Defines where to show the Tooltip preferably: top, right, bottom or left.
*/
Expand Down
7 changes: 3 additions & 4 deletions packages/components/src/components/link/test/html.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export const getLinkHtml = (props: LinkProps, innerHTML = ''): string => {
_hideLabel: false,
_icons: {},
_tooltipAlign: 'right',
_targetDescription: 'Der Link wird in einem neuen Tab geöffnet.',
_ariaCurrentValue: 'page',
},
props
Expand All @@ -23,7 +22,7 @@ export const getLinkHtml = (props: LinkProps, innerHTML = ''): string => {
<kol-link>
<mock:shadow-root>
<kol-link-wc>
<a${state._hideLabel === true && !hasExpertSlot && typeof state._label === 'string' ? ` aria-label="${state._label}"` : ''} class="${
<a${state._hideLabel === true && !hasExpertSlot && typeof state._label === 'string' ? ` aria-label="${state._label} (kol-open-link-in-tab)"` : ''} class="${
state._hideLabel === true ? ' hide-label' : ''
}${typeof state._target === 'string' && state._target !== '_self' ? ' external-link' : ''}" href="${
typeof state._href === 'string' && state._href.length > 0 ? state._href : 'javascript:void(0)'
Expand All @@ -46,10 +45,10 @@ export const getLinkHtml = (props: LinkProps, innerHTML = ''): string => {
typeof state._target === 'string' && state._target !== '_self'
? getIconHtml(
{
_label: 'Der Link wird in einem neuen Tab geöffnet.',
_label: 'kol-open-link-in-tab',
_icons: 'codicon codicon-link-external',
},
' class="external-link-icon"'
` class="external-link-icon"${state._hideLabel ? ' aria-hidden=""' : ''}`
)
: ''
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ executeTests<LinkProps>(
_hideLabel: [false, true],
_label: ['Label'],
_target: ['_self', '_blank', 'egal'],
_targetDescription: ['Der Link wird in einem neuen Tab geöffnet.'],
_tooltipAlign: ['top', 'right', 'bottom', 'left'],
_download: ['', 'download-file.zip'],
},
Expand Down
1 change: 0 additions & 1 deletion packages/components/src/components/link/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { PropAccessKey } from '../../types/props/access-key';
*/
export type RequiredProps = PropHref;
export type OptionalProps = {
targetDescription: string;
tabIndex: number;
} & PropAccessKey &
PropAriaCurrentValue &
Expand Down
Loading

0 comments on commit 59b8053

Please sign in to comment.