UNPKG

@oruga-ui/oruga-next

Version:

UI components for Vue.js and CSS framework agnostic

544 lines (543 loc) 20.9 kB
/*! 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