<script setup lang="ts">
// ---------------------------------------------------------------------
// 🔒 AUTOGENERATED @synergy-design-system/vue wrappers for @synergy-design-system/components
// Please do not edit this file directly!
// It will get recreated when running pnpm build.
// ---------------------------------------------------------------------

/**
 * @summary Buttons represent actions that are available to the user.
 * @documentation https://synergy-design-system.github.io/?path=/docs/components-syn-button--docs
 * @status stable
 * @since 1.0.0
 *
 * @dependency syn-icon
 * @dependency syn-spinner
 *
 * @event syn-blur - Emitted when the button loses focus.
 * @event syn-focus - Emitted when the button gains focus.
 * @event syn-invalid - Emitted when the form control has been checked for validity and its constraints aren't satisfied.
 *
 * @slot - The button's label.
 * @slot prefix - A presentational prefix icon or similar element.
 * @slot suffix - A presentational suffix icon or similar element.
 *
 * @csspart base - The component's base wrapper.
 * @csspart prefix - The container that wraps the prefix.
 * @csspart label - The button's label.
 * @csspart suffix - The container that wraps the suffix.
 * @csspart caret - The button's caret icon, an `<syn-icon>` element.
 * @csspart spinner - The spinner that shows when the button is in the loading state.
 */
import { computed, ref } from 'vue';
import '@synergy-design-system/components/components/button/button.js';

import type { SynBlurEvent } from '@synergy-design-system/components';
import type { SynFocusEvent } from '@synergy-design-system/components';
import type { SynInvalidEvent } from '@synergy-design-system/components';
import type SynButton from '@synergy-design-system/components/components/button/button.component.js';

// DOM Reference to the element
const nativeElement = ref<SynButton>();

defineExpose({
  nativeElement,
});

// Map attributes
const props = defineProps<{
  title?: SynButton['title'];

  /**
   * The button's theme variant.
   */
  variant?: SynButton['variant'];

  /**
   * The button's size.
   */
  size?: SynButton['size'];

  /**
   * Draws the button with a caret.
   * Used to indicate that the button triggers a dropdown menu or similar behavior.
   */
  caret?: SynButton['caret'];

  /**
   * Disables the button.
   */
  disabled?: SynButton['disabled'];

  /**
   * Draws the button in a loading state.
   */
  loading?: SynButton['loading'];

  /**
* The type of button.
* Note that the default value is `button` instead of `submit`, which is opposite of how native
`<button>` elements behave.
* When the type is `submit`, the button will submit the surrounding form.
 */
  type?: SynButton['type'];

  /**
* The name of the button, submitted as a name/value pair with form data, but only when this button is the submitter.
This attribute is ignored when `href` is present.
 */
  name?: SynButton['name'];

  /**
* The value of the button, submitted as a pair with the button's name as part of the form data, but only when this
button is the submitter.
* This attribute is ignored when `href` is present.
 */
  value?: SynButton['value'];

  /**
   * When set, the underlying button will be rendered as an `<a>` with this `href` instead of a `<button>`.
   */
  href?: SynButton['href'];

  /**
   * Tells the browser where to open the link.
   * Only used when `href` is present.
   */
  target?: SynButton['target'];

  /**
* When using `href`, this attribute will map to the underlying link's `rel` attribute.
* Unlike regular links, the
default is `noreferrer noopener` to prevent security exploits.
* However, if you're using `target` to point to a
specific tab/window, this will prevent that from working correctly.
* You can remove or change the default value by
setting the attribute to an empty string or a value of your choice, respectively.
 */
  rel?: SynButton['rel'];

  /**
   * Tells the browser to download the linked file as this filename.
   * Only used when `href` is present.
   */
  download?: SynButton['download'];

  /**
* The "form owner" to associate the button with.
* If omitted, the closest containing form will be used instead.
* The
value of this attribute must be an id of a form in the same document or shadow root as the button.
 */
  form?: SynButton['form'];

  /**
   * Used to override the form owner's `action` attribute.
   */
  formAction?: SynButton['formAction'];

  /**
   * Used to override the form owner's `enctype` attribute.
   */
  formEnctype?: SynButton['formEnctype'];

  /**
   * Used to override the form owner's `method` attribute.
   */
  formMethod?: SynButton['formMethod'];

  /**
   * Used to override the form owner's `novalidate` attribute.
   */
  formNoValidate?: SynButton['formNoValidate'];

  /**
   * Used to override the form owner's `target` attribute.
   */
  formTarget?: SynButton['formTarget'];
}>();

// Make sure prop binding only forwards the props that are actually there.
// This is needed because :param="param" also adds an empty attribute
// when using web-components, which breaks optional arguments like size in SynInput
// @see https://github.com/vuejs/core/issues/5190#issuecomment-1003112498
const visibleProps = computed(() =>
  Object.fromEntries(
    Object.entries(props).filter(([, value]) => typeof value !== 'undefined'),
  ),
);

// Map events
defineEmits<{
  /**
   * Emitted when the button loses focus.
   */
  'syn-blur': [e: SynBlurEvent];

  /**
   * Emitted when the button gains focus.
   */
  'syn-focus': [e: SynFocusEvent];

  /**
   * Emitted when the form control has been checked for validity and its constraints aren't satisfied.
   */
  'syn-invalid': [e: SynInvalidEvent];
}>();
</script>

<script lang="ts">
export type { SynBlurEvent } from '@synergy-design-system/components';
export type { SynFocusEvent } from '@synergy-design-system/components';
export type { SynInvalidEvent } from '@synergy-design-system/components';
</script>

<template>
  <syn-button
    @syn-blur="$emit('syn-blur', $event)"
    @syn-focus="$emit('syn-focus', $event)"
    @syn-invalid="$emit('syn-invalid', $event)"
    v-bind="visibleProps"
    ref="nativeElement">
    <slot></slot>
  </syn-button>
</template>
