Skip to content

Commit 8dbdef8

Browse files
committed
Bump version to 0.12.75
1 parent 0c71b24 commit 8dbdef8

13 files changed

Lines changed: 254 additions & 27 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"publish:icons": "pnpm --filter @aster-ui/icons publish --access public",
1313
"publish:icons-prefixed": "pnpm --filter @aster-ui/icons-prefixed publish --access public",
1414
"publish:prefixed": "pnpm --filter @aster-ui/prefixed publish --access public",
15-
"sync-prefixed": "rm -rf packages/prefixed/src && cp -r packages/asterui/src packages/prefixed/ && npx tsx scripts/daisyui-prefix.ts --prefix d- --dir packages/prefixed/src && jq --arg v $(jq -r .version packages/asterui/package.json) '.version = $v' packages/prefixed/package.json > tmp.json && mv tmp.json packages/prefixed/package.json",
15+
"sync-prefixed": "rm -rf packages/prefixed/src && cp -r packages/asterui/src packages/prefixed/ && npx tsx scripts/daisyui-prefix.ts --prefix d- --dir packages/prefixed/src && jq --arg v $(jq -r .version packages/asterui/package.json) '.version = $v' packages/prefixed/package.json > tmp.json && mv tmp.json packages/prefixed/package.json && pnpm --filter @aster-ui/prefixed build",
1616
"sync-icons-prefixed": "rm -rf packages/icons-prefixed/src packages/icons-prefixed/scripts && cp -r packages/icons/src packages/icons/scripts packages/icons-prefixed/ && sed -i \"s/'asterui'/'@aster-ui\\/prefixed'/g\" packages/icons-prefixed/src/context.tsx packages/icons-prefixed/scripts/generate.ts && jq --arg v $(jq -r .version packages/icons/package.json) '.version = $v' packages/icons-prefixed/package.json > tmp.json && mv tmp.json packages/icons-prefixed/package.json"
1717
}
1818
}

packages/asterui/CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@ description: All notable changes to AsterUI
77

88
All notable changes to AsterUI are documented here.
99

10+
## v0.12.75 (2025-12-27)
11+
12+
### Components
13+
14+
- **Button**: Added `type` prop for syntactic sugar API alignment (`'primary' | 'default' | 'dashed' | 'link' | 'text'`)
15+
- **Button**: Added `block` boolean prop as alternative to `shape="block"`
16+
- **Button**: Added `ghost` boolean prop as alternative to `variant="ghost"`
17+
- **Button**: Added `variant="text"` for text-only buttons
18+
- **Button**: Added `aria-label` prop for icon-only button accessibility
19+
- **Button**: Added data-state attributes for testing (`data-state-loading`, `data-state-disabled`, `data-state-active`, `data-state-pressed`)
20+
21+
### Documentation
22+
23+
- Updated Button documentation across all 5 languages (English, French, Chinese, Spanish, Portuguese)
24+
- Fixed XMarkIcon size mismatch in AI-readable documentation
25+
- Added data attributes section to Button API documentation
26+
1027
## v0.12.74 (2025-12-26)
1128

1229
### Components

packages/asterui/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "asterui",
3-
"version": "0.12.74",
3+
"version": "0.12.75",
44
"description": "React UI component library with DaisyUI",
55
"homepage": "https://asterui.com",
66
"repository": {

packages/asterui/src/components/Button.tsx

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ const dLoading = 'loading'
3131
const dLoadingSpinner = 'loading-spinner'
3232

3333
type BaseButtonProps = {
34+
/** Syntactic sugar for setting variant and color together. Will be overridden by explicit variant & color props. */
35+
type?: 'primary' | 'default' | 'dashed' | 'link' | 'text'
3436
/** Button color */
3537
color?: 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error' | 'neutral'
3638
/** Button style variant */
37-
variant?: 'solid' | 'outline' | 'dash' | 'soft' | 'ghost' | 'link'
39+
variant?: 'solid' | 'outline' | 'dash' | 'soft' | 'ghost' | 'link' | 'text'
3840
/** Button size */
3941
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
4042
/** Active/pressed visual state */
@@ -43,6 +45,10 @@ type BaseButtonProps = {
4345
loading?: boolean
4446
/** Button shape */
4547
shape?: 'square' | 'circle' | 'wide' | 'block' | 'round'
48+
/** Make the button full width */
49+
block?: boolean
50+
/** Make background transparent and invert text and border colors */
51+
ghost?: boolean
4652
/** Disable click animation */
4753
noAnimation?: boolean
4854
/** Icon element to display */
@@ -55,6 +61,8 @@ type BaseButtonProps = {
5561
danger?: boolean
5662
/** Toggle button pressed state (sets aria-pressed) */
5763
pressed?: boolean
64+
/** Accessible label for icon-only buttons */
65+
'aria-label'?: string
5866
/** Test ID for testing */
5967
'data-testid'?: string
6068
}
@@ -79,30 +87,62 @@ export const Button = forwardRef<HTMLButtonElement | HTMLAnchorElement, ButtonPr
7987
(
8088
{
8189
children,
90+
type,
8291
color,
8392
variant,
8493
size,
8594
active = false,
8695
loading = false,
8796
shape,
97+
block = false,
98+
ghost = false,
8899
noAnimation = false,
89100
icon,
90101
iconPlacement,
91102
iconPosition,
92103
danger = false,
93104
pressed,
94105
className = '',
106+
'aria-label': ariaLabel,
95107
'data-testid': testId,
96108
...props
97109
},
98110
ref
99111
) => {
100112
const { componentSize } = useConfig()
101113
const effectiveSize = size ?? componentSize ?? 'md'
114+
115+
// Apply type prop (syntactic sugar) - explicit variant/color takes precedence
116+
let derivedVariant = variant
117+
let derivedColor = color
118+
if (type && !variant && !color) {
119+
switch (type) {
120+
case 'primary':
121+
derivedVariant = 'solid'
122+
derivedColor = 'primary'
123+
break
124+
case 'default':
125+
derivedVariant = 'outline'
126+
break
127+
case 'dashed':
128+
derivedVariant = 'dash'
129+
break
130+
case 'link':
131+
derivedVariant = 'link'
132+
break
133+
case 'text':
134+
derivedVariant = 'text'
135+
break
136+
}
137+
}
138+
102139
// danger prop is a shorthand for color="error"
103-
const effectiveColor = danger ? 'error' : color
140+
const effectiveColor = danger ? 'error' : derivedColor
141+
const effectiveVariant = ghost && !derivedVariant ? 'ghost' : derivedVariant
104142
// iconPlacement takes precedence over deprecated iconPosition
105143
const effectiveIconPlacement = iconPlacement ?? iconPosition ?? 'start'
144+
// block prop is a shorthand for shape="block"
145+
const effectiveShape = block && !shape ? 'block' : shape
106146

107147
const colorClasses = {
108148
primary: dBtnPrimary,
@@ -122,6 +162,7 @@ export const Button = forwardRef<HTMLButtonElement | HTMLAnchorElement, ButtonPr
122162
soft: dBtnSoft,
123163
ghost: dBtnGhost,
124164
link: dBtnLink,
165+
text: dBtnGhost, // text variant uses ghost styling
125166
}
126167

127168
const sizeClasses = {
@@ -143,10 +184,10 @@ export const Button = forwardRef<HTMLButtonElement | HTMLAnchorElement, ButtonPr
143184
const classes = [
144185
dBtn,
145186
effectiveColor && colorClasses[effectiveColor],
146-
variant && variantClasses[variant],
187+
effectiveVariant && variantClasses[effectiveVariant],
147188
sizeClasses[effectiveSize],
148189
active && dBtnActive,
149-
shape && shapeClasses[shape],
190+
effectiveShape && shapeClasses[effectiveShape],
150191
noAnimation && 'no-animation',
151192
className,
152193
]
@@ -215,10 +256,15 @@ export const Button = forwardRef<HTMLButtonElement | HTMLAnchorElement, ButtonPr
215256
aria-disabled={isDisabled || undefined}
216257
aria-busy={loading || undefined}
217258
aria-pressed={pressed}
259+
aria-label={ariaLabel}
218260
tabIndex={isDisabled ? -1 : 0}
219261
onKeyDown={handleKeyDown}
220262
onClick={handleClick}
221263
data-testid={testId}
264+
data-state-loading={loading || undefined}
265+
data-state-disabled={isDisabled || undefined}
266+
data-state-active={active || undefined}
267+
data-state-pressed={pressed}
222268
{...anchorProps}
223269
>
224270
{content}
@@ -228,15 +274,21 @@ export const Button = forwardRef<HTMLButtonElement | HTMLAnchorElement, ButtonPr
228274

229275
const { htmlType, ...buttonProps } = props as Omit<ButtonAsButton, keyof BaseButtonProps>
230276
const buttonType: 'button' | 'submit' | 'reset' = htmlType ?? 'button'
277+
const isDisabled = loading || buttonProps.disabled
231278
return (
232279
<button
233280
ref={ref as React.Ref<HTMLButtonElement>}
234281
type={buttonType}
235282
className={classes}
236283
aria-busy={loading || undefined}
237284
aria-pressed={pressed}
238-
disabled={loading || buttonProps.disabled}
285+
aria-label={ariaLabel}
286+
disabled={isDisabled}
239287
data-testid={testId}
288+
data-state-loading={loading || undefined}
289+
data-state-disabled={isDisabled || undefined}
290+
data-state-active={active || undefined}
291+
data-state-pressed={pressed}
240292
{...buttonProps}
241293
>
242294
{content}

packages/docs/public/docs/button.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,10 @@ import { XMarkIcon } from '@aster-ui/icons'
180180
const App: React.FC = () => (
181181
<Space direction="horizontal" wrap size="sm" align="center">
182182
<Button color="primary" shape="square">
183-
<XMarkIcon size="lg" />
183+
<XMarkIcon />
184184
</Button>
185185
<Button color="primary" shape="circle">
186-
<XMarkIcon size="lg" />
186+
<XMarkIcon />
187187
</Button>
188188
</Space>
189189
)
@@ -463,20 +463,34 @@ export default App
463463

464464
| Property | Description | Type | Default |
465465
|----------|-------------|------|---------|
466+
| `type` | Syntactic sugar for setting variant and color together. Overridden by explicit variant & color props | `'primary' \| 'default' \| 'dashed' \| 'link' \| 'text'` | `-` |
466467
| `color` | Button color | `'primary' \| 'secondary' \| 'accent' \| 'info' \| 'success' \| 'warning' \| 'error' \| 'neutral'` | `-` |
467-
| `variant` | Button style variant | `'solid' \| 'outline' \| 'dash' \| 'soft' \| 'ghost' \| 'link'` | `-` |
468+
| `variant` | Button style variant | `'solid' \| 'outline' \| 'dash' \| 'soft' \| 'ghost' \| 'link' \| 'text'` | `-` |
468469
| `size` | Button size | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` |
469470
| `active` | Active/pressed visual state | `boolean` | `false` |
470471
| `loading` | Show loading spinner and disable button | `boolean` | `false` |
471472
| `shape` | Button shape | `'square' \| 'circle' \| 'wide' \| 'block' \| 'round'` | `-` |
473+
| `block` | Make the button full width | `boolean` | `false` |
474+
| `ghost` | Make background transparent and invert text and border colors | `boolean` | `false` |
472475
| `icon` | Icon element to display | `ReactNode` | `-` |
473-
| `iconPosition` | Position of the icon | `'start' \| 'end'` | `'start'` |
476+
| `iconPlacement` | Position of the icon | `'start' \| 'end'` | `'start'` |
474477
| `danger` | Applies error/danger styling (shorthand for color="error") | `boolean` | `false` |
475478
| `pressed` | Toggle button pressed state (sets aria-pressed) | `boolean` | `-` |
476479
| `noAnimation` | Disable click animation | `boolean` | `false` |
477480
| `disabled` | Disabled state | `boolean` | `false` |
481+
| `aria-label` | Accessible label for icon-only buttons | `string` | `-` |
478482
| `className` | Additional CSS classes | `string` | `-` |
479483
| `children` | Button content | `ReactNode` | `-` |
480484
| `href` | URL to navigate to (renders as anchor element) | `string` | `-` |
481485
| `target` | Where to open the linked URL (when href is set) | `string` | `-` |
482486
| `htmlType` | HTML button type (only when href is not set) | `'button' \| 'submit' \| 'reset'` | `'button'` |
487+
| `data-testid` | Test ID for testing | `string` | `-` |
488+
489+
### Data Attributes
490+
491+
The Button component exposes the following data attributes for testing and state inspection:
492+
493+
- `data-state-loading`: Present when button is in loading state
494+
- `data-state-disabled`: Present when button is disabled
495+
- `data-state-active`: Present when button is in active state
496+
- `data-state-pressed`: Present when button is in pressed state (toggle buttons)

packages/docs/src/content/docs/changelog.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@ description: All notable changes to AsterUI
77

88
All notable changes to AsterUI are documented here.
99

10+
## v0.12.75 (2025-12-27)
11+
12+
### Components
13+
14+
- **Button**: Added `type` prop for syntactic sugar API alignment (`'primary' | 'default' | 'dashed' | 'link' | 'text'`)
15+
- **Button**: Added `block` boolean prop as alternative to `shape="block"`
16+
- **Button**: Added `ghost` boolean prop as alternative to `variant="ghost"`
17+
- **Button**: Added `variant="text"` for text-only buttons
18+
- **Button**: Added `aria-label` prop for icon-only button accessibility
19+
- **Button**: Added data-state attributes for testing (`data-state-loading`, `data-state-disabled`, `data-state-active`, `data-state-pressed`)
20+
21+
### Documentation
22+
23+
- Updated Button documentation across all 5 languages (English, French, Chinese, Spanish, Portuguese)
24+
- Fixed XMarkIcon size mismatch in AI-readable documentation
25+
- Added data attributes section to Button API documentation
26+
1027
## v0.12.74 (2025-12-26)
1128

1229
### Components

packages/docs/src/content/docs/components/button.mdx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,29 +134,44 @@ import { Button } from 'asterui'
134134

135135
| Property | Description | Type | Default |
136136
|----------|-------------|------|---------|
137+
| `type` | Syntactic sugar for setting variant and color together. Overridden by explicit variant & color props | `'primary' \| 'default' \| 'dashed' \| 'link' \| 'text'` | - |
137138
| `color` | Button color | `'primary' \| 'secondary' \| 'accent' \| 'info' \| 'success' \| 'warning' \| 'error' \| 'neutral'` | - |
138-
| `variant` | Button style variant | `'solid' \| 'outline' \| 'dash' \| 'soft' \| 'ghost' \| 'link'` | - |
139+
| `variant` | Button style variant | `'solid' \| 'outline' \| 'dash' \| 'soft' \| 'ghost' \| 'link' \| 'text'` | - |
139140
| `size` | Button size | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` |
140141
| `active` | Active/pressed visual state | `boolean` | `false` |
141142
| `loading` | Show loading spinner and disable button | `boolean` | `false` |
142143
| `shape` | Button shape | `'square' \| 'circle' \| 'wide' \| 'block' \| 'round'` | - |
144+
| `block` | Make the button full width | `boolean` | `false` |
145+
| `ghost` | Make background transparent and invert text and border colors | `boolean` | `false` |
143146
| `icon` | Icon element to display | `ReactNode` | - |
144-
| `iconPosition` | Position of the icon | `'start' \| 'end'` | `'start'` |
147+
| `iconPlacement` | Position of the icon | `'start' \| 'end'` | `'start'` |
145148
| `danger` | Applies error/danger styling (shorthand for color="error") | `boolean` | `false` |
146149
| `pressed` | Toggle button pressed state (sets aria-pressed) | `boolean` | - |
147150
| `noAnimation` | Disable click animation | `boolean` | `false` |
148151
| `disabled` | Disabled state | `boolean` | `false` |
152+
| `aria-label` | Accessible label for icon-only buttons | `string` | - |
149153
| `href` | URL to navigate to (renders as anchor element) | `string` | - |
150154
| `target` | Where to open the linked URL (when href is set) | `string` | - |
151155
| `htmlType` | HTML button type (only when href is not set) | `'button' \| 'submit' \| 'reset'` | `'button'` |
152156
| `className` | Additional CSS classes | `string` | - |
153157
| `children` | Button content | `ReactNode` | - |
158+
| `data-testid` | Test ID for testing | `string` | - |
159+
160+
### Data Attributes
161+
162+
The Button component exposes the following data attributes for testing and state inspection:
163+
164+
- `data-state-loading`: Present when button is in loading state
165+
- `data-state-disabled`: Present when button is disabled
166+
- `data-state-active`: Present when button is in active state
167+
- `data-state-pressed`: Present when button is in pressed state (toggle buttons)
154168

155169
## Accessibility
156170

157171
- Uses native `<button>` element for proper keyboard support
158172
- Renders as `<a>` element when `href` is provided for proper link semantics
159173
- Loading state sets `aria-busy="true"` and disables the button
160174
- Toggle buttons use `aria-pressed` for screen reader support
175+
- Icon-only buttons should use `aria-label` for screen reader support
161176
- Disabled state is properly communicated to assistive technologies
162177
- Focus states are visible for keyboard navigation

packages/docs/src/content/docs/es/components/button.mdx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,29 +134,44 @@ import { Button } from 'asterui'
134134

135135
| Propiedad | Descripción | Tipo | Predeterminado |
136136
|----------|-------------|------|---------|
137+
| `type` | Azúcar sintáctico para establecer variant y color juntos. Anulado por props variant & color explícitas | `'primary' \| 'default' \| 'dashed' \| 'link' \| 'text'` | - |
137138
| `color` | Color del botón | `'primary' \| 'secondary' \| 'accent' \| 'info' \| 'success' \| 'warning' \| 'error' \| 'neutral'` | - |
138-
| `variant` | Variante de estilo del botón | `'solid' \| 'outline' \| 'dash' \| 'soft' \| 'ghost' \| 'link'` | - |
139+
| `variant` | Variante de estilo del botón | `'solid' \| 'outline' \| 'dash' \| 'soft' \| 'ghost' \| 'link' \| 'text'` | - |
139140
| `size` | Tamaño del botón | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` |
140141
| `active` | Estado visual activo/presionado | `boolean` | `false` |
141142
| `loading` | Mostrar spinner de carga y deshabilitar botón | `boolean` | `false` |
142143
| `shape` | Forma del botón | `'square' \| 'circle' \| 'wide' \| 'block' \| 'round'` | - |
144+
| `block` | Hacer el botón de ancho completo | `boolean` | `false` |
145+
| `ghost` | Hacer el fondo transparente e invertir los colores de texto y borde | `boolean` | `false` |
143146
| `icon` | Elemento de icono a mostrar | `ReactNode` | - |
144-
| `iconPosition` | Posición del icono | `'start' \| 'end'` | `'start'` |
147+
| `iconPlacement` | Posición del icono | `'start' \| 'end'` | `'start'` |
145148
| `danger` | Aplica estilo de error/peligro (atajo para color="error") | `boolean` | `false` |
146149
| `pressed` | Estado presionado del botón de alternancia (establece aria-pressed) | `boolean` | - |
147150
| `noAnimation` | Deshabilitar animación de clic | `boolean` | `false` |
148151
| `disabled` | Estado deshabilitado | `boolean` | `false` |
152+
| `aria-label` | Etiqueta accesible para botones solo con icono | `string` | - |
149153
| `href` | URL a la que navegar (renderiza como elemento anchor) | `string` | - |
150154
| `target` | Dónde abrir la URL enlazada (cuando se establece href) | `string` | - |
151155
| `htmlType` | Tipo de botón HTML (solo cuando href no está establecido) | `'button' \| 'submit' \| 'reset'` | `'button'` |
152156
| `className` | Clases CSS adicionales | `string` | - |
153157
| `children` | Contenido del botón | `ReactNode` | - |
158+
| `data-testid` | ID de prueba para testing | `string` | - |
159+
160+
### Atributos de datos
161+
162+
El componente Button expone los siguientes atributos de datos para testing e inspección de estado:
163+
164+
- `data-state-loading`: Presente cuando el botón está en estado de carga
165+
- `data-state-disabled`: Presente cuando el botón está deshabilitado
166+
- `data-state-active`: Presente cuando el botón está en estado activo
167+
- `data-state-pressed`: Presente cuando el botón está en estado presionado (botones de alternancia)
154168

155169
## Accesibilidad
156170

157171
- Usa el elemento nativo `<button>` para soporte adecuado de teclado
158172
- Se renderiza como elemento `<a>` cuando se proporciona `href` para semántica adecuada de enlace
159173
- El estado de carga establece `aria-busy="true"` y deshabilita el botón
160174
- Los botones de alternancia usan `aria-pressed` para soporte de lector de pantalla
175+
- Los botones solo con icono deben usar `aria-label` para soporte de lector de pantalla
161176
- El estado deshabilitado se comunica adecuadamente a tecnologías de asistencia
162177
- Los estados de foco son visibles para navegación por teclado

0 commit comments

Comments
 (0)