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

Commit f92679e

Browse files
committed
feat(button): add button component
1 parent 6a866fa commit f92679e

File tree

9 files changed

+191
-41
lines changed

9 files changed

+191
-41
lines changed

packages/c-button/examples/base-button.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
<template>
22
<div>
3-
<c-button class="my-other-class"> Base button ◻️ </c-button>
3+
<c-button mr="3" color-scheme="blue"> Base button</c-button>
4+
<c-button mr="3" color-scheme="green"> Base button</c-button>
5+
<c-button mr="3" color-scheme="orange"> Base button</c-button>
6+
<c-button mr="3" color-scheme="pink"> Base button</c-button>
47
</div>
58
</template>
69

710
<script lang="ts">
8-
import CButton from '@chakra-ui/c-button/src'
11+
import { CButton } from '@chakra-ui/c-button/src'
912
import { defineComponent } from 'vue'
1013
1114
export default defineComponent({
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<template>
2+
<c-button mr="3" size="xs" color-scheme="teal"> Tiny button </c-button>
3+
<c-button mr="3" size="sm" color-scheme="teal"> Small button </c-button>
4+
<c-button mr="3" size="md" color-scheme="teal"> Medium button </c-button>
5+
<c-button mr="3" size="lg" color-scheme="teal"> Large button </c-button>
6+
</template>
7+
8+
<script lang="ts">
9+
import { CButton } from '@chakra-ui/c-button/src'
10+
import { defineComponent } from 'vue'
11+
12+
export default defineComponent({
13+
components: { CButton },
14+
})
15+
</script>

packages/c-button/package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,14 @@
1616
"build": "concurrently yarn:build:*",
1717
"build:esm": "cross-env BABEL_ENV=esm babel src --root-mode upward --extensions .ts -d dist/esm --source-maps",
1818
"build:cjs": "cross-env BABEL_ENV=cjs babel src --root-mode upward --extensions .ts -d dist/cjs --source-maps",
19-
"build:types": "tsc --emitDeclarationOnly --declaration --declarationDir dist/types"
19+
"build:types": "tsc --emitDeclarationOnly --declaration --declarationDir dist/types",
20+
"watch": "concurrently yarn:watch:*",
21+
"watch:esm": "cross-env BABEL_ENV=esm babel src --root-mode upward --extensions .ts -d dist/esm --source-maps --watch",
22+
"watch:cjs": "cross-env BABEL_ENV=cjs babel src --root-mode upward --extensions .ts -d dist/cjs --source-maps --watch",
23+
"watch:types": "tsc --emitDeclarationOnly --declaration --declarationDir dist/types --watch"
2024
},
2125
"dependencies": {
26+
"@chakra-ui/styled-system": "^1.4.1",
2227
"@chakra-ui/vue-system": "*"
2328
}
2429
}

packages/c-button/src/button.ts

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import { h, defineComponent, PropType, computed } from 'vue'
2+
import {
3+
chakra,
4+
DOMElements,
5+
useStyleConfig,
6+
ThemingProps,
7+
} from '@chakra-ui/vue-system'
8+
import {
9+
SystemCSSProperties,
10+
SystemStyleObject,
11+
} from '@chakra-ui/styled-system'
12+
import { Colors } from '@chakra-ui/vue-theme/dist/types/foundations/colors'
13+
import { ComponentThemeConfig } from '@chakra-ui/vue-theme'
14+
import { dataAttr } from '@chakra-ui/vue-utils'
15+
16+
type ButtonTypes = 'button' | 'reset' | 'submit'
17+
export type ButtonSizes = 'xs' | 'sm' | 'md' | 'lg'
18+
export type ButtonVariants =
19+
| 'subtle'
20+
| 'solid'
21+
| 'outline'
22+
| 'ghost'
23+
| 'link'
24+
| string
25+
26+
const props = {
27+
as: {
28+
type: String as PropType<DOMElements>,
29+
default: 'button',
30+
},
31+
isLoading: Boolean as PropType<boolean>,
32+
isActive: Boolean as PropType<boolean>,
33+
isDisabled: Boolean as PropType<boolean>,
34+
loadingText: String as PropType<string>,
35+
isFullWidth: Boolean as PropType<boolean>,
36+
type: String as PropType<ButtonTypes>,
37+
leftIcon: String as PropType<string>,
38+
rightIcon: String as PropType<string>,
39+
colorScheme: String as PropType<keyof Colors>,
40+
variant: {
41+
type: String as PropType<ButtonVariants>,
42+
default: 'solid',
43+
},
44+
size: {
45+
type: String as PropType<ButtonSizes>,
46+
default: 'md',
47+
},
48+
styleConfig: String as PropType<ComponentThemeConfig>,
49+
50+
/** Not sure if the SystemCSSProperties is the right prop type for this */
51+
iconSpacing: {
52+
type: [String, Number, Array] as PropType<
53+
SystemCSSProperties['marginRight']
54+
>,
55+
default: '0.5rem',
56+
},
57+
}
58+
59+
/** TODO: How to get component props in typescript */
60+
61+
const CButton = defineComponent({
62+
name: 'CButton',
63+
props,
64+
setup(props, { attrs, slots }) {
65+
const themingProps = computed<ThemingProps>(() => ({
66+
colorScheme: props.colorScheme,
67+
variant: props.variant,
68+
size: props.size,
69+
styleConfig: props.styleConfig,
70+
}))
71+
72+
const styles = useStyleConfig('Button', themingProps.value)
73+
74+
console.log('size: ', props.size)
75+
console.log('variant: ', props.variant)
76+
console.log('colorScheme: ', props.colorScheme)
77+
78+
const buttonStyles: SystemStyleObject = {
79+
display: 'inline-flex',
80+
appearance: 'none',
81+
alignItems: 'center',
82+
justifyContent: 'center',
83+
transition: 'all 250ms',
84+
userSelect: 'none',
85+
position: 'relative',
86+
whiteSpace: 'nowrap',
87+
verticalAlign: 'middle',
88+
outline: 'none',
89+
width: props.isFullWidth ? '100%' : 'auto',
90+
...styles.value,
91+
}
92+
93+
return () =>
94+
h(
95+
chakra(props.as, 'button'),
96+
{
97+
disabled: props.isDisabled || props.isLoading,
98+
type: props.as === 'button' ? undefined : props.type,
99+
dataActive: dataAttr(props.isActive),
100+
dataLoading: dataAttr(props.isLoading),
101+
...buttonStyles,
102+
...attrs,
103+
},
104+
slots
105+
)
106+
},
107+
})
108+
109+
export default CButton

packages/c-button/src/index.ts

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1 @@
1-
import { h, defineComponent, PropType } from 'vue'
2-
import { chakra, DOMElements } from '@chakra-ui/vue-system'
3-
4-
const CButton = defineComponent({
5-
name: 'CButton',
6-
props: {
7-
as: {
8-
type: String as PropType<DOMElements>,
9-
default: 'button',
10-
},
11-
},
12-
setup(_, { attrs, slots }) {
13-
return () =>
14-
h(
15-
chakra('button', 'button'),
16-
{
17-
...attrs,
18-
},
19-
slots
20-
)
21-
},
22-
})
23-
24-
export default CButton
1+
export { default as CButton } from './button'

packages/c-button/tests/__snapshots__/c-button.test.ts.snap

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
exports[`should render properly 1`] = `
44
<DocumentFragment>
55
<button
6-
class="chakra-button css-0"
7-
/>
6+
class="chakra-button css-myeq6i"
7+
>
8+
Happy button
9+
</button>
810
</DocumentFragment>
911
`;
Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,39 @@
1-
import { render } from '../../test-utils/src'
1+
import { render, userEvent } from '../../test-utils/src'
22
import CButton from '../src'
33

4+
const renderComponent = (props?: any) => {
5+
const base = {
6+
components: {
7+
CButton,
8+
},
9+
template: '<CButton>Happy button</CButton>',
10+
...props,
11+
}
12+
return render(base)
13+
}
14+
415
it('should render properly', () => {
5-
const { asFragment } = render(CButton)
16+
const { asFragment } = renderComponent()
617
expect(asFragment()).toMatchSnapshot()
718
})
19+
20+
it('should be in the DOM', () => {
21+
const { baseElement } = renderComponent()
22+
expect(baseElement).toBeInTheDocument()
23+
})
24+
25+
it('should emit click event on click', async () => {
26+
const handleClick = jest.fn()
27+
const { getByTestId } = renderComponent({
28+
template:
29+
'<c-button data-testid="button" @click="handleClick">Happy button</c-button>',
30+
setup() {
31+
return {
32+
handleClick,
33+
}
34+
},
35+
})
36+
37+
await userEvent.click(getByTestId('button'))
38+
expect(handleClick).toHaveBeenCalled()
39+
})

playground/src/.generated/imports.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,24 @@ import Component_4 from '@chakra-ui/c-alert/examples/with-icon.vue'
55
import Component_5 from '@chakra-ui/c-alert/examples/with-status.vue'
66
import Component_6 from '@chakra-ui/c-alert/examples/with-title.vue'
77
import Component_7 from '@chakra-ui/c-button/examples/base-button.vue'
8-
import Component_8 from '@chakra-ui/c-icon/examples/base-icon.vue'
9-
import Component_9 from '@chakra-ui/c-icon/examples/with-color.vue'
10-
import Component_10 from '@chakra-ui/c-icon/examples/with-icon-library.vue'
11-
import Component_11 from '@chakra-ui/c-icon/examples/with-size.vue'
12-
import Component_12 from "../components/Home.vue";
8+
import Component_8 from '@chakra-ui/c-button/examples/with-button-size.vue'
9+
import Component_9 from '@chakra-ui/c-icon/examples/base-icon.vue'
10+
import Component_10 from '@chakra-ui/c-icon/examples/with-color.vue'
11+
import Component_11 from '@chakra-ui/c-icon/examples/with-icon-library.vue'
12+
import Component_12 from '@chakra-ui/c-icon/examples/with-size.vue'
13+
import Component_13 from "../components/Home.vue";
1314

1415
export default {
15-
"../components/Home.vue": Component_12,
16+
"../components/Home.vue": Component_13,
1617
"@chakra-ui/c-alert/examples/base-alert.vue": Component_2,
1718
"@chakra-ui/c-alert/examples/with-accent.vue": Component_3,
1819
"@chakra-ui/c-alert/examples/with-icon.vue": Component_4,
1920
"@chakra-ui/c-alert/examples/with-status.vue": Component_5,
2021
"@chakra-ui/c-alert/examples/with-title.vue": Component_6,
2122
"@chakra-ui/c-button/examples/base-button.vue": Component_7,
22-
"@chakra-ui/c-icon/examples/base-icon.vue": Component_8,
23-
"@chakra-ui/c-icon/examples/with-color.vue": Component_9,
24-
"@chakra-ui/c-icon/examples/with-icon-library.vue": Component_10,
25-
"@chakra-ui/c-icon/examples/with-size.vue": Component_11
23+
"@chakra-ui/c-button/examples/with-button-size.vue": Component_8,
24+
"@chakra-ui/c-icon/examples/base-icon.vue": Component_9,
25+
"@chakra-ui/c-icon/examples/with-color.vue": Component_10,
26+
"@chakra-ui/c-icon/examples/with-icon-library.vue": Component_11,
27+
"@chakra-ui/c-icon/examples/with-size.vue": Component_12
2628
}

playground/src/.generated/routes.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@
4343
"name": "Base button",
4444
"path": "/c-button/base-button",
4545
"component": "@chakra-ui/c-button/examples/base-button.vue"
46+
},
47+
{
48+
"name": "With button size",
49+
"path": "/c-button/with-button-size",
50+
"component": "@chakra-ui/c-button/examples/with-button-size.vue"
4651
}
4752
]
4853
},

0 commit comments

Comments
 (0)