UNPKG

@dvcol/neo-svelte

Version:

Neomorphic ui library for svelte 5

216 lines (215 loc) 7.45 kB
import type { Snippet } from 'svelte'; import type { HTMLAnchorAttributes, HTMLButtonAttributes, KeyboardEventHandler } from 'svelte/elements'; import type { NeoImageProps } from '../media/neo-image.model.js'; import type { HTMLActionProps } from '../utils/action.utils.js'; import type { BorderRadiusInput } from '../utils/border.utils.js'; import type { Color } from '../utils/colors.utils.js'; import type { HTMLFlexProps, HTMLNeoBaseElement, HTMLRefProps, SvelteEvent } from '../utils/html-element.utils.js'; import type { BlurElevation, BlurElevationString, ShadowElevation, ShadowElevationString, ShadowHoverElevation, ShadowHoverElevationsString } from '../utils/shadow.utils.js'; export type NeoButtonBlur = BlurElevation | BlurElevationString; export type NeoButtonElevation = ShadowElevation | ShadowElevationString; export type NeoButtonHoverElevation = ShadowHoverElevation | ShadowHoverElevationsString; export type NeoButtonActiveElevation = ShadowHoverElevation | ShadowHoverElevationsString; export interface NeoButtonStates { /** * The url to navigate to when the anchor is clicked. */ href?: string; /** * If true, the button will be disabled and a spinner will be displayed alongside the text. * If an icon is provided, the spinner will replace the icon. */ loading?: boolean; /** * Disables all button interactions. */ disabled?: boolean; /** * If true, the button will ignore click events like a disabled button, but will still be interactive. */ readonly?: boolean; /** * If true, the button will be disabled and a loading skeleton will be displayed instead of the text. */ skeleton?: boolean; /** * If the button is currently hovered. */ hovered?: boolean; /** * If the button is currently focused. */ focused?: boolean; /** * If true, the button will not propagate the click event to its parent elements. * This is useful for preventing unwanted side effects when clicking the button. */ propagation?: boolean; /** * If true, the button will act as a toggle button. */ toggle?: boolean; /** * Bindable value for the toggle state. * @bindable */ checked?: boolean; } export type NeoButtonContext = NeoButtonStates & { /** * Reference to the button HTML element. */ ref?: HTMLRefProps['ref']; /** * The current state of the button. */ pressed: boolean; }; export type NeoButtonProps<Tag extends keyof HTMLElementTagNameMap = 'button'> = { /** * Snippet to display as the button content. */ children?: Snippet<[NeoButtonContext]>; /** * Optional snippet or text to display as the button label. */ label?: Snippet<[NeoButtonContext]> | string; /** * Optional icon snippet to display before the text. */ icon?: Snippet<[NeoButtonContext]> | string; /** * The HTML tag to use for the button. * If an `href` is provided, the tag will default to `'a'`. * @default 'button' */ tag?: Tag | keyof HTMLElementTagNameMap; /** * If true, the button will start as flat on first render. * @see [@starting-style](https://developer.mozilla.org/en-US/docs/Web/CSS/@starting-style) for browser support */ start?: boolean; /** * Text color to use for the button. */ color?: Color | CSSStyleDeclaration['color']; /** * Shorthand for a flat borderless inset button. * * @defaults`{ elevation: 0, hover: -1, active: -3, pressed: false, borderless: true }` */ text?: boolean; /** * If true, button specific styles will be removed (padding, text align & justification). * And the button will act as a flex container. * * @defaults`{ elevation: 0, hover: -1, active: -2, pressed: false, scale: false, borderless: true }` */ container?: boolean; /** * Input elevation. * * @default 3 (absolute value) */ elevation?: NeoButtonElevation; /** * Whether to increase/decrease the elevation when hovered/focused. * * @default -1 (relative to base elevation) */ hover?: NeoButtonHoverElevation; /** * Whether to increase/decrease the elevation when active. * * @default -2 (absolute value) */ active?: NeoButtonActiveElevation; /** * The blur level to apply to the button when in glass mode. * * @default elevation, min: 1, max: 5 * @see glass */ blur?: NeoButtonBlur; /** * Whether the pressed state should be displayed as recessed or pressed. * * @default true if `elevation` + `hover` > 0 && `active` < 0 */ pressed?: boolean; /** * Whether to scale the button content on active state. * * @default true */ scale?: boolean | number; /** * If true, the button will be displayed with no elevation. */ borderless?: boolean; /** * If true, the button will be displayed with a glass effect. */ glass?: boolean; /** * Set the button to be filled with the background color. */ filled?: boolean; /** * Tints the button with the current color. */ tinted?: boolean; /** * If true, the button will have a rounded border. */ rounded?: BorderRadiusInput; /** * If true, the flex direction of the button will be reversed. */ reverse?: boolean; /** * If true, the button will be surrounded by coalescing waves. * The waves will reverse direction on hover or active states. */ coalesce?: boolean; /** * If true, the button will be surrounded by expanding waves. * The waves will reverse direction on hover or active states. */ pulse?: boolean; /** * Aspect ratio of the button. * * @see [aspect-ratio](https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio) */ ratio?: CSSStyleDeclaration['aspectRatio']; /** * Callback function to be called when the toggle state changes. * @param checked */ onchecked?: (checked: boolean) => unknown; /** * Callback function to be called when the button is clicked. * @param e * @param checked */ onclick?: (e: SvelteEvent<MouseEvent>, checked?: boolean) => unknown; /** * Callback function to be called when a key is pressed. * @param e */ onkeydown?: KeyboardEventHandler<HTMLButtonElement>; /** * Callback function to be called when a key is released. * @param e */ onkeyup?: KeyboardEventHandler<HTMLButtonElement>; /** * Optional props to pass to the icon image component if the icon is a string. */ imageProps?: Partial<NeoImageProps>; } & NeoButtonStates & HTMLFlexProps & HTMLActionProps & HTMLRefProps & Partial<Omit<Tag extends 'button' ? HTMLButtonAttributes : Tag extends 'a' ? HTMLAnchorAttributes : HTMLNeoBaseElement<HTMLElementTagNameMap[Tag]>, 'onclick' | 'onkeydown' | 'onkeyup'>>; export type NeoButtonTemplate = Pick<NeoButtonProps, 'elevation' | 'hover' | 'active' | 'pressed' | 'borderless' | 'glass' | 'tinted' | 'rounded' | 'reverse' | 'coalesce' | 'pulse'>; export declare const NeoRaisedButton: NeoButtonTemplate; export declare const NeoFlatButton: NeoButtonTemplate; export declare const NeoTextButton: NeoButtonTemplate;