UNPKG

@sandlada/vue-mdc

Version:

![Vue MDC Logo](https://raw.githubusercontent.com/sandlada/vue-mdc/refs/heads/main/docs/vue-mdc-cover.png)

229 lines (228 loc) 7.22 kB
/** * @license * Copyright 2025 Sandlada & Kai Orion * SPDX-License-Identifier: MIT */ import { defineComponent, ref, computed, toRef, onMounted, onBeforeUnmount, createVNode } from "vue"; import { useReflectAttribute } from "../../node_modules/@glare-labs/vue-reflect-attribute/build/vue-reflect-attribute.js"; import { componentNamePrefix } from "../../internals/component-name-prefix/component-name-prefix.js"; import { isServer } from "../../utils/is-server.js"; import { useObserveProps } from "../../utils/observe-props.js"; import { Elevation } from "../elevation/elevation.js"; import { FocusRing } from "../focus-ring/focus-ring.js"; import "../../internals/navigation/render-navigation-destination.js"; import { Ripple } from "../ripple/ripple.js"; import { props, ButtonAppearance } from "./button.definition.js"; import css from "./styles/button.module.scss.js"; const Button = /* @__PURE__ */ defineComponent({ name: `${componentNamePrefix}-button`, slots: {}, props, setup(props2, { slots }) { const root = ref(null); const _selected = ref(props2.defaultSelected); const selected = computed({ get: () => _selected.value, set: (value) => { _selected.value = value; } }); const _appearance = ref(props2.appearance); const _size = ref(props2.size); const _shape = ref(props2.shape); const _togglable = ref(props2.togglable); const _defaultSelected = ref(props2.defaultSelected); const _disabled = ref(props2.disabled); const _type = ref(props2.type); const _href = ref(props2.href); const _target = ref(props2.target); const _form = ref(props2.form); const _name = ref(props2.name); const _value = ref(props2.value); useReflectAttribute(root, { attributes: [{ attribute: "appearance", ref: _appearance, reflect: true, type: "string" }, { attribute: "size", ref: _size, reflect: true, type: "string" }, { attribute: "shape", ref: _shape, reflect: true, type: "string" }, { attribute: "togglable", ref: _togglable, reflect: true, type: "boolean" }, { attribute: "default-selected", ref: _defaultSelected, reflect: true, type: "boolean" }, { attribute: "disabled", ref: _disabled, reflect: true, type: "boolean" }, { attribute: "type", ref: _type, reflect: true, type: "string" }, { attribute: "href", ref: _href, reflect: true, type: "string" }, { attribute: "target", ref: _target, reflect: true, type: "string" }, { attribute: "form", ref: _form, reflect: true, type: "string" }, { attribute: "name", ref: _name, reflect: true, type: "string" }, { attribute: "value", ref: _value, reflect: true, type: "string" }], onAttributeChange: (attr, oldValue, newValue) => { } }); useObserveProps([{ id: "size", property: toRef(props2, "size"), callback: (value) => { _size.value = value; } }, { id: "appearance", property: toRef(props2, "appearance"), callback: (value) => { _appearance.value = value; } }, { id: "size", property: toRef(props2, "size"), callback: (value) => { _size.value = value; } }, { id: "shape", property: toRef(props2, "shape"), callback: (value) => { _shape.value = value; } }, { id: "togglable", property: toRef(props2, "togglable"), callback: (value) => { _togglable.value = value; } }, { id: "disabled", property: toRef(props2, "disabled"), callback: (value) => { _disabled.value = value; } }, { id: "type", property: toRef(props2, "type"), callback: (value) => { _type.value = value; } }, { id: "href", property: toRef(props2, "href"), callback: (value) => { _href.value = value; } }]); const handleClick = async (e) => { if (_href.value && _disabled.value) { e.stopImmediatePropagation(); e.preventDefault(); return; } selected.value = !selected.value; }; onMounted(() => { if (isServer()) { return; } root.value?.addEventListener("click", handleClick); }); onBeforeUnmount(() => { root.value?.removeEventListener("click", handleClick); }); return () => { const elevationButtonArray = [ButtonAppearance.Elevated, ButtonAppearance.Filled, ButtonAppearance.FilledTonal]; const needElevation = elevationButtonArray.includes(_appearance.value); const needOutline = _appearance.value === ButtonAppearance.Outlined; const iconState = slots["leading-icon"] ? css.left : slots["trailing-icon"] ? css.right : null; const isLink = _href.value !== null; const isTogglable = _appearance.value !== "text" && _togglable.value; const className = [css[_appearance.value], iconState, _disabled.value && css.disabled, css[_size.value], css[_shape.value], isTogglable && css.togglable, isTogglable && (selected.value ? css.selected : css.unselected)]; const renderContent = createVNode("span", { "class": css.button }, [createVNode("span", { "class": css.touch }, null), slots["leading-icon"] && slots["leading-icon"](), createVNode("span", { "class": [css.label] }, [slots.default && slots.default()]), slots["trailing-icon"] && slots["trailing-icon"]()]); const renderButtonWrapper = createVNode("button", { "data-component": "button", "class": className, "role": "button", "ref": root, "tabindex": _disabled.value ? -1 : 0 }, [createVNode(Ripple, null, null), createVNode(FocusRing, { "shapeInherit": false }, null), needElevation && createVNode(Elevation, null, null), needOutline && createVNode("div", { "aria-hidden": "true", "class": [css.outline] }, null), createVNode("div", { "aria-hidden": "true", "class": [css.background] }, null), renderContent]); const renderLinkWrapper = createVNode("a", { "data-component": "button", "class": className, "role": "button", "ref": root, "tabindex": _disabled.value ? -1 : 0 }, [createVNode(Ripple, null, null), createVNode(FocusRing, { "shapeInherit": false }, null), needElevation && createVNode(Elevation, null, null), needOutline && createVNode("div", { "aria-hidden": "true", "class": [css.outline] }, null), createVNode("div", { "aria-hidden": "true", "class": [css.background] }, null), renderContent]); return isLink ? renderLinkWrapper : renderButtonWrapper; }; }, inheritAttrs: true }); export { Button }; //# sourceMappingURL=button.js.map