728x90
반응형
Watch 를 이용해 isOpen의 값 변화를 주어 Expander 를 만들어 보겠습니다.
button 마크업에 onclick 이벤트로 expanderClick 함수를 호출하였고,
isOpen의 값을 변경하였습니다.
Watch에서 값 변경을 인식하여 현재 컴포넌트의 상태값을 변경해주는 로직입니다.
import { Component, Host, h, Prop, Watch, Element } from '@stencil/core';
@Component({
tag: 'td-expander',
styleUrl: 'td-expander.less',
shadow: true,
})
export class TdExpander {
@Prop() itemType: string;
@Prop() panelId: string;
@Element() el!: HTMLKcLoadingElement;
@Prop() isOpen = false;
@Watch('isOpen')
onIsOpenChange(newValue: boolean, oldValue: boolean) {
const { el } = this;
if (newValue === true && oldValue === false) {
this.activeMode(el, 'true');
} else if (newValue === false && oldValue === true) {
this.activeMode(el, 'false');
}
}
private activeMode = (el, value) => {
let ele = el as HTMLElement;
if (value === 'true') {
ele.setAttribute('is-open', 'true');
} else if (value === 'false') {
ele.setAttribute('is-open', 'false');
}
};
private expanderClick = (ev?: Event) => {
if (ev) {
ev.preventDefault();
ev.stopPropagation();
}
const icon = ev.currentTarget as HTMLElement;
const button = this.el.shadowRoot.querySelector('button');
if (this.isOpen == false) {
this.isOpen = true;
button.setAttribute('aria-expanded', 'true');
button.nextElementSibling.setAttribute('aria-hidden', 'false');
} else {
this.isOpen = false;
button.setAttribute('aria-expanded', 'false');
button.nextElementSibling.setAttribute('aria-hidden', 'true');
}
};
render() {
const { itemType, iconType, size, panelId } = this;
let classArray = ['expander', itemType == null ? '' : itemType];
let classes = classArray.join(' ');
return (
<Host class={classes} is-open="false">
<button
type="button"
class="btn-expander"}
slot="header"
item-type={itemType}
onClick={this.expanderClick}
expanded="false"
aria-controls={panelId}>
<slot name="header"></slot>
</button>
<div id={panelId}>
<div class="expander__contents">
<slot name="content"></slot>
</div>
</div>
</Host>
);
}
}
css는 다음과 같아요~
:host(isOpen=true){
::slotted(.expander__content) {
display:block;
}
}
:host(isOpen=false){
::slotted(.expander__content) {
display:none;
}
}
728x90
반응형
'공부하기' 카테고리의 다른 글
Node.js 설치하기 (1) | 2024.01.08 |
---|---|
특수문자 (1) | 2024.01.04 |
[Stencil]컴포넌트 구성 셋 (0) | 2024.01.03 |
[Stencil]Web components API (0) | 2024.01.03 |
web components :part() (0) | 2024.01.03 |