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.
271 lines • 10.1 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 { ContextProvider } from '@lit/context';
import { html, LitElement } from 'lit';
import { property } from 'lit/decorators.js';
import { addThemingController } from '../../theming/theming-controller.js';
import { addInternalsController } from '../common/controllers/internals.js';
import { addKeybindings, arrowDown, arrowLeft, arrowRight, arrowUp, endKey, homeKey, } from '../common/controllers/key-bindings.js';
import { addSlotController, setSlots } from '../common/controllers/slot.js';
import { registerComponent } from '../common/definitions/register.js';
import { EventEmitterMixin } from '../common/mixins/event-emitter.js';
import { addSafeEventListener, findElementFromEventPath, first, getRoot, isLTR, last, wrap, } from '../common/util.js';
import { STEPPER_CONTEXT } from './common/context.js';
import { createStepperState } from './common/state.js';
import IgcStepComponent from './step.js';
import { styles } from './themes/stepper/stepper.base.css.js';
import { styles as bootstrap } from './themes/stepper/stepper.bootstrap.css.js';
import { styles as fluent } from './themes/stepper/stepper.fluent.css.js';
import { styles as indigo } from './themes/stepper/stepper.indigo.css.js';
const STEPPER_SYNC_PROPERTIES = [
'orientation',
'stepType',
'contentTop',
'verticalAnimation',
'horizontalAnimation',
'animationDuration',
'titlePosition',
];
export default class IgcStepperComponent extends EventEmitterMixin(LitElement) {
static { this.tagName = 'igc-stepper'; }
static { this.styles = styles; }
static register() {
registerComponent(IgcStepperComponent, IgcStepComponent);
}
get _isHorizontal() {
return this.orientation === 'horizontal';
}
get steps() {
return this._state.steps;
}
constructor() {
super();
this._state = createStepperState();
this._contextProvider = new ContextProvider(this, {
context: STEPPER_CONTEXT,
initialValue: {
stepper: this,
state: this._state,
},
});
this._internals = addInternalsController(this, {
initialARIA: {
role: 'tablist',
},
});
this._slots = addSlotController(this, {
slots: setSlots(),
onChange: this._handleSlotChange,
});
this.orientation = 'horizontal';
this.stepType = 'full';
this.linear = false;
this.contentTop = false;
this.verticalAnimation = 'grow';
this.horizontalAnimation = 'slide';
this.animationDuration = 320;
this.titlePosition = 'auto';
addSafeEventListener(this, 'click', this._handleInteraction);
addThemingController(this, {
light: { bootstrap, fluent, indigo },
dark: { bootstrap, fluent, indigo },
});
addKeybindings(this, {
skip: this._skipKeyboard,
})
.set(arrowUp, this._handleArrowUp)
.set(arrowDown, this._handleArrowDown)
.set(arrowLeft, this._handleArrowLeft)
.set(arrowRight, this._handleArrowRight)
.set(homeKey, this._handleHomeKey)
.set(endKey, this._handleEndKey)
.setActivateHandler(this._handleInteraction);
}
update(properties) {
this._syncStepperAttributes(properties);
if (properties.has('orientation')) {
this._internals.setARIA({ ariaOrientation: this.orientation });
}
if (properties.has('linear')) {
this._state.setVisitedState(this.linear);
}
super.update(properties);
}
_skipKeyboard(_, event) {
return !findElementFromEventPath('[data-step-header]', event);
}
_handleHomeKey() {
this._getStepHeader(first(this._state.accessibleSteps))?.focus();
}
_handleEndKey() {
this._getStepHeader(last(this._state.accessibleSteps))?.focus();
}
_handleArrowDown() {
if (!this._isHorizontal) {
const step = this._getActiveStepComponent();
if (step) {
this._getStepHeader(this._getNextStep(step))?.focus();
}
}
}
_handleArrowUp() {
if (!this._isHorizontal) {
const step = this._getActiveStepComponent();
if (step) {
this._getStepHeader(this._getPreviousStep(step))?.focus();
}
}
}
_handleArrowLeft() {
const step = this._getActiveStepComponent();
if (step) {
const next = isLTR(this)
? this._getPreviousStep(step)
: this._getNextStep(step);
this._getStepHeader(next)?.focus();
}
}
_handleArrowRight() {
const step = this._getActiveStepComponent();
if (step) {
const next = isLTR(this)
? this._getNextStep(step)
: this._getPreviousStep(step);
this._getStepHeader(next)?.focus();
}
}
_handleInteraction(event) {
const step = findElementFromEventPath(IgcStepComponent.tagName, event);
if (step && this._state.isAccessible(step)) {
this._activateStep(step);
}
}
_handleSlotChange() {
this._state.setSteps(this._slots.getAssignedElements('[default]', {
selector: IgcStepComponent.tagName,
}));
this._state.stepsChanged();
this.style.setProperty('--steps-count', this.steps.length.toString());
}
_syncStepperAttributes(properties) {
if (STEPPER_SYNC_PROPERTIES.some((p) => properties.has(p))) {
this._contextProvider.updateObservers();
}
}
_animateSteps(nextStep, currentStep) {
const steps = this._state.steps;
if (steps.indexOf(nextStep) > steps.indexOf(currentStep)) {
currentStep.toggleAnimation('out');
nextStep.toggleAnimation('in');
}
else {
currentStep.toggleAnimation('in', 'reverse');
nextStep.toggleAnimation('out', 'reverse');
}
}
_emitChanging(args) {
return this.emitEvent('igcActiveStepChanging', {
detail: args,
cancelable: true,
});
}
_emitChanged(args) {
this.emitEvent('igcActiveStepChanged', {
detail: args,
});
}
_activateStep(step, shouldEmit = true) {
if (step === this._state.activeStep) {
return;
}
if (!shouldEmit) {
this._state.changeActiveStep(step);
return;
}
const steps = this._state.steps;
const activeIndex = steps.indexOf(this._state.activeStep);
const index = steps.indexOf(step);
const args = { oldIndex: activeIndex, newIndex: index };
if (!this._emitChanging(args)) {
return;
}
if (this._state.activeStep) {
this._animateSteps(step, this._state.activeStep);
}
this._state.changeActiveStep(step);
this._emitChanged({ index });
}
_moveToNextStep(next = true) {
const step = this._state.getAdjacentStep(next);
if (step) {
if (this._state.activeStep) {
this._animateSteps(step, this._state.activeStep);
}
this._state.changeActiveStep(step);
}
}
_getNextStep(step) {
const steps = this._state.accessibleSteps;
const next = wrap(0, steps.length - 1, steps.indexOf(step) + 1);
return steps[next];
}
_getPreviousStep(step) {
const steps = this._state.accessibleSteps;
const previous = wrap(0, steps.length - 1, steps.indexOf(step) - 1);
return steps[previous];
}
_getActiveStepComponent() {
const active = getRoot(this).activeElement;
return active ? active.closest(IgcStepComponent.tagName) : null;
}
_getStepHeader(step) {
return step?.renderRoot.querySelector('[data-step-header]') ?? null;
}
navigateTo(index) {
const step = this._state.steps[index];
if (step) {
this._activateStep(step, false);
}
}
next() {
this._moveToNextStep();
}
prev() {
this._moveToNextStep(false);
}
reset() {
this._state.reset();
}
render() {
return html `<slot></slot>`;
}
}
__decorate([
property({ reflect: true })
], IgcStepperComponent.prototype, "orientation", void 0);
__decorate([
property({ reflect: true, attribute: 'step-type' })
], IgcStepperComponent.prototype, "stepType", void 0);
__decorate([
property({ type: Boolean, reflect: true })
], IgcStepperComponent.prototype, "linear", void 0);
__decorate([
property({ type: Boolean, reflect: true, attribute: 'content-top' })
], IgcStepperComponent.prototype, "contentTop", void 0);
__decorate([
property({ attribute: 'vertical-animation' })
], IgcStepperComponent.prototype, "verticalAnimation", void 0);
__decorate([
property({ attribute: 'horizontal-animation' })
], IgcStepperComponent.prototype, "horizontalAnimation", void 0);
__decorate([
property({ type: Number, attribute: 'animation-duration' })
], IgcStepperComponent.prototype, "animationDuration", void 0);
__decorate([
property({ reflect: false, attribute: 'title-position' })
], IgcStepperComponent.prototype, "titlePosition", void 0);
//# sourceMappingURL=stepper.js.map