RiseUI
Components

Button

Clickable button with HeroUI v3 variants, sizes, icons, loading, and full width — aligned with @heroui/react and button.css (rounded-3xl, gap-2, press scale 0.97).

Usage

Basic `onPress` / `onPressed` handler.

RiseButton(
  label: 'Click me',
  onPressed: () {},
)

Variants

Primary, secondary, tertiary, outline, ghost, danger, danger soft.

Wrap(
  spacing: 12,
  runSpacing: 12,
  children: [
    RiseButton(label: 'Primary', onPressed: () {}),
    RiseButton(variant: RiseButtonVariant.secondary, label: 'Secondary', onPressed: () {}),
    RiseButton(variant: RiseButtonVariant.tertiary, label: 'Tertiary', onPressed: () {}),
    RiseButton(variant: RiseButtonVariant.outline, label: 'Outline', onPressed: () {}),
    RiseButton(variant: RiseButtonVariant.ghost, label: 'Ghost', onPressed: () {}),
    RiseButton(variant: RiseButtonVariant.danger, label: 'Danger', onPressed: () {}),
    RiseButton(variant: RiseButtonVariant.dangerSoft, label: 'Danger soft', onPressed: () {}),
  ],
)

With icons

Leading icon + label in a row.

RiseButton(
  onPressed: () {},
  child: Row(
    mainAxisSize: MainAxisSize.min,
    children: [
      Icon(Icons.search, size: 18),
      SizedBox(width: 8),
      Text('Search'),
    ],
  ),
)

Icon only

`isIconOnly: true` — square hit target.

RiseButton(
  isIconOnly: true,
  onPressed: () {},
  child: Icon(Icons.more_horiz),
)

Loading

Spinner + label while pending (disabled tap).

RiseButton(
  isDisabled: true,
  onPressed: null,
  child: Row(
    mainAxisSize: MainAxisSize.min,
    children: [
      SizedBox(
        width: 16,
        height: 16,
        child: CircularProgressIndicator(strokeWidth: 2, color: accentForeground),
      ),
      SizedBox(width: 10),
      Text('Uploading…'),
    ],
  ),
)

Loading state

Outline button with leading icon (upload).

RiseButton(
  variant: RiseButtonVariant.outline,
  onPressed: () {},
  child: Row(
    mainAxisSize: MainAxisSize.min,
    children: [
      Icon(Icons.attach_file, size: 18),
      SizedBox(width: 8),
      Text('Upload File'),
    ],
  ),
)

Sizes

`sm` · `md` · `lg` — heights 32 / 40 / 44.

Row(
  mainAxisSize: MainAxisSize.min,
  children: [
    RiseButton(size: RiseButtonSize.sm, label: 'Small', onPressed: () {}),
    SizedBox(width: 16),
    RiseButton(size: RiseButtonSize.md, label: 'Medium', onPressed: () {}),
    SizedBox(width: 16),
    RiseButton(size: RiseButtonSize.lg, label: 'Large', onPressed: () {}),
  ],
)

Full width

`fullWidth: true`.

Column(
  crossAxisAlignment: CrossAxisAlignment.stretch,
  children: [
    RiseButton(fullWidth: true, label: 'Primary Button', onPressed: () {}),
    RiseButton(
      fullWidth: true,
      variant: RiseButtonVariant.outline,
      onPressed: () {},
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [Icon(Icons.add, size: 18), SizedBox(width: 8), Text('With Icon')],
      ),
    ),
  ],
)

Disabled

`isDisabled: true` across variants.

RiseButton(
  isDisabled: true,
  label: 'Primary',
  onPressed: () {},
)

Social buttons

Outline + `fullWidth` stacked rows (swap icons for brand assets — no separate social primitive).

Column(
  crossAxisAlignment: CrossAxisAlignment.stretch,
  children: [
    RiseButton(
      fullWidth: true,
      variant: RiseButtonVariant.outline,
      onPressed: () {},
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(Icons.g_mobiledata, size: 20),
          SizedBox(width: 10),
          Text('Sign in with Google'),
        ],
      ),
    ),
    SizedBox(height: 12),
    RiseButton(
      fullWidth: true,
      variant: RiseButtonVariant.outline,
      onPressed: () {},
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(Icons.code, size: 20),
          SizedBox(width: 10),
          Text('Sign in with GitHub'),
        ],
      ),
    ),
    SizedBox(height: 12),
    RiseButton(
      fullWidth: true,
      variant: RiseButtonVariant.outline,
      onPressed: () {},
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(Icons.apple, size: 20),
          SizedBox(width: 10),
          Text('Sign in with Apple'),
        ],
      ),
    ),
  ],
)

Compound label

Compose `child` with `RiseButtonLabel` for variant-colored text (e.g. icon + label + muted suffix).

RiseButton(
  variant: RiseButtonVariant.secondary,
  onPressed: () {},
  child: Row(
    mainAxisSize: MainAxisSize.min,
    children: [
      Icon(Icons.mail_outlined, size: 18),
      SizedBox(width: 8),
      RiseButtonLabel('Messages'),
      SizedBox(width: 6),
      Text(
        '12',
        style: Theme.of(context).textTheme.labelSmall?.copyWith(
          color: context.riseTheme.mutedForeground(0.85),
        ),
      ),
    ],
  ),
)