@channel.io/bezier-react 4.0.0-next.2 → 4.0.0-next.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/Button/Button.module.scss.js +1 -1
- package/dist/cjs/styles.css +1 -1
- package/dist/cjs/types/props-helpers.js +8 -0
- package/dist/cjs/types/props-helpers.js.map +1 -1
- package/dist/cjs/v3/BaseStack/BaseStack.js +46 -0
- package/dist/cjs/v3/BaseStack/BaseStack.js.map +1 -0
- package/dist/cjs/v3/BaseStack/BaseStack.module.scss.js +8 -0
- package/dist/cjs/v3/BaseStack/BaseStack.module.scss.js.map +1 -0
- package/dist/cjs/v3/Box/Box.js +56 -0
- package/dist/cjs/v3/Box/Box.js.map +1 -0
- package/dist/cjs/v3/Box/Box.module.scss.js +8 -0
- package/dist/cjs/v3/Box/Box.module.scss.js.map +1 -0
- package/dist/cjs/v3/Divider/Divider.js +32 -0
- package/dist/cjs/v3/Divider/Divider.js.map +1 -0
- package/dist/cjs/v3/Divider/Divider.module.scss.js +8 -0
- package/dist/cjs/v3/Divider/Divider.module.scss.js.map +1 -0
- package/dist/cjs/v3/HStack/HStack.js +19 -0
- package/dist/cjs/v3/HStack/HStack.js.map +1 -0
- package/dist/cjs/v3/Icon/Icon.js +51 -0
- package/dist/cjs/v3/Icon/Icon.js.map +1 -0
- package/dist/cjs/v3/Icon/Icon.module.scss.js +8 -0
- package/dist/cjs/v3/Icon/Icon.module.scss.js.map +1 -0
- package/dist/cjs/v3/SmoothCornersBox/SmoothCornersBox.js +53 -0
- package/dist/cjs/v3/SmoothCornersBox/SmoothCornersBox.js.map +1 -0
- package/dist/cjs/v3/SmoothCornersBox/SmoothCornersBox.module.scss.js +8 -0
- package/dist/cjs/v3/SmoothCornersBox/SmoothCornersBox.module.scss.js.map +1 -0
- package/dist/cjs/v3/Spinner/Spinner.js +45 -0
- package/dist/cjs/v3/Spinner/Spinner.js.map +1 -0
- package/dist/cjs/v3/Spinner/Spinner.module.scss.js +8 -0
- package/dist/cjs/v3/Spinner/Spinner.module.scss.js.map +1 -0
- package/dist/cjs/v3/Text/Text.js +60 -0
- package/dist/cjs/v3/Text/Text.js.map +1 -0
- package/dist/cjs/v3/Text/Text.module.scss.js +8 -0
- package/dist/cjs/v3/Text/Text.module.scss.js.map +1 -0
- package/dist/cjs/v3/VStack/VStack.js +19 -0
- package/dist/cjs/v3/VStack/VStack.js.map +1 -0
- package/dist/cjs/v3/index.js +22 -0
- package/dist/cjs/v3/index.js.map +1 -0
- package/dist/esm/components/Button/Button.module.scss.mjs +1 -1
- package/dist/esm/styles.css +1 -1
- package/dist/esm/types/props-helpers.mjs +5 -1
- package/dist/esm/types/props-helpers.mjs.map +1 -1
- package/dist/esm/v3/BaseStack/BaseStack.mjs +44 -0
- package/dist/esm/v3/BaseStack/BaseStack.mjs.map +1 -0
- package/dist/esm/v3/BaseStack/BaseStack.module.scss.mjs +4 -0
- package/dist/esm/v3/BaseStack/BaseStack.module.scss.mjs.map +1 -0
- package/dist/esm/v3/Box/Box.mjs +54 -0
- package/dist/esm/v3/Box/Box.mjs.map +1 -0
- package/dist/esm/v3/Box/Box.module.scss.mjs +4 -0
- package/dist/esm/v3/Box/Box.module.scss.mjs.map +1 -0
- package/dist/esm/v3/Divider/Divider.mjs +30 -0
- package/dist/esm/v3/Divider/Divider.mjs.map +1 -0
- package/dist/esm/v3/Divider/Divider.module.scss.mjs +4 -0
- package/dist/esm/v3/Divider/Divider.module.scss.mjs.map +1 -0
- package/dist/esm/v3/HStack/HStack.mjs +17 -0
- package/dist/esm/v3/HStack/HStack.mjs.map +1 -0
- package/dist/esm/v3/Icon/Icon.mjs +49 -0
- package/dist/esm/v3/Icon/Icon.mjs.map +1 -0
- package/dist/esm/v3/Icon/Icon.module.scss.mjs +4 -0
- package/dist/esm/v3/Icon/Icon.module.scss.mjs.map +1 -0
- package/dist/esm/v3/SmoothCornersBox/SmoothCornersBox.mjs +51 -0
- package/dist/esm/v3/SmoothCornersBox/SmoothCornersBox.mjs.map +1 -0
- package/dist/esm/v3/SmoothCornersBox/SmoothCornersBox.module.scss.mjs +4 -0
- package/dist/esm/v3/SmoothCornersBox/SmoothCornersBox.module.scss.mjs.map +1 -0
- package/dist/esm/v3/Spinner/Spinner.mjs +43 -0
- package/dist/esm/v3/Spinner/Spinner.mjs.map +1 -0
- package/dist/esm/v3/Spinner/Spinner.module.scss.mjs +4 -0
- package/dist/esm/v3/Spinner/Spinner.module.scss.mjs.map +1 -0
- package/dist/esm/v3/Text/Text.mjs +58 -0
- package/dist/esm/v3/Text/Text.mjs.map +1 -0
- package/dist/esm/v3/Text/Text.module.scss.mjs +4 -0
- package/dist/esm/v3/Text/Text.module.scss.mjs.map +1 -0
- package/dist/esm/v3/VStack/VStack.mjs +17 -0
- package/dist/esm/v3/VStack/VStack.mjs.map +1 -0
- package/dist/esm/v3/index.mjs +9 -0
- package/dist/esm/v3/index.mjs.map +1 -0
- package/dist/types/types/beta-tokens.d.ts +4 -0
- package/dist/types/types/beta-tokens.d.ts.map +1 -1
- package/dist/types/types/props-helpers.d.ts +48 -1
- package/dist/types/types/props-helpers.d.ts.map +1 -1
- package/dist/types/types/props.d.ts +44 -0
- package/dist/types/types/props.d.ts.map +1 -1
- package/dist/types/v3/BaseStack/BaseStack.d.ts +6 -0
- package/dist/types/v3/BaseStack/BaseStack.d.ts.map +1 -0
- package/dist/types/v3/BaseStack/BaseStack.types.d.ts +45 -0
- package/dist/types/v3/BaseStack/BaseStack.types.d.ts.map +1 -0
- package/dist/types/v3/Box/Box.d.ts +19 -0
- package/dist/types/v3/Box/Box.d.ts.map +1 -0
- package/dist/types/v3/Box/Box.types.d.ts +12 -0
- package/dist/types/v3/Box/Box.types.d.ts.map +1 -0
- package/dist/types/v3/Box/index.d.ts +3 -0
- package/dist/types/v3/Box/index.d.ts.map +1 -0
- package/dist/types/v3/Divider/Divider.d.ts +13 -0
- package/dist/types/v3/Divider/Divider.d.ts.map +1 -0
- package/dist/types/v3/Divider/Divider.types.d.ts +27 -0
- package/dist/types/v3/Divider/Divider.types.d.ts.map +1 -0
- package/dist/types/v3/Divider/index.d.ts +3 -0
- package/dist/types/v3/Divider/index.d.ts.map +1 -0
- package/dist/types/v3/HStack/HStack.d.ts +7 -0
- package/dist/types/v3/HStack/HStack.d.ts.map +1 -0
- package/dist/types/v3/HStack/HStack.types.d.ts +2 -0
- package/dist/types/v3/HStack/HStack.types.d.ts.map +1 -0
- package/dist/types/v3/HStack/index.d.ts +3 -0
- package/dist/types/v3/HStack/index.d.ts.map +1 -0
- package/dist/types/v3/Icon/Icon.d.ts +19 -0
- package/dist/types/v3/Icon/Icon.d.ts.map +1 -0
- package/dist/types/v3/Icon/Icon.types.d.ts +21 -0
- package/dist/types/v3/Icon/Icon.types.d.ts.map +1 -0
- package/dist/types/v3/Icon/index.d.ts +3 -0
- package/dist/types/v3/Icon/index.d.ts.map +1 -0
- package/dist/types/v3/SmoothCornersBox/SmoothCornersBox.d.ts +15 -0
- package/dist/types/v3/SmoothCornersBox/SmoothCornersBox.d.ts.map +1 -0
- package/dist/types/v3/SmoothCornersBox/SmoothCornersBox.types.d.ts +61 -0
- package/dist/types/v3/SmoothCornersBox/SmoothCornersBox.types.d.ts.map +1 -0
- package/dist/types/v3/SmoothCornersBox/index.d.ts +3 -0
- package/dist/types/v3/SmoothCornersBox/index.d.ts.map +1 -0
- package/dist/types/v3/Spinner/Spinner.d.ts +15 -0
- package/dist/types/v3/Spinner/Spinner.d.ts.map +1 -0
- package/dist/types/v3/Spinner/Spinner.types.d.ts +5 -0
- package/dist/types/v3/Spinner/Spinner.types.d.ts.map +1 -0
- package/dist/types/v3/Spinner/index.d.ts +3 -0
- package/dist/types/v3/Spinner/index.d.ts.map +1 -0
- package/dist/types/v3/Text/Text.d.ts +16 -0
- package/dist/types/v3/Text/Text.d.ts.map +1 -0
- package/dist/types/v3/Text/Text.types.d.ts +44 -0
- package/dist/types/v3/Text/Text.types.d.ts.map +1 -0
- package/dist/types/v3/Text/index.d.ts +3 -0
- package/dist/types/v3/Text/index.d.ts.map +1 -0
- package/dist/types/v3/VStack/VStack.d.ts +7 -0
- package/dist/types/v3/VStack/VStack.d.ts.map +1 -0
- package/dist/types/v3/VStack/VStack.types.d.ts +2 -0
- package/dist/types/v3/VStack/VStack.types.d.ts.map +1 -0
- package/dist/types/v3/VStack/index.d.ts +3 -0
- package/dist/types/v3/VStack/index.d.ts.map +1 -0
- package/dist/types/v3/index.d.ts +9 -0
- package/dist/types/v3/index.d.ts.map +1 -0
- package/package.json +6 -1
- package/src/components/AlphaButton/Button.module.scss +1 -1
- package/src/components/AlphaFloatingButton/FloatingButton.module.scss +1 -1
- package/src/components/Button/Button.module.scss +9 -1
- package/src/types/beta-tokens.ts +8 -0
- package/src/types/props-helpers.ts +22 -1
- package/src/types/props.ts +52 -0
- package/src/v3/BaseStack/BaseStack.module.scss +73 -0
- package/src/v3/BaseStack/BaseStack.test.tsx +83 -0
- package/src/v3/BaseStack/BaseStack.tsx +72 -0
- package/src/v3/BaseStack/BaseStack.types.ts +59 -0
- package/src/v3/Box/Box.module.scss +13 -0
- package/src/v3/Box/Box.stories.tsx +27 -0
- package/src/v3/Box/Box.test.tsx +57 -0
- package/src/v3/Box/Box.tsx +77 -0
- package/src/v3/Box/Box.types.ts +24 -0
- package/src/v3/Box/index.ts +2 -0
- package/src/v3/Divider/Divider.module.scss +52 -0
- package/src/v3/Divider/Divider.stories.tsx +95 -0
- package/src/v3/Divider/Divider.test.tsx +47 -0
- package/src/v3/Divider/Divider.tsx +57 -0
- package/src/v3/Divider/Divider.types.ts +32 -0
- package/src/v3/Divider/index.ts +2 -0
- package/src/v3/HStack/HStack.stories.tsx +58 -0
- package/src/v3/HStack/HStack.test.tsx +14 -0
- package/src/v3/HStack/HStack.tsx +21 -0
- package/src/v3/HStack/HStack.types.ts +1 -0
- package/src/v3/HStack/index.ts +2 -0
- package/src/v3/Icon/Icon.module.scss +20 -0
- package/src/v3/Icon/Icon.stories.tsx +173 -0
- package/src/v3/Icon/Icon.test.tsx +64 -0
- package/src/v3/Icon/Icon.tsx +67 -0
- package/src/v3/Icon/Icon.types.ts +32 -0
- package/src/v3/Icon/index.ts +2 -0
- package/src/v3/SmoothCornersBox/SmoothCornersBox.module.scss +48 -0
- package/src/v3/SmoothCornersBox/SmoothCornersBox.stories.tsx +41 -0
- package/src/v3/SmoothCornersBox/SmoothCornersBox.test.tsx +83 -0
- package/src/v3/SmoothCornersBox/SmoothCornersBox.tsx +84 -0
- package/src/v3/SmoothCornersBox/SmoothCornersBox.types.ts +69 -0
- package/src/v3/SmoothCornersBox/index.ts +2 -0
- package/src/v3/Spinner/Spinner.module.scss +58 -0
- package/src/v3/Spinner/Spinner.stories.tsx +28 -0
- package/src/v3/Spinner/Spinner.test.tsx +65 -0
- package/src/v3/Spinner/Spinner.tsx +61 -0
- package/src/v3/Spinner/Spinner.types.ts +12 -0
- package/src/v3/Spinner/index.ts +2 -0
- package/src/v3/Text/Text.module.scss +69 -0
- package/src/v3/Text/Text.stories.tsx +52 -0
- package/src/v3/Text/Text.test.tsx +84 -0
- package/src/v3/Text/Text.tsx +81 -0
- package/src/v3/Text/Text.types.ts +70 -0
- package/src/v3/Text/index.ts +2 -0
- package/src/v3/VStack/VStack.stories.tsx +58 -0
- package/src/v3/VStack/VStack.test.tsx +14 -0
- package/src/v3/VStack/VStack.tsx +21 -0
- package/src/v3/VStack/VStack.types.ts +1 -0
- package/src/v3/VStack/index.ts +2 -0
- package/src/v3/index.ts +10 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { ChannelBtnFilledIcon, icons } from '@channel.io/bezier-icons'
|
|
2
|
+
import { type Meta, type StoryObj } from '@storybook/react'
|
|
3
|
+
|
|
4
|
+
import { type BetaSemanticColor } from '~/src/types/beta-tokens'
|
|
5
|
+
import { HStack } from '~/src/v3/HStack'
|
|
6
|
+
import { Text } from '~/src/v3/Text'
|
|
7
|
+
import { VStack } from '~/src/v3/VStack'
|
|
8
|
+
|
|
9
|
+
import { Icon } from './Icon'
|
|
10
|
+
import { type IconProps, type IconSize } from './Icon.types'
|
|
11
|
+
|
|
12
|
+
const SIZES: IconSize[] = ['10', '12', '16', '20', '24', '36', '44']
|
|
13
|
+
|
|
14
|
+
const COLORS: BetaSemanticColor[] = [
|
|
15
|
+
'icon-neutral',
|
|
16
|
+
'icon-neutral-heavier',
|
|
17
|
+
'icon-accent-blue',
|
|
18
|
+
'icon-accent-cobalt',
|
|
19
|
+
'icon-accent-teal',
|
|
20
|
+
'icon-accent-green',
|
|
21
|
+
'icon-accent-olive',
|
|
22
|
+
'icon-accent-yellow',
|
|
23
|
+
'icon-accent-orange',
|
|
24
|
+
'icon-accent-red',
|
|
25
|
+
'icon-accent-pink',
|
|
26
|
+
'icon-accent-purple',
|
|
27
|
+
'icon-accent-navy',
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
const meta: Meta<typeof Icon> = {
|
|
31
|
+
title: 'V3 components/Icon',
|
|
32
|
+
component: Icon,
|
|
33
|
+
args: {
|
|
34
|
+
source: 'channel-btn-filled' as unknown as IconProps['source'],
|
|
35
|
+
size: '24',
|
|
36
|
+
color: 'icon-neutral',
|
|
37
|
+
},
|
|
38
|
+
argTypes: {
|
|
39
|
+
source: {
|
|
40
|
+
control: 'select',
|
|
41
|
+
options: Object.keys(icons),
|
|
42
|
+
mapping: icons,
|
|
43
|
+
},
|
|
44
|
+
size: {
|
|
45
|
+
control: 'select',
|
|
46
|
+
options: SIZES,
|
|
47
|
+
table: {
|
|
48
|
+
defaultValue: { summary: '"24"' },
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
// `color` accepts any beta semantic color token (`V3ColorProps`), so it is
|
|
52
|
+
// left as a free-text control rather than a restricted option list.
|
|
53
|
+
color: {
|
|
54
|
+
control: 'text',
|
|
55
|
+
table: {
|
|
56
|
+
defaultValue: { summary: '"icon-neutral"' },
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export default meta
|
|
63
|
+
|
|
64
|
+
type Story = StoryObj<typeof Icon>
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Adjust `source` / `size` / `color` with the controls panel.
|
|
68
|
+
*/
|
|
69
|
+
export const Primary: Story = {}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Each size (based on the `icon-neutral` color).
|
|
73
|
+
*/
|
|
74
|
+
export const Sizes: Story = {
|
|
75
|
+
tags: ['!autodocs'],
|
|
76
|
+
parameters: { controls: { disable: true } },
|
|
77
|
+
render: () => (
|
|
78
|
+
<VStack spacing={12}>
|
|
79
|
+
{SIZES.map((size) => (
|
|
80
|
+
<HStack
|
|
81
|
+
key={size}
|
|
82
|
+
align="center"
|
|
83
|
+
spacing={24}
|
|
84
|
+
>
|
|
85
|
+
<Text
|
|
86
|
+
typo="12"
|
|
87
|
+
color="text-neutral"
|
|
88
|
+
style={{ width: 32 }}
|
|
89
|
+
>
|
|
90
|
+
{size}
|
|
91
|
+
</Text>
|
|
92
|
+
<Icon
|
|
93
|
+
source={ChannelBtnFilledIcon}
|
|
94
|
+
size={size}
|
|
95
|
+
color="icon-neutral"
|
|
96
|
+
/>
|
|
97
|
+
</HStack>
|
|
98
|
+
))}
|
|
99
|
+
</VStack>
|
|
100
|
+
),
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Each color (based on the `l` size).
|
|
105
|
+
*/
|
|
106
|
+
export const Colors: Story = {
|
|
107
|
+
tags: ['!autodocs'],
|
|
108
|
+
parameters: { controls: { disable: true } },
|
|
109
|
+
render: () => (
|
|
110
|
+
<VStack spacing={12}>
|
|
111
|
+
{COLORS.map((color) => (
|
|
112
|
+
<HStack
|
|
113
|
+
key={color}
|
|
114
|
+
align="center"
|
|
115
|
+
spacing={24}
|
|
116
|
+
>
|
|
117
|
+
<Text
|
|
118
|
+
typo="12"
|
|
119
|
+
color="text-neutral"
|
|
120
|
+
style={{ width: 160 }}
|
|
121
|
+
>
|
|
122
|
+
{color}
|
|
123
|
+
</Text>
|
|
124
|
+
<Icon
|
|
125
|
+
source={ChannelBtnFilledIcon}
|
|
126
|
+
size="36"
|
|
127
|
+
color={color}
|
|
128
|
+
/>
|
|
129
|
+
</HStack>
|
|
130
|
+
))}
|
|
131
|
+
</VStack>
|
|
132
|
+
),
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Every icon available in `@channel.io/bezier-icons`.
|
|
137
|
+
*/
|
|
138
|
+
export const AllIcons: Story = {
|
|
139
|
+
tags: ['!autodocs'],
|
|
140
|
+
parameters: { controls: { disable: true } },
|
|
141
|
+
render: () => (
|
|
142
|
+
<HStack
|
|
143
|
+
wrap
|
|
144
|
+
spacing={8}
|
|
145
|
+
>
|
|
146
|
+
{Object.entries(icons).map(([name, source]) => (
|
|
147
|
+
<VStack
|
|
148
|
+
key={name}
|
|
149
|
+
display="inline-flex"
|
|
150
|
+
align="center"
|
|
151
|
+
justify="center"
|
|
152
|
+
wrap
|
|
153
|
+
spacing={12}
|
|
154
|
+
width={120}
|
|
155
|
+
height={120}
|
|
156
|
+
>
|
|
157
|
+
<Icon
|
|
158
|
+
source={source}
|
|
159
|
+
size="24"
|
|
160
|
+
/>
|
|
161
|
+
<Text
|
|
162
|
+
typo="12"
|
|
163
|
+
color="text-neutral"
|
|
164
|
+
align="center"
|
|
165
|
+
style={{ wordBreak: 'break-word' }}
|
|
166
|
+
>
|
|
167
|
+
{name}
|
|
168
|
+
</Text>
|
|
169
|
+
</VStack>
|
|
170
|
+
))}
|
|
171
|
+
</HStack>
|
|
172
|
+
),
|
|
173
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
|
|
3
|
+
import { AllIcon } from '@channel.io/bezier-icons'
|
|
4
|
+
|
|
5
|
+
import { colorTokenCssVar } from '~/src/utils/style'
|
|
6
|
+
import { render } from '~/src/utils/test'
|
|
7
|
+
|
|
8
|
+
import { Icon } from './Icon'
|
|
9
|
+
import { type IconProps } from './Icon.types'
|
|
10
|
+
|
|
11
|
+
import styles from './Icon.module.scss'
|
|
12
|
+
|
|
13
|
+
describe('Icon', () => {
|
|
14
|
+
const renderIcon = (props?: Partial<IconProps>) =>
|
|
15
|
+
render(
|
|
16
|
+
<Icon
|
|
17
|
+
source={AllIcon}
|
|
18
|
+
{...props}
|
|
19
|
+
/>
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
it('should render with default style', () => {
|
|
23
|
+
const { container } = renderIcon()
|
|
24
|
+
const rendered = container.querySelector('svg')
|
|
25
|
+
|
|
26
|
+
expect(rendered).toHaveClass(styles.Icon)
|
|
27
|
+
expect(rendered).toHaveClass(styles['size-24'])
|
|
28
|
+
expect(rendered).toHaveStyle(
|
|
29
|
+
`--b-v3-icon-color: ${colorTokenCssVar('icon-neutral')}`
|
|
30
|
+
)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('should forward ref', () => {
|
|
34
|
+
const ref = React.createRef<SVGSVGElement>()
|
|
35
|
+
|
|
36
|
+
render(
|
|
37
|
+
<Icon
|
|
38
|
+
ref={ref}
|
|
39
|
+
source={AllIcon}
|
|
40
|
+
/>
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
expect(ref.current).toBeInTheDocument()
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('should receive color, size, margin, style, and class name', () => {
|
|
47
|
+
const { container } = renderIcon({
|
|
48
|
+
color: 'icon-neutral-heavier',
|
|
49
|
+
size: '44',
|
|
50
|
+
marginTop: 10,
|
|
51
|
+
style: { display: 'block' },
|
|
52
|
+
className: 'test-class',
|
|
53
|
+
})
|
|
54
|
+
const rendered = container.querySelector('svg')
|
|
55
|
+
|
|
56
|
+
expect(rendered).toHaveClass(styles['size-44'])
|
|
57
|
+
expect(rendered).toHaveClass('test-class')
|
|
58
|
+
expect(rendered).toHaveStyle(
|
|
59
|
+
`--b-v3-icon-color: ${colorTokenCssVar('icon-neutral-heavier')}`
|
|
60
|
+
)
|
|
61
|
+
expect(rendered).toHaveStyle('display: block')
|
|
62
|
+
expect(rendered).toHaveStyle('--b-margin-top: 10px')
|
|
63
|
+
})
|
|
64
|
+
})
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { forwardRef, memo } from 'react'
|
|
4
|
+
import * as React from 'react'
|
|
5
|
+
|
|
6
|
+
import classNames from 'classnames'
|
|
7
|
+
|
|
8
|
+
import { type BetaSemanticColor } from '~/src/types/beta-tokens'
|
|
9
|
+
import { getMarginStyles, splitByMarginProps } from '~/src/types/props-helpers'
|
|
10
|
+
import { colorTokenCssVar } from '~/src/utils/style'
|
|
11
|
+
|
|
12
|
+
import { type IconProps } from './Icon.types'
|
|
13
|
+
|
|
14
|
+
import styles from './Icon.module.scss'
|
|
15
|
+
|
|
16
|
+
const DEFAULT_ICON_COLOR = 'icon-neutral' satisfies BetaSemanticColor
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* `Icon` renders a Bezier icon as an SVG element.
|
|
20
|
+
* Inject an icon component from the `@channel.io/bezier-icons` package into the `source` prop.
|
|
21
|
+
* @example
|
|
22
|
+
*
|
|
23
|
+
* ```tsx
|
|
24
|
+
* import { HeartFilledIcon } from '@channel.io/bezier-icons'
|
|
25
|
+
*
|
|
26
|
+
* <Icon
|
|
27
|
+
* source={HeartFilledIcon}
|
|
28
|
+
* size="24"
|
|
29
|
+
* color="icon-neutral"
|
|
30
|
+
* />
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export const Icon = memo(
|
|
34
|
+
forwardRef<SVGSVGElement, IconProps>(function Icon(props, forwardedRef) {
|
|
35
|
+
const [marginProps, marginRest] = splitByMarginProps(props)
|
|
36
|
+
const marginStyles = getMarginStyles(marginProps)
|
|
37
|
+
|
|
38
|
+
const {
|
|
39
|
+
className,
|
|
40
|
+
size = '24',
|
|
41
|
+
color = DEFAULT_ICON_COLOR,
|
|
42
|
+
source: SourceElement,
|
|
43
|
+
style,
|
|
44
|
+
...rest
|
|
45
|
+
} = marginRest
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<SourceElement
|
|
49
|
+
ref={forwardedRef}
|
|
50
|
+
style={
|
|
51
|
+
{
|
|
52
|
+
'--b-v3-icon-color': colorTokenCssVar(color),
|
|
53
|
+
...marginStyles.style,
|
|
54
|
+
...style,
|
|
55
|
+
} as React.CSSProperties
|
|
56
|
+
}
|
|
57
|
+
className={classNames(
|
|
58
|
+
styles.Icon,
|
|
59
|
+
styles[`size-${size}`],
|
|
60
|
+
marginStyles.className,
|
|
61
|
+
className
|
|
62
|
+
)}
|
|
63
|
+
{...rest}
|
|
64
|
+
/>
|
|
65
|
+
)
|
|
66
|
+
})
|
|
67
|
+
)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type BezierIcon } from '@channel.io/bezier-icons'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
type BezierComponentProps,
|
|
5
|
+
type SizeProps,
|
|
6
|
+
type V3ColorProps,
|
|
7
|
+
type V3MarginProps,
|
|
8
|
+
} from '~/src/types/props'
|
|
9
|
+
|
|
10
|
+
export type IconSize = '10' | '12' | '16' | '20' | '24' | '36' | '44'
|
|
11
|
+
|
|
12
|
+
interface IconOwnProps {
|
|
13
|
+
/**
|
|
14
|
+
* Controls which icon should be rendered.
|
|
15
|
+
* Inject the icon component from the `@channel.io/bezier-icons` package into this prop.
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* import { HeartFilledIcon } from '@channel.io/bezier-icons'
|
|
19
|
+
* import { Icon } from '@channel.io/bezier-react/v3'
|
|
20
|
+
*
|
|
21
|
+
* <Icon source={HeartFilledIcon} {...} />
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
source: BezierIcon
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface IconProps
|
|
28
|
+
extends Omit<BezierComponentProps<'svg'>, keyof V3ColorProps>,
|
|
29
|
+
V3MarginProps,
|
|
30
|
+
SizeProps<IconSize>,
|
|
31
|
+
V3ColorProps,
|
|
32
|
+
IconOwnProps {}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
.SmoothCornersBox {
|
|
2
|
+
--b-smooth-corners-box-border-radius: 0;
|
|
3
|
+
--b-smooth-corners-box-shadow-offset-x: 0;
|
|
4
|
+
--b-smooth-corners-box-shadow-offset-y: 0;
|
|
5
|
+
--b-smooth-corners-box-shadow-blur-radius: 0px;
|
|
6
|
+
--b-smooth-corners-box-shadow-spread-radius: 0px;
|
|
7
|
+
--b-smooth-corners-box-shadow-color: transparent;
|
|
8
|
+
--b-smooth-corners-box-padding: 0px;
|
|
9
|
+
--b-smooth-corners-box-margin: 0px;
|
|
10
|
+
--b-smooth-corners-box-background-color: transparent;
|
|
11
|
+
|
|
12
|
+
box-sizing: content-box;
|
|
13
|
+
margin: var(--b-smooth-corners-box-margin);
|
|
14
|
+
|
|
15
|
+
background-color: var(--b-smooth-corners-box-background-color);
|
|
16
|
+
background-image: var(--b-smooth-corners-box-background-image);
|
|
17
|
+
background-size: cover;
|
|
18
|
+
border-radius: var(--b-smooth-corners-box-border-radius);
|
|
19
|
+
box-shadow: var(--b-smooth-corners-box-shadow-offset-x)
|
|
20
|
+
var(--b-smooth-corners-box-shadow-offset-y)
|
|
21
|
+
var(--b-smooth-corners-box-shadow-blur-radius)
|
|
22
|
+
var(--b-smooth-corners-box-shadow-spread-radius)
|
|
23
|
+
var(--b-smooth-corners-box-shadow-color);
|
|
24
|
+
|
|
25
|
+
&:where([data-state='enabled']) {
|
|
26
|
+
@supports (background: paint(smooth-corners)) {
|
|
27
|
+
--smooth-corners: var(--b-smooth-corners-box-border-radius);
|
|
28
|
+
--smooth-corners-shadow: var(--b-smooth-corners-box-shadow-offset-x),
|
|
29
|
+
var(--b-smooth-corners-box-shadow-offset-y),
|
|
30
|
+
var(--b-smooth-corners-box-shadow-blur-radius),
|
|
31
|
+
var(--b-smooth-corners-box-shadow-spread-radius),
|
|
32
|
+
var(--b-smooth-corners-box-shadow-color);
|
|
33
|
+
--smooth-corners-bg-color: var(--b-smooth-corners-box-background-color);
|
|
34
|
+
--smooth-corners-padding: var(--b-smooth-corners-box-padding);
|
|
35
|
+
|
|
36
|
+
margin: calc(
|
|
37
|
+
var(--b-smooth-corners-box-margin) +
|
|
38
|
+
(-1 * var(--b-smooth-corners-box-padding))
|
|
39
|
+
);
|
|
40
|
+
padding: var(--b-smooth-corners-box-padding);
|
|
41
|
+
|
|
42
|
+
background: paint(smooth-corners);
|
|
43
|
+
border-radius: 0;
|
|
44
|
+
border-image-source: var(--b-smooth-corners-box-background-image);
|
|
45
|
+
box-shadow: none;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type Meta, type StoryFn, type StoryObj } from '@storybook/react'
|
|
2
|
+
|
|
3
|
+
import { SmoothCornersBox } from './SmoothCornersBox'
|
|
4
|
+
import { type SmoothCornersBoxProps } from './SmoothCornersBox.types'
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof SmoothCornersBox> = {
|
|
7
|
+
title: 'V3 components/SmoothCornersBox',
|
|
8
|
+
component: SmoothCornersBox,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default meta
|
|
12
|
+
|
|
13
|
+
const Template: StoryFn<SmoothCornersBoxProps> = ({
|
|
14
|
+
children,
|
|
15
|
+
...otherSmoothCornersBoxProps
|
|
16
|
+
}) => (
|
|
17
|
+
<SmoothCornersBox
|
|
18
|
+
style={{ width: 200, height: 200 }}
|
|
19
|
+
{...otherSmoothCornersBoxProps}
|
|
20
|
+
>
|
|
21
|
+
{children}
|
|
22
|
+
</SmoothCornersBox>
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
export const Primary: StoryObj<SmoothCornersBoxProps> = {
|
|
26
|
+
render: Template,
|
|
27
|
+
args: {
|
|
28
|
+
disabled: false,
|
|
29
|
+
borderRadius: '42%',
|
|
30
|
+
shadow: {
|
|
31
|
+
offsetX: 0,
|
|
32
|
+
offsetY: 4,
|
|
33
|
+
blurRadius: 20,
|
|
34
|
+
spreadRadius: 0,
|
|
35
|
+
color: 'elevation-large',
|
|
36
|
+
},
|
|
37
|
+
margin: 0,
|
|
38
|
+
backgroundColor: 'fill-absolute-white',
|
|
39
|
+
backgroundImage: '',
|
|
40
|
+
},
|
|
41
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { render } from '~/src/utils/test'
|
|
2
|
+
|
|
3
|
+
import { SmoothCornersBox } from './SmoothCornersBox'
|
|
4
|
+
import { type SmoothCornersBoxProps } from './SmoothCornersBox.types'
|
|
5
|
+
|
|
6
|
+
import styles from './SmoothCornersBox.module.scss'
|
|
7
|
+
|
|
8
|
+
describe('SmoothCornersBox', () => {
|
|
9
|
+
const renderSmoothCornersBox = (
|
|
10
|
+
{ children, ...rest }: SmoothCornersBoxProps = { borderRadius: 0 }
|
|
11
|
+
) => render(<SmoothCornersBox {...rest}>{children}</SmoothCornersBox>)
|
|
12
|
+
|
|
13
|
+
it('should render with disabled state by default', () => {
|
|
14
|
+
const children = 'Hello, Channel!'
|
|
15
|
+
const { getByText } = renderSmoothCornersBox({ children, borderRadius: 10 })
|
|
16
|
+
const rendered = getByText(children)
|
|
17
|
+
|
|
18
|
+
expect(rendered).toHaveClass(styles.SmoothCornersBox)
|
|
19
|
+
expect(rendered).toHaveAttribute('data-state', 'disabled')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('each style property must have the correct unit.', () => {
|
|
23
|
+
const children = 'Hello, Channel!'
|
|
24
|
+
const { getByText } = renderSmoothCornersBox({
|
|
25
|
+
children,
|
|
26
|
+
borderRadius: 10,
|
|
27
|
+
margin: 10,
|
|
28
|
+
shadow: {
|
|
29
|
+
offsetX: 10,
|
|
30
|
+
offsetY: 10,
|
|
31
|
+
blurRadius: 10,
|
|
32
|
+
spreadRadius: 10,
|
|
33
|
+
color: 'fill-neutral',
|
|
34
|
+
},
|
|
35
|
+
backgroundColor: 'fill-neutral',
|
|
36
|
+
backgroundImage: 'foo/bar',
|
|
37
|
+
className: 'test-class',
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const rendered = getByText(children)
|
|
41
|
+
const computedStyle = window.getComputedStyle(rendered)
|
|
42
|
+
|
|
43
|
+
expect(rendered).toHaveClass('test-class')
|
|
44
|
+
expect(
|
|
45
|
+
computedStyle.getPropertyValue('--b-smooth-corners-box-border-radius')
|
|
46
|
+
).toBe('10')
|
|
47
|
+
expect(
|
|
48
|
+
computedStyle.getPropertyValue('--b-smooth-corners-box-shadow-offset-x')
|
|
49
|
+
).toBe('10px')
|
|
50
|
+
expect(
|
|
51
|
+
computedStyle.getPropertyValue('--b-smooth-corners-box-shadow-offset-y')
|
|
52
|
+
).toBe('10px')
|
|
53
|
+
expect(
|
|
54
|
+
computedStyle.getPropertyValue(
|
|
55
|
+
'--b-smooth-corners-box-shadow-blur-radius'
|
|
56
|
+
)
|
|
57
|
+
).toBe('10px')
|
|
58
|
+
expect(
|
|
59
|
+
computedStyle.getPropertyValue(
|
|
60
|
+
'--b-smooth-corners-box-shadow-spread-radius'
|
|
61
|
+
)
|
|
62
|
+
).toBe('10px')
|
|
63
|
+
expect(
|
|
64
|
+
computedStyle.getPropertyValue('--b-smooth-corners-box-shadow-color')
|
|
65
|
+
).toBe('var(--color-fill-neutral)')
|
|
66
|
+
expect(
|
|
67
|
+
computedStyle.getPropertyValue('--b-smooth-corners-box-padding')
|
|
68
|
+
).toBe('20px')
|
|
69
|
+
expect(
|
|
70
|
+
computedStyle.getPropertyValue('--b-smooth-corners-box-margin')
|
|
71
|
+
).toBe('10px')
|
|
72
|
+
expect(
|
|
73
|
+
computedStyle.getPropertyValue(
|
|
74
|
+
'--b-smooth-corners-box-background-color'
|
|
75
|
+
)
|
|
76
|
+
).toBe('var(--color-fill-neutral)')
|
|
77
|
+
expect(
|
|
78
|
+
computedStyle.getPropertyValue(
|
|
79
|
+
'--b-smooth-corners-box-background-image'
|
|
80
|
+
)
|
|
81
|
+
).toBe('url(foo/bar)')
|
|
82
|
+
})
|
|
83
|
+
})
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { forwardRef } from 'react'
|
|
4
|
+
import * as React from 'react'
|
|
5
|
+
|
|
6
|
+
import classNames from 'classnames'
|
|
7
|
+
|
|
8
|
+
import { colorTokenCssVar, cssUrl, px } from '~/src/utils/style'
|
|
9
|
+
|
|
10
|
+
import { FeatureType, useFeatureFlag } from '~/src/components/FeatureProvider'
|
|
11
|
+
|
|
12
|
+
import { type SmoothCornersBoxProps } from './SmoothCornersBox.types'
|
|
13
|
+
|
|
14
|
+
import styles from './SmoothCornersBox.module.scss'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* `SmoothCornersBox` is a simple `div` element with smooth corners.
|
|
18
|
+
* It is available by enabling the `SmoothCornersFeature`.
|
|
19
|
+
* @example
|
|
20
|
+
*
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <AppProvider features={[SmoothCornersFeature]}>
|
|
23
|
+
* <SmoothCornersBox />
|
|
24
|
+
* </AppProvider>
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export const SmoothCornersBox = forwardRef<
|
|
28
|
+
HTMLDivElement,
|
|
29
|
+
SmoothCornersBoxProps
|
|
30
|
+
>(function SmoothCornersBox(
|
|
31
|
+
{
|
|
32
|
+
children,
|
|
33
|
+
style,
|
|
34
|
+
className,
|
|
35
|
+
disabled,
|
|
36
|
+
borderRadius,
|
|
37
|
+
margin,
|
|
38
|
+
shadow,
|
|
39
|
+
backgroundColor,
|
|
40
|
+
backgroundImage,
|
|
41
|
+
...rest
|
|
42
|
+
},
|
|
43
|
+
forwardedRef
|
|
44
|
+
) {
|
|
45
|
+
const shadowBlurRadius = shadow?.blurRadius ?? 0
|
|
46
|
+
const shadowSpreadRadius = shadow?.spreadRadius ?? 0
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<div
|
|
50
|
+
{...rest}
|
|
51
|
+
ref={forwardedRef}
|
|
52
|
+
style={
|
|
53
|
+
{
|
|
54
|
+
...style,
|
|
55
|
+
'--b-smooth-corners-box-border-radius': borderRadius,
|
|
56
|
+
'--b-smooth-corners-box-shadow-offset-x': px(shadow?.offsetX),
|
|
57
|
+
'--b-smooth-corners-box-shadow-offset-y': px(shadow?.offsetY),
|
|
58
|
+
'--b-smooth-corners-box-shadow-blur-radius': `${shadowBlurRadius}px`,
|
|
59
|
+
'--b-smooth-corners-box-shadow-spread-radius': `${shadowSpreadRadius}px`,
|
|
60
|
+
'--b-smooth-corners-box-shadow-color': colorTokenCssVar(
|
|
61
|
+
shadow?.color
|
|
62
|
+
),
|
|
63
|
+
/**
|
|
64
|
+
* NOTE: Calculate in javascript because it cannot access calculated values via CSS calc() in the paint worklet.
|
|
65
|
+
* @see {@link ~/src/features/SmoothCorners/smoothCornersScript.ts}
|
|
66
|
+
*/
|
|
67
|
+
'--b-smooth-corners-box-padding': `${Math.max(shadowBlurRadius, shadowSpreadRadius) * 2}px`,
|
|
68
|
+
'--b-smooth-corners-box-margin': `${margin ?? 0}px`,
|
|
69
|
+
'--b-smooth-corners-box-background-color':
|
|
70
|
+
colorTokenCssVar(backgroundColor),
|
|
71
|
+
'--b-smooth-corners-box-background-image': cssUrl(backgroundImage),
|
|
72
|
+
} as React.CSSProperties
|
|
73
|
+
}
|
|
74
|
+
className={classNames(styles.SmoothCornersBox, className)}
|
|
75
|
+
data-state={
|
|
76
|
+
useFeatureFlag(FeatureType.SmoothCorners) && !disabled
|
|
77
|
+
? 'enabled'
|
|
78
|
+
: 'disabled'
|
|
79
|
+
}
|
|
80
|
+
>
|
|
81
|
+
{children}
|
|
82
|
+
</div>
|
|
83
|
+
)
|
|
84
|
+
})
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { type BetaSemanticColor } from '~/src/types/beta-tokens'
|
|
2
|
+
import type {
|
|
3
|
+
BezierComponentProps,
|
|
4
|
+
ChildrenProps,
|
|
5
|
+
DisableProps,
|
|
6
|
+
} from '~/src/types/props'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* NOTE: The `inset` property is not currently supported.
|
|
10
|
+
*/
|
|
11
|
+
interface BoxShadow {
|
|
12
|
+
/**
|
|
13
|
+
* The value specifies the horizontal distance. Negative values place the shadow to the left of the element.
|
|
14
|
+
* @default 0
|
|
15
|
+
*/
|
|
16
|
+
offsetX?: number
|
|
17
|
+
/**
|
|
18
|
+
* The value specifies the vertical distance. Negative values place the shadow above the element.
|
|
19
|
+
* @default 0
|
|
20
|
+
*/
|
|
21
|
+
offsetY?: number
|
|
22
|
+
/**
|
|
23
|
+
* The larger this value, the bigger the blur, so the shadow becomes bigger and lighter. Negative values are not allowed.
|
|
24
|
+
* @default 0
|
|
25
|
+
*/
|
|
26
|
+
blurRadius?: number
|
|
27
|
+
/**
|
|
28
|
+
* Positive values will cause the shadow to expand and grow bigger, negative values will cause the shadow to shrink.
|
|
29
|
+
* @default 0
|
|
30
|
+
*/
|
|
31
|
+
spreadRadius?: number
|
|
32
|
+
/**
|
|
33
|
+
* The color of the shadow.
|
|
34
|
+
* @default transparent
|
|
35
|
+
*/
|
|
36
|
+
color?: BetaSemanticColor
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface SmoothCornersBoxOwnProps {
|
|
40
|
+
/**
|
|
41
|
+
* Rounds the corners of an element's outer border edge.
|
|
42
|
+
* @default 0
|
|
43
|
+
*/
|
|
44
|
+
borderRadius: number | string
|
|
45
|
+
/**
|
|
46
|
+
* Shadow effects around an element's frame.
|
|
47
|
+
*/
|
|
48
|
+
shadow?: BoxShadow
|
|
49
|
+
/**
|
|
50
|
+
* The margin area on all four sides of an element.
|
|
51
|
+
* @default 0
|
|
52
|
+
*/
|
|
53
|
+
margin?: number
|
|
54
|
+
/**
|
|
55
|
+
* The background color of an element.
|
|
56
|
+
* @default 'transparent'
|
|
57
|
+
*/
|
|
58
|
+
backgroundColor?: BetaSemanticColor
|
|
59
|
+
/**
|
|
60
|
+
* The background image url of an element.
|
|
61
|
+
*/
|
|
62
|
+
backgroundImage?: string
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface SmoothCornersBoxProps
|
|
66
|
+
extends BezierComponentProps<'div'>,
|
|
67
|
+
ChildrenProps,
|
|
68
|
+
DisableProps,
|
|
69
|
+
SmoothCornersBoxOwnProps {}
|