{
  "tag": "ed-button",
  "kind": "component",
  "summary": "Buttons represent actions that are available to the user.",
  "status": "experimental",
  "level": "atom",
  "since": "1.0",
  "docs": "https://test-apps.eurodata.de/a/eurodata-ui/docs/components/button/",
  "usage": "https://test-apps.eurodata.de/a/eurodata-ui/docs/components/button/usage/",
  "playwright": "getByTestId('…')",
  "dependencies": [
    "ed-icon",
    "ed-progress-ring"
  ],
  "use": [
    "Triggering a consequence — saving, submitting, deleting, publishing, opening a dialog",
    "The action the current view exists for — the thing the user came here to do",
    "Any high-consequence or irreversible action, and any change of state in the current context — never a link for those"
  ],
  "notFor": [
    {
      "when": "Navigation to another page — never from a button's click handler",
      "instead": "a link button (set `href`), or a text link when it needs no button-level prominence"
    },
    {
      "when": "An action inside a sentence or paragraph",
      "instead": "a text link"
    },
    {
      "when": "A sequence of steps",
      "instead": "[Wizard](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/wizard), with its built-in Previous and Next"
    },
    {
      "when": "Choosing between two to four modes of one view",
      "instead": "a [Radio Group](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/radio-group) in its button appearance"
    },
    {
      "when": "A binary status such as on/off",
      "instead": "a [Switch](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/switch)"
    }
  ],
  "rules": [
    {
      "id": "button/one-accent-per-scope",
      "rule": "Use at most one accent button per scope. A scope is the screen, and inside it every area that completes an action of its own: an open overlay ([Dialog](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/dialog), [Drawer](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/drawer), [Alert Dialog](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/alert-dialog), or a [Popover](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/popover) such as an open filter panel), a side pane beside the main content, each tab's panel, and an expanded inline-edit area with its own confirm button. Toolbars and sections on the same surface share its scope. Set every scope visibly apart from the area around it — space, a border or a change of background — or its accent button reads as a competitor. Zero is valid.",
      "why": "Several equally dominant buttons eliminate the hierarchy and leave users unsure which action matters; redesign the priority before adding a second. An area that finishes its own task is where the user's attention is while working in it, so its confirming action may lead there.",
      "check": "warning"
    },
    {
      "id": "button/explicit-secondary-appearance",
      "rule": "Give every secondary action an explicit lower-emphasis appearance, `outlined` or `plain` — which of the two, the container's rules decide. In a row of buttons the confirming action keeps the default accent and every other button in the row gets one. Never `plain` for the primary call to action.",
      "why": "Accent is the default, so a Cancel written next to a Save renders as a second competing primary. This is the most frequent way the accent limit is broken, and dialog and drawer footers are where it happens.",
      "check": "error"
    },
    {
      "id": "button/consumer-appearances",
      "rule": "Use `accent`, `outlined` and `plain` in product UI, never `filled` or `filled-outlined`. `filled` is reserved for the slotted action and close buttons inside a [Toast](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/toast-item) or [Notification](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/notification).",
      "check": "error"
    },
    {
      "id": "button/brand-variant",
      "rule": "Use the brand variant. The `ai` variant is for AI-powered actions only; status variants only for actions slotted into a [Notification](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/notification) or [Toast](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/toast-item).",
      "why": "A destructive action shows itself through its confirmation dialog, the trash icon and its place — never through a red button.",
      "check": "error"
    },
    {
      "id": "button/label-pattern",
      "rule": "Label with Noun + Verb. In standard views put an icon before the label where the action has one that fits (add, save, delete, export, print); an action without a telling icon stays text-only. Buttons in modal dialogs carry no icon. A copy button keeps its icon in a dialog too, as [Copy Button](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/copy-button) asks.",
      "why": "Noun and verb say what happens; a telling icon lets the eye find the action without reading. An icon forced onto every button says nothing and makes the ones that mean something harder to see.",
      "check": "warning"
    },
    {
      "id": "button/name-the-object",
      "rule": "Name the object on a destructive, irreversible or high-stakes action that stands on its own or confirms one — never \"OK\", \"Yes\", \"No\", \"Submit\" or a verb alone. Where the object stands in the same line as the button, the container's rule decides.",
      "check": "warning"
    },
    {
      "id": "button/separate-destructive",
      "rule": "Keep a destructive action physically apart from the safe ones, never directly beside a frequently used safe action.",
      "check": "warning"
    },
    {
      "id": "button/loading-until-resolved",
      "rule": "Enter the loading state immediately on click and keep it until the operation resolves. A confirm that closes its dialog right away shows progress and failure elsewhere — a progress indicator, an upload list, a toast.",
      "why": "An async operation behind a closed dialog is invisible, and so is its failure.",
      "check": "warning"
    },
    {
      "id": "button/explain-disabled",
      "rule": "A disabled button explains itself: an [`ed-tooltip`](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/tooltip) whose `for` names the button's id says what makes it available, and in a form, where there is room, a visible hint beside it says it too.",
      "why": "A disabled button is skipped by keyboard focus and explains nothing on its own.",
      "check": "error"
    },
    {
      "id": "button/text-label",
      "rule": "Give every button a visible text label. Icon-only only where the container's rules allow it, and then always with an [`ed-tooltip`](https://test-apps.eurodata.de/a/eurodata-ui/docs/components/tooltip) and an accessible name; never icon-only for a destructive action outside such a place.",
      "why": "Icon recognition is subjective and generational, never universal: to someone who never saw a floppy disk, the save icon is a vending machine dispensing a can.",
      "check": "error"
    },
    {
      "id": "form-controls/default-density",
      "rule": "Keep `density` at its default, and the same for every control in one row or form. Choose `compact` or `spacious` only where the user asks for it or the space leaves no other way — a form with many fields is no reason — and then for the whole layout, never to fine-tune spacing case by case. Where a container decides the density of the controls inside it, its rules say so.",
      "why": "The default is the intended spacing for almost every screen.",
      "check": "warning"
    }
  ],
  "api": {
    "attributes": [
      {
        "name": "title",
        "property": "title",
        "type": "string",
        "default": "''"
      },
      {
        "name": "variant",
        "property": "variant",
        "type": "'new' | 'warning' | 'brand' | 'ai' | 'info' | 'neutral' | 'success' | 'danger'",
        "default": "'brand'",
        "description": "The button's theme variant. Defaults to `brand` if not within another element with a variant."
      },
      {
        "name": "navbar",
        "property": "navbar",
        "type": "boolean",
        "default": "false",
        "description": "Flags the buttons as a navbar button. This is for convenience to make a full-height, at least squared, header-colored button."
      },
      {
        "name": "appearance",
        "property": "appearance",
        "type": "'accent' | 'filled-outlined' | 'filled' | 'outlined' | 'plain'",
        "default": "'accent'",
        "description": "The button's visual appearance."
      },
      {
        "name": "density",
        "property": "density",
        "type": "'compact' | 'default' | 'spacious'",
        "default": "'default'",
        "description": "Controls the component's spacing density without affecting font-size."
      },
      {
        "name": "with-caret",
        "property": "withCaret",
        "type": "boolean",
        "default": "false",
        "description": "Draws the button with a caret. Used to indicate that the button triggers a dropdown menu or similar behavior."
      },
      {
        "name": "with-start",
        "property": "withStart",
        "type": "boolean",
        "default": "false",
        "description": "Only required for SSR. Set to `true` if you're slotting in a `start` element so the server-rendered markup\nincludes the start slot before the component hydrates on the client."
      },
      {
        "name": "with-end",
        "property": "withEnd",
        "type": "boolean",
        "default": "false",
        "description": "Only required for SSR. Set to `true` if you're slotting in an `end` element so the server-rendered markup\nincludes the end slot before the component hydrates on the client."
      },
      {
        "name": "loading",
        "property": "loading",
        "type": "boolean",
        "default": "false",
        "description": "Draws the button in a loading state."
      },
      {
        "name": "aria-label",
        "property": "ariaLabel",
        "type": "null | string",
        "default": "null",
        "description": "The button's accessible name for when the visible content isn't the desired name (e.g.\nicon-only buttons). Mirrored onto the internal button/anchor, where the role lives — an\naria-label left on the host alone would sit on a role-less element and be ignored by\nassistive tech."
      },
      {
        "name": "pill",
        "property": "pill",
        "type": "boolean",
        "default": "false",
        "description": "Draws a pill-style button with rounded edges."
      },
      {
        "name": "type",
        "property": "type",
        "type": "'reset' | 'button' | 'submit'",
        "default": "'button'",
        "description": "The type of button. Note that the default value is `button` instead of `submit`, which is opposite of how native\n`<button>` elements behave. When the type is `submit`, the button will submit the surrounding form."
      },
      {
        "name": "name",
        "property": "name",
        "type": "null | string",
        "default": "null",
        "description": "The name of the button, submitted as a name/value pair with form data, but only when this button is the submitter.\nThis attribute is ignored when `href` is present."
      },
      {
        "name": "value",
        "property": "value",
        "type": "string",
        "description": "The value of the button, submitted as a pair with the button's name as part of the form data, but only when this\nbutton is the submitter. This attribute is ignored when `href` is present."
      },
      {
        "name": "href",
        "property": "href",
        "type": "string",
        "description": "When set, the underlying button will be rendered as an `<a>` with this `href` instead of a `<button>`."
      },
      {
        "name": "target",
        "property": "target",
        "type": "string",
        "description": "Tells the browser where to open the link. Only used when `href` is present.\n\nTakes the `_blank`, `_self`, `_parent` and `_top` keywords, or the name of a window: a link\nwhose target names an already open window navigates that window instead of opening another one.\nNote that `rel=\"noopener\"` suppresses the lookup, so a named target then opens a new window\nevery time.\n\nThe implicit opener isolation browsers apply covers `_blank` only. A named target leaves\n`window.opener` set on the opened page, so a link pointing at untrusted content needs\n`rel=\"noopener\"` spelled out."
      },
      {
        "name": "rel",
        "property": "rel",
        "type": "string | undefined",
        "description": "When using `href`, this attribute will map to the underlying link's `rel` attribute."
      },
      {
        "name": "download",
        "property": "download",
        "type": "string | undefined",
        "description": "Tells the browser to download the linked file as this filename. Only used when `href` is present."
      },
      {
        "name": "formaction",
        "property": "formAction",
        "type": "string",
        "description": "Used to override the form owner's `action` attribute."
      },
      {
        "name": "formenctype",
        "property": "formEnctype",
        "type": "'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/plain'",
        "description": "Used to override the form owner's `enctype` attribute."
      },
      {
        "name": "formmethod",
        "property": "formMethod",
        "type": "'post' | 'get' | 'dialog'",
        "description": "Used to override the form owner's `method` attribute.\n\n`dialog` is the third keyword HTML defines here: inside a `<dialog>` it closes the dialog and\nsubmits nothing, with the button's value becoming the dialog's return value."
      },
      {
        "name": "formnovalidate",
        "property": "formNoValidate",
        "type": "boolean",
        "description": "Used to override the form owner's `novalidate` attribute."
      },
      {
        "name": "formtarget",
        "property": "formTarget",
        "type": "string",
        "description": "Used to override the form owner's `target` attribute. Takes the same values as `target`: the four keywords or a\nwindow name."
      },
      {
        "name": "error",
        "property": "error",
        "type": "null | string",
        "default": "null",
        "description": "Draws an error-style input with danger colored border and icon. Set to an empty string (or use the bare attribute `<ed-input error>`) to render error styling without a visible message; submission is still blocked with a localized fallback validation message. Set to a non-empty string to additionally display that message in the message area, above the hint, and use it as the validation message. Set to `null` (the default) or remove the attribute to clear the error."
      },
      {
        "name": "warning",
        "property": "warning",
        "type": "null | string",
        "default": "null",
        "description": "Draws a warning-style input with warning colored border and icon. Set to an empty string (or use the bare attribute `<ed-input warning>`) to render warning styling without a visible message. Set to a non-empty string to additionally display that message in the message area, above the hint. Warnings do not block form submission. Set to `null` (the default) or remove the attribute to clear the warning."
      },
      {
        "name": "ai",
        "property": "ai",
        "type": "boolean",
        "default": "false",
        "description": "Draws an ai-style input with AI colored border and icon. Suppressed visually once\n`hasInteracted` flips, but the property and attribute are preserved so the styling\nreturns after `formResetCallback` clears `hasInteracted`."
      },
      {
        "name": "hint",
        "property": "hint",
        "type": "string",
        "default": "''",
        "description": "The form control's hint text. If you need to display HTML, use the `hint` slot instead."
      },
      {
        "name": "disabled",
        "property": "disabled",
        "type": "boolean",
        "description": "Disables the form control. HTML treats a control as disabled when either its own `disabled` is\nset or an ancestor `<fieldset>` is disabled, so reading this reports the combined state while\nwriting it sets only this element's own. Keeping the two apart is what lets a fieldset be\nre-enabled without clearing a disabled state the consumer set in the meantime."
      },
      {
        "name": "dir",
        "property": "dir",
        "type": "string"
      },
      {
        "name": "lang",
        "property": "lang",
        "type": "string"
      }
    ],
    "properties": [
      {
        "name": "form",
        "type": "HTMLFormElement | null",
        "description": "By default, form controls are associated with the nearest containing `<form>` element. This attribute allows you\nto place the form control outside of a form and associate it with the form that has this `id`. The form must be in\nthe same document or shadow root for this to work."
      },
      {
        "name": "validationTarget",
        "type": "undefined | HTMLElement",
        "description": "Override this to change where constraint validation popups are anchored."
      }
    ],
    "methods": [
      {
        "name": "click",
        "description": "Simulates a click on the button."
      },
      {
        "name": "focus",
        "parameters": [
          {
            "name": "options",
            "type": "FocusOptions",
            "optional": true
          }
        ],
        "description": "Sets focus on the button."
      },
      {
        "name": "blur",
        "description": "Removes focus from the button."
      },
      {
        "name": "setCustomValidity",
        "parameters": [
          {
            "name": "message",
            "type": "string"
          }
        ],
        "description": "Do not use this when creating a \"Validator\". This is intended for end users of components.\nWe track manually defined custom errors so we don't clear them on accident in our validators."
      },
      {
        "name": "resetValidity",
        "description": "Reset validity is a way of removing manual custom errors and native validation."
      }
    ],
    "events": [
      {
        "name": "blur",
        "react": "onBlur",
        "description": "Emitted when the button loses focus."
      },
      {
        "name": "focus",
        "react": "onFocus",
        "description": "Emitted when the button gains focus."
      },
      {
        "name": "ed-invalid",
        "react": "onEdInvalid",
        "description": "Emitted when the form control has been checked for validity and its constraints aren't satisfied."
      }
    ],
    "slots": [
      {
        "name": "",
        "description": "The button's label."
      },
      {
        "name": "start",
        "description": "An element, such as `<ed-icon>`, placed before the label."
      },
      {
        "name": "end",
        "description": "An element, such as `<ed-icon>`, placed after the label."
      }
    ],
    "cssProperties": [],
    "parts": [
      {
        "name": "base",
        "description": "The component's base wrapper."
      },
      {
        "name": "start",
        "description": "The container that wraps the `start` slot."
      },
      {
        "name": "label",
        "description": "The button's label."
      },
      {
        "name": "end",
        "description": "The container that wraps the `end` slot."
      },
      {
        "name": "caret",
        "description": "The button's caret icon, a `<ed-icon>` element."
      },
      {
        "name": "spinner",
        "description": "The spinner that shows when the button is in the loading state."
      }
    ],
    "states": [
      {
        "name": "disabled",
        "description": "Applied when the button is disabled."
      },
      {
        "name": "icon-button",
        "description": "Applied when the button contains only a `<ed-icon>` with no other content."
      },
      {
        "name": "link",
        "description": "Applied when the button is rendered as a link (i.e. `href` is set)."
      },
      {
        "name": "loading",
        "description": "Applied when the button is in the loading state."
      },
      {
        "name": "required",
        "description": "The control is required."
      },
      {
        "name": "optional",
        "description": "The control is not required."
      },
      {
        "name": "invalid",
        "description": "The value fails constraint validation, whether or not the user has touched the control yet."
      },
      {
        "name": "valid",
        "description": "The value passes constraint validation."
      },
      {
        "name": "user-invalid",
        "description": "Invalid, and the user has interacted with the control. This is the one to style for an error: it behaves like the platform's `:user-invalid`, so an untouched field is not marked wrong before the user has had a chance to fill it in."
      },
      {
        "name": "user-valid",
        "description": "Valid, and the user has interacted with the control."
      },
      {
        "name": "dirty",
        "description": "The user has interacted with the control."
      },
      {
        "name": "error",
        "description": "The `error` property is set, or the control is `user-invalid`."
      },
      {
        "name": "warning",
        "description": "The `warning` property is set."
      },
      {
        "name": "ai",
        "description": "The `ai` property is set and the user has not interacted with the control yet."
      }
    ]
  },
  "import": "import '@eurodata/eurodata-ui/dist/components/button/button.js';",
  "react": {
    "component": "EdButton",
    "import": "import EdButton from '@eurodata/eurodata-ui/dist/react/button/index.js';"
  }
}
