Skip to content
This repository was archived by the owner on Sep 20, 2024. It is now read-only.

Commit da1c7f6

Browse files
Merge pull request #20 from chakra-ui/feat/icon-button
feat(icon-button): adds icon button component and improves a11y test
2 parents 12a93fa + fd1d64e commit da1c7f6

File tree

17 files changed

+451
-83
lines changed

17 files changed

+451
-83
lines changed

docs/components/button.md

Lines changed: 200 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,202 @@
11
# Button
22

3-
> TODO
3+
The Button component is used to trigger an action or event, such as submitting a form, opening a dialog, canceling an action, or performing a delete operation.
4+
5+
## Import
6+
7+
```bash
8+
import { CButton, CButtonGroup } from "@chakra-ui/vue-next"
9+
```
10+
11+
- `CButton`: The button component with support for custom icons, spinners, etc.
12+
- `CButtonGroup`: Used to group buttons whose actions are related, with an option to flush them together.
13+
14+
## Usage
15+
```vue
16+
<c-button color-scheme="blue">Button</c-button>
17+
```
18+
19+
### Button sizes
20+
Use the `size` prop to change the size of the button. You can set the value to `xs`, `sm`, `md`, or `lg`.
21+
22+
```vue{1,4,7,10}
23+
<c-button color-scheme="teal" size="xs">
24+
Button
25+
</c-button>
26+
<c-button color-scheme="teal" size="sm">
27+
Button
28+
</c-button>
29+
<c-button color-scheme="teal" size="md">
30+
Button
31+
</c-button>
32+
<c-button color-scheme="teal" size="lg">
33+
Button
34+
</c-button>
35+
```
36+
37+
### Button variants
38+
39+
Use the `variant` prop to change the visual style of the Button. You can set the
40+
value to `solid`, `ghost`, `outline`, or `link`.
41+
42+
```vue{1,4,7,10}
43+
<c-button color-scheme="teal" variant="solid">
44+
Button
45+
</c-button>
46+
<c-button color-scheme="teal" variant="outline">
47+
Button
48+
</c-button>
49+
<c-button color-scheme="teal" variant="ghost">
50+
Button
51+
</c-button>
52+
<c-button color-scheme="teal" variant="link">
53+
Button
54+
</c-button>
55+
```
56+
57+
### Button with icon
58+
59+
You can add left and right icons to the Button component using the `left-icon`
60+
and `right-icon` props respectively.
61+
62+
::: warning TODO
63+
TODO: Link to icon documentation
64+
65+
:::
66+
67+
### Button loading state
68+
69+
Pass the `is-loading` prop to show its loading state. By default, the button will
70+
show a spinner and leave the button's width unchanged.
71+
72+
You can also pass the `loading-text` prop to show a spinner and the loading text.
73+
```vue
74+
<c-button is-loading color-scheme="teal" variant="solid">
75+
Email
76+
</c-button>
77+
<c-button is-loading loading-text="Submitting" color-scheme="teal" variant="outline">
78+
Submit
79+
</c-button>
80+
```
81+
82+
### Grouping Buttons
83+
84+
You can use the `CStack` or `CButtonGroup` component to group buttons. When you
85+
use the `CButtonGroup` component, it allows you to:
86+
87+
- Set the `size` and `variant` of all buttons within it.
88+
- Add `spacing` between the buttons.
89+
- Flush the buttons together by removing the border radius of the its children
90+
as needed.
91+
92+
```vue
93+
<c-button-group size="sm" is-attached variant="outline">
94+
<c-button mr="-px">Save</c-button>
95+
<c-icon-button aria-label="Add to friends" icon="plus" />
96+
</c-button-group>
97+
```
98+
99+
## Accessibility
100+
101+
- `CButton` has `role` of `button`.
102+
- When `CButton` has focus, <kbd>Space</kbd> or <kbd>Enter</kbd> activates it.
103+
104+
## Composition
105+
106+
Theming props passed into the `CButton` component (e.g. `variant`, `colorScheme`, etc.) are converted to style props. This means you can override any style of the `CButton` via type style props.
107+
108+
## Props
109+
110+
### Button Props
111+
112+
`CButton` composes the `CBox` component, so you can pass all its props.
113+
These are props specific to the `CButton` component:
114+
115+
## Composition
116+
117+
All props you pass (`variant`, `colorScheme`, etc.) are converted to style
118+
props. This means you can override any style of the Button via props.
119+
120+
```vue
121+
<!--
122+
The size prop affects the height of the button.
123+
It can still be overriden by passing a custom height
124+
-->
125+
<c-button
126+
size="md"
127+
height="48px"
128+
width="200px"
129+
border="2px"
130+
border-color="green.500"
131+
>
132+
Button
133+
</c-button>
134+
```
135+
136+
---
137+
138+
## Custom Button
139+
140+
In the event that you need to make your own custom button, you can leverage the
141+
`CBox` component. It provides the `hover`, `focus`, `active` and `disabled` style
142+
props to style the button.
143+
144+
```vue
145+
<!-- Button from facebook.com -->
146+
<c-box
147+
as="button"
148+
height="24px"
149+
line-height="1.2"
150+
transition="all 0.2s cubic-bezier(.08,.52,.52,1)"
151+
border="1px"
152+
px="8px"
153+
border-radius="2px"
154+
font-size="14px"
155+
font-weight="semibold"
156+
bg="#f5f6f7"
157+
border-color="#ccd0d5"
158+
color="#4b4f56"
159+
:_hover="{ bg: '#ebedf0' }"
160+
:_active="{
161+
bg: '#dddfe2',
162+
transform: 'scale(0.98)',
163+
borderColor: '#bec3c9',
164+
}"
165+
:_focus="{
166+
boxShadow:
167+
'0 0 1px 2px rgba(88, 144, 255, .75), 0 1px 1px rgba(0, 0, 0, .15)",
168+
}"
169+
>
170+
Join Group
171+
</c-box>
172+
```
173+
## Props
174+
### Button Props
175+
| Name | Type | Description | Default |
176+
| :---: | :---: | :---: | :---: |
177+
|`colorScheme`|`"blue" | "cyan" | "gray" | "green" | "orange" | "pink" | "purple" | "red" | "teal" | "yellow" | "whiteAlpha" | "blackAlpha" | "linkedin" | "facebook" | "messenger" | "whatsapp" | "twitter" | "telegram"`| Theme color scheme |`"gray"`|
178+
|`iconSpacing`|`SystemProps["marginRight"]`| The space between the icon and the label | - |
179+
|`iconSpacing` | `SystemProps["marginRight"]` | The space between the button icon and label. | - |
180+
|`isActive` | `boolean` | If `true`, the button will be styled in its active state. | - |
181+
|`isDisabled` | `boolean` | If `true`, the button will be disabled. | - |
182+
|`isFullWidth` | `boolean` | If `true`, the button will take up the full width of its container.| - |
183+
|`isLoading` | `boolean` | If `true`, the button will show a spinner.| | - |
184+
|`leftIcon` | `string` | If added, the button will show an icon before the button's label. | - |
185+
|`loadingText` | `string` | The label to show in the button when `isLoading` is true If no text is passed, it only shows the spinner | - |
186+
|`rightIcon` | `string` | If added, the button will show an icon after the button's label. | - |
187+
|`size` | `"sm" | "md" | "lg" | "xs"` | |`"md"` |
188+
|`variant` | `"link" | "outline" | "solid" | "ghost" | "unstyled"` | | `"solid"` |
189+
190+
### Button Group Props
191+
192+
`CButtonGroup` composes the `CBox` component, so you can pass all its props.
193+
These are props specific to the `CButtonGroup` component:
194+
195+
| Name | Type | Description | Default |
196+
| :---: | :---: | :---: | :---: |
197+
| `colorScheme` | `"blue" | "cyan" | "gray" | "green" | "orange" | "pink" | "purple" | "red" | "teal" | "yellow" | "whiteAlpha" | "blackAlpha" | |"linkedin" | "facebook" | "messenger" | "whatsapp" | "twitter" | "telegram"` | Color Schemes for ButtonGroup are not implemented in the default theme. You can extend the theme to implement them. |-|
198+
| `isAttached` | `boolean` | If `true`, the borderRadius of button that are direct children will be altered to look flushed together |-|
199+
| `isDisabled` | `boolean` | If `true`, all wrapped button will be disabled | -|
200+
| `size` | `"sm" | "md" | "lg" | "xs"`| |-|
201+
| `spacing` | `SystemProps["marginRight"]` The spacing between the buttons | `'0.5rem'`|
202+
| `variant` | `"link" | "outline" | "solid" | "ghost" | "unstyled"` | |

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,14 @@
1717
"playground:build": "yarn install && yarn build && yarn bootstrap && NODE_ENV=production vite build playground --config ./vite.config.ts",
1818
"test": "cross-env NODE_ENV=test jest --config jest.config.js",
1919
"lint": "eslint '*/**/*.{js,ts,tsx}' --quiet --fix",
20-
2120
"docs:dev": "vitepress dev docs",
2221
"docs:build": "vitepress build docs",
2322
"docs:serve": "vitepress serve docs",
24-
2523
"core": "yarn workspace @chakra-ui/vue-next",
2624
"nuxt": "yarn workspace @chakra-ui/nuxt-next",
2725
"system": "yarn workspace @chakra-ui/vue-system",
2826
"utils": "yarn workspace @chakra-ui/vue-utils",
2927
"theme": "yarn workspace @chakra-ui/vue-theme",
30-
3128
"c-alert": "yarn workspace @chakra-ui/c-alert",
3229
"c-theme-provider": "yarn workspace @chakra-ui/c-theme-provider",
3330
"c-box": "yarn workspace @chakra-ui/c-box",
@@ -49,6 +46,7 @@
4946
"@testing-library/user-event": "^12.6.2",
5047
"@testing-library/vue": "^6.3.4",
5148
"@types/jest": "^26.0.20",
49+
"@types/jest-axe": "^3.5.1",
5250
"@types/recursive-readdir": "^2.2.0",
5351
"@typescript-eslint/eslint-plugin": "^2.34.0",
5452
"@typescript-eslint/parser": "4.0.1",
@@ -58,6 +56,7 @@
5856
"@vue/eslint-config-typescript": "^5.1.0",
5957
"@vuedx/typecheck": "^0.4.1",
6058
"@vuedx/typescript-plugin-vue": "^0.4.1",
59+
"axe-core": "^4.1.2",
6160
"babel-jest": "^26.6.3",
6261
"chokidar": "^3.5.1",
6362
"concurrently": "^5.3.0",
@@ -78,6 +77,7 @@
7877
"husky": "^4.3.8",
7978
"hygen": "^6.0.4",
8079
"jest": "^26.6.3",
80+
"jest-axe": "^4.1.0",
8181
"jest-transform-stub": "^2.0.0",
8282
"lerna": "^3.22.1",
8383
"lint-staged": "^10.5.3",
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<template>
2+
<chakra.p mt="3" font-weight="bold">IconButton</chakra.p>
3+
<c-icon-button
4+
icon="star"
5+
aria-label="Favourite album"
6+
mr="3"
7+
size="xs"
8+
color-scheme="teal"
9+
/>
10+
<c-icon-button
11+
icon="star"
12+
aria-label="Favourite album"
13+
mr="3"
14+
size="sm"
15+
color-scheme="teal"
16+
/>
17+
<c-icon-button
18+
icon="star"
19+
aria-label="Favourite album"
20+
mr="3"
21+
size="md"
22+
color-scheme="teal"
23+
/>
24+
<c-icon-button
25+
icon="star"
26+
aria-label="Favourite album"
27+
mr="3"
28+
size="lg"
29+
color-scheme="teal"
30+
/>
31+
</template>
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
<template>
2-
<c-button-group variant="outline" is-attached>
3-
<c-button color-scheme="blue">Save</c-button>
4-
<c-button>Cancel</c-button>
5-
</c-button-group>
2+
<chakra.div>
3+
<c-button-group
4+
shadow="xl"
5+
variant="outline"
6+
:color-scheme="'purple'"
7+
is-attached
8+
>
9+
<c-button variant="solid">Save</c-button>
10+
<c-button>Cancel</c-button>
11+
</c-button-group>
12+
</chakra.div>
613
</template>

packages/c-button/src/button-group.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ const props = {
4444
styleConfig: String as PropType<ComponentThemeConfig>,
4545
}
4646

47-
interface ButtonGroupContext extends ThemingProps {
47+
type ButtonGroupContext = () => ThemingProps & {
4848
isDisabled?: boolean
4949
}
5050

@@ -59,12 +59,12 @@ const CButtonGroup = defineComponent({
5959
name: 'CButtonGroup',
6060
props,
6161
setup(props, { attrs, slots }) {
62-
ButtonGroupProvider({
62+
ButtonGroupProvider(() => ({
6363
size: props.size,
6464
colorScheme: props.colorScheme,
6565
variant: props.variant,
6666
isDisabled: props.isDisabled,
67-
})
67+
}))
6868

6969
const styles = computed(() => {
7070
let groupStyles: SystemStyleObject = {
@@ -92,7 +92,7 @@ const CButtonGroup = defineComponent({
9292
h(
9393
chakra('div', { label: 'button__group' }),
9494
{
95-
__css: styles.value,
95+
__css: { ...styles.value },
9696
role: 'group',
9797
...attrs,
9898
},

0 commit comments

Comments
 (0)