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