@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
167 lines (166 loc) • 4.33 kB
JavaScript
import Vue from "vue";
import utils from "../../common/utils.js";
import { TOGGLE_CHECKED_VALUES, TOGGLE_SIZE_MODIFIERS } from "./toggle_constants.js";
import normalizeComponent from "../../_virtual/_plugin-vue2_normalizer.js";
const _sfc_main = {
name: "DtToggle",
inheritAttrs: false,
model: {
prop: "checked",
event: "change"
},
props: {
/**
* The id of the toggle
*/
id: {
type: String,
default() {
return utils.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
};
},
computed: {
inputListeners() {
return {
...this.$listeners,
click: (_) => 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: {
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) {
Vue.util.warn(
"You must provide an aria-label when there is no label passed",
this
);
}
}
}
};
var _sfc_render = function render() {
var _vm = this, _c = _vm._self._c;
return _c("div", { staticClass: "d-toggle-wrapper" }, [_vm.$slots.default ? _c("label", _vm._b({ class: _vm.labelClass, attrs: { "for": _vm.id, "data-qa": "toggle-label" } }, "label", _vm.labelChildProps, false), [_vm._t("default")], 2) : _vm._e(), _c("button", _vm._g(_vm._b({ class: _vm.toggleClasses, attrs: { "id": _vm.id, "role": _vm.toggleRole, "type": "button", "aria-checked": _vm.internalChecked.toString(), "disabled": _vm.disabled, "aria-disabled": _vm.disabled.toString() } }, "button", _vm.$attrs, false), _vm.inputListeners), [_vm.showIcon ? _c("span", { staticClass: "d-toggle__inner" }) : _vm._e()])]);
};
var _sfc_staticRenderFns = [];
var __component__ = /* @__PURE__ */ normalizeComponent(
_sfc_main,
_sfc_render,
_sfc_staticRenderFns
);
const toggle = __component__.exports;
export {
toggle as default
};
//# sourceMappingURL=toggle.vue.js.map