fix(segment): nested interactive is not rendered (#26575)

This commit is contained in:
Liam DeBeasi
2023-01-09 13:08:01 -05:00
committed by GitHub
parent df4882d4d1
commit 77ce9e066e
6 changed files with 57 additions and 31 deletions

View File

@ -1,10 +1,11 @@
import type { ComponentInterface } from '@stencil/core';
import { Component, Element, Host, Prop, State, forceUpdate, h } from '@stencil/core';
import { Component, Element, Host, Prop, Method, State, forceUpdate, h } from '@stencil/core';
import { getIonMode } from '../../global/ionic-global';
import type { SegmentButtonLayout } from '../../interface';
import type { ButtonInterface } from '../../utils/element-interface';
import { addEventListener, removeEventListener } from '../../utils/helpers';
import type { Attributes } from '../../utils/helpers';
import { addEventListener, removeEventListener, inheritAttributes } from '../../utils/helpers';
import { hostContext } from '../../utils/theme';
let ids = 0;
@ -26,6 +27,8 @@ let ids = 0;
})
export class SegmentButton implements ComponentInterface, ButtonInterface {
private segmentEl: HTMLIonSegmentElement | null = null;
private nativeEl: HTMLButtonElement | undefined;
private inheritedAttributes: Attributes = {};
@Element() el!: HTMLElement;
@ -69,6 +72,12 @@ export class SegmentButton implements ComponentInterface, ButtonInterface {
}
}
componentWillLoad() {
this.inheritedAttributes = {
...inheritAttributes(this.el, ['aria-label']),
};
}
private get hasLabel() {
return !!this.el.querySelector('ion-label');
}
@ -87,20 +96,26 @@ export class SegmentButton implements ComponentInterface, ButtonInterface {
}
};
private get tabIndex() {
return this.checked && !this.disabled ? 0 : -1;
/**
* @internal
* Focuses the native <button> element
* inside of ion-segment-button.
*/
@Method()
async setFocus() {
const { nativeEl } = this;
if (nativeEl !== undefined) {
nativeEl.focus();
}
}
render() {
const { checked, type, disabled, hasIcon, hasLabel, layout, segmentEl, tabIndex } = this;
const { checked, type, disabled, hasIcon, hasLabel, layout, segmentEl } = this;
const mode = getIonMode(this);
const hasSegmentColor = () => segmentEl?.color !== undefined;
return (
<Host
role="tab"
aria-selected={checked ? 'true' : 'false'}
aria-disabled={disabled ? 'true' : null}
tabIndex={tabIndex}
class={{
[mode]: true,
'in-toolbar': hostContext('ion-toolbar', this.el),
@ -119,7 +134,16 @@ export class SegmentButton implements ComponentInterface, ButtonInterface {
'ion-focusable': true,
}}
>
<button type={type} tabIndex={-1} class="button-native" part="native" disabled={disabled}>
<button
aria-selected={checked ? 'true' : 'false'}
role="tab"
ref={(el) => (this.nativeEl = el)}
type={type}
class="button-native"
part="native"
disabled={disabled}
{...this.inheritedAttributes}
>
<span class="button-inner">
<slot></slot>
</span>