Skip to content

Early previewhamur is not on npm yet. The components are being built in the open, follow along on GitHub.

InputsReact

Button

A button that can render as another tag or stay focusable while disabled.

Rendered by React 19.3.1

import * as React from 'react'
import { Button } from '@hamur/react/button'

export default function ButtonExample() {
  const [count, setCount] = React.useState(0)
  return (
    <div className="stack">
      <div className="row">
        <Button className="button" onClick={() => setCount(count + 1)}>
          Save changes
        </Button>
        <Button className="button" disabled>
          Disabled
        </Button>
        <Button className="button" disabled focusableWhenDisabled>
          Focusable
        </Button>
      </div>
      <p className="muted">Saved {count} times</p>
    </div>
  )
}
43Tests passing in React · 0 failing
3.8 KiBSize
Not measured yetMemory
Not measured yetSpeed
productdevbook and 7 upstream authors8 commits · last

Installation

npm i @hamur/react

Not on npm yet. The package goes out under the chosen name.

Anatomy

Import the component and assemble its parts:

<Button />

Examples

Loading

focusableWhenDisabled keeps focus on the button while it is disabled during a loading state.

ButtonLoading.tsx
import { useId, useState } from 'react'
import { Button } from '@hamur/react/button'

export default function ButtonLoadingExample() {
  const [loading, setLoading] = useState(false)
  const labelId = useId()

  return (
    <Button
      className="button"
      disabled={loading}
      focusableWhenDisabled
      aria-labelledby={labelId}
      onClick={() => {
        setLoading(true)
        setTimeout(() => setLoading(false), 4000)
      }}
    >
      <span id={labelId}>{loading ? 'Submitting' : 'Submit'}</span>
    </Button>
  )
}

API reference

2 props across 1 parts, in React syntax. className, style, render are listed once, under Shared props.

ButtonButton

A button component that can be used to trigger actions. Renders a <button>.

Button props
PropTypeDefault
focusableWhenDisabledWhether the button should be focusable when disabled.booleanfalse
nativeButtonWhether the component renders a native <button> element when replacing itbooleantrue
Button data attributes
Data attributeDescription
data-disabledPresent when the button is disabled.

Shared props

Every part that renders an element takes these.

Shared props
PropType
classNameCSS class applied to the element, or a function that returns a class based on the component's state.string | ((state: State) => string | undefined)
styleStyle applied to the element, or a function that returns a style object based on the component's state.React.CSSProperties | ((state: State) => React.CSSProperties | undefined)
renderAllows you to replace the component's HTML element with a different tag, or compose it with another component.React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, State>

Keyboard and accessibility

Keyboard

Keyboard
KeysDoesPart
EnterSpaceActivates the button with a real click, also when it renders an element other than <button>Button
SpaceOn an element rendered as a link, activates it without scrolling the pageButton

Accessibility

What the parts set
PartSetsSo that
Buttonrole="button" and tabindex="0" when nativeButton is offanother element is still read and reached as a button
Buttondisabled, or aria-disabled="true" when it is not a native button or focusableWhenDisabled is ona screen reader says it is unavailable
Buttonkeeps focus when disabled with focusableWhenDisabledfocus does not jump away while a button shows a loading state

Focus order

  1. Button is one tab stop. Disabled, it leaves the tab order unless focusableWhenDisabled is on.