Newer
Older
vmk-ui-kit / src / vue / components / GnButton.js
@Eugene Sukhodolskiy Eugene Sukhodolskiy 2 days ago 1 KB Implement Button component and Vue adapter
/**
 * GnButton — primary command component.
 *
 * API-compatible with gnexus-ui-kit GnButton.
 *
 * @typedef {Object} GnButtonProps
 * @property {string} [variant='primary'] - primary | secondary | accent | success | warning | danger | error | info
 * @property {string} [size='md'] - xxs | xs | sm | md | lg
 * @property {string} [icon=''] - VMK icon key (e.g. "essentials/plus") or legacy Phosphor name with ph- prefix
 * @property {boolean} [loading=false] - Show spinner and disable interaction
 * @property {boolean} [disabled=false] - Disabled state
 * @property {string} [type='button'] - button | submit | reset
 *
 * @slots default - Button label text
 */

import { defineComponent, h } from "vue";
import { cx, iconNode, normalizeVariant, normalizeSize } from "../utils.js";

export default defineComponent({
	name: "GnButton",
	inheritAttrs: false,
	props: {
		variant: { type: String, default: "primary" },
		size: { type: String, default: "md" },
		icon: { type: String, default: "" },
		loading: { type: Boolean, default: false },
		disabled: { type: Boolean, default: false },
		type: { type: String, default: "button" }
	},
	setup(props, { attrs, slots }) {
		return () => {
			const hasIcon = Boolean(props.icon || props.loading);
			const variant = normalizeVariant(props.variant);

			return h("button", {
				...attrs,
				type: props.type,
				disabled: props.disabled || props.loading,
				class: cx(
					"btn",
					`btn-${variant}`,
					normalizeSize(props.size),
					{
						"with-icon": hasIcon,
						"is-loading": props.loading
					},
					attrs.class
				)
			}, [
				props.loading ? iconNode("essentials/loading") : iconNode(props.icon),
				slots.default?.()
			]);
		};
	}
});