@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
654 lines (653 loc) • 23.3 kB
JavaScript
Object.defineProperties(exports, {
__esModule: { value: true },
[Symbol.toStringTag]: { value: "Module" }
});
const require_kendo_core = require("./kendo.core-kmRaf_Lg.js");
require("./kendo.progressbar.js");
require("./kendo.icons.js");
//#region ../src/kendo.stepper.js
const __meta__ = {
id: "stepper",
name: "Stepper",
category: "web",
description: "The Stepper widget displays navigation steps.",
depends: [
"core",
"progressbar",
"icons"
]
};
(function($, undefined) {
var kendo = window.kendo, Widget = kendo.ui.Widget, keys = kendo.keys, extend = $.extend, encode = kendo.htmlEncode, STEPPER = ".kendoStepper", CLICK = "click", ACTIVATE = "activate", SELECT = "select", KEYDOWN = "keydown", FOCUSOUT = "focusout", DOT = ".", SPACE = " ", VERTICAL = "vertical", TABINDEX = "tabindex", ARIA_CURRENT = "aria-current", ARIA_DISABLED = "aria-disabled", ARIA_INVALID = "aria-invalid", ARIA_HIDDEN = "aria-hidden";
var stepStyles = {
step: "k-step",
firstStep: "k-step-first",
lastStep: "k-step-last",
doneStep: "k-step-done",
successStep: "k-step-success",
errorStep: "k-step-error",
currentStep: "k-step-current",
focusStep: "k-focus",
disabledStep: "k-disabled",
stepLink: "k-step-link",
stepIndicator: "k-step-indicator",
stepLabel: "k-step-label"
};
var stepperStyles = {
widget: "k-stepper",
stepperLinear: "k-stepper-linear",
stepList: "k-step-list",
stepListHorizontal: "k-step-list-horizontal",
stepListVertical: "k-step-list-vertical"
};
var Step = kendo.Class.extend({
init: function(options) {
this.options = extend({}, this.options, options);
this._render();
},
options: {
label: "",
icon: "",
successIcon: "",
iconTemplate: null,
enabled: true,
error: false,
selected: false,
isFirstStep: false,
isLastStep: false,
indicatorVisible: true,
labelVisible: true,
index: 0,
previous: false,
selectable: true
},
_indicatorTemplate: ({ successIcon, index, icon, previous, error }) => {
let indicatorContent;
if (successIcon && previous && !error) indicatorContent = kendo.ui.icon({
icon: encode(successIcon),
iconClass: "k-step-indicator-icon"
});
else if (icon) indicatorContent = kendo.ui.icon({
icon: encode(icon),
iconClass: "k-step-indicator-icon"
});
else if (previous && !error) indicatorContent = kendo.ui.icon({
icon: "check",
iconClass: "k-step-indicator-icon"
});
else indicatorContent = `<span class="k-step-indicator-text">${encode(index + 1)}</span>`;
return "<span class=\"k-step-indicator\" aria-hidden=\"true\">" + indicatorContent + "</span>";
},
_labelTemplate: ({ label, indicatorVisible, previous, error }) => "<span class=\"k-step-label\"><span class=\"k-step-text\">" + encode(label) + "</span> " + (error || !indicatorVisible && !error && previous ? kendo.ui.icon($("<span aria-hidden=\"true\"></span>"), { icon: error ? "warning-circle" : "check-circle" }) : "") + "</span>",
deselect: function() {
this.options.selected = false;
this._link();
this._stepClasses();
},
enable: function(value) {
if (this.options.enabled !== value) {
this.options.enabled = value;
this.options.selectable = value;
this._link();
this._stepClasses();
}
},
select: function() {
this.options.selected = true;
this._link();
this._stepClasses();
},
getEnabled: function() {
return this.options.enabled;
},
getIndex: function() {
return this.options.index;
},
setPrevious: function(previous) {
this.options.previous = previous;
this._link();
this._stepClasses();
},
getSelectable: function() {
return this.options.selectable;
},
getSelected: function() {
return this.options.selected;
},
setValid: function(valid) {
if (this.options.error === valid) {
this.options.error = !valid;
this._link();
this._stepClasses();
}
},
_indicator: function() {
var options = this.options, stepIndicator;
if (!!options.iconTemplate) {
stepIndicator = $("<span>").addClass(stepStyles.stepIndicator).attr(ARIA_HIDDEN, "true");
stepIndicator.append(kendo.template(options.iconTemplate)(options));
} else stepIndicator = kendo.template(this._indicatorTemplate)(options);
this.element.find(DOT + stepStyles.stepLink).append(stepIndicator);
},
_label: function() {
var stepLabel = kendo.template(this._labelTemplate)(this.options);
this.element.find(DOT + stepStyles.stepLink).append(stepLabel);
},
_link: function() {
var options = this.options;
this.element.find(DOT + stepStyles.stepLink).empty();
this._linkAttributes();
if (options.indicatorVisible) this._indicator();
if (options.labelVisible) this._label();
},
_linkAttributes: function() {
var options = this.options, link = this.element.find(DOT + stepStyles.stepLink);
link.removeAttr(ARIA_DISABLED + SPACE + ARIA_INVALID + SPACE + ARIA_CURRENT + SPACE + TABINDEX);
if (!options.selected) link.attr(TABINDEX, "-1");
else link.attr(ARIA_CURRENT, "step");
if (!options.enabled || !options.selectable) link.attr(ARIA_DISABLED, "true");
if (options.error) link.attr(ARIA_INVALID, "true");
},
_render: function() {
var stepLink = $("<a href='#'>").addClass(stepStyles.stepLink).attr("title", this.options.label);
this.element = $("<li>").append(stepLink);
this._link();
this._stepClasses();
},
_stepClasses: function() {
var options = this.options, stepClasses = stepStyles.step;
if (options.isFirstStep) stepClasses += SPACE + stepStyles.firstStep;
if (options.isLastStep) stepClasses += SPACE + stepStyles.lastStep;
if (!options.enabled) stepClasses += SPACE + stepStyles.disabledStep;
if (options.error) stepClasses += SPACE + stepStyles.errorStep;
if (options.previous) {
stepClasses += SPACE + stepStyles.doneStep;
if (!options.error) stepClasses += SPACE + stepStyles.successStep;
} else if (options.selected) {
stepClasses += SPACE + stepStyles.currentStep;
stepClasses += SPACE + stepStyles.focusStep;
}
this.element.removeClass().addClass(stepClasses);
}
});
var Stepper = Widget.extend({
init: function(element, options) {
var that = this;
options = options || {};
Widget.fn.init.call(that, element, options);
that._indicatorAndLabel();
that._wrapper();
if (options.steps && options.steps.length) {
that._processSteps(options.steps);
that._progressBar();
}
that._attachEvents();
that._resizeObserver = require_kendo_core.domUtilsService.createResizeObserver({
element: that.wrapper,
onResize: function() {
that.resize();
}
});
Widget.fn.endInit.call(that);
},
options: {
orientation: "horizontal",
linear: true,
indicator: true,
label: true,
selectOnFocus: false,
steps: null,
name: "Stepper"
},
events: [
ACTIVATE,
SELECT,
"kendoKeydown"
],
destroy: function() {
var that = this;
if (that.progressBar) Widget.fn.destroy.call(that.progressBar);
Widget.fn.destroy.call(that);
if (that._resizeObserver) {
that._resizeObserver.destroy();
that._resizeObserver = null;
}
that.wrapper.off(STEPPER);
},
setOptions: function(options) {
var that = this;
Widget.fn.setOptions.call(that, options);
if (that.progressBar) Widget.fn.destroy.call(that.progressBar);
that._indicatorAndLabel();
that._addStepList();
if (that.options.steps && that.options.steps.length) {
that._processSteps(that.options.steps);
that._progressBar();
}
},
enable: function(value) {
var steps = this.steps(), stepsOptions = this.options.steps;
var enableStep = function(step, idx) {
step.enable(value);
stepsOptions[idx] = step.options;
};
if (value) this.wrapper.removeAttr(ARIA_DISABLED);
else this.wrapper.attr(ARIA_DISABLED, "true");
this.progressBar.enable(value);
steps.forEach(enableStep);
},
insertAt: function(index, stepOptions) {
var steps = this.options.steps, selectedStep;
var findSelectedStep = function(step) {
if (step.selected) selectedStep = step;
};
if (!stepOptions || isNaN(index)) return;
if (index < 0) index = steps.length + index;
if (index < 0) return;
if (!steps) steps = [];
if (steps.length === 0 || index >= steps.length) index = steps.length;
steps.forEach(findSelectedStep);
if (stepOptions.selected === true) selectedStep.selected = false;
steps.splice(index, 0, stepOptions);
this._createSteps();
this._renderSteps();
this._resetProgressBar();
this._calculateDimensions();
},
next: function() {
if (!this._steps || this._steps.length <= 1) return;
var selectedIndex = this.selectedStep.getIndex();
if (selectedIndex + 1 === this._steps.length) return;
else this._select(selectedIndex + 1);
},
previous: function() {
if (!this._steps || this._steps.length <= 1) return;
var selectedIndex = this.selectedStep.getIndex();
if (selectedIndex === 0) return;
else this._select(selectedIndex - 1);
},
removeAt: function(index) {
var steps = this.options.steps, removedStep, newSelected, newSelectedIndex;
if (isNaN(index) || !steps || steps.length < 2 || index >= steps.length) return;
if (index < 0) index = steps.length + index;
if (index < 0) return;
removedStep = steps.splice(index, 1)[0];
if (removedStep.selected === true && steps.length > 0) {
if (index > 0) newSelectedIndex = index - 1;
else newSelectedIndex = 0;
newSelected = steps[newSelectedIndex];
if (typeof newSelected === "string") {
newSelected = { label: newSelected };
steps[newSelectedIndex] = newSelected;
}
newSelected.selected = true;
newSelected.previous = false;
}
this._createSteps();
this._renderSteps();
this._resetProgressBar();
this._calculateDimensions();
},
resize: function() {
this._calculateDimensions();
},
select: function(stepIndex) {
var that = this;
if (stepIndex === undefined || stepIndex === null || isNaN(stepIndex)) return that.selectedStep;
if (stepIndex >= that._steps.length || stepIndex < 0) return;
stepIndex = Number(stepIndex);
that._select(stepIndex);
},
steps: function(steps) {
if (steps === undefined) return this._steps;
this._processSteps(steps);
this._resetProgressBar();
this._calculateDimensions();
},
_processSteps: function(steps) {
var that = this, selectedStep;
var findSelectedStep = function(step) {
if (step.selected) selectedStep = step;
};
steps.forEach(findSelectedStep);
if (!selectedStep) {
if (typeof steps[0] === "string") steps[0] = { label: steps[0] };
steps[0].selected = true;
}
that.options.steps = steps;
that._createSteps();
that._renderSteps();
},
_addStepList: function() {
var that = this;
that.wrapper.empty().append($("<ol />").addClass(stepperStyles.stepList));
that._stepList = that.wrapper.find(DOT + stepperStyles.stepList);
if (that.options.orientation === VERTICAL) that._stepList.addClass(stepperStyles.stepListVertical);
else that._stepList.addClass(stepperStyles.stepListHorizontal);
},
_attachEvents: function() {
var that = this;
that.wrapper.on(CLICK + STEPPER, DOT + stepStyles.step, that._selectClickHandler.bind(that)).on(CLICK + STEPPER, that._wrapperClickHandler.bind(that)).on(FOCUSOUT + STEPPER, that._focusout.bind(that)).on(KEYDOWN + STEPPER, that, that._keydown.bind(that));
},
_calculateDimensions: function() {
if (!this._steps) return;
var orientation = this.options.orientation, numberOfSteps = this._steps.length, stepList = this._stepList, steps = stepList.find(DOT + stepStyles.step), stepWidth = stepList.width() / numberOfSteps, stepHeight = stepList.height() / numberOfSteps, progressElement = this.progressBar.element, margin = "margin-left", style = {};
if (orientation === VERTICAL) {
steps.css("max-height", 100 / numberOfSteps + "%");
progressElement.css({
"margin-top": -1 * (stepList.height() - 16),
"height": stepHeight * (numberOfSteps - 1)
});
} else {
steps.css("max-width", 100 / numberOfSteps + "%");
if (kendo.support.isRtl(this.wrapper)) margin = "margin-right";
style[margin] = stepWidth / 2;
style.width = stepWidth * (numberOfSteps - 1);
progressElement.css(style);
}
},
_createStep: function(stepOptions, idx, isLastStep) {
var that = this, isFirstStep = idx === 0, options = that.options, indicatorVisible = options.indicator, labelVisible = options.label;
stepOptions = extend({}, stepOptions, { enabled: stepOptions.enabled === false ? false : true });
stepOptions = extend({}, stepOptions, {
isFirstStep,
isLastStep,
indicatorVisible,
labelVisible,
index: idx
});
return new Step(stepOptions);
},
_createSteps: function() {
var that = this, stepsOptions = that.options.steps, selected = false, step, idx, isLastStep, stepOpt;
that._steps = [];
for (idx = 0; idx < stepsOptions.length; idx++) {
stepOpt = stepsOptions[idx];
if (typeof stepOpt === "string") stepOpt = { label: stepOpt };
if (stepOpt !== undefined) {
isLastStep = idx === stepsOptions.length - 1;
if (stepOpt.selected) selected = true;
else stepOpt = that._selectablePreviousState(stepOpt, selected, idx);
step = that._createStep(stepOpt, idx, isLastStep);
that._steps.push(step);
if (step.getSelected()) that.selectedStep = step;
}
}
},
_indicatorAndLabel: function() {
if (!this.options.indicator && !this.options.label) {
this.options.indicator = true;
this.options.label = true;
}
},
_focusout: function(e) {
var that = this;
if (!that.wrapper.get(0).contains(e.relatedTarget)) setTimeout(function() {
that._leaveStepper();
});
},
_focusStep: function(newStep) {
var focusedStep = this.wrapper.find(DOT + stepStyles.focusStep), allStepLinks = this.wrapper.find(DOT + stepStyles.stepLink);
if (newStep.length > 0) {
focusedStep.removeClass(stepStyles.focusStep);
allStepLinks.attr(TABINDEX, "-1");
newStep.find(DOT + stepStyles.stepLink).removeAttr(TABINDEX)[0].focus();
}
},
_focusNextStep: function() {
var nextStep = $(document.activeElement).closest(DOT + stepStyles.step).next();
this._focusStep(nextStep);
},
_focusPreviousStep: function() {
var previousStep = $(document.activeElement).closest(DOT + stepStyles.step).prev();
this._focusStep(previousStep);
},
_focusFirstStep: function() {
var firstStep = this.wrapper.find(DOT + stepStyles.firstStep);
this._focusStep(firstStep);
},
_focusLastStep: function() {
var lastStep = this.wrapper.find(DOT + stepStyles.lastStep);
this._focusStep(lastStep);
},
_keydown: function(e) {
var that = this, keyCode = e.keyCode, focusedStepIndex = $(document.activeElement).closest(DOT + stepStyles.step).index(), stepsCount = that.steps().length;
if (keyCode === keys.TAB) {
if (e.shiftKey && focusedStepIndex > 0) {
e.preventDefault();
that._tabKey(e, -1);
} else if (!e.shiftKey && focusedStepIndex < stepsCount - 1) {
e.preventDefault();
that._tabKey(e, 1);
}
} else if (keyCode > 34 && keyCode < 41) {
e.preventDefault();
that._navKeys(e);
} else if (keyCode === keys.ENTER || keyCode === keys.SPACEBAR) {
e.preventDefault();
that._selectHandler(e, $(document.activeElement).closest(DOT + stepStyles.step));
} else e.preventDefault();
},
_leaveStepper: function() {
var selectedStep = this.wrapper.find(DOT + stepStyles.currentStep);
this.wrapper.find(DOT + stepStyles.stepLink).removeClass(stepStyles.focusStep).attr(TABINDEX, "-1");
selectedStep.addClass(stepStyles.focusStep);
selectedStep.find(DOT + stepStyles.stepLink).removeAttr(TABINDEX);
},
_navKeys: function(e) {
if (this.options.selectOnFocus) this._navKeysSelect(e);
else this._navKeysFocus(e);
},
_navKeysFocus: function(e) {
var keyCode = e.keyCode, rtl = kendo.support.isRtl(this.wrapper), orientation = this.options.orientation;
switch (keyCode) {
case keys.DOWN:
if (rtl && orientation !== VERTICAL) this._focusPreviousStep();
else this._focusNextStep();
break;
case keys.RIGHT:
if (rtl) this._focusPreviousStep();
else this._focusNextStep();
break;
case keys.UP:
if (rtl && orientation !== VERTICAL) this._focusNextStep();
else this._focusPreviousStep();
break;
case keys.LEFT:
if (rtl) this._focusNextStep();
else this._focusPreviousStep();
break;
case keys.HOME:
this._focusFirstStep();
break;
case keys.END:
this._focusLastStep();
break;
}
},
_navKeysSelect: function(e) {
var keyCode = e.keyCode, focusedStepIndex = $(document.activeElement).closest(DOT + stepStyles.step).index(), rtl = kendo.support.isRtl(this.wrapper), steps = this.steps(), orientation = this.options.orientation, targetStep;
switch (keyCode) {
case keys.DOWN:
if (rtl && orientation !== VERTICAL) targetStep = steps[focusedStepIndex - 1];
else targetStep = steps[focusedStepIndex + 1];
break;
case keys.RIGHT:
if (rtl) targetStep = steps[focusedStepIndex - 1];
else targetStep = steps[focusedStepIndex + 1];
break;
case keys.UP:
if (rtl && orientation !== VERTICAL) targetStep = steps[focusedStepIndex + 1];
else targetStep = steps[focusedStepIndex - 1];
break;
case keys.LEFT:
if (rtl) targetStep = steps[focusedStepIndex + 1];
else targetStep = steps[focusedStepIndex - 1];
break;
case keys.HOME:
targetStep = steps[0];
break;
case keys.END:
targetStep = steps[steps.length - 1];
break;
}
if (targetStep) {
this._focusStep(targetStep.element);
this._selectHandlerOnKey(e, targetStep.element);
}
},
_progressBar: function() {
var wrapper = this.wrapper, progressBarOptions = this._progressOptions();
this.progressBar = $("<div>").kendoProgressBar(progressBarOptions).getKendoProgressBar();
this.progressBar.element.css("position", "absolute");
this._calculateDimensions();
wrapper.append(this.progressBar.element);
},
_progressOptions: function() {
var options = this.options, orientation = options.orientation, stepsOptions = options.steps, numberOfSteps, progressBarOptions;
if (!stepsOptions || stepsOptions.length === 0) return;
else numberOfSteps = stepsOptions.length;
progressBarOptions = {
max: numberOfSteps - 1,
value: this.select().getIndex(),
orientation,
showStatus: false
};
if (orientation === VERTICAL) progressBarOptions.reverse = true;
return progressBarOptions;
},
_resetProgressBar: function() {
var progressBar = this.progressBar, newOptions;
if (!progressBar) return;
newOptions = this._progressOptions();
progressBar.setOptions(newOptions);
},
_renderSteps: function() {
var steps = this._steps, stepsList = this._stepList, step, idx;
stepsList.empty();
for (idx = 0; idx < steps.length; idx++) {
step = steps[idx];
stepsList.append(step.element);
}
},
_resetStep: function(i, index, forward) {
var step = this._steps[i];
if (i === index) {
step.options.previous = false;
step.options.selected = true;
} else if ((forward || i > index) && (!forward || i < index)) {
step.options.selected = false;
step.options.previous = forward;
}
if (this.options.linear && (i < index - 1 || i > index + 1)) step.options.selectable = false;
else step.options.selectable = true;
step._link();
step._stepClasses();
this.options.steps[i] = step.options;
},
_select: function(index) {
var options = this.options, linear = options.linear, selectedIndex = this.select().getIndex(), stepsOptions = options.steps, targetStep = this._steps[index], forward, i, min, max;
if (!targetStep || !targetStep.getEnabled()) return;
if (index > selectedIndex) {
forward = true;
if (linear) {
min = Math.max(selectedIndex - 1, 0);
max = Math.min(index + 1, stepsOptions.length - 1);
} else {
min = selectedIndex;
max = index;
}
} else {
forward = false;
if (linear) {
min = Math.max(index - 1, 0);
max = Math.min(selectedIndex + 1, stepsOptions.length - 1);
} else {
min = index;
max = selectedIndex;
}
}
for (i = min; i <= max; i++) this._resetStep(i, index, forward);
this.selectedStep = targetStep;
this.progressBar.value(index);
},
_selectablePreviousState: function(stepOpt, selected, idx) {
var stepsOptions = this.options.steps, linear = this.options.linear;
if (!selected) {
stepOpt.previous = true;
if (linear && !stepsOptions[idx + 1].selected) stepOpt.selectable = false;
else stepOpt.selectable = true;
} else if (linear && !stepsOptions[idx - 1].selected) stepOpt.selectable = false;
else stepOpt.selectable = true;
return stepOpt;
},
_selectClickHandler: function(e) {
var stepElement = $(e.target).closest(DOT + stepStyles.step);
e.preventDefault();
this._preventWrapperClick = true;
this._selectHandler(e, stepElement);
},
_selectHandler: function(e, stepElement) {
var that = this, step = that._steps[stepElement.index()], currentStep = this.select();
if (!step || step.getIndex() === currentStep.getIndex() || !step.getEnabled() || !step.getSelectable()) {
that._focusStep(currentStep.element);
return;
}
if (!that.trigger(SELECT, {
sender: that,
originalEvent: e,
step
})) {
that._select(step.getIndex());
stepElement.find(DOT + stepStyles.stepLink)[0].focus();
that.trigger(ACTIVATE, {
sender: that,
originalEvent: e,
step
});
}
},
_selectHandlerOnKey: function(e, stepElement) {
var that = this, step = that._steps[stepElement.index()];
if (!step.getEnabled() || !step.getSelectable()) return;
if (!that.trigger(SELECT, {
sender: that,
originalEvent: e,
step
})) {
that._select(step.getIndex());
stepElement.find(DOT + stepStyles.stepLink)[0].focus();
that.trigger(ACTIVATE, {
sender: that,
originalEvent: e,
step
});
}
},
_tabKey: function(e, shift) {
var selectOnFocus = this.options.selectOnFocus, focusedStepElement = $(document.activeElement).closest(DOT + stepStyles.step), focusedStepIndex = focusedStepElement.index(), targetStep = $(focusedStepElement.parent().find(DOT + stepStyles.step)[focusedStepIndex + shift]);
this._focusStep(targetStep);
if (selectOnFocus) this._selectHandlerOnKey(e, targetStep);
},
_wrapper: function() {
var that = this;
that.wrapper = that.element;
that.wrapper.addClass(stepperStyles.widget);
if (that.options.linear) that.wrapper.addClass(stepperStyles.stepperLinear);
this._addStepList();
},
_wrapperClickHandler: function(e) {
var currentStep = this.select();
if (!this._preventWrapperClick) {
e.preventDefault();
this._focusStep(currentStep.element);
} else this._preventWrapperClick = false;
}
});
kendo.stepper = { Step };
kendo.ui.plugin(Stepper);
})(window.kendo.jQuery);
var kendo_stepper_default = kendo;
//#endregion
exports.__meta__ = __meta__;
exports.default = kendo_stepper_default;