@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
289 lines (288 loc) • 7.82 kB
JavaScript
import { warn as m, createElementBlock as a, openBlock as o, mergeProps as y, toHandlers as O, createCommentVNode as u, normalizeClass as c, renderSlot as f } from "vue";
import { hasSlotContent as l } from "../../common/utils/index.js";
import { BUTTON_TYPES as _, INVALID_COMBINATION as p, BUTTON_SIZE_MODIFIERS as r, BUTTON_IMPORTANCE_MODIFIERS as h, BUTTON_KIND_MODIFIERS as b, BUTTON_ICON_SIZES as k, ICON_POSITION_MODIFIERS as I } from "./button-constants.js";
import { DialtoneLocalization as S } from "../../localization/index.js";
import { _ as v } from "../../_plugin-vue_export-helper-CHgC5LLL.js";
import { getLinkKindModifier as N, LINK_KIND_MODIFIERS as B } from "../link/link-constants.js";
const g = {
compatConfig: { MODE: 3 },
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: (t) => Object.keys(I).includes(t)
},
/**
* The fill and outline of the button associated with its visual importance.
* @values clear, outlined, primary
*/
importance: {
type: String,
default: "primary",
validator: (t) => Object.keys(h).includes(t)
},
/**
* 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: (t) => Object.keys(B).includes(t)
},
/**
* 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: (t) => _.includes(t)
},
/**
* 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: (t) => Object.keys(r).includes(t)
},
/**
* 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: (t) => Object.keys(b).includes(t)
},
/**
* 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 focus in event
*
* @event focusin
* @type {FocusEvent}
*/
"focusin",
/**
* Native button focus out event
*
* @event focusout
* @type {FocusEvent}
*/
"focusout"
],
data() {
return {
ICON_POSITION_MODIFIERS: I,
// whether the button is currently in focus
isInFocus: !1,
hasSlotContent: l,
i18n: new S()
};
},
computed: {
buttonListeners() {
return {
focusin: (t) => {
this.isInFocus = this.assertiveOnFocus, this.$emit("focusin", t);
},
focusout: (t) => {
this.isInFocus = !1, this.$emit("focusout", t);
}
};
},
computedAriaLive() {
return this.assertiveOnFocus && this.isInFocus ? "assertive" : this.$attrs.ariaLive;
},
iconSize() {
return k[this.size];
}
},
watch: {
$props: {
deep: !0,
immediate: !0,
handler() {
process.env.NODE_ENV !== "production" && (this.circle && this.link && m("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",
N(this.linkKind, this.linkInverted),
r[this.size]
] : this.kind === "unstyled" ? ["d-btn--unstyled"] : [
"d-btn",
h[this.importance],
b[this.kind],
r[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(t, d, e) {
if (this.kind === "unstyled")
return !0;
for (const i of p)
if (t === i.circle && d === i.kind && e === i.importance)
return console.warn(i.message), !1;
return !0;
},
shouldRenderIcon() {
return l(this.$slots.icon) && !this.link;
},
isIconOnly() {
return this.shouldRenderIcon() && !l(this.$slots.default);
},
isVerticalIconLayout() {
return !this.isIconOnly() && ["top", "bottom"].includes(this.iconPosition);
}
}
}, C = ["type", "disabled", "aria-live", "aria-label"];
function D(t, d, e, i, s, n) {
return o(), a("button", y({
class: [
"base-button__button",
n.buttonClasses()
],
"data-qa": "dt-button",
type: e.type,
disabled: e.disabled,
style: { width: e.width },
"aria-live": n.computedAriaLive,
"aria-label": e.loading ? s.i18n.$t("DIALTONE_LOADING") : t.$attrs["aria-label"]
}, O(n.buttonListeners, !0)), [
n.shouldRenderIcon() ? (o(), a("span", {
key: 0,
"data-qa": "dt-button-icon",
class: c([
"base-button__icon",
{
"d-btn__icon": e.kind !== "unstyled",
[s.ICON_POSITION_MODIFIERS[e.iconPosition]]: e.kind !== "unstyled"
}
])
}, [
f(t.$slots, "icon", { iconSize: n.iconSize })
], 2)) : u("", !0),
s.hasSlotContent(t.$slots.default) ? (o(), a("span", {
key: 1,
"data-qa": "dt-button-label",
class: c([
"base-button__label",
{ "d-btn__label": e.kind !== "unstyled" },
e.labelClass
])
}, [
f(t.$slots, "default")
], 2)) : u("", !0)
], 16, C);
}
const R = /* @__PURE__ */ v(g, [["render", D]]);
export {
R as default
};
//# sourceMappingURL=button.js.map