@channel.io/bezier-react 4.0.0-next.3 → 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/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/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/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,57 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
|
|
3
|
+
import { render } from '~/src/utils/test'
|
|
4
|
+
|
|
5
|
+
import { Box } from './Box'
|
|
6
|
+
import { type BoxProps } from './Box.types'
|
|
7
|
+
|
|
8
|
+
import styles from './Box.module.scss'
|
|
9
|
+
|
|
10
|
+
describe('Box', () => {
|
|
11
|
+
const renderBox = (props?: Partial<BoxProps>) =>
|
|
12
|
+
render(<Box {...props}>Hello, Channel!</Box>)
|
|
13
|
+
|
|
14
|
+
it('should render with default style', () => {
|
|
15
|
+
const { getByText } = renderBox()
|
|
16
|
+
const rendered = getByText('Hello, Channel!')
|
|
17
|
+
|
|
18
|
+
expect(rendered).toHaveClass(styles.Box)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('should render as the given element', () => {
|
|
22
|
+
const { getByText } = renderBox({ as: 'section' })
|
|
23
|
+
const rendered = getByText('Hello, Channel!')
|
|
24
|
+
|
|
25
|
+
expect(rendered.tagName).toBe('SECTION')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('should forward ref', () => {
|
|
29
|
+
const ref = React.createRef<HTMLElement>()
|
|
30
|
+
|
|
31
|
+
render(<Box ref={ref} />)
|
|
32
|
+
|
|
33
|
+
expect(ref.current).toBeInTheDocument()
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('should receive display style', () => {
|
|
37
|
+
const { getByText } = renderBox({ display: 'inline-block' })
|
|
38
|
+
const rendered = getByText('Hello, Channel!')
|
|
39
|
+
|
|
40
|
+
expect(rendered).toHaveClass(styles['display-inline-block'])
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('should receive layout and margin styles', () => {
|
|
44
|
+
const { getByText } = renderBox({
|
|
45
|
+
width: '100px',
|
|
46
|
+
marginTop: 10,
|
|
47
|
+
style: { backgroundColor: 'red' },
|
|
48
|
+
className: 'test-class',
|
|
49
|
+
})
|
|
50
|
+
const rendered = getByText('Hello, Channel!')
|
|
51
|
+
|
|
52
|
+
expect(rendered).toHaveStyle('--b-width: 100px')
|
|
53
|
+
expect(rendered).toHaveStyle('--b-margin-top: 10px')
|
|
54
|
+
expect(rendered).toHaveStyle('background-color: red')
|
|
55
|
+
expect(rendered).toHaveClass('test-class')
|
|
56
|
+
})
|
|
57
|
+
})
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { createElement, forwardRef } from 'react'
|
|
4
|
+
import type { CSSProperties } from 'react'
|
|
5
|
+
|
|
6
|
+
import classNames from 'classnames'
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
getV3LayoutStyles,
|
|
10
|
+
getV3MarginStyles,
|
|
11
|
+
splitByV3LayoutProps,
|
|
12
|
+
splitByV3MarginProps,
|
|
13
|
+
} from '~/src/types/props-helpers'
|
|
14
|
+
|
|
15
|
+
import type { BoxProps } from './Box.types'
|
|
16
|
+
|
|
17
|
+
import styles from './Box.module.scss'
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* `Box` is a primitive layout component. It provides an easy way to access design tokens.
|
|
21
|
+
* @example
|
|
22
|
+
*
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <Box
|
|
25
|
+
* width="100px"
|
|
26
|
+
* height="100px"
|
|
27
|
+
* padding="6px"
|
|
28
|
+
* margin="6px"
|
|
29
|
+
* backgroundColor="fill-neutral"
|
|
30
|
+
* >
|
|
31
|
+
* <div>{ ... }</div>
|
|
32
|
+
* </Box>
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export const Box = forwardRef<HTMLElement, BoxProps>(
|
|
36
|
+
function Box(props, forwardedRef) {
|
|
37
|
+
const [marginProps, marginRest] = splitByV3MarginProps(props)
|
|
38
|
+
const [layoutProps, layoutRest] = splitByV3LayoutProps(marginRest)
|
|
39
|
+
const marginStyles = getV3MarginStyles(marginProps)
|
|
40
|
+
const layoutStyles = getV3LayoutStyles(layoutProps)
|
|
41
|
+
|
|
42
|
+
const {
|
|
43
|
+
children,
|
|
44
|
+
style,
|
|
45
|
+
className,
|
|
46
|
+
as = 'div',
|
|
47
|
+
display,
|
|
48
|
+
...rest
|
|
49
|
+
} = layoutRest
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* NOTE: Keep the existing loose polymorphic Box pattern for API parity.
|
|
53
|
+
* TODO: Replace this with a typed polymorphic helper when ref inference is standardized.
|
|
54
|
+
*/
|
|
55
|
+
return createElement(
|
|
56
|
+
as,
|
|
57
|
+
{
|
|
58
|
+
ref: forwardedRef,
|
|
59
|
+
style: {
|
|
60
|
+
...marginStyles.style,
|
|
61
|
+
...layoutStyles.style,
|
|
62
|
+
...style,
|
|
63
|
+
} as CSSProperties,
|
|
64
|
+
className: classNames(
|
|
65
|
+
styles.Box,
|
|
66
|
+
display && styles[`display-${display}`],
|
|
67
|
+
marginStyles.className,
|
|
68
|
+
layoutStyles.className,
|
|
69
|
+
className
|
|
70
|
+
),
|
|
71
|
+
'data-testid': 'bezier-box',
|
|
72
|
+
...rest,
|
|
73
|
+
},
|
|
74
|
+
children
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
BezierComponentProps,
|
|
3
|
+
ChildrenProps,
|
|
4
|
+
PolymorphicProps,
|
|
5
|
+
V3LayoutProps,
|
|
6
|
+
V3MarginProps,
|
|
7
|
+
} from '~/src/types/props'
|
|
8
|
+
|
|
9
|
+
type Display = 'block' | 'inline' | 'inline-block'
|
|
10
|
+
|
|
11
|
+
interface BoxOwnProps {
|
|
12
|
+
/**
|
|
13
|
+
* Display type of the box.
|
|
14
|
+
*/
|
|
15
|
+
display?: Display
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface BoxProps
|
|
19
|
+
extends Omit<BezierComponentProps<'div'>, keyof BoxOwnProps>,
|
|
20
|
+
PolymorphicProps,
|
|
21
|
+
ChildrenProps,
|
|
22
|
+
V3MarginProps,
|
|
23
|
+
V3LayoutProps,
|
|
24
|
+
BoxOwnProps {}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
.Divider {
|
|
2
|
+
--b-v3-divider-indent-size: 6px;
|
|
3
|
+
--b-v3-divider-thickness: 1px;
|
|
4
|
+
|
|
5
|
+
flex-shrink: 0;
|
|
6
|
+
background-color: var(--color-border-neutral);
|
|
7
|
+
border-radius: var(--b-v3-divider-thickness);
|
|
8
|
+
|
|
9
|
+
&:where(.horizontal) {
|
|
10
|
+
width: calc(100% - 2 * var(--b-v3-divider-indent-size));
|
|
11
|
+
height: var(--b-v3-divider-thickness);
|
|
12
|
+
margin: var(--b-v3-divider-indent-size);
|
|
13
|
+
|
|
14
|
+
&:where(.without-indent) {
|
|
15
|
+
width: 100%;
|
|
16
|
+
margin: 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
&:where(.without-side-indent) {
|
|
20
|
+
width: 100%;
|
|
21
|
+
margin-right: 0;
|
|
22
|
+
margin-left: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
&:where(.without-parallel-indent) {
|
|
26
|
+
margin-top: 0;
|
|
27
|
+
margin-bottom: 0;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&:where(.vertical) {
|
|
32
|
+
width: var(--b-v3-divider-thickness);
|
|
33
|
+
height: calc(100% - 2 * var(--b-v3-divider-indent-size));
|
|
34
|
+
margin: var(--b-v3-divider-indent-size);
|
|
35
|
+
|
|
36
|
+
&:where(.without-indent) {
|
|
37
|
+
height: 100%;
|
|
38
|
+
margin: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&:where(.without-side-indent) {
|
|
42
|
+
height: 100%;
|
|
43
|
+
margin-top: 0;
|
|
44
|
+
margin-bottom: 0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
&:where(.without-parallel-indent) {
|
|
48
|
+
margin-right: 0;
|
|
49
|
+
margin-left: 0;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { Meta, StoryFn, StoryObj } from '@storybook/react'
|
|
2
|
+
|
|
3
|
+
import { Divider } from './Divider'
|
|
4
|
+
import { type DividerProps } from './Divider.types'
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
title: 'V3 components/Divider',
|
|
8
|
+
component: Divider,
|
|
9
|
+
argTypes: {
|
|
10
|
+
orientation: {
|
|
11
|
+
control: {
|
|
12
|
+
type: 'radio',
|
|
13
|
+
},
|
|
14
|
+
options: ['horizontal', 'vertical'],
|
|
15
|
+
},
|
|
16
|
+
withoutSideIndent: {
|
|
17
|
+
control: {
|
|
18
|
+
type: 'boolean',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
withoutParallelIndent: {
|
|
22
|
+
control: {
|
|
23
|
+
type: 'boolean',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
withoutIndent: {
|
|
27
|
+
control: {
|
|
28
|
+
type: 'boolean',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
} satisfies Meta<typeof Divider>
|
|
33
|
+
|
|
34
|
+
export default meta
|
|
35
|
+
|
|
36
|
+
const Template: StoryFn<DividerProps> = (props) => (
|
|
37
|
+
<div
|
|
38
|
+
style={{
|
|
39
|
+
display: 'flex',
|
|
40
|
+
alignItems: 'center',
|
|
41
|
+
justifyContent: 'center',
|
|
42
|
+
width: 200,
|
|
43
|
+
height: 200,
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
<Divider {...props} />
|
|
47
|
+
</div>
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
export const Primary: StoryObj<DividerProps> = {
|
|
51
|
+
render: Template,
|
|
52
|
+
|
|
53
|
+
args: {
|
|
54
|
+
orientation: 'horizontal',
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const Vertical: StoryObj<DividerProps> = {
|
|
59
|
+
render: Template,
|
|
60
|
+
|
|
61
|
+
args: {
|
|
62
|
+
orientation: 'vertical',
|
|
63
|
+
},
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const CompositionTemplate: StoryFn<DividerProps> = ({
|
|
67
|
+
orientation,
|
|
68
|
+
...rest
|
|
69
|
+
}) => (
|
|
70
|
+
<div
|
|
71
|
+
style={{
|
|
72
|
+
display: 'flex',
|
|
73
|
+
flexDirection: orientation === 'horizontal' ? 'column' : 'row',
|
|
74
|
+
alignItems: 'center',
|
|
75
|
+
justifyContent: 'center',
|
|
76
|
+
width: 200,
|
|
77
|
+
height: 200,
|
|
78
|
+
}}
|
|
79
|
+
>
|
|
80
|
+
<div>Channel</div>
|
|
81
|
+
<Divider
|
|
82
|
+
orientation={orientation}
|
|
83
|
+
{...rest}
|
|
84
|
+
/>
|
|
85
|
+
<div>Bezier</div>
|
|
86
|
+
</div>
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
export const Composition: StoryObj<DividerProps> = {
|
|
90
|
+
render: CompositionTemplate,
|
|
91
|
+
|
|
92
|
+
args: {
|
|
93
|
+
orientation: 'horizontal',
|
|
94
|
+
},
|
|
95
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { render } from '~/src/utils/test'
|
|
2
|
+
|
|
3
|
+
import { Divider } from './Divider'
|
|
4
|
+
import { type DividerProps } from './Divider.types'
|
|
5
|
+
|
|
6
|
+
import styles from './Divider.module.scss'
|
|
7
|
+
|
|
8
|
+
describe('Divider', () => {
|
|
9
|
+
const renderDivider = (props?: Partial<DividerProps>) =>
|
|
10
|
+
render(<Divider {...props} />)
|
|
11
|
+
|
|
12
|
+
it('should render default Divider', () => {
|
|
13
|
+
const { getByRole } = renderDivider()
|
|
14
|
+
const divider = getByRole('separator')
|
|
15
|
+
|
|
16
|
+
expect(divider).toHaveClass(styles.Divider)
|
|
17
|
+
expect(divider).toHaveClass(styles.horizontal)
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('should render vertical divider with aria-orientation attribute', () => {
|
|
21
|
+
const { getByRole } = renderDivider({ orientation: 'vertical' })
|
|
22
|
+
const divider = getByRole('separator')
|
|
23
|
+
|
|
24
|
+
expect(divider).toHaveClass(styles.vertical)
|
|
25
|
+
expect(divider).toHaveAttribute('aria-orientation', 'vertical')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('should receive indent styles', () => {
|
|
29
|
+
const { getByRole } = renderDivider({
|
|
30
|
+
withoutIndent: true,
|
|
31
|
+
withoutParallelIndent: true,
|
|
32
|
+
withoutSideIndent: true,
|
|
33
|
+
})
|
|
34
|
+
const divider = getByRole('separator')
|
|
35
|
+
|
|
36
|
+
expect(divider).toHaveClass(styles['without-indent'])
|
|
37
|
+
expect(divider).toHaveClass(styles['without-parallel-indent'])
|
|
38
|
+
expect(divider).toHaveClass(styles['without-side-indent'])
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('should not have aria attributes when decorative is true', () => {
|
|
42
|
+
const { getByRole } = renderDivider({ decorative: true })
|
|
43
|
+
const divider = getByRole('separator')
|
|
44
|
+
|
|
45
|
+
expect(divider).not.toHaveAttribute('aria-orientation')
|
|
46
|
+
})
|
|
47
|
+
})
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { forwardRef } from 'react'
|
|
4
|
+
|
|
5
|
+
import * as SeparatorPrimitive from '@radix-ui/react-separator'
|
|
6
|
+
import classNames from 'classnames'
|
|
7
|
+
|
|
8
|
+
import type { DividerProps } from './Divider.types'
|
|
9
|
+
|
|
10
|
+
import styles from './Divider.module.scss'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* `Divider` is a component to visually or semantically separate content.
|
|
14
|
+
* @example
|
|
15
|
+
*
|
|
16
|
+
* ```tsx
|
|
17
|
+
* <Divider
|
|
18
|
+
* withoutSideIndent
|
|
19
|
+
* />
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export const Divider = forwardRef<HTMLDivElement, DividerProps>(
|
|
23
|
+
(
|
|
24
|
+
{
|
|
25
|
+
orientation = 'horizontal',
|
|
26
|
+
decorative,
|
|
27
|
+
withoutSideIndent = false,
|
|
28
|
+
withoutParallelIndent = false,
|
|
29
|
+
withoutIndent = false,
|
|
30
|
+
style,
|
|
31
|
+
className,
|
|
32
|
+
...rest
|
|
33
|
+
},
|
|
34
|
+
forwardedRef
|
|
35
|
+
) => (
|
|
36
|
+
<SeparatorPrimitive.Root
|
|
37
|
+
asChild
|
|
38
|
+
orientation={orientation}
|
|
39
|
+
decorative={decorative}
|
|
40
|
+
>
|
|
41
|
+
<div
|
|
42
|
+
ref={forwardedRef}
|
|
43
|
+
style={style}
|
|
44
|
+
className={classNames(
|
|
45
|
+
styles.Divider,
|
|
46
|
+
styles[orientation],
|
|
47
|
+
withoutIndent && styles['without-indent'],
|
|
48
|
+
withoutParallelIndent && styles['without-parallel-indent'],
|
|
49
|
+
withoutSideIndent && styles['without-side-indent'],
|
|
50
|
+
className
|
|
51
|
+
)}
|
|
52
|
+
role="separator"
|
|
53
|
+
{...rest}
|
|
54
|
+
/>
|
|
55
|
+
</SeparatorPrimitive.Root>
|
|
56
|
+
)
|
|
57
|
+
)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { SeparatorProps as SeparatorPrimitiveProps } from '@radix-ui/react-separator'
|
|
2
|
+
|
|
3
|
+
import type { BezierComponentProps } from '~/src/types/props'
|
|
4
|
+
|
|
5
|
+
interface DividerOwnProps {
|
|
6
|
+
/**
|
|
7
|
+
* If true, the divider will be rendered without side padding,
|
|
8
|
+
* which stands for the padding on the left and right sides of the horizontal divider,
|
|
9
|
+
* and the top and bottom sides of the vertical divider.
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
withoutSideIndent?: boolean
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* If true, the divider will be rendered without parallel padding,
|
|
16
|
+
* which stands for the padding on the top and bottom sides of the horizontal divider,
|
|
17
|
+
* and the left and right sides of the vertical divider.
|
|
18
|
+
* @default false
|
|
19
|
+
*/
|
|
20
|
+
withoutParallelIndent?: boolean
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* If true, the divider will be rendered without padding,
|
|
24
|
+
* @default false
|
|
25
|
+
*/
|
|
26
|
+
withoutIndent?: boolean
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface DividerProps
|
|
30
|
+
extends BezierComponentProps<'div'>,
|
|
31
|
+
SeparatorPrimitiveProps,
|
|
32
|
+
DividerOwnProps {}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { type Meta, type StoryFn, type StoryObj } from '@storybook/react'
|
|
4
|
+
|
|
5
|
+
import { range } from '~/src/utils/number'
|
|
6
|
+
import { Box } from '~/src/v3/Box'
|
|
7
|
+
import { Text } from '~/src/v3/Text'
|
|
8
|
+
|
|
9
|
+
import { HStack } from './HStack'
|
|
10
|
+
|
|
11
|
+
const meta = {
|
|
12
|
+
title: 'V3 components/HStack',
|
|
13
|
+
component: HStack,
|
|
14
|
+
} satisfies Meta<typeof HStack>
|
|
15
|
+
|
|
16
|
+
type Story = StoryObj<typeof meta>
|
|
17
|
+
|
|
18
|
+
function DecorativeBox({ children }: React.PropsWithChildren<{}>) {
|
|
19
|
+
return (
|
|
20
|
+
<Box
|
|
21
|
+
width={50}
|
|
22
|
+
height={50}
|
|
23
|
+
backgroundColor="fill-neutral"
|
|
24
|
+
borderRadius="8"
|
|
25
|
+
borderWidth={1}
|
|
26
|
+
borderColor="border-neutral"
|
|
27
|
+
>
|
|
28
|
+
<Text>{children}</Text>
|
|
29
|
+
</Box>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const Template: StoryFn<typeof HStack> = (args) => (
|
|
34
|
+
<HStack
|
|
35
|
+
{...args}
|
|
36
|
+
borderColor="border-neutral"
|
|
37
|
+
borderWidth={1}
|
|
38
|
+
>
|
|
39
|
+
{range(4).map((i) => (
|
|
40
|
+
<DecorativeBox key={`item-${i}`}>{i + 1}</DecorativeBox>
|
|
41
|
+
))}
|
|
42
|
+
</HStack>
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
export const Primary: Story = {
|
|
46
|
+
render: Template,
|
|
47
|
+
args: {
|
|
48
|
+
justify: 'start',
|
|
49
|
+
align: 'start',
|
|
50
|
+
reverse: false,
|
|
51
|
+
wrap: true,
|
|
52
|
+
width: 300,
|
|
53
|
+
height: 300,
|
|
54
|
+
spacing: 6,
|
|
55
|
+
},
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export default meta
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { render } from '~/src/utils/test'
|
|
2
|
+
import styles from '~/src/v3/BaseStack/BaseStack.module.scss'
|
|
3
|
+
|
|
4
|
+
import { HStack } from './HStack'
|
|
5
|
+
|
|
6
|
+
describe('HStack', () => {
|
|
7
|
+
it('should render horizontal stack', () => {
|
|
8
|
+
const { getByText } = render(<HStack>Hello, Channel!</HStack>)
|
|
9
|
+
const rendered = getByText('Hello, Channel!')
|
|
10
|
+
|
|
11
|
+
expect(rendered).toHaveClass(styles.BaseStack)
|
|
12
|
+
expect(rendered).toHaveClass(styles['direction-horizontal'])
|
|
13
|
+
})
|
|
14
|
+
})
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { createElement, forwardRef } from 'react'
|
|
4
|
+
|
|
5
|
+
import { BaseStack } from '~/src/v3/BaseStack/BaseStack'
|
|
6
|
+
|
|
7
|
+
import type { HStackProps } from './HStack.types'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* `HStack` is a shorthand component equivalent to `Stack` with a horizontal direction property.
|
|
11
|
+
* @see BaseStack
|
|
12
|
+
*/
|
|
13
|
+
export const HStack = forwardRef<HTMLElement, HStackProps>(
|
|
14
|
+
function HStack(props, forwardedRef) {
|
|
15
|
+
return createElement(BaseStack, {
|
|
16
|
+
...props,
|
|
17
|
+
direction: 'horizontal',
|
|
18
|
+
ref: forwardedRef,
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { HStackProps } from '~/src/v3/BaseStack/BaseStack.types'
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
@use '../../styles/mixins/dimension';
|
|
2
|
+
|
|
3
|
+
$icon-sizes: '10', '12', '16', '20', '24', '36', '44';
|
|
4
|
+
|
|
5
|
+
.Icon {
|
|
6
|
+
--b-v3-icon-size: initial;
|
|
7
|
+
--b-v3-icon-color: initial;
|
|
8
|
+
|
|
9
|
+
@include dimension.square(var(--b-v3-icon-size));
|
|
10
|
+
|
|
11
|
+
flex: 0 0 auto;
|
|
12
|
+
color: var(--b-v3-icon-color);
|
|
13
|
+
transition: color var(--motion-transition-fast);
|
|
14
|
+
|
|
15
|
+
@each $size in $icon-sizes {
|
|
16
|
+
&:where(.size-#{$size}) {
|
|
17
|
+
--b-v3-icon-size: #{$size}px;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|