igniteui-webcomponents
Version:
Ignite UI for Web Components is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach.
231 lines • 8.45 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { consume } from '@lit/context';
import { html, LitElement, nothing } from 'lit';
import { property } from 'lit/decorators.js';
import { cache } from 'lit/directives/cache.js';
import { createRef, ref } from 'lit/directives/ref.js';
import { EaseInOut } from '../../animations/easings.js';
import { addAnimationController } from '../../animations/player.js';
import { addThemingController } from '../../theming/theming-controller.js';
import { addSlotController, setSlots } from '../common/controllers/slot.js';
import { registerComponent } from '../common/definitions/register.js';
import { partMap } from '../common/part-map.js';
import { bodyAnimations, contentAnimations } from './common/animations.js';
import { STEPPER_CONTEXT } from './common/context.js';
import { styles as shared } from './themes/step/shared/step.common.css.js';
import { styles } from './themes/step/step.base.css.js';
import { all } from './themes/step/themes.js';
export default class IgcStepComponent extends LitElement {
static { this.tagName = 'igc-step'; }
static { this.styles = [styles, shared]; }
static register() {
registerComponent(IgcStepComponent);
}
get _stepper() {
return this._stepperContext?.stepper;
}
get _state() {
return this._stepperContext?.state;
}
get _isHorizontal() {
return this._orientation === 'horizontal';
}
get _hasTitle() {
return this._slots.hasAssignedElements('title');
}
get _hasSubtitle() {
return this._slots.hasAssignedElements('subtitle');
}
get _animation() {
const animation = this._isHorizontal
? this._stepper?.horizontalAnimation
: this._stepper?.verticalAnimation;
return animation ?? (this._isHorizontal ? 'slide' : 'grow');
}
get _animationDuration() {
return this._stepper?.animationDuration ?? 320;
}
get _contentTop() {
return this._stepper?.contentTop ?? false;
}
get _index() {
return this._stepper?.steps.indexOf(this) ?? -1;
}
get _orientation() {
return this._stepper?.orientation ?? 'horizontal';
}
get _titlePosition() {
return this._stepper?.titlePosition ?? 'auto';
}
get _stepType() {
return this._stepper?.stepType ?? 'full';
}
get _previousComplete() {
return this._state?.get(this)?.previousCompleted ?? false;
}
get _visited() {
return this._state?.get(this)?.visited ?? false;
}
get _isAccessible() {
return this._state?.isAccessible(this) ?? true;
}
constructor() {
super();
this._bodyRef = createRef();
this._contentRef = createRef();
this._bodyPlayer = addAnimationController(this, this._bodyRef);
this._contentPlayer = addAnimationController(this, this._contentRef);
this._slots = addSlotController(this, {
slots: setSlots('indicator', 'title', 'subtitle'),
});
this.invalid = false;
this.active = false;
this.optional = false;
this.disabled = false;
this.complete = false;
addThemingController(this, all);
}
willUpdate(changed) {
if (changed.has('active') ||
changed.has('complete') ||
changed.has('disabled') ||
changed.has('invalid') ||
changed.has('optional')) {
this._state?.onStepPropertyChanged(this, changed);
}
}
async toggleAnimation(type, direction = 'normal') {
const bodyAnimation = bodyAnimations.get(this._animation).get(type);
const contentAnimation = contentAnimations.get(this._animation).get(type);
const bodyHeight = getComputedStyle(this).getPropertyValue('--vertical-body-height');
const options = {
duration: this._animationDuration,
easing: EaseInOut.Quad,
direction,
};
const step = {
height: bodyHeight,
};
const result = await Promise.all([
this._bodyPlayer.playExclusive(bodyAnimation({ keyframe: options, step })),
this._contentPlayer.playExclusive(contentAnimation({ keyframe: options, step })),
]);
return result.every(Boolean);
}
get _headerContainerParts() {
return {
'header-container': true,
disabled: !this._isAccessible,
'complete-start': this.complete,
'complete-end': this._previousComplete,
optional: this.optional,
invalid: this.invalid && this._visited && !this.active && this._isAccessible,
top: this._titlePosition === 'top',
bottom: this._titlePosition === 'bottom' ||
(this._isHorizontal && this._titlePosition === 'auto'),
start: this._titlePosition === 'start',
end: this._titlePosition === 'end' ||
(!this._isHorizontal && this._titlePosition === 'auto'),
};
}
get _textParts() {
const hasText = this._hasTitle || this._hasSubtitle;
return {
text: true,
empty: this._stepType === 'indicator' ||
(this._stepType === 'full' && !hasText),
};
}
_renderIndicator() {
return this._stepType !== 'title'
? html `
<div part="indicator">
<slot name="indicator">
<span>${this._index + 1}</span>
</slot>
</div>
`
: nothing;
}
_renderTitleAndSubtitle() {
return html `
<div part=${partMap(this._textParts)}>
<div part="title">
<slot name="title"></slot>
</div>
<div part="subtitle">
<slot name="subtitle"></slot>
</div>
</div>
`;
}
_renderHeader() {
const index = this._index + 1;
const size = this._stepper?.steps.length ?? 0;
return html `
<div part=${partMap(this._headerContainerParts)}>
<div
data-step-header
role="tab"
part="header"
id="igc-step-header-${index}"
aria-selected=${this.active}
aria-controls="igc-step-content-${index}"
aria-posinset=${index}
aria-setsize=${size}
tabindex=${this.active ? 0 : -1}
>
${this._renderIndicator()} ${this._renderTitleAndSubtitle()}
</div>
</div>
`;
}
_renderContent() {
const index = this._index + 1;
return html `
<div
${ref(this._bodyRef)}
id="igc-step-content-${index}"
part="body"
role="tabpanel"
aria-labelledby="igc-step-header-${index}"
>
<div ${ref(this._contentRef)} part="content">
<slot></slot>
</div>
</div>
`;
}
render() {
const renderBeforeHeader = this._contentTop && this._isHorizontal;
return html `
${cache(renderBeforeHeader
? html `${this._renderContent()} ${this._renderHeader()}`
: html `${this._renderHeader()} ${this._renderContent()}`)}
`;
}
}
__decorate([
consume({ context: STEPPER_CONTEXT, subscribe: true })
], IgcStepComponent.prototype, "_stepperContext", void 0);
__decorate([
property({ type: Boolean, reflect: true })
], IgcStepComponent.prototype, "invalid", void 0);
__decorate([
property({ type: Boolean, reflect: true })
], IgcStepComponent.prototype, "active", void 0);
__decorate([
property({ type: Boolean, reflect: true })
], IgcStepComponent.prototype, "optional", void 0);
__decorate([
property({ type: Boolean, reflect: true })
], IgcStepComponent.prototype, "disabled", void 0);
__decorate([
property({ type: Boolean, reflect: true })
], IgcStepComponent.prototype, "complete", void 0);
//# sourceMappingURL=step.js.map