/**
* GnButton - Primary command component.
*
* @typedef {Object} GnButtonProps
* @property {string} [variant='primary'] - primary | secondary | accent | success | warning | danger | error | info
* @property {string} [size='md'] - sm | md | lg
* @property {string} [icon=''] - Phosphor icon name with ph- prefix (e.g. "ph-plus", "ph-house")
* @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 } from "../utils.js";
export default defineComponent({
name: "GnButton",
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}`,
{
"btn-small": props.size === "sm",
"btn-large": props.size === "lg",
"with-icon": hasIcon,
"loading-state": props.loading
},
attrs.class
)
}, [
props.loading ? iconNode("ph-bold ph-spinner") : iconNode(props.icon),
slots.default?.()
]);
};
}
});