Components/Button
VerifiedSince 1.0.0

Button

Tactile button system with flat variants

Button

Usage

Buttons trigger explicit actions. Keep a clear hierarchy in the interface:

  • Keep a single primary button per view to avoid hierarchy conflicts
  • Use variant and size to convey action priority
  • Async actions should show loading to avoid repeated triggers

Variants

Appearance

Base visuals and semantic variants.

Demo will load when visible.
<template>
  <TxButton>Default</TxButton>
  <TxButton variant="primary">Primary</TxButton>
  <TxButton variant="secondary">Secondary</TxButton>
  <TxButton variant="ghost">Ghost</TxButton>
  <TxButton variant="danger">Danger</TxButton>
  <TxButton variant="success">Success</TxButton>
  <TxButton variant="warning">Warning</TxButton>
  <TxButton variant="info">Info</TxButton>
</template>

Disabled

Disabled states.

Demo will load when visible.
<template>
  <TxButton disabled>Default</TxButton>
  <TxButton variant="primary" disabled>Primary</TxButton>
  <TxButton variant="secondary" disabled>Secondary</TxButton>
  <TxButton variant="ghost" disabled>Ghost</TxButton>
  <TxButton variant="danger" disabled>Danger</TxButton>
</template>

Loading

Show loading feedback during async actions.

Demo will load when visible.
<script setup>
import { ref } from 'vue'

const loading = ref(false)

async function handleClick() {
  if (loading.value) return
  loading.value = true
  setTimeout(() => { loading.value = false }, 1200)
}
</script>

<template>
  <TxButton variant="primary" :loading="loading" @click="handleClick">
    {{ loading ? 'Loading' : 'Click to load' }}
  </TxButton>
  <TxButton variant="secondary" :loading="loading" @click="handleClick">
    {{ loading ? 'Loading' : 'Click to load' }}
  </TxButton>
  <TxButton circle icon="i-carbon-edit" :loading="loading" @click="handleClick" />
</template>

Sizes

Buttons provide three sizes beyond the default, affecting density and tactile feel.

Demo will load when visible.
<template>
  <TxButton size="lg">Large</TxButton>
  <TxButton size="md">Medium</TxButton>
  <TxButton size="sm">Small</TxButton>
</template>

Block

Block buttons fill the container width for full-width primary actions.

Demo will load when visible.
<template>
  <TxButton block variant="primary">Block Button</TxButton>
</template>

Shapes

Adjust shapes with plain / round / circle / dashed.

Demo will load when visible.
<template>
  <TxButton dashed>Dashed</TxButton>
  <TxButton plain variant="primary">Plain</TxButton>
  <TxButton round variant="primary">Round</TxButton>
  <TxButton circle icon="i-carbon-edit" />
</template>

Haptics

Haptic feedback for mobile interactions, with multiple intensity options.

Demo will load when visible.
<template>
  <TxButton variant="primary" vibrate-type="light">Light</TxButton>
  <TxButton variant="primary" vibrate-type="medium">Medium</TxButton>
  <TxButton variant="primary" vibrate-type="heavy">Heavy</TxButton>
  <TxButton variant="danger" vibrate-type="error">Error</TxButton>
  <TxButton variant="secondary" :vibrate="false">No Haptics</TxButton>
</template>

API Specifications

Button Attributes

ParameterTypeDefaultDescription
variant
primary
secondary
ghost
danger
success
warning
info
flat
bare
-

Visual variant

type
primary
success
warning
danger
info
text
-

Semantic tone alias. Used only when `variant` is not set; `text` maps to `ghost`.

size
sm
md
lg
large
small
mini
'md'

Button size

block
boolean
false

Block-level (full width)

plain
boolean
false

Plain style

dashed
boolean
false

Dashed style

round
boolean
false

Rounded style

circle
boolean
false

Circular button

loading
boolean
false

Loading state

disabled
boolean
false

Disabled state

icon
string
-

Icon class name

autofocus
boolean
false

Autofocus

native-type
button
submit
reset
'button'

Native type attribute

vibrate
boolean
true

Enable haptics

vibrate-type
light
medium
heavy
bit
success
warning
error
'light'

Haptic type

Parameter
variant
Type
primary
secondary
ghost
danger
success
warning
info
flat
bare
Default
-
Description

Visual variant

Parameter
type
Type
primary
success
warning
danger
info
text
Default
-
Description

Semantic tone alias. Used only when `variant` is not set; `text` maps to `ghost`.

Parameter
size
Type
sm
md
lg
large
small
mini
Default
'md'
Description

Button size

Parameter
block
Type
boolean
Default
false
Description

Block-level (full width)

Parameter
plain
Type
boolean
Default
false
Description

Plain style

Parameter
dashed
Type
boolean
Default
false
Description

Dashed style

Parameter
round
Type
boolean
Default
false
Description

Rounded style

Parameter
circle
Type
boolean
Default
false
Description

Circular button

Parameter
loading
Type
boolean
Default
false
Description

Loading state

Parameter
disabled
Type
boolean
Default
false
Description

Disabled state

Parameter
icon
Type
string
Default
-
Description

Icon class name

Parameter
autofocus
Type
boolean
Default
false
Description

Autofocus

Parameter
native-type
Type
button
submit
reset
Default
'button'
Description

Native type attribute

Parameter
vibrate
Type
boolean
Default
true
Description

Enable haptics

Parameter
vibrate-type
Type
light
medium
heavy
bit
success
warning
error
Default
'light'
Description

Haptic type

Button Events

ParameterTypeDefaultDescription
click
(event: MouseEvent) => void
-

Triggered on click

Parameter
click
Type
(event: MouseEvent) => void
Default
-
Description

Triggered on click

Types

EXAMPLE.TS
import type { TxButtonProps } from '@talex-touch/tuffex'

export interface ButtonProps extends TxButtonProps {}

Composition Notes

Split Button

A combined button for "primary action + more actions" (e.g., RUN + …).

Demo will load when visible.
<template>
  <TxSplitButton
    variant="primary"
    size="sm"
    icon="i-ri-play-fill"
    :loading="splitLoading"
    @click="handleRun"
  >
    RUN
    <template #menu="{ close }">
      <div style="display: flex; flex-direction: column; gap: 6px;">
        <TxButton size="sm" plain block icon="i-ri-settings-3-line" @click="close()">
          Settings
        </TxButton>
        <TxButton size="sm" plain block icon="i-ri-folder-open-line" @click="close()">
          Open Folder
        </TxButton>
      </div>
    </template>
  </TxSplitButton>
</template>

Primary + Ghost

Pair primary with ghost for clear hierarchy.

Demo will load when visible.
<template>
  <TxButton icon="i-ri-add-line">Create Project</TxButton>
  <TxButton variant="ghost">Learn More</TxButton>
</template>

Design Principles

  • Keep a single primary button to avoid hierarchy conflicts.
  • Keep variant consistent within similar actions.
  • Async actions must use loading to avoid duplicate triggers.
  • Prefer vibrate on mobile to enhance tactile feedback.

Design Notes

  • Emphasize press feedback with smooth rebound.
  • Translucent surfaces need proper background contrast.
  • Keep icon/text spacing consistent to avoid visual drift.

Source

View source
packages/tuffex/packages/components/src/button/index.ts