@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
259 lines (258 loc) • 8.02 kB
JavaScript
"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const common_utils = require("../../common/utils.cjs");
const collapsible_lazy_show = require("./collapsible_lazy_show.vue.cjs");
const vue3 = require("@dialpad/dialtone-icons/vue3");
const vue = require("vue");
const _pluginVue_exportHelper = require("../../_virtual/_plugin-vue_export-helper.cjs");
const button = require("../button/button.vue.cjs");
const lazy_show = require("../lazy_show/lazy_show.vue.cjs");
const _sfc_main = {
compatConfig: { MODE: 3 },
name: "DtCollapsible",
components: {
DtButton: button.default,
DtCollapsibleLazyShow: collapsible_lazy_show.default,
DtLazyShow: lazy_show.default,
DtIconChevronDown: vue3.DtIconChevronDown,
DtIconChevronRight: vue3.DtIconChevronRight
},
props: {
/**
* Text that is displayed on the anchor if nothing is passed in the slot.
* Ignored if the anchor slot is used.
*/
anchorText: {
type: String,
default: null
},
/**
* Controls whether the collapsible is shown. Leaving this null will have the collapsible start
* expanded and trigger on click by default. If you set this value, the default trigger
* behavior will be disabled, and you can control it as you need.
* Supports .sync modifier
* @values null, true, false
*/
open: {
type: Boolean,
default: null
},
/**
* The id of the content wrapper.
*/
id: {
type: String,
default() {
return common_utils.getUniqueString();
}
},
/**
* HTML element type (tag name) of the root element of the component.
*/
elementType: {
type: String,
default: "div"
},
/**
* HTML element type (tag name) of the content wrapper element.
*/
contentElementType: {
type: String,
default: "div"
},
/**
* Additional class name for the anchor wrapper element.
*/
anchorClass: {
type: [String, Array, Object],
default: null
},
/**
* Additional class name for the content wrapper element.
*/
contentClass: {
type: [String, Array, Object],
default: null
},
/**
* The maximum width of the anchor and collapsible element.
* Possible units rem|px|%|em
*/
maxWidth: {
type: String,
default: null
},
/**
* The maximum height of the collapsible element.
* Possible units rem|px|%|em
*/
maxHeight: {
type: String,
default: null
},
/**
* Label on the collapsible content. Should provide this or ariaLabelledBy but not both.
*/
ariaLabel: {
type: String,
default: null
},
/**
* Id of the element that labels the collapsible content. Defaults to the anchor element.
* Should provide this or ariaLabel but not both.
*/
ariaLabelledBy: {
type: String,
default: null
}
},
emits: [
/**
* Event fired to sync the open prop with the parent component
* @event update:open
*/
"update:open",
/**
* Event fired when the content is shown or hidden
*
* @event opened
* @type {Boolean}
*/
"opened"
],
data() {
return {
isOpen: true
};
},
computed: {
labelledBy() {
return this.ariaLabelledBy || !this.ariaLabel && common_utils.getUniqueString("DtCollapsible__anchor");
},
collapsibleListeners() {
return common_utils.extractVueListeners(this.$attrs);
}
},
watch: {
open: {
handler: function(open) {
if (open !== null) {
this.isOpen = open;
}
},
immediate: true
}
},
created() {
this.validateProperAnchor();
},
methods: {
onLeaveTransitionComplete() {
this.$emit("opened", false);
if (this.open !== null) {
this.$emit("update:open", false);
}
},
onEnterTransitionComplete() {
this.$emit("opened", true, this.$refs.content);
if (this.open !== null) {
this.$emit("update:open", true);
}
},
defaultToggleOpen() {
if (this.open === null) {
this.toggleOpen();
}
},
toggleOpen() {
this.isOpen = !this.isOpen;
},
validateProperAnchor() {
if (!this.anchorText && !common_utils.hasSlotContent(this.$slots.anchor)) {
console.error("anchor text and anchor slot content cannot both be falsy");
}
}
}
};
const _hoisted_1 = ["id"];
const _hoisted_2 = ["title"];
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_dt_icon_chevron_down = vue.resolveComponent("dt-icon-chevron-down");
const _component_dt_icon_chevron_right = vue.resolveComponent("dt-icon-chevron-right");
const _component_dt_button = vue.resolveComponent("dt-button");
const _component_dt_collapsible_lazy_show = vue.resolveComponent("dt-collapsible-lazy-show");
return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent($props.elementType), vue.mergeProps({ ref: "collapsible" }, vue.toHandlers($options.collapsibleListeners)), {
default: vue.withCtx(() => [
vue.createElementVNode("div", {
id: !$props.ariaLabelledBy && $options.labelledBy,
ref: "anchor",
class: vue.normalizeClass($props.anchorClass)
}, [
vue.renderSlot(_ctx.$slots, "anchor", {
attrs: {
"aria-controls": $props.id,
"aria-expanded": $data.isOpen.toString(),
"role": "button"
}
}, () => [
vue.createVNode(_component_dt_button, {
importance: "clear",
kind: "muted",
"aria-controls": $props.id,
"aria-expanded": `${$data.isOpen}`,
style: vue.normalizeStyle({
"width": $props.maxWidth
}),
onClick: $options.defaultToggleOpen
}, {
default: vue.withCtx(() => [
$data.isOpen ? (vue.openBlock(), vue.createBlock(_component_dt_icon_chevron_down, {
key: 0,
class: "d-collapsible__icon",
size: "300"
})) : (vue.openBlock(), vue.createBlock(_component_dt_icon_chevron_right, {
key: 1,
class: "d-collapsible__icon",
size: "300"
})),
vue.createElementVNode("span", {
class: "d-collapsible__anchor-text",
title: $props.anchorText
}, vue.toDisplayString($props.anchorText), 9, _hoisted_2)
]),
_: 1
}, 8, ["aria-controls", "aria-expanded", "style", "onClick"])
])
], 10, _hoisted_1),
vue.createVNode(_component_dt_collapsible_lazy_show, vue.mergeProps({
id: $props.id,
ref: "contentWrapper",
"aria-hidden": `${!$data.isOpen}`,
"aria-labelledby": $options.labelledBy,
"aria-label": $props.ariaLabel,
show: $data.isOpen,
"element-type": $props.contentElementType,
class: $props.contentClass,
style: {
"max-height": $props.maxHeight,
"max-width": $props.maxWidth
},
"data-qa": "dt-collapsible--content",
tabindex: "-1",
appear: ""
}, vue.toHandlers($options.collapsibleListeners), {
onAfterLeave: $options.onLeaveTransitionComplete,
onAfterEnter: $options.onEnterTransitionComplete
}), {
default: vue.withCtx(() => [
vue.renderSlot(_ctx.$slots, "content")
]),
_: 3
}, 16, ["id", "aria-hidden", "aria-labelledby", "aria-label", "show", "element-type", "class", "style", "onAfterLeave", "onAfterEnter"])
]),
_: 3
}, 16);
}
const DtCollapsible = /* @__PURE__ */ _pluginVue_exportHelper.default(_sfc_main, [["render", _sfc_render]]);
exports.default = DtCollapsible;
//# sourceMappingURL=collapsible.vue.cjs.map