@oruga-ui/oruga-next
Version:
UI components for Vue.js and CSS framework agnostic
544 lines (543 loc) • 21.7 kB
JavaScript
"use strict";
/*! Oruga v0.11.0 | MIT License | github.com/oruga-ui/oruga */
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const vue = require("vue");
const config = require("./config-eYBvpFOZ.cjs");
const defineClasses = require("./defineClasses-Cqhbv-UT.cjs");
const useParentProvider = require("./useParentProvider-CPNahRzD.cjs");
const Button_vue_vue_type_script_setup_true_lang = require("./Button.vue_vue_type_script_setup_true_lang-BSST4v3C.cjs");
const Icon_vue_vue_type_script_setup_true_lang = require("./Icon.vue_vue_type_script_setup_true_lang-ZtEqoTvT.cjs");
const helpers = require("./helpers.cjs");
const useMatchMedia = require("./useMatchMedia-EgWTgaUx.cjs");
const useOptions = require("./useOptions-YcqJ438a.cjs");
const useSequentialId = require("./useSequentialId-BnH6otip.cjs");
const _hoisted_1$1 = ["id", "data-id", "hidden", "aria-labelledby"];
const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
...{
isOruga: true,
name: "OStepItem",
configField: "steps",
inheritAttrs: false
},
__name: "StepItem",
props: {
override: { type: Boolean, default: void 0 },
value: { default: void 0 },
label: { default: void 0 },
step: { default: void 0 },
variant: { default: void 0 },
disabled: { type: Boolean, default: false },
clickable: { type: Boolean, default: void 0 },
visible: { type: Boolean, default: true },
icon: { default: () => config.getDefault("steps.icon") },
iconPack: { default: () => config.getDefault("steps.iconPack") },
content: { default: void 0 },
component: { default: void 0 },
props: { default: void 0 },
events: { default: void 0 },
stepClass: {},
stepActiveClass: {},
stepVariantClass: {},
stepPositionClass: {},
stepClickableClass: {},
stepDisabledClass: {},
stepPreviousClass: {},
stepNextClass: {},
stepLabelClass: {},
stepIconClass: {},
stepPanelClass: {}
},
emits: ["activate", "deactivate"],
setup(__props, { emit: __emit }) {
const props = __props;
const emits = __emit;
const itemValue = props.value ?? vue.useId();
const slots = vue.useSlots();
const providedData = vue.computed(() => ({
...props,
value: itemValue,
$slots: slots,
stepClasses: stepClasses.value,
iconClasses: stepIconClasses.value,
labelClasses: stepLabelClasses.value,
isClickable: isClickable.value,
isTransitioning: isTransitioning.value,
activate,
deactivate
}));
const { parent, item } = useParentProvider.useProviderChild(
{ data: providedData }
);
const transitionName = vue.ref();
const isActive = vue.computed(() => item.value.index === parent.value.activeIndex);
const isTransitioning = vue.ref(false);
const nextAnimation = vue.computed(() => {
const idx = parent.value.vertical && parent.value.animation.length === 4 ? 2 : 0;
return parent.value.animation[idx];
});
const prevAnimation = vue.computed(() => {
const idx = parent.value.vertical && parent.value.animation.length === 4 ? 3 : 1;
return parent.value.animation[idx];
});
const isClickable = vue.computed(
() => props.clickable || item.value.index < parent.value.activeIndex
);
function activate(oldIndex) {
transitionName.value = item.value.index < oldIndex ? nextAnimation.value : prevAnimation.value;
emits("activate");
}
function deactivate(newIndex) {
transitionName.value = newIndex < item.value.index ? nextAnimation.value : prevAnimation.value;
emits("deactivate");
}
function afterEnter() {
isTransitioning.value = true;
}
function beforeLeave() {
isTransitioning.value = true;
}
const stepClasses = defineClasses.defineClasses(
["stepClass", "o-steps__step"],
[
"stepVariantClass",
"o-steps__step--",
vue.computed(() => {
var _a;
return ((_a = parent.value) == null ? void 0 : _a.variant) || props.variant;
}),
vue.computed(() => {
var _a;
return !!((_a = parent.value) == null ? void 0 : _a.variant) || !!props.variant;
})
],
["stepActiveClass", "o-steps__step--active", null, isActive],
["stepClickableClass", "o-steps__step--clickable", null, isClickable],
[
"stepDisabledClass",
"o-steps__step--disabled",
null,
vue.computed(() => props.disabled)
],
[
"stepPreviousClass",
"o-steps__step--previous",
null,
vue.computed(() => {
var _a;
return item.value.index < ((_a = parent.value) == null ? void 0 : _a.activeIndex);
})
],
[
"stepNextClass",
"o-steps__step--next",
null,
vue.computed(() => {
var _a;
return item.value.index > ((_a = parent.value) == null ? void 0 : _a.activeIndex);
})
],
[
"stepPositionClass",
"o-steps__step--",
vue.computed(() => {
var _a;
return (_a = parent.value) == null ? void 0 : _a.labelPosition;
}),
vue.computed(() => {
var _a;
return !!((_a = parent.value) == null ? void 0 : _a.labelPosition);
})
]
);
const stepLabelClasses = defineClasses.defineClasses([
"stepLabelClass",
"o-steps__step-label"
]);
const stepIconClasses = defineClasses.defineClasses(["stepIconClass", "o-steps__step-icon"]);
const panelClasses = defineClasses.defineClasses(["stepPanelClass", "o-steps__panel"]);
return (_ctx, _cache) => {
return vue.unref(parent) ? (vue.openBlock(), vue.createBlock(vue.Transition, {
key: 0,
css: vue.unref(parent).animated,
name: transitionName.value,
appear: vue.unref(parent).animateInitially,
onAfterEnter: afterEnter,
onBeforeLeave: beforeLeave
}, {
default: vue.withCtx(() => [
vue.withDirectives(vue.createElementVNode("div", vue.mergeProps(_ctx.$attrs, {
id: `tabpanel-${vue.unref(item).identifier}`,
"data-oruga": "steps-item",
"data-id": `steps-${vue.unref(item).identifier}`,
class: vue.unref(panelClasses),
role: "tabpanel",
hidden: !isActive.value,
"aria-labelledby": `tab-${vue.unref(item).identifier}`,
"aria-roledescription": "item"
}), [
vue.renderSlot(_ctx.$slots, "default", {
active: isActive.value && _ctx.visible
}, () => [
_ctx.component ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.component), vue.mergeProps({ key: 0 }, _ctx.$props.props, vue.toHandlers(_ctx.$props.events || {})), null, 16)) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
vue.createTextVNode(vue.toDisplayString(_ctx.content), 1)
], 64))
])
], 16, _hoisted_1$1), [
[vue.vShow, isActive.value && _ctx.visible]
])
]),
_: 3
}, 8, ["css", "name", "appear"])) : vue.createCommentVNode("", true);
};
}
});
const _hoisted_1 = ["aria-label", "aria-orientation"];
const _hoisted_2 = ["id", "tabindex", "aria-current", "aria-controls", "aria-selected", "onClick", "onKeydown"];
const _hoisted_3 = { key: 1 };
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
...{
isOruga: true,
name: "OSteps",
configField: "steps"
},
__name: "Steps",
props: /* @__PURE__ */ vue.mergeModels({
override: { type: Boolean, default: void 0 },
modelValue: { default: void 0 },
options: { default: void 0 },
variant: { default: () => config.getDefault("steps.variant") },
size: { default: () => config.getDefault("steps.size") },
vertical: { type: Boolean, default: false },
position: { default: void 0 },
iconPack: { default: () => config.getDefault("steps.iconPack") },
iconPrev: { default: () => config.getDefault("steps.iconPrev", "chevron-left") },
iconNext: { default: () => config.getDefault("steps.iconNext", "chevron-right") },
hasNavigation: { type: Boolean, default: true },
activateOnFocus: { type: Boolean, default: false },
animated: { type: Boolean, default: () => config.getDefault("steps.animated", true) },
animation: { default: () => config.getDefault("steps.animation", [
"slide-next",
"slide-prev",
"slide-down",
"slide-up"
]) },
animateInitially: { type: Boolean, default: () => config.getDefault("steps.animateInitially", false) },
labelPosition: { default: () => config.getDefault("steps.labelPosition", "bottom") },
rounded: { type: Boolean, default: true },
mobileBreakpoint: { default: () => config.getDefault("steps.mobileBreakpoint") },
ariaLabel: { default: () => config.getDefault("steps.ariaLabel") },
ariaNextLabel: { default: () => config.getDefault("steps.ariaNextLabel", "Next") },
ariaPreviousLabel: { default: () => config.getDefault("steps.ariaPreviousLabel", "Previous") },
rootClass: {},
mobileClass: {},
sizeClass: {},
variantClass: {},
verticalClass: {},
positionClass: {},
listClass: {},
animatedClass: {},
dividerClass: {},
markerClass: {},
markerRoundedClass: {},
contentClass: {},
transitioningClass: {},
navigationClass: {}
}, {
"modelValue": { default: void 0 },
"modelModifiers": {}
}),
emits: /* @__PURE__ */ vue.mergeModels(["update:model-value", "change"], ["update:modelValue"]),
setup(__props, { emit: __emit }) {
const props = __props;
const emits = __emit;
const { isMobile } = useMatchMedia.useMatchMedia(props.mobileBreakpoint);
const rootRef = vue.useTemplateRef("rootElement");
const provideData = vue.computed(() => {
var _a;
return {
activeIndex: ((_a = activeItem.value) == null ? void 0 : _a.index) ?? 0,
labelPosition: props.labelPosition,
vertical: props.vertical,
animated: props.animated,
animation: props.animation,
animateInitially: props.animateInitially,
variant: props.variant
};
});
const { childItems } = useParentProvider.useProviderParent({
rootRef,
data: provideData
});
const items = vue.computed(() => {
if (!childItems.value) return [];
return childItems.value.map((column) => ({
index: column.index,
identifier: column.identifier,
...vue.toValue(column.data)
}));
});
const { nextSequence } = useSequentialId.useSequentialId();
const groupedOptions = vue.computed(
() => useOptions.normalizeOptions(props.options, nextSequence)
);
const vmodel = vue.useModel(__props, "modelValue");
vue.watch(
() => props.modelValue,
(value) => {
if (vmodel.value !== value) performAction(value);
}
);
const activeItem = vue.ref();
vue.watchEffect(() => {
activeItem.value = helpers.isDefined(vmodel.value) ? items.value.find((item) => item.value === vmodel.value) || items.value[0] : items.value[0];
});
const isTransitioning = vue.computed(
() => items.value.some((item) => item.isTransitioning)
);
function activateItem(fowardIndex) {
var _a;
const index2 = (((_a = activeItem.value) == null ? void 0 : _a.index) ?? 0) + fowardIndex;
if (index2 < 0 || index2 >= items.value.length) return;
const item = items.value[index2];
if (vmodel.value !== item.value) performAction(item.value);
}
function itemClick(item) {
if (!item.isClickable) return;
if (vmodel.value !== item.value) performAction(item.value);
}
const hasPrev = vue.computed(
() => {
var _a;
return helpers.isDefined(getFirstViableIndex((((_a = activeItem.value) == null ? void 0 : _a.index) ?? 0) - 1, false));
}
);
const hasNext = vue.computed(
() => {
var _a;
return helpers.isDefined(getFirstViableIndex((((_a = activeItem.value) == null ? void 0 : _a.index) ?? 0) + 1, true));
}
);
function onNext(index2) {
const viableIndex = getFirstViableIndex(index2 + 1, true);
if (helpers.isDefined(viableIndex)) moveFocus(viableIndex);
}
function onPrev(index2) {
const viableIndex = getFirstViableIndex(index2 - 1, false);
if (helpers.isDefined(viableIndex)) moveFocus(viableIndex);
}
function onHomePressed() {
const viableIndex = getFirstViableIndex(0, true);
if (helpers.isDefined(viableIndex)) moveFocus(viableIndex);
}
function onEndPressed() {
const viableIndex = getFirstViableIndex(items.value.length - 1, false);
if (helpers.isDefined(viableIndex)) moveFocus(viableIndex);
}
function moveFocus(index2) {
var _a;
if (index2 < 0 || index2 >= items.value.length) return;
const item = items.value[index2];
if (props.activateOnFocus) {
itemClick(item);
} else {
const el = (_a = rootRef.value) == null ? void 0 : _a.querySelector(
`#tab-${item.identifier}`
);
el == null ? void 0 : el.focus();
}
}
function getFirstViableIndex(startingIndex, forward) {
const direction = forward ? 1 : -1;
let newIndex = startingIndex;
for (; newIndex > 0 && newIndex < items.value.length; newIndex += direction) {
const item = items.value[newIndex];
if (item.visible && !item.disabled) break;
}
if (newIndex < 0 || newIndex >= items.value.length) return void 0;
return newIndex;
}
function performAction(newValue) {
var _a;
const oldValue = (_a = activeItem.value) == null ? void 0 : _a.value;
const oldItem = activeItem.value;
const newItem = items.value.find((item) => item.value === newValue) || items.value[0];
if (oldItem && newItem) {
oldItem.deactivate(newItem.index);
newItem.activate(oldItem.index);
}
vue.nextTick(() => {
vmodel.value = newValue;
emits("change", newValue, oldValue);
});
}
const rootClasses = defineClasses.defineClasses(
["rootClass", "o-steps"],
[
"sizeClass",
"o-steps--",
vue.computed(() => props.size),
vue.computed(() => !!props.size)
],
[
"variantClass",
"o-steps--",
vue.computed(() => props.variant),
vue.computed(() => !!props.variant)
],
[
"verticalClass",
"o-steps--vertical",
null,
vue.computed(() => props.vertical)
],
[
"positionClass",
"o-steps--position-",
vue.computed(() => props.position),
vue.computed(() => !!props.position && props.vertical)
],
["mobileClass", "o-steps--mobile", null, isMobile]
);
const tablistClasses = defineClasses.defineClasses(
["listClass", "o-steps__list"],
[
"animatedClass",
"o-steps__list--animated",
null,
vue.computed(() => props.animated)
]
);
const dividerClasses = defineClasses.defineClasses(["dividerClass", "o-steps__divider"]);
const markerClasses = defineClasses.defineClasses(
["markerClass", "o-steps__marker"],
[
"markerRoundedClass",
"o-steps__marker--rounded",
null,
vue.computed(() => props.rounded)
]
);
const contentClasses = defineClasses.defineClasses(
["contentClass", "o-steps__content"],
[
"transitioningClass",
"o-steps__content-transitioning",
null,
isTransitioning
]
);
const navigationClasses = defineClasses.defineClasses([
"navigationClass",
"o-steps__navigation"
]);
return (_ctx, _cache) => {
return vue.openBlock(), vue.createElementBlock("div", {
ref: "rootElement",
"data-oruga": "steps",
class: vue.normalizeClass(vue.unref(rootClasses))
}, [
vue.createElementVNode("ol", {
class: vue.normalizeClass(vue.unref(tablistClasses)),
role: "tablist",
"aria-label": _ctx.ariaLabel,
"aria-orientation": _ctx.vertical ? "vertical" : "horizontal"
}, [
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(items.value, (childItem, index2) => {
var _a, _b, _c;
return vue.withDirectives((vue.openBlock(), vue.createElementBlock("li", {
id: `tab-${childItem.identifier}`,
key: childItem.identifier,
class: vue.normalizeClass(childItem.stepClasses),
role: "tab",
tabindex: childItem.value === ((_a = activeItem.value) == null ? void 0 : _a.value) ? 0 : -1,
"aria-current": childItem.value === ((_b = activeItem.value) == null ? void 0 : _b.value) ? "step" : void 0,
"aria-controls": `tabpanel-${childItem.identifier}`,
"aria-selected": childItem.value === ((_c = activeItem.value) == null ? void 0 : _c.value),
onClick: ($event) => itemClick(childItem),
onKeydown: [
vue.withKeys(vue.withModifiers(($event) => itemClick(childItem), ["prevent"]), ["enter"]),
vue.withKeys(vue.withModifiers(($event) => itemClick(childItem), ["prevent"]), ["space"]),
vue.withKeys(vue.withModifiers(($event) => onPrev(childItem.index), ["prevent"]), ["left"]),
vue.withKeys(vue.withModifiers(($event) => onNext(childItem.index), ["prevent"]), ["right"]),
vue.withKeys(vue.withModifiers(onHomePressed, ["prevent"]), ["home"]),
vue.withKeys(vue.withModifiers(onEndPressed, ["prevent"]), ["end"])
]
}, [
index2 > 0 ? (vue.openBlock(), vue.createElementBlock("span", {
key: 0,
class: vue.normalizeClass(vue.unref(dividerClasses))
}, null, 2)) : vue.createCommentVNode("", true),
vue.createElementVNode("div", {
class: vue.normalizeClass(vue.unref(markerClasses))
}, [
childItem.icon ? (vue.openBlock(), vue.createBlock(Icon_vue_vue_type_script_setup_true_lang._sfc_main, {
key: 0,
class: vue.normalizeClass(childItem.iconClasses),
icon: childItem.icon,
pack: childItem.iconPack,
size: _ctx.size
}, null, 8, ["class", "icon", "pack", "size"])) : childItem.step ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3, vue.toDisplayString(childItem.step), 1)) : vue.createCommentVNode("", true)
], 2),
vue.createElementVNode("div", {
class: vue.normalizeClass(childItem.labelClasses)
}, vue.toDisplayString(childItem.label), 3)
], 42, _hoisted_2)), [
[vue.vShow, childItem.visible]
]);
}), 128))
], 10, _hoisted_1),
vue.createElementVNode("section", {
class: vue.normalizeClass(vue.unref(contentClasses))
}, [
vue.renderSlot(_ctx.$slots, "default", {}, () => [
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(groupedOptions.value, (option) => {
return vue.withDirectives((vue.openBlock(), vue.createBlock(_sfc_main$1, vue.mergeProps({ ref_for: true }, option.attrs, {
key: option.key,
value: option.value,
label: option.label
}), null, 16, ["value", "label"])), [
[vue.vShow, !option.hidden]
]);
}), 128))
])
], 2),
vue.renderSlot(_ctx.$slots, "navigation", {
previous: { disabled: !hasPrev.value, action: () => activateItem(-1) },
next: { disabled: !hasNext.value, action: () => activateItem(1) }
}, () => [
_ctx.hasNavigation ? (vue.openBlock(), vue.createElementBlock("nav", {
key: 0,
class: vue.normalizeClass(vue.unref(navigationClasses))
}, [
vue.createVNode(Button_vue_vue_type_script_setup_true_lang._sfc_main, {
role: "button",
"icon-left": _ctx.iconPrev,
"icon-pack": _ctx.iconPack,
disabled: !hasPrev.value,
"aria-label": _ctx.ariaPreviousLabel,
onClick: _cache[0] || (_cache[0] = vue.withModifiers(($event) => activateItem(-1), ["prevent"]))
}, null, 8, ["icon-left", "icon-pack", "disabled", "aria-label"]),
vue.createVNode(Button_vue_vue_type_script_setup_true_lang._sfc_main, {
role: "button",
"icon-left": _ctx.iconNext,
"icon-pack": _ctx.iconPack,
disabled: !hasNext.value,
"aria-label": _ctx.ariaNextLabel,
onClick: _cache[1] || (_cache[1] = vue.withModifiers(($event) => activateItem(1), ["prevent"]))
}, null, 8, ["icon-left", "icon-pack", "disabled", "aria-label"])
], 2)) : vue.createCommentVNode("", true)
])
], 2);
};
}
});
const index = {
install(app) {
config.registerComponent(app, _sfc_main);
config.registerComponent(app, _sfc_main$1);
}
};
exports.OStepItem = _sfc_main$1;
exports.OSteps = _sfc_main;
exports.default = index;
//# sourceMappingURL=steps.cjs.map