UNPKG

buefy

Version:

Lightweight UI components for Vue.js (v3) based on Bulma

574 lines (563 loc) 16.1 kB
import { defineComponent, createElementBlock, openBlock, mergeProps, createElementVNode, h, resolveComponent, withDirectives, resolveDirective, createBlock, resolveDynamicComponent, withCtx, renderSlot, withKeys, withModifiers, Fragment, createTextVNode, toDisplayString, normalizeClass } from 'vue'; import { _ as _export_sfc } from './_plugin-vue_export-helper-OJRSZE6i.js'; import { C as CompatFallthroughMixin } from './CompatFallthroughMixin-C8LPuwDr.js'; import { a as registerComponent } from './plugins-B172kuKE.js'; import './config-CKuo-p6e.js'; var _sfc_main$3 = defineComponent({ name: "NavbarBurger", props: { isOpened: { type: Boolean, default: false } } }); const _hoisted_1 = ["aria-expanded"]; const _hoisted_2 = /* @__PURE__ */ createElementVNode( "span", { "aria-hidden": "true" }, null, -1 /* HOISTED */ ); const _hoisted_3 = /* @__PURE__ */ createElementVNode( "span", { "aria-hidden": "true" }, null, -1 /* HOISTED */ ); const _hoisted_4 = /* @__PURE__ */ createElementVNode( "span", { "aria-hidden": "true" }, null, -1 /* HOISTED */ ); const _hoisted_5 = /* @__PURE__ */ createElementVNode( "span", { "aria-hidden": "true" }, null, -1 /* HOISTED */ ); const _hoisted_6 = [ _hoisted_2, _hoisted_3, _hoisted_4, _hoisted_5 ]; function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) { return openBlock(), createElementBlock("a", mergeProps({ role: "button", class: ["navbar-burger burger", { "is-active": _ctx.isOpened }], "aria-label": "menu", "aria-expanded": _ctx.isOpened || void 0 }, _ctx.$attrs, { tabindex: "0" }), [..._hoisted_6], 16, _hoisted_1); } var NavbarBurger = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$2]]); const isTouch = typeof window !== "undefined" && ("ontouchstart" in window || navigator.maxTouchPoints > 0); const events = isTouch ? ["touchstart", "click"] : ["click"]; const instances = []; function processArgs(bindingValue) { const isFunction = typeof bindingValue === "function"; if (!isFunction && typeof bindingValue !== "object") { throw new Error(`v-click-outside: Binding value should be a function or an object, ${typeof bindingValue} given`); } return { handler: isFunction ? bindingValue : bindingValue.handler, middleware: !isFunction && bindingValue.middleware || ((isClickOutside) => !!isClickOutside), events: !isFunction && bindingValue.events || events }; } function onEvent({ el, event, handler, middleware }) { const isClickOutside = event.target !== el && !el.contains(event.target); if (!isClickOutside || !middleware(event, el)) { return; } handler(event, el); } function toggleEventListeners({ eventHandlers }, action) { eventHandlers.forEach(({ event, handler }) => { document[`${action}EventListener`](event, handler); }); } function beforeMount(el, { value }) { const { handler, middleware, events: events2 } = processArgs(value); const instance = { el, eventHandlers: events2.map((eventName) => ({ event: eventName, handler: (event) => onEvent({ event, el, handler, middleware }) })) }; toggleEventListeners(instance, "add"); instances.push(instance); } function updated(el, { value }) { const { handler, middleware, events: events2 } = processArgs(value); const instance = instances.filter((instance2) => instance2.el === el)[0]; toggleEventListeners(instance, "remove"); instance.eventHandlers = events2.map((eventName) => ({ event: eventName, handler: (event) => onEvent({ event, el, handler, middleware }) })); toggleEventListeners(instance, "add"); } function unmounted(el) { const instance = instances.filter((instance2) => instance2.el === el)[0]; toggleEventListeners(instance, "remove"); } const directive = { beforeMount, updated, unmounted }; const FIXED_TOP_CLASS = "is-fixed-top"; const BODY_FIXED_TOP_CLASS = "has-navbar-fixed-top"; const BODY_SPACED_FIXED_TOP_CLASS = "has-spaced-navbar-fixed-top"; const FIXED_BOTTOM_CLASS = "is-fixed-bottom"; const BODY_FIXED_BOTTOM_CLASS = "has-navbar-fixed-bottom"; const BODY_SPACED_FIXED_BOTTOM_CLASS = "has-spaced-navbar-fixed-bottom"; const BODY_CENTERED_CLASS = "has-navbar-centered"; const isFilled = (str) => !!str; var _sfc_main$2 = defineComponent({ name: "BNavbar", components: { NavbarBurger }, directives: { clickOutside: directive }, props: { type: [String, Object], transparent: { type: Boolean, default: false }, fixedTop: { type: Boolean, default: false }, fixedBottom: { type: Boolean, default: false }, modelValue: { type: Boolean, default: false }, centered: { type: Boolean, default: false }, wrapperClass: { type: [String, Array, Object] }, closeOnClick: { type: Boolean, default: true }, mobileBurger: { type: Boolean, default: true }, spaced: Boolean, shadow: Boolean }, emits: { // eslint-disable-next-line @typescript-eslint/no-unused-vars "update:modelValue": (_value) => true }, data() { return { internalIsActive: this.modelValue, _isNavBar: true // Used internally by NavbarItem }; }, computed: { isOpened() { return this.internalIsActive; }, computedClasses() { return [ this.type, { [FIXED_TOP_CLASS]: this.fixedTop, [FIXED_BOTTOM_CLASS]: this.fixedBottom, [BODY_CENTERED_CLASS]: this.centered, "is-spaced": this.spaced, "has-shadow": this.shadow, "is-transparent": this.transparent } ]; } }, watch: { modelValue: { handler(active) { this.internalIsActive = active; }, immediate: true }, fixedTop(isSet) { this.setBodyFixedTopClass(isSet); }, bottomTop(isSet) { this.setBodyFixedBottomClass(isSet); } }, methods: { toggleActive() { this.internalIsActive = !this.internalIsActive; this.emitUpdateParentEvent(); }, closeMenu() { if (this.closeOnClick && this.internalIsActive) { this.internalIsActive = false; this.emitUpdateParentEvent(); } }, emitUpdateParentEvent() { this.$emit("update:modelValue", this.internalIsActive); }, setBodyClass(className) { if (typeof window !== "undefined") { document.body.classList.add(className); } }, removeBodyClass(className) { if (typeof window !== "undefined") { document.body.classList.remove(className); } }, checkIfFixedPropertiesAreColliding() { const areColliding = this.fixedTop && this.fixedBottom; if (areColliding) { throw new Error("You should choose if the BNavbar is fixed bottom or fixed top, but not both"); } }, genNavbar() { const navBarSlots = [ this.genNavbarBrandNode(), this.genNavbarSlotsNode() ]; if (!isFilled(this.wrapperClass)) { return this.genNavbarSlots(navBarSlots); } const navWrapper = h( "div", { class: this.wrapperClass }, navBarSlots ); return this.genNavbarSlots([navWrapper]); }, genNavbarSlots(slots) { const vnode = h( "nav", { class: ["navbar", this.computedClasses], role: "navigation", "aria-label": "main navigation" }, slots ); return withDirectives(vnode, [ [resolveDirective("click-outside"), this.closeMenu] ]); }, genNavbarBrandNode() { const children = this.$slots.brand != null ? [this.$slots.brand(), this.genBurgerNode()] : this.genBurgerNode(); return h( "div", { class: "navbar-brand" }, children ); }, genBurgerNode() { if (this.mobileBurger) { const defaultBurgerNode = h( resolveComponent("navbar-burger"), { isOpened: this.isOpened, onClick: this.toggleActive, onKeyup: (event) => { if (event.keyCode !== 13) return; this.toggleActive(); } } ); const hasBurgerSlot = !!this.$slots.burger; return hasBurgerSlot ? this.$slots.burger({ isOpened: this.isOpened, toggleActive: this.toggleActive }) : defaultBurgerNode; } }, genNavbarSlotsNode() { return h( "div", { class: ["navbar-menu", { "is-active": this.isOpened }] }, [ this.genMenuPosition("start"), this.genMenuPosition("end") ] ); }, genMenuPosition(positionName) { return h( "div", { class: `navbar-${positionName}` }, this.$slots[positionName] != null ? this.$slots[positionName]() : [] ); }, setBodyFixedTopClass(isSet) { this.checkIfFixedPropertiesAreColliding(); if (isSet) { this.setBodyClass(BODY_FIXED_TOP_CLASS); this.spaced && this.setBodyClass(BODY_SPACED_FIXED_TOP_CLASS); } else { this.removeBodyClass(BODY_FIXED_TOP_CLASS); this.removeBodyClass(BODY_SPACED_FIXED_TOP_CLASS); } }, setBodyFixedBottomClass(isSet) { this.checkIfFixedPropertiesAreColliding(); if (isSet) { this.setBodyClass(BODY_FIXED_BOTTOM_CLASS); this.spaced && this.setBodyClass(BODY_SPACED_FIXED_BOTTOM_CLASS); } else { this.removeBodyClass(BODY_FIXED_BOTTOM_CLASS); this.removeBodyClass(BODY_SPACED_FIXED_BOTTOM_CLASS); } } }, beforeMount() { this.fixedTop && this.setBodyFixedTopClass(true); this.fixedBottom && this.setBodyFixedBottomClass(true); }, beforeUnmount() { if (this.fixedTop) { const className = this.spaced ? BODY_SPACED_FIXED_TOP_CLASS : BODY_FIXED_TOP_CLASS; this.removeBodyClass(className); } else if (this.fixedBottom) { const className = this.spaced ? BODY_SPACED_FIXED_BOTTOM_CLASS : BODY_FIXED_BOTTOM_CLASS; this.removeBodyClass(className); } }, render() { return this.genNavbar(); } }); const clickableWhiteList = ["div", "span", "input"]; var _sfc_main$1 = defineComponent({ name: "BNavbarItem", inheritAttrs: false, props: { tag: { type: [String, Object], default: "a" }, active: Boolean }, methods: { /* * Keypress event that is bound to the document */ keyPress({ key }) { if (key === "Escape" || key === "Esc") { this.closeMenuRecursive(this, ["NavBar"]); } }, /* * Close parent if clicked outside. */ handleClickEvent(event) { const isOnWhiteList = clickableWhiteList.some((item) => item === event.target.localName); if (!isOnWhiteList) { const parent = this.closeMenuRecursive(this, ["NavbarDropdown", "NavBar"]); if (parent && parent.$data._isNavbarDropdown) this.closeMenuRecursive(parent, ["NavBar"]); } }, /* * Close parent recursively */ closeMenuRecursive(current, targetComponents) { const parent = current.$parent; if (!parent) return null; const foundItem = targetComponents.reduce((acc, item) => { if (parent.$data[`_is${item}`]) { parent.closeMenu(); return parent; } return acc; }, null); return foundItem || this.closeMenuRecursive(parent, targetComponents); } }, mounted() { if (typeof window !== "undefined") { this.$el.addEventListener("click", this.handleClickEvent); document.addEventListener("keyup", this.keyPress); } }, beforeUnmount() { if (typeof window !== "undefined") { this.$el.removeEventListener("click", this.handleClickEvent); document.removeEventListener("keyup", this.keyPress); } } }); function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) { return openBlock(), createBlock(resolveDynamicComponent(_ctx.tag), mergeProps({ class: ["navbar-item", { "is-active": _ctx.active }] }, _ctx.$attrs), { default: withCtx(() => [ renderSlot(_ctx.$slots, "default") ]), _: 3 /* FORWARDED */ }, 16, ["class"]); } var NavbarItem = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1]]); var _sfc_main = defineComponent({ name: "BNavbarDropdown", directives: { clickOutside: directive }, mixins: [CompatFallthroughMixin], props: { label: String, hoverable: Boolean, active: Boolean, right: Boolean, arrowless: Boolean, boxed: Boolean, closeOnClick: { type: Boolean, default: true }, collapsible: Boolean, tag: { type: [String, Object], default: "a" } }, emits: { // eslint-disable-next-line @typescript-eslint/no-unused-vars "active-change": (_active) => true }, data() { return { newActive: this.active, isHoverable: this.hoverable, _isNavbarDropdown: true // Used internally by NavbarItem }; }, watch: { active(value) { this.newActive = value; }, newActive(value) { this.$emit("active-change", value); } }, methods: { toggleMenu() { this.newActive = !this.newActive; }, showMenu() { this.newActive = true; }, /* * See naming convetion of navbaritem */ closeMenu() { this.newActive = !this.closeOnClick; if (this.hoverable && this.closeOnClick) { this.isHoverable = false; } }, checkHoverable() { if (this.hoverable) { this.isHoverable = true; } } } }); function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _directive_click_outside = resolveDirective("click-outside"); return withDirectives((openBlock(), createElementBlock( "div", mergeProps({ class: ["navbar-item has-dropdown", { "is-hoverable": _ctx.isHoverable, "is-active": _ctx.newActive }], onMouseenter: _cache[0] || (_cache[0] = (...args) => _ctx.checkHoverable && _ctx.checkHoverable(...args)) }, _ctx.rootAttrs), [ (openBlock(), createBlock(resolveDynamicComponent(_ctx.tag), mergeProps({ class: ["navbar-link", { "is-arrowless": _ctx.arrowless, "is-active": _ctx.newActive && _ctx.collapsible }] }, _ctx.fallthroughAttrs, { "aria-haspopup": "true", onClick: withModifiers(_ctx.toggleMenu, ["prevent"]), onKeyup: withKeys(_ctx.toggleMenu, ["enter"]), tabindex: "0" }), { default: withCtx(() => [ _ctx.label ? (openBlock(), createElementBlock( Fragment, { key: 0 }, [ createTextVNode( toDisplayString(_ctx.label), 1 /* TEXT */ ) ], 64 /* STABLE_FRAGMENT */ )) : renderSlot(_ctx.$slots, "label", { key: 1 }) ]), _: 3 /* FORWARDED */ }, 16, ["class", "onClick", "onKeyup"])), createElementVNode( "div", { class: normalizeClass(["navbar-dropdown", { "is-right": _ctx.right, "is-boxed": _ctx.boxed, "is-hidden-touch": _ctx.collapsible && !_ctx.newActive }]) }, [ renderSlot(_ctx.$slots, "default") ], 2 /* CLASS */ ) ], 16 /* FULL_PROPS */ )), [ [_directive_click_outside, _ctx.closeMenu] ]); } var NavbarDropdown = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]); const Plugin = { install(Vue) { registerComponent(Vue, _sfc_main$2); registerComponent(Vue, NavbarItem); registerComponent(Vue, NavbarDropdown); } }; export { _sfc_main$2 as BNavbar, NavbarDropdown as BNavbarDropdown, NavbarItem as BNavbarItem, Plugin as default };