diff --git a/core/src/components/card/card.tsx b/core/src/components/card/card.tsx index 5756c52ba7..96bb8d2d78 100644 --- a/core/src/components/card/card.tsx +++ b/core/src/components/card/card.tsx @@ -1,9 +1,11 @@ import type { ComponentInterface } from '@stencil/core'; -import { Component, Host, Prop, h } from '@stencil/core'; +import { Element, Component, Host, Prop, h } from '@stencil/core'; import { getIonMode } from '../../global/ionic-global'; import type { AnimationBuilder, Color, Mode, RouterDirection } from '../../interface'; import type { AnchorInterface, ButtonInterface } from '../../utils/element-interface'; +import type { Attributes } from '../../utils/helpers'; +import { inheritAttributes } from '../../utils/helpers'; import { createColorClasses, openURL } from '../../utils/theme'; /** @@ -20,6 +22,9 @@ import { createColorClasses, openURL } from '../../utils/theme'; shadow: true, }) export class Card implements ComponentInterface, AnchorInterface, ButtonInterface { + private inheritedAriaAttributes: Attributes = {}; + + @Element() el!: HTMLElement; /** * The color to use from your application's color palette. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. @@ -81,6 +86,10 @@ export class Card implements ComponentInterface, AnchorInterface, ButtonInterfac */ @Prop() target: string | undefined; + componentWillLoad() { + this.inheritedAriaAttributes = inheritAttributes(this.el, ['aria-label']); + } + private isClickable(): boolean { return this.href !== undefined || this.button; } @@ -91,7 +100,7 @@ export class Card implements ComponentInterface, AnchorInterface, ButtonInterfac if (!clickable) { return []; } - const { href, routerAnimation, routerDirection } = this; + const { href, routerAnimation, routerDirection, inheritedAriaAttributes } = this; const TagType = clickable ? (href === undefined ? 'button' : 'a') : ('div' as any); const attrs = TagType === 'button' @@ -106,6 +115,7 @@ export class Card implements ComponentInterface, AnchorInterface, ButtonInterfac return ( { + it('should reflect aria-label to button', async () => { + const page = await newSpecPage({ + components: [Card], + html: ``, + }); + + const button = page.body.querySelector('ion-card')!.shadowRoot!.querySelector('button')!; + const ariaLabel = button.getAttribute('aria-label'); + + expect(ariaLabel).toEqual('Test'); + }); +}); diff --git a/core/src/components/card/test/basic/index.html b/core/src/components/card/test/basic/index.html new file mode 100644 index 0000000000..58c780a49b --- /dev/null +++ b/core/src/components/card/test/basic/index.html @@ -0,0 +1,40 @@ + + + + + Card - Basic + + + + + + + + + + + + + Card - Basic + + + + + + + Card Subtitle + Card Title + + + + Keep close to Nature's heart... and break clear away, once in awhile, and climb a mountain or spend a week + in the woods. Wash your spirit clean. + + + + + + diff --git a/core/src/components/item/item.tsx b/core/src/components/item/item.tsx index d58c66e869..f25ac50790 100644 --- a/core/src/components/item/item.tsx +++ b/core/src/components/item/item.tsx @@ -5,7 +5,8 @@ import { chevronForward } from 'ionicons/icons'; import { getIonMode } from '../../global/ionic-global'; import type { AnimationBuilder, Color, CssClassMap, RouterDirection, StyleEventDetail } from '../../interface'; import type { AnchorInterface, ButtonInterface } from '../../utils/element-interface'; -import { raf } from '../../utils/helpers'; +import type { Attributes } from '../../utils/helpers'; +import { inheritAttributes, raf } from '../../utils/helpers'; import { printIonError } from '../../utils/logging'; import { createColorClasses, hostContext, openURL } from '../../utils/theme'; import type { InputChangeEventDetail } from '../input/input-interface'; @@ -38,6 +39,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac private labelColorStyles = {}; private itemStyles = new Map(); private clickListener?: (ev: Event) => void; + private inheritedAriaAttributes: Attributes = {}; @Element() el!: HTMLIonItemElement; @@ -226,6 +228,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac componentDidLoad() { raf(() => { + this.inheritedAriaAttributes = inheritAttributes(this.el, ['aria-label']); this.setMultipleInputs(); this.focusable = this.isFocusable(); }); @@ -359,12 +362,14 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac target, routerAnimation, routerDirection, + inheritedAriaAttributes, } = this; const childStyles = {} as any; const mode = getIonMode(this); const clickable = this.isClickable(); const canActivate = this.canActivate(); const TagType = clickable ? (href === undefined ? 'button' : 'a') : ('div' as any); + const attrs = TagType === 'button' ? { type: this.type } @@ -390,6 +395,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac const ariaDisabled = disabled || childStyles['item-interactive-disabled'] ? 'true' : null; const fillValue = fill || 'none'; const inList = hostContext('ion-list', this.el); + return ( - +