@dialpad/dialtone-vue
Version:
Vue component library for Dialpad's design system Dialtone
276 lines (275 loc) • 7.5 kB
JavaScript
import r from "vue";
import { BUTTON_TYPES as d, INVALID_COMBINATION as u, BUTTON_SIZE_MODIFIERS as s, BUTTON_IMPORTANCE_MODIFIERS as a, BUTTON_KIND_MODIFIERS as o, BUTTON_ICON_SIZES as c, ICON_POSITION_MODIFIERS as l } from "./button-constants.js";
import { DialtoneLocalization as f } from "../../localization/index.js";
import { n as p } from "../../_plugin-vue2_normalizer-DSLOjnn3.js";
import { getLinkKindModifier as h, LINK_KIND_MODIFIERS as I } from "../link/link-constants.js";
const _ = {
name: "DtButton",
props: {
/**
* Whether the button is a circle or not.
* @values true, false
*/
circle: {
type: Boolean,
default: !1
},
/**
* The position of the icon slot within the button.
* @values left, right, top, bottom
*/
iconPosition: {
type: String,
default: "left",
validator: (e) => Object.keys(l).includes(e)
},
/**
* The fill and outline of the button associated with its visual importance.
* @values clear, outlined, primary
*/
importance: {
type: String,
default: "primary",
validator: (e) => Object.keys(a).includes(e)
},
/**
* Whether the button should be styled as a link or not.
* @values true, false
* @see DtLink
*/
link: {
type: Boolean,
default: !1
},
/**
* The color of the link and button if the button is styled as a link.
* @values default, warning, danger, success, muted
* @see DtLink
*/
linkKind: {
type: String,
default: "default",
validator: (e) => Object.keys(I).includes(e)
},
/**
* Determines whether the link should have inverted styling if the button is styled as a link.
* @values true, false
* @see DtLink
*/
linkInverted: {
type: Boolean,
default: !1
},
/**
* HTML button disabled attribute
* <a class="d-link" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#disabled" target="_blank"> (Reference) </a>
* @values true, false
*/
disabled: {
type: Boolean,
default: !1
},
/**
* HTML button type attribute
* <a
* class="d-link"
* href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type"
* target="_blank"
* >
* (Reference)
* </a>
* @values button, submit, reset
*/
type: {
type: String,
default: "button",
validator: (e) => d.includes(e)
},
/**
* Button width, accepts
* <a class="d-link" href="https://developer.mozilla.org/en-US/docs/Web/CSS/width" target="_blank">
* CSS width attribute
* </a>
* values
*/
width: {
type: String,
default: null
},
/**
* The size of the button.
* @values xs, sm, md, lg, xl
*/
size: {
type: String,
default: "md",
validator: (e) => Object.keys(s).includes(e)
},
/**
* Used to customize the label container
*/
labelClass: {
type: [String, Array, Object],
default: ""
},
/**
* Whether the button should display a loading animation or not.
* @values true, false
*/
loading: {
type: Boolean,
default: !1
},
/**
* The color of the button.
* @values default, unstyled, muted, danger, positive, inverted
*/
kind: {
type: String,
default: "default",
validator: (e) => Object.keys(o).includes(e)
},
/**
* Determines whether a screenreader reads live updates of
* the button content to the user while the button
* is in focus. default is to not.
* @values true, false
*/
assertiveOnFocus: {
type: Boolean,
default: !1
},
/**
* Determines whether the button should have active styling
* default is false.
* @values true, false
*/
active: {
type: Boolean,
default: !1
}
},
emits: [
/**
* Native button click event
*
* @event click
* @type {PointerEvent | KeyboardEvent}
*/
"click",
/**
* Native button focus in event
*
* @event focusin
* @type {FocusEvent}
*/
"focusin",
/**
* Native button focus out event
*
* @event focusout
* @type {FocusEvent}
*/
"focusout"
],
data() {
return {
ICON_POSITION_MODIFIERS: l,
// whether the button is currently in focus
isInFocus: !1,
i18n: new f()
};
},
computed: {
buttonListeners() {
return this.assertiveOnFocus ? {
...this.$listeners,
focusin: () => {
this.isInFocus = !0;
},
focusout: () => {
this.isInFocus = !1;
}
} : this.$listeners;
},
computedAriaLive() {
return this.assertiveOnFocus && this.isInFocus ? "assertive" : this.$attrs.ariaLive;
},
iconSize() {
return c[this.size];
}
},
watch: {
$props: {
deep: !0,
immediate: !0,
handler() {
process.env.NODE_ENV !== "production" && (this.circle && this.link && r.util.warn("You cannot enable circle and link at the same time", this), this.isInvalidPropCombination(this.circle, this.kind, this.importance));
}
}
},
methods: {
buttonClasses() {
return this.link ? [
"d-link",
h(this.linkKind, this.linkInverted),
s[this.size]
] : this.kind === "unstyled" ? ["d-btn--unstyled"] : [
"d-btn",
a[this.importance],
o[this.kind],
s[this.size],
{
"d-btn--circle": this.circle,
"d-btn--loading": this.loading,
"d-btn--icon-only": this.isIconOnly(),
"d-btn--vertical": this.isVerticalIconLayout(),
"d-btn--active": this.active
}
];
},
isInvalidPropCombination(e, t, i) {
if (this.kind === "unstyled")
return !0;
for (const n of u)
if (e === n.circle && t === n.kind && i === n.importance)
return console.warn(n.message), !1;
return !0;
},
shouldRenderIcon() {
return this.$scopedSlots.icon && this.$scopedSlots.icon() && !this.link;
},
isIconOnly() {
return this.shouldRenderIcon() && !this.$slots.default;
},
isVerticalIconLayout() {
return !this.isIconOnly() && ["top", "bottom"].includes(this.iconPosition);
}
}
};
var b = function() {
var t = this, i = t._self._c;
return i("button", t._g({ class: [
"base-button__button",
t.buttonClasses()
], style: { width: t.width }, attrs: { "data-qa": "dt-button", type: t.type, disabled: t.disabled, "aria-live": t.computedAriaLive, "aria-label": t.loading ? t.i18n.$t("DIALTONE_LOADING") : t.$attrs["aria-label"] } }, t.buttonListeners), [t.shouldRenderIcon() ? i("span", { class: [
"base-button__icon",
{
"d-btn__icon": t.kind !== "unstyled",
[t.ICON_POSITION_MODIFIERS[t.iconPosition]]: t.kind !== "unstyled"
}
], attrs: { "data-qa": "dt-button-icon" } }, [t._t("icon", null, { iconSize: t.iconSize })], 2) : t._e(), t.$slots.default ? i("span", { class: [
"base-button__label",
{ "d-btn__label": t.kind !== "unstyled" },
t.labelClass
], attrs: { "data-qa": "dt-button-label" } }, [t._t("default")], 2) : t._e()]);
}, y = [], O = /* @__PURE__ */ p(
_,
b,
y
);
const T = O.exports;
export {
T as default
};
//# sourceMappingURL=button.js.map