dap-design-system
Version:
Official design system for the DÁP (dap.gov.hu)
325 lines (324 loc) • 20.5 kB
TypeScript
import { PropertyValueMap } from 'lit';
import { GenericFormElement } from '../../internal/mixin/genericFormElement';
import { ButtonShape, ButtonVariant, HtmlButtonType, LinkTarget } from '../../common/types';
import { default as DapDSIcon } from '../icon/icon.component';
import { ButtonSize } from '../icon-button/icon-button.component';
import { default as SystemLoadingSpinner } from '../icons/system/system-loading-spinner/system-loading-spinner.component';
/**
* `dap-ds-button` is a versatile button component for triggering actions and navigation.
* @element dap-ds-button
* @summary A button is a clickable element that can be used to trigger an action, submit forms, or navigate to other pages.
* @title - Button
*
* @example Basic Usage
* ```html
* <dap-ds-button>Click me</dap-ds-button>
* <dap-ds-button variant="outline">Secondary action</dap-ds-button>
* <dap-ds-button href="/dashboard">Navigate</dap-ds-button>
* ```
*
* @example Form Integration
* ```html
* <form>
* <dap-ds-button htmlType="submit">Submit Form</dap-ds-button>
* <dap-ds-button htmlType="reset" variant="outline">Reset</dap-ds-button>
* </form>
* ```
*
* @example Accessibility
* ```html
* <!-- Icon-only buttons require aria-label -->
* <dap-ds-button aria-label="Close dialog" shape="circle">
* <dap-ds-icon name="close-line"></dap-ds-icon>
* </dap-ds-button>
* ```
*
* @property {string} sizeMap - The size map of the button.
* @example
* ```html
* <dap-ds-button sizeMap="sm:lg,xs:xs">Small</dap-ds-button>
* ```
*
* @event dds-loading-timeout - Emitted when the loading timeout is reached
*
* @slot - The content of the button. Can contain text, icons, or other elements.
*
* @csspart base - The main button container.
* @csspart high-contrast - The high contrast part of the button.
* @csspart content - The content wrapper inside the button.
*
* @cssproperty --dds-button-padding-x - Horizontal padding of the button (default: var(--dds-spacing-300))
* @cssproperty --dds-button-padding-y - Vertical padding of the button (default: var(--dds-spacing-300))
* @cssproperty --dds-button-border-radius - Border radius of the button (default: var(--dds-radius-rounded))
* @cssproperty --dds-button-font-weight - Font weight of the button (default: 700)
* @cssproperty --dds-button-line-height - Line height of the button (default: var(--dds-font-line-height-large))
* @cssproperty --dds-button-transition - Transition property of the button (default: all 0.2s ease-in-out)
* @cssproperty --dds-button-disabled-opacity - Opacity of disabled button (default: 0.5)
*
* @cssproperty --dds-button-size-lg - Size of large button (default: var(--dds-spacing-1200))
* @cssproperty --dds-button-size-md - Size of medium button (default: var(--dds-spacing-1000))
* @cssproperty --dds-button-size-sm - Size of small button (default: var(--dds-spacing-800))
* @cssproperty --dds-button-size-xs - Size of extra small button (default: var(--dds-spacing-600))
*
* @cssproperty --dds-button-circle-lg - Size of large circle button (default: var(--dds-spacing-1200))
* @cssproperty --dds-button-circle-md - Size of medium circle button (default: var(--dds-spacing-1000))
* @cssproperty --dds-button-circle-sm - Size of small circle button (default: var(--dds-spacing-800))
* @cssproperty --dds-button-circle-xs - Size of extra small circle button (default: var(--dds-spacing-600))
*
* Primary button properties:
* @cssproperty --dds-button-primary-color-bg - Background color of primary button (default: var(--dds-button-primary-background-enabled))
* @cssproperty --dds-button-primary-color-bg-hover - Background color of primary button on hover (default: var(--dds-button-primary-background-hover))
* @cssproperty --dds-button-primary-color-bg-active - Background color of primary button when active (default: var(--dds-button-primary-background-pressed))
* @cssproperty --dds-button-primary-color-bg-disabled - Background color of disabled primary button (default: var(--dds-button-primary-background-disabled))
* @cssproperty --dds-button-primary-color-text - Text color of primary button (default: var(--dds-button-primary-text-enabled))
* @cssproperty --dds-button-primary-color-text-disabled - Text color of disabled primary button (default: var(--dds-button-primary-text-disabled))
*
* Primary inverted button properties:
* @cssproperty --dds-button-primary-inverted-color-bg - Background color of primary inverted button (default: var(--dds-button-primary-background-inverted-enabled))
* @cssproperty --dds-button-primary-inverted-color-bg-hover - Background color of primary inverted button on hover (default: var(--dds-button-primary-background-inverted-hover))
* @cssproperty --dds-button-primary-inverted-color-bg-active - Background color of primary inverted button when active (default: var(--dds-button-primary-background-inverted-pressed))
* @cssproperty --dds-button-primary-inverted-color-bg-disabled - Background color of disabled primary inverted button (default: var(--dds-button-primary-background-inverted-disabled))
* @cssproperty --dds-button-primary-inverted-color-text - Text color of primary inverted button (default: var(--dds-button-primary-text-inverted))
* @cssproperty --dds-button-primary-inverted-color-text-disabled - Text color of disabled primary inverted button (default: var(--dds-button-primary-text-inverted-disabled))
*
* Outline button properties:
* @cssproperty --dds-button-outline-color-border - Border color of outline button (default: var(--dds-button-outline-border-enabled))
* @cssproperty --dds-button-outline-color-border-hover - Border color of outline button on hover (default: var(--dds-button-outline-border-hover))
* @cssproperty --dds-button-outline-color-border-active - Border color of outline button when active (default: var(--dds-button-outline-border-pressed))
* @cssproperty --dds-button-outline-color-border-disabled - Border color of disabled outline button (default: var(--dds-button-outline-border-disabled))
* @cssproperty --dds-button-outline-color-text - Text color of outline button (default: var(--dds-button-outline-text-enabled))
* @cssproperty --dds-button-outline-color-text-hover - Text color of outline button on hover (default: var(--dds-button-outline-text-hover))
* @cssproperty --dds-button-outline-color-text-active - Text color of outline button when active (default: var(--dds-button-outline-text-pressed))
* @cssproperty --dds-button-outline-color-text-disabled - Text color of disabled outline button (default: var(--dds-button-outline-text-disabled))
*
* Outline inverted button properties:
* @cssproperty --dds-button-outline-inverted-color-border - Border color of outline inverted button (default: var(--dds-button-outline-border-inverted-enabled))
* @cssproperty --dds-button-outline-inverted-color-border-hover - Border color of outline inverted button on hover (default: var(--dds-button-outline-border-inverted-hover))
* @cssproperty --dds-button-outline-inverted-color-border-active - Border color of outline inverted button when active (default: var(--dds-button-outline-border-inverted-pressed))
* @cssproperty --dds-button-outline-inverted-color-border-disabled - Border color of disabled outline inverted button (default: var(--dds-button-outline-border-inverted-disabled))
* @cssproperty --dds-button-outline-inverted-color-text - Text color of outline inverted button (default: var(--dds-button-outline-text-inverted-enabled))
* @cssproperty --dds-button-outline-inverted-color-text-hover - Text color of outline inverted button on hover (default: var(--dds-button-outline-text-inverted-hover))
* @cssproperty --dds-button-outline-inverted-color-text-active - Text color of outline inverted button when active (default: var(--dds-button-outline-text-inverted-pressed))
* @cssproperty --dds-button-outline-inverted-color-text-disabled - Text color of disabled outline inverted button (default: var(--dds-button-outline-text-inverted-disabled))
*
* Subtle button properties:
* @cssproperty --dds-button-subtle-color-bg - Background color of subtle button (default: var(--dds-button-subtle-background-enabled))
* @cssproperty --dds-button-subtle-color-bg-hover - Background color of subtle button on hover (default: var(--dds-button-subtle-background-hover))
* @cssproperty --dds-button-subtle-color-bg-active - Background color of subtle button when active (default: var(--dds-button-subtle-background-pressed))
* @cssproperty --dds-button-subtle-color-bg-disabled - Background color of disabled subtle button (default: var(--dds-button-subtle-background-disabled))
* @cssproperty --dds-button-subtle-color-border - Border color of subtle button (default: var(--dds-button-subtle-border-enabled))
* @cssproperty --dds-button-subtle-color-border-hover - Border color of subtle button on hover (default: var(--dds-button-subtle-border-hover))
* @cssproperty --dds-button-subtle-color-border-active - Border color of subtle button when active (default: var(--dds-button-subtle-border-pressed))
* @cssproperty --dds-button-subtle-color-border-disabled - Border color of disabled subtle button (default: var(--dds-button-subtle-border-disabled))
* @cssproperty --dds-button-subtle-color-text - Text color of subtle button (default: var(--dds-button-subtle-text-enabled))
* @cssproperty --dds-button-subtle-color-text-hover - Text color of subtle button on hover (default: var(--dds-button-subtle-text-hover))
* @cssproperty --dds-button-subtle-color-text-active - Text color of subtle button when active (default: var(--dds-button-subtle-text-pressed))
* @cssproperty --dds-button-subtle-color-text-disabled - Text color of disabled subtle button (default: var(--dds-button-subtle-text-disabled))
*
* Clean button properties:
* @cssproperty --dds-button-clean-color-text - Text color of clean button (default: var(--dds-text-link-base))
* @cssproperty --dds-button-clean-color-text-hover - Text color of clean button on hover (default: var(--dds-text-link-hover))
* @cssproperty --dds-button-clean-color-text-active - Text color of clean button when active (default: var(--dds-text-link-pressed))
* @cssproperty --dds-button-clean-color-text-disabled - Text color of disabled clean button (default: var(--dds-text-neutral-disabled))
*
* Clean inverted button properties:
* @cssproperty --dds-button-clean-inverted-color-text - Text color of clean inverted button (default: var(--dds-button-primary-text-inverted))
* @cssproperty --dds-button-clean-inverted-color-text-hover - Text color of clean inverted button on hover (default: var(--dds-button-primary-text-inverted))
* @cssproperty --dds-button-clean-inverted-color-text-active - Text color of clean inverted button when active (default: var(--dds-button-primary-text-inverted))
* @cssproperty --dds-button-clean-inverted-color-text-disabled - Text color of disabled clean inverted button (default: var(--dds-text-neutral-disabled))
*
* Danger button properties:
* @cssproperty --dds-button-danger-color-bg - Background color of danger button (default: var(--dds-button-primary-background-destructive-enabled))
* @cssproperty --dds-button-danger-color-bg-hover - Background color of danger button on hover (default: var(--dds-button-primary-background-destructive-hover))
* @cssproperty --dds-button-danger-color-bg-active - Background color of danger button when active (default: var(--dds-button-primary-background-destructive-pressed))
* @cssproperty --dds-button-danger-color-text - Text color of danger button (default: var(--dds-button-primary-text-enabled))
* @cssproperty --dds-button-danger-outline-color-border - Border color of danger outline button (default: var(--dds-button-outline-border-destructive-enabled))
* @cssproperty --dds-button-danger-outline-color-border-hover - Border color of danger outline button on hover (default: var(--dds-button-outline-border-destructive-hover))
* @cssproperty --dds-button-danger-outline-color-border-active - Border color of danger outline button when active (default: var(--dds-button-outline-border-destructive-pressed))
* @cssproperty --dds-button-danger-outline-color-text - Text color of danger outline button (default: var(--dds-button-outline-text-destructive-enabled))
* @cssproperty --dds-button-danger-outline-color-text-hover - Text color of danger outline button on hover (default: var(--dds-button-outline-text-destructive-hover))
* @cssproperty --dds-button-danger-outline-color-text-active - Text color of danger outline button when active (default: var(--dds-button-outline-text-destructive-pressed))
* @cssproperty --dds-button-danger-subtle-color-bg - Background color of danger subtle button (default: var(--dds-button-subtle-background-destructive-enabled))
* @cssproperty --dds-button-danger-subtle-color-bg-hover - Background color of danger subtle button on hover (default: var(--dds-button-subtle-background-destructive-hover))
* @cssproperty --dds-button-danger-subtle-color-bg-active - Background color of danger subtle button when active (default: var(--dds-button-subtle-background-destructive-pressed))
* @cssproperty --dds-button-danger-subtle-color-text - Text color of danger subtle button (default: var(--dds-button-subtle-text-destructive-enabled))
* @cssproperty --dds-button-danger-subtle-color-text-hover - Text color of danger subtle button on hover (default: var(--dds-button-subtle-text-destructive-hover))
* @cssproperty --dds-button-danger-subtle-color-text-active - Text color of danger subtle button when active (default: var(--dds-button-subtle-text-destructive-pressed))
* @cssproperty --dds-button-danger-clean-color-text - Text color of danger clean button (default: var(--dds-text-negative-subtle))
* @cssproperty --dds-button-danger-clean-color-text-hover - Text color of danger clean button on hover (default: var(--dds-text-negative-base))
* @cssproperty --dds-button-danger-clean-color-text-active - Text color of danger clean button when active (default: var(--dds-text-negative-strong))
*/
export default class DapDSButton extends GenericFormElement {
static tagName: string;
/** Components rendered inside the button, auto-registered on first use. */
static dependencies: {
'dap-ds-icon': typeof DapDSIcon;
'dap-ds-icon-loading-spinner': typeof SystemLoadingSpinner;
};
/**
* @ignore
*/
readonly button: HTMLButtonElement | HTMLLinkElement;
/** The visual style variant of the button
* @type { 'primary' | 'outline' | 'subtle' | 'subtle-neutral' | 'subtle-quiet' | 'subtle-quiet-inverted' | 'clean' | 'primary-inverted' | 'outline-inverted' | 'subtle-inverted' | 'clean-inverted' | 'subtle-menu' | 'subtle-menu-item' }
* @default 'primary'
* @example
* ```html
* <dap-ds-button variant="primary">Primary action</dap-ds-button>
* <dap-ds-button variant="outline">Secondary action</dap-ds-button>
* <dap-ds-button variant="subtle">Tertiary action</dap-ds-button>
* ```
* @group Visual
*/
variant: ButtonVariant;
/** The size of the button affecting padding and font size
* @type { 'lg' | 'md' | 'sm' | 'xs' }
* @default 'md'
* @example
* ```html
* <dap-ds-button size="xs">Extra small</dap-ds-button>
* <dap-ds-button size="sm">Small</dap-ds-button>
* <dap-ds-button>Medium (default)</dap-ds-button>
* <dap-ds-button size="lg">Large</dap-ds-button>
* ```
* @group Visual
*/
size: ButtonSize;
/** Whether the button is in loading state, showing a spinner and disabling interaction
* @default false
* @example
* ```html
* <dap-ds-button loading>Submitting...</dap-ds-button>
* ```
* @group State
*/
loading: boolean;
/** Whether the button represents a destructive action (applies danger styling)
* @default false
* @example
* ```html
* <dap-ds-button danger>Delete Account</dap-ds-button>
* <dap-ds-button variant="outline" danger>Remove Item</dap-ds-button>
* ```
* @group State
*/
danger: boolean;
/** The shape of the button - use 'circle' for icon-only buttons
* @type { 'button' | 'circle' }
* @default 'button'
* @example
* ```html
* <dap-ds-button shape="circle" aria-label="Close">
* <dap-ds-icon name="close-line"></dap-ds-icon>
* </dap-ds-button>
* ```
* @group Visual
*/
shape: ButtonShape;
/** The HTML type attribute for form interaction
* @type { 'button' | 'submit' | 'reset' }
* @default 'button'
* @example
* ```html
* <form>
* <dap-ds-button htmlType="submit">Submit</dap-ds-button>
* <dap-ds-button htmlType="reset">Reset</dap-ds-button>
* </form>
* ```
* @group Form
*/
htmlType: HtmlButtonType;
/** The URL to navigate to. When present, the button renders as an anchor element
* @example
* ```html
* <dap-ds-button href="/dashboard">Go to Dashboard</dap-ds-button>
* <dap-ds-button href="https://example.com" target="_blank">External Link</dap-ds-button>
* ```
* @group Navigation
*/
href?: string;
/** The target attribute for link navigation
* @type { '_blank' | '_self' | '_parent' | '_top' }
* @default '_self'
* @example
* ```html
* <dap-ds-button href="https://example.com" target="_blank">Open in new tab</dap-ds-button>
* ```
* @group Navigation
*/
target: LinkTarget;
/** The rel attribute for link security and behavior
* @default 'noreferrer noopener'
* @example
* ```html
* <dap-ds-button href="https://example.com" rel="noopener">Safe external link</dap-ds-button>
* ```
* @group Navigation
*/
rel?: string;
/** Controls loading timeout in milliseconds
* @default 0
* @group State
*/
loadingTimeout: number;
/** Enables high contrast theme toggle functionality (internal use)
* @default false
* @ignore
*/
hc: boolean;
/** Whether the button is active
* @default false
* @example
* ```html
* <dap-ds-button active>Active</dap-ds-button>
* ```
*/
active: boolean;
/**
* Enable OKLCH proof-of-concept theming (experimental)
* @default false
* @internal
* @ignore
*/
oklchPoc: boolean;
/** The text for the target blank link, applicable when target is _blank. PRO TIP: Use parenthesis to wrap the text */
targetBlankText: string;
/** Overrides the ARIA role on the internal native button/anchor element. Use when the host's semantics must differ from the native element (e.g. role="link" on a button acting as a SPA navigation trigger). */
forceRole?: string;
static readonly styles: import('lit').CSSResult;
private loadingTimer?;
/** Persisted aria-label for the inner button; host attribute is removed so we keep the value here */
private _ariaLabelForButton;
/** Internal flag to ignore the aria-label change triggered by our own attribute cleanup */
private _ignoreNextAriaLabelChange;
private getSecureRel;
private validateAriaPressed;
private getAriaExpanded;
private validateProperties;
private isValidUrl;
private handleClick;
private handleKeyDown;
private toggleHighContrast;
private startLoadingTimeout;
private clearLoadingTimeout;
/**
* `this.button` is a `@query`, so it is null until Lit has rendered the shadow root.
* A caller focusing a button the same tick it mounts -- a "Save" button that appears
* only after the form it belongs to opens, say -- would otherwise get a TypeError,
* not a no-op. Throwing out of a focus() call breaks whatever effect made it.
*/
focus(options?: FocusOptions): void;
blur(): void;
/**
* @ignore
*/
get focusElement(): HTMLLinkElement | HTMLButtonElement;
/** Aria-label for the inner button; survives host attribute removal so Lit does not clear it */
private get effectiveAriaLabel();
protected updated(changedProperties: Map<string | number | symbol, unknown>): void;
protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void;
disconnectedCallback(): void;
render(): import('lit-html').TemplateResult;
private getLoadingIconSize;
private _getLoadingSpinner;
}