@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
188 lines (187 loc) • 4.97 kB
JavaScript
import { warn, openBlock, createElementBlock, mergeProps, renderSlot, createCommentVNode, createElementVNode } from "vue";
import { getUniqueString, hasSlotContent, removeClassStyleAttrs, addClassStyleAttrs } from "../../common/utils.js";
import { TOGGLE_CHECKED_VALUES, TOGGLE_SIZE_MODIFIERS } from "./toggle_constants.js";
import _export_sfc from "../../_virtual/_plugin-vue_export-helper.js";
const _sfc_main = {
compatConfig: { MODE: 3 },
name: "DtToggle",
inheritAttrs: false,
model: {
prop: "checked",
event: "change"
},
props: {
/**
* The id of the toggle
*/
id: {
type: String,
default() {
return getUniqueString();
}
},
/**
* Disables the toggle interactions
* @values true, false
*/
disabled: {
type: Boolean,
default: false
},
/**
* Value of the toggle
* @model checked
* @values true, false, 'mixed'
*/
checked: {
type: [Boolean, String],
default: false,
validator: (v) => TOGGLE_CHECKED_VALUES.includes(v)
},
/**
* Whether the component toggles on click. If you set this to false it means you will handle the toggling manually
* via the checked prop or v-model. Change events will still be triggered.
* @values true, false
*/
toggleOnClick: {
type: Boolean,
default: true
},
/**
* The size of the toggle.
* @values sm, md
*/
size: {
type: String,
default: "md",
validator: (s) => Object.keys(TOGGLE_SIZE_MODIFIERS).includes(s)
},
/**
* Shows the icon
* @values true, false
*/
showIcon: {
type: Boolean,
default: true
},
/**
* Used to customize the label container
*/
labelClass: {
type: [String, Array, Object],
default: ""
},
/**
* A set of props that are passed into the label container
*/
labelChildProps: {
type: Object,
default: () => ({})
}
},
emits: [
/**
* Toggle change event
*
* @event change
* @type {Boolean}
* @model change
*/
"change"
],
data() {
return {
internalChecked: this.checked,
hasSlotContent
};
},
computed: {
inputListeners() {
return {
...removeClassStyleAttrs(this.$attrs),
onClick: (_) => this.toggleCheckedValue()
};
},
isIndeterminate() {
return this.internalChecked === "mixed";
},
toggleRole() {
return this.isIndeterminate ? "checkbox" : "switch";
},
toggleClasses() {
return [
"d-toggle",
TOGGLE_SIZE_MODIFIERS[this.size],
{
"d-toggle--checked": this.internalChecked === true,
"d-toggle--disabled": this.disabled,
"d-toggle--indeterminate": this.isIndeterminate
}
];
}
},
watch: {
checked(newChecked) {
this.internalChecked = newChecked;
}
},
mounted() {
this.runValidations();
},
methods: {
addClassStyleAttrs,
toggleCheckedValue() {
this.$emit("change", !this.internalChecked);
if (this.toggleOnClick) {
this.internalChecked = !this.internalChecked;
}
},
hasSlotLabel() {
return !!this.$slots.default;
},
runValidations() {
this.validateInputLabels(this.hasSlotLabel(), this.$attrs["aria-label"]);
},
validateInputLabels(hasLabel, ariaLabel) {
if (!hasLabel && !ariaLabel) {
warn(
"You must provide an aria-label when there is no label passed",
this
);
}
}
}
};
const _hoisted_1 = ["for"];
const _hoisted_2 = ["id", "role", "aria-checked", "disabled", "aria-disabled"];
const _hoisted_3 = {
key: 0,
class: "d-toggle__inner"
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return openBlock(), createElementBlock("div", mergeProps({ class: "d-toggle-wrapper" }, $options.addClassStyleAttrs(_ctx.$attrs)), [
$data.hasSlotContent(_ctx.$slots.default) ? (openBlock(), createElementBlock("label", mergeProps({
key: 0,
class: $props.labelClass,
for: $props.id
}, $props.labelChildProps, { "data-qa": "toggle-label" }), [
renderSlot(_ctx.$slots, "default")
], 16, _hoisted_1)) : createCommentVNode("", true),
createElementVNode("button", mergeProps({
id: $props.id,
role: $options.toggleRole,
type: "button",
"aria-checked": $data.internalChecked.toString(),
disabled: $props.disabled,
"aria-disabled": $props.disabled.toString(),
class: $options.toggleClasses
}, $options.inputListeners), [
$props.showIcon ? (openBlock(), createElementBlock("span", _hoisted_3)) : createCommentVNode("", true)
], 16, _hoisted_2)
], 16);
}
const toggle = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export {
toggle as default
};
//# sourceMappingURL=toggle.vue.js.map