@sanity/ui 3.1.14 → 3.3.0
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/_chunks-cjs/_visual-editing.js +323 -292
- package/dist/_chunks-cjs/_visual-editing.js.map +1 -1
- package/dist/_chunks-es/_visual-editing.mjs +323 -292
- package/dist/_chunks-es/_visual-editing.mjs.map +1 -1
- package/dist/_visual-editing.d.mts +195 -76
- package/dist/_visual-editing.d.ts +195 -76
- package/dist/index.d.mts +308 -140
- package/dist/index.d.ts +308 -140
- package/dist/index.js +97 -93
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +97 -93
- package/dist/index.mjs.map +1 -1
- package/dist/theme.d.mts +10 -4
- package/dist/theme.d.ts +10 -4
- package/package.json +1 -1
- package/src/core/components/autocomplete/autocomplete.tsx +1 -1
- package/src/core/components/autocomplete/types.ts +2 -2
- package/src/core/components/breadcrumbs/breadcrumbs.test.tsx +51 -0
- package/src/core/components/breadcrumbs/breadcrumbs.tsx +7 -3
- package/src/core/components/hotkeys/hotkeys.test.tsx +42 -0
- package/src/core/components/hotkeys/hotkeys.tsx +7 -3
- package/src/core/components/menu/__workshop__/asComponent.tsx +1 -1
- package/src/core/components/menu/menu.spacing.test.tsx +63 -0
- package/src/core/components/menu/menu.tsx +8 -2
- package/src/core/components/menu/menuDivider.ts +16 -5
- package/src/core/components/menu/menuGroup.spacing.test.tsx +63 -0
- package/src/core/components/menu/menuGroup.tsx +22 -8
- package/src/core/components/menu/menuItem.spacing.test.tsx +59 -0
- package/src/core/components/menu/menuItem.tsx +25 -8
- package/src/core/components/skeleton/skeleton.tsx +2 -2
- package/src/core/components/tab/tabList.test.tsx +48 -0
- package/src/core/components/tab/tabList.tsx +2 -2
- package/src/core/components/tab/tabPanel.tsx +2 -2
- package/src/core/components/toast/styles.ts +2 -2
- package/src/core/components/tree/__workshop__/basic.perf.ts +1 -1
- package/src/core/components/tree/__workshop__/tabFromElement.tsx +1 -1
- package/src/core/components/tree/tree.test.tsx +55 -0
- package/src/core/components/tree/tree.tsx +19 -10
- package/src/core/components/tree/treeGroup.tsx +3 -3
- package/src/core/components/tree/treeItem.test.tsx +65 -0
- package/src/core/components/tree/treeItem.tsx +11 -4
- package/src/core/components/tree/types.ts +4 -0
- package/src/core/primitives/avatar/avatar.tsx +19 -11
- package/src/core/primitives/badge/badge.tsx +20 -12
- package/src/core/primitives/box/__workshop__/asComponent.tsx +31 -0
- package/src/core/primitives/box/__workshop__/index.ts +5 -0
- package/src/core/primitives/box/box.test.tsx +142 -0
- package/src/core/primitives/box/box.tsx +41 -18
- package/src/core/primitives/button/__workshop__/disabled.tsx +2 -2
- package/src/core/primitives/button/__workshop__/sanityUploadButton.tsx +1 -1
- package/src/core/primitives/button/__workshop__/uploadButton.tsx +1 -1
- package/src/core/primitives/button/button.test.tsx +41 -3
- package/src/core/primitives/button/button.tsx +36 -12
- package/src/core/primitives/card/__workshop__/asComponent.tsx +1 -1
- package/src/core/primitives/card/card.tsx +24 -13
- package/src/core/primitives/code/code.tsx +16 -7
- package/src/core/primitives/container/container.tsx +23 -10
- package/src/core/primitives/flex/flex.tsx +21 -11
- package/src/core/primitives/grid/grid.test.tsx +80 -0
- package/src/core/primitives/grid/grid.tsx +39 -13
- package/src/core/primitives/heading/heading.tsx +19 -11
- package/src/core/primitives/inline/inline.test.tsx +51 -0
- package/src/core/primitives/inline/inline.tsx +28 -12
- package/src/core/primitives/kbd/kbd.tsx +19 -11
- package/src/core/primitives/label/label.tsx +19 -11
- package/src/core/primitives/popover/__workshop__/SidePanelStory.tsx +1 -1
- package/src/core/primitives/select/select.test.tsx +52 -0
- package/src/core/primitives/select/select.tsx +8 -2
- package/src/core/primitives/stack/stack.test.tsx +57 -0
- package/src/core/primitives/stack/stack.tsx +27 -13
- package/src/core/primitives/text/text.tsx +19 -11
- package/src/core/primitives/textInput/textInput.test.tsx +48 -0
- package/src/core/primitives/textInput/textInput.tsx +9 -4
- package/src/core/primitives/types.ts +33 -0
- package/src/core/types/component.ts +32 -0
- package/src/core/types/index.ts +1 -0
- package/src/core/utils/virtualList/virtualList.tsx +2 -2
- package/src/theme/system/css.ts +10 -4
|
@@ -8,31 +8,32 @@ import {
|
|
|
8
8
|
responsiveFlexStyle,
|
|
9
9
|
ResponsiveFlexStyleProps,
|
|
10
10
|
} from '../../styles/internal'
|
|
11
|
-
import {
|
|
11
|
+
import {ElementType, Props} from '../../types'
|
|
12
|
+
import {Box, BoxOwnProps} from '../box'
|
|
12
13
|
import {ResponsiveFlexItemProps, ResponsiveFlexProps} from '../types'
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* @public
|
|
16
17
|
*/
|
|
17
|
-
export interface
|
|
18
|
-
extends Omit<
|
|
18
|
+
export interface FlexOwnProps
|
|
19
|
+
extends Omit<BoxOwnProps, 'display'>,
|
|
19
20
|
ResponsiveFlexProps,
|
|
20
21
|
ResponsiveFlexItemProps {
|
|
21
22
|
gap?: number | number[]
|
|
22
23
|
}
|
|
23
24
|
|
|
25
|
+
/**
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export type FlexProps<E extends ElementType = 'div'> = Props<FlexOwnProps, E>
|
|
29
|
+
|
|
24
30
|
const StyledFlex = styled(Box)<FlexItemStyleProps & ResponsiveFlexStyleProps>(
|
|
25
31
|
flexItemStyle,
|
|
26
32
|
responsiveFlexStyle,
|
|
27
33
|
)
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
*
|
|
32
|
-
* @public
|
|
33
|
-
*/
|
|
34
|
-
export const Flex = forwardRef(function Flex(
|
|
35
|
-
props: FlexProps & Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'wrap'>,
|
|
35
|
+
const FlexComponent = forwardRef(function Flex(
|
|
36
|
+
props: FlexOwnProps & {as?: ElementType} & Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'wrap'>,
|
|
36
37
|
ref: React.ForwardedRef<HTMLDivElement>,
|
|
37
38
|
) {
|
|
38
39
|
const {align, as, direction = 'row', gap, justify, wrap, ...restProps} = props
|
|
@@ -51,4 +52,13 @@ export const Flex = forwardRef(function Flex(
|
|
|
51
52
|
/>
|
|
52
53
|
)
|
|
53
54
|
})
|
|
54
|
-
|
|
55
|
+
FlexComponent.displayName = 'ForwardRef(Flex)'
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The `Flex` component is a wrapper component for flexible elements (`Box`, `Card` and `Flex`).
|
|
59
|
+
*
|
|
60
|
+
* @public
|
|
61
|
+
*/
|
|
62
|
+
export const Flex = FlexComponent as unknown as <E extends ElementType = 'div'>(
|
|
63
|
+
props: FlexProps<E>,
|
|
64
|
+
) => React.JSX.Element
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/** @jest-environment jsdom */
|
|
2
|
+
|
|
3
|
+
import {render} from '../../../../test'
|
|
4
|
+
import {responsiveGridStyle} from '../../styles/internal'
|
|
5
|
+
import {Grid} from './grid'
|
|
6
|
+
|
|
7
|
+
jest.mock('../../styles/internal', () => {
|
|
8
|
+
const actual = jest.requireActual('../../styles/internal')
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
...actual,
|
|
12
|
+
responsiveGridStyle: jest.fn(actual.responsiveGridStyle),
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
describe('primitives/grid', () => {
|
|
17
|
+
const mockedResponsiveGridStyle = jest.mocked(responsiveGridStyle)
|
|
18
|
+
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
mockedResponsiveGridStyle.mockClear()
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it('should support `columns` and `gridTemplateColumns` with the same behavior', () => {
|
|
24
|
+
render(
|
|
25
|
+
<Grid columns={2}>
|
|
26
|
+
<div>A</div>
|
|
27
|
+
</Grid>,
|
|
28
|
+
)
|
|
29
|
+
expect(mockedResponsiveGridStyle).toHaveBeenCalledWith(expect.objectContaining({$columns: [2]}))
|
|
30
|
+
|
|
31
|
+
mockedResponsiveGridStyle.mockClear()
|
|
32
|
+
render(
|
|
33
|
+
<Grid gridTemplateColumns={2}>
|
|
34
|
+
<div>A</div>
|
|
35
|
+
</Grid>,
|
|
36
|
+
)
|
|
37
|
+
expect(mockedResponsiveGridStyle).toHaveBeenCalledWith(expect.objectContaining({$columns: [2]}))
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('should prefer `gridTemplateColumns` over `columns` when both are provided', () => {
|
|
41
|
+
render(
|
|
42
|
+
<Grid columns={1} gridTemplateColumns={3}>
|
|
43
|
+
<div>A</div>
|
|
44
|
+
</Grid>,
|
|
45
|
+
)
|
|
46
|
+
expect(mockedResponsiveGridStyle).toHaveBeenCalledWith(expect.objectContaining({$columns: [3]}))
|
|
47
|
+
expect(mockedResponsiveGridStyle).not.toHaveBeenCalledWith(
|
|
48
|
+
expect.objectContaining({$columns: [1]}),
|
|
49
|
+
)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('should support `rows` and `gridTemplateRows` with the same behavior', () => {
|
|
53
|
+
render(
|
|
54
|
+
<Grid rows={2}>
|
|
55
|
+
<div>A</div>
|
|
56
|
+
</Grid>,
|
|
57
|
+
)
|
|
58
|
+
expect(mockedResponsiveGridStyle).toHaveBeenCalledWith(expect.objectContaining({$rows: [2]}))
|
|
59
|
+
|
|
60
|
+
mockedResponsiveGridStyle.mockClear()
|
|
61
|
+
render(
|
|
62
|
+
<Grid gridTemplateRows={2}>
|
|
63
|
+
<div>A</div>
|
|
64
|
+
</Grid>,
|
|
65
|
+
)
|
|
66
|
+
expect(mockedResponsiveGridStyle).toHaveBeenCalledWith(expect.objectContaining({$rows: [2]}))
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
it('should prefer `gridTemplateRows` over `rows` when both are provided', () => {
|
|
70
|
+
render(
|
|
71
|
+
<Grid gridTemplateRows={3} rows={1}>
|
|
72
|
+
<div>A</div>
|
|
73
|
+
</Grid>,
|
|
74
|
+
)
|
|
75
|
+
expect(mockedResponsiveGridStyle).toHaveBeenCalledWith(expect.objectContaining({$rows: [3]}))
|
|
76
|
+
expect(mockedResponsiveGridStyle).not.toHaveBeenCalledWith(
|
|
77
|
+
expect.objectContaining({$rows: [1]}),
|
|
78
|
+
)
|
|
79
|
+
})
|
|
80
|
+
})
|
|
@@ -3,27 +3,44 @@ import {styled} from 'styled-components'
|
|
|
3
3
|
|
|
4
4
|
import {_getArrayProp} from '../../styles'
|
|
5
5
|
import {responsiveGridStyle, ResponsiveGridStyleProps} from '../../styles/internal'
|
|
6
|
-
import {
|
|
6
|
+
import {ElementType, Props} from '../../types'
|
|
7
|
+
import {Box, BoxOwnProps} from '../box'
|
|
7
8
|
import {ResponsiveGridProps} from '../types'
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* @public
|
|
11
12
|
*/
|
|
12
|
-
export interface
|
|
13
|
-
|
|
14
|
-
const StyledGrid = styled(Box)<ResponsiveGridStyleProps>(responsiveGridStyle)
|
|
13
|
+
export interface GridOwnProps extends Omit<BoxOwnProps, 'display'>, ResponsiveGridProps {}
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
|
-
* The `Grid` component is for building 2-dimensional layers (based on CSS grid).
|
|
18
|
-
*
|
|
19
16
|
* @public
|
|
20
17
|
*/
|
|
21
|
-
export
|
|
22
|
-
|
|
18
|
+
export type GridProps<E extends ElementType = 'div'> = Props<GridOwnProps, E>
|
|
19
|
+
|
|
20
|
+
const StyledGrid = styled(Box)<ResponsiveGridStyleProps>(responsiveGridStyle)
|
|
21
|
+
|
|
22
|
+
const GridComponent = forwardRef(function Grid(
|
|
23
|
+
props: GridOwnProps & {as?: ElementType} & Omit<
|
|
24
|
+
React.HTMLProps<HTMLDivElement>,
|
|
25
|
+
'as' | 'height' | 'rows'
|
|
26
|
+
>,
|
|
23
27
|
ref: React.ForwardedRef<HTMLDivElement>,
|
|
24
28
|
) {
|
|
25
|
-
const {
|
|
26
|
-
|
|
29
|
+
const {
|
|
30
|
+
as,
|
|
31
|
+
autoRows,
|
|
32
|
+
autoCols,
|
|
33
|
+
autoFlow,
|
|
34
|
+
columns,
|
|
35
|
+
gridTemplateColumns,
|
|
36
|
+
gap,
|
|
37
|
+
gapX,
|
|
38
|
+
gapY,
|
|
39
|
+
rows,
|
|
40
|
+
gridTemplateRows,
|
|
41
|
+
children,
|
|
42
|
+
...restProps
|
|
43
|
+
} = props
|
|
27
44
|
|
|
28
45
|
return (
|
|
29
46
|
<StyledGrid
|
|
@@ -33,11 +50,11 @@ export const Grid = forwardRef(function Grid(
|
|
|
33
50
|
$autoRows={_getArrayProp(autoRows)}
|
|
34
51
|
$autoCols={_getArrayProp(autoCols)}
|
|
35
52
|
$autoFlow={_getArrayProp(autoFlow)}
|
|
36
|
-
$columns={_getArrayProp(columns)}
|
|
53
|
+
$columns={_getArrayProp(gridTemplateColumns === undefined ? columns : gridTemplateColumns)}
|
|
37
54
|
$gap={_getArrayProp(gap)}
|
|
38
55
|
$gapX={_getArrayProp(gapX)}
|
|
39
56
|
$gapY={_getArrayProp(gapY)}
|
|
40
|
-
$rows={_getArrayProp(rows)}
|
|
57
|
+
$rows={_getArrayProp(gridTemplateRows === undefined ? rows : gridTemplateRows)}
|
|
41
58
|
forwardedAs={as}
|
|
42
59
|
ref={ref}
|
|
43
60
|
>
|
|
@@ -45,4 +62,13 @@ export const Grid = forwardRef(function Grid(
|
|
|
45
62
|
</StyledGrid>
|
|
46
63
|
)
|
|
47
64
|
})
|
|
48
|
-
|
|
65
|
+
GridComponent.displayName = 'ForwardRef(Grid)'
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The `Grid` component is for building 2-dimensional layers (based on CSS grid).
|
|
69
|
+
*
|
|
70
|
+
* @public
|
|
71
|
+
*/
|
|
72
|
+
export const Grid = GridComponent as unknown as <E extends ElementType = 'div'>(
|
|
73
|
+
props: GridProps<E>,
|
|
74
|
+
) => React.JSX.Element
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
responsiveTextAlignStyle,
|
|
10
10
|
ResponsiveTextAlignStyleProps,
|
|
11
11
|
} from '../../styles/internal'
|
|
12
|
-
import {TextAlign} from '../../types'
|
|
12
|
+
import {ElementType, Props, TextAlign} from '../../types'
|
|
13
13
|
import {SpanWithTextOverflow} from '../../utils/spanWithTextOverflow'
|
|
14
14
|
import {headingBaseStyle} from './styles'
|
|
15
15
|
import {HeadingStyleProps} from './types'
|
|
@@ -17,10 +17,9 @@ import {HeadingStyleProps} from './types'
|
|
|
17
17
|
/**
|
|
18
18
|
* @public
|
|
19
19
|
*/
|
|
20
|
-
export interface
|
|
20
|
+
export interface HeadingOwnProps {
|
|
21
21
|
accent?: boolean
|
|
22
22
|
align?: TextAlign | TextAlign[]
|
|
23
|
-
as?: React.ElementType | keyof React.JSX.IntrinsicElements
|
|
24
23
|
muted?: boolean
|
|
25
24
|
size?: number | number[]
|
|
26
25
|
/**
|
|
@@ -32,17 +31,17 @@ export interface HeadingProps {
|
|
|
32
31
|
weight?: ThemeFontWeightKey
|
|
33
32
|
}
|
|
34
33
|
|
|
34
|
+
/**
|
|
35
|
+
* @public
|
|
36
|
+
*/
|
|
37
|
+
export type HeadingProps<E extends ElementType = 'div'> = Props<HeadingOwnProps, E>
|
|
38
|
+
|
|
35
39
|
const StyledHeading = styled.div<
|
|
36
40
|
HeadingStyleProps & ResponsiveTextAlignStyleProps & ResponsiveFontStyleProps
|
|
37
41
|
>(headingBaseStyle, responsiveTextAlignStyle, responsiveHeadingFont)
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
*
|
|
42
|
-
* @public
|
|
43
|
-
*/
|
|
44
|
-
export const Heading = forwardRef(function Heading(
|
|
45
|
-
props: HeadingProps & Omit<React.HTMLProps<HTMLElement>, 'as' | 'size'>,
|
|
43
|
+
const HeadingComponent = forwardRef(function Heading(
|
|
44
|
+
props: HeadingOwnProps & {as?: ElementType} & Omit<React.HTMLProps<HTMLElement>, 'as' | 'size'>,
|
|
46
45
|
ref: React.ForwardedRef<HTMLElement>,
|
|
47
46
|
) {
|
|
48
47
|
const {
|
|
@@ -77,4 +76,13 @@ export const Heading = forwardRef(function Heading(
|
|
|
77
76
|
</StyledHeading>
|
|
78
77
|
)
|
|
79
78
|
})
|
|
80
|
-
|
|
79
|
+
HeadingComponent.displayName = 'ForwardRef(Heading)'
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Typographic headings.
|
|
83
|
+
*
|
|
84
|
+
* @public
|
|
85
|
+
*/
|
|
86
|
+
export const Heading = HeadingComponent as unknown as <E extends ElementType = 'div'>(
|
|
87
|
+
props: HeadingProps<E>,
|
|
88
|
+
) => React.JSX.Element
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** @jest-environment jsdom */
|
|
2
|
+
|
|
3
|
+
import {render} from '../../../../test'
|
|
4
|
+
import {Inline} from './inline'
|
|
5
|
+
import {inlineSpaceStyle} from './styles'
|
|
6
|
+
|
|
7
|
+
jest.mock('./styles', () => {
|
|
8
|
+
const actual = jest.requireActual('./styles')
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
...actual,
|
|
12
|
+
inlineSpaceStyle: jest.fn(actual.inlineSpaceStyle),
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
describe('primitives/inline', () => {
|
|
17
|
+
const mockedInlineSpaceStyle = jest.mocked(inlineSpaceStyle)
|
|
18
|
+
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
mockedInlineSpaceStyle.mockClear()
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it('should support `space` and `gap` with the same behavior', () => {
|
|
24
|
+
render(
|
|
25
|
+
<Inline space={2}>
|
|
26
|
+
<span>One</span>
|
|
27
|
+
<span>Two</span>
|
|
28
|
+
</Inline>,
|
|
29
|
+
)
|
|
30
|
+
expect(mockedInlineSpaceStyle).toHaveBeenCalledWith(expect.objectContaining({$space: [2]}))
|
|
31
|
+
|
|
32
|
+
mockedInlineSpaceStyle.mockClear()
|
|
33
|
+
render(
|
|
34
|
+
<Inline gap={2}>
|
|
35
|
+
<span>One</span>
|
|
36
|
+
<span>Two</span>
|
|
37
|
+
</Inline>,
|
|
38
|
+
)
|
|
39
|
+
expect(mockedInlineSpaceStyle).toHaveBeenCalledWith(expect.objectContaining({$space: [2]}))
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('should prefer `gap` over `space` when both are provided', () => {
|
|
43
|
+
render(
|
|
44
|
+
<Inline gap={3} space={1}>
|
|
45
|
+
<span>One</span>
|
|
46
|
+
<span>Two</span>
|
|
47
|
+
</Inline>,
|
|
48
|
+
)
|
|
49
|
+
expect(mockedInlineSpaceStyle).toHaveBeenCalledWith(expect.objectContaining({$space: [3]}))
|
|
50
|
+
})
|
|
51
|
+
})
|
|
@@ -2,30 +2,37 @@ import {Children, forwardRef, useMemo} from 'react'
|
|
|
2
2
|
import {styled} from 'styled-components'
|
|
3
3
|
|
|
4
4
|
import {_getArrayProp} from '../../styles'
|
|
5
|
-
import {
|
|
5
|
+
import {ElementType, Props} from '../../types'
|
|
6
|
+
import {Box, BoxOwnProps} from '../box'
|
|
6
7
|
import {inlineBaseStyle, inlineSpaceStyle} from './styles'
|
|
7
8
|
import {ResponsiveInlineSpaceStyleProps} from './types'
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* @public
|
|
11
12
|
*/
|
|
12
|
-
export interface
|
|
13
|
-
/**
|
|
13
|
+
export interface InlineOwnProps extends Omit<BoxOwnProps, 'display'> {
|
|
14
|
+
/**
|
|
15
|
+
* The spacing between children.
|
|
16
|
+
* @deprecated Use `gap` instead. `space` will be removed in v4.
|
|
17
|
+
*/
|
|
14
18
|
space?: number | number[]
|
|
19
|
+
/** The spacing between children. */
|
|
20
|
+
gap?: number | number[]
|
|
15
21
|
}
|
|
16
22
|
|
|
17
|
-
const StyledInline = styled(Box)<ResponsiveInlineSpaceStyleProps>(inlineBaseStyle, inlineSpaceStyle)
|
|
18
|
-
|
|
19
23
|
/**
|
|
20
|
-
* The `Inline` component is a layout utility for aligning and spacing items horizontally.
|
|
21
|
-
*
|
|
22
24
|
* @public
|
|
23
25
|
*/
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
+
export type InlineProps<E extends ElementType = 'div'> = Props<InlineOwnProps, E>
|
|
27
|
+
|
|
28
|
+
const StyledInline = styled(Box)<ResponsiveInlineSpaceStyleProps>(inlineBaseStyle, inlineSpaceStyle)
|
|
29
|
+
|
|
30
|
+
const InlineComponent = forwardRef(function Inline(
|
|
31
|
+
props: InlineOwnProps & {as?: ElementType} & React.HTMLProps<HTMLDivElement>,
|
|
26
32
|
ref,
|
|
27
33
|
) {
|
|
28
|
-
const {as, children: childrenProp, space, ...restProps} = props
|
|
34
|
+
const {as, children: childrenProp, gap, space: deprecated_space, ...restProps} = props
|
|
35
|
+
const spacing = gap === undefined ? deprecated_space : gap
|
|
29
36
|
|
|
30
37
|
const children = useMemo(
|
|
31
38
|
() => Children.map(childrenProp, (child) => child && <div>{child}</div>),
|
|
@@ -36,7 +43,7 @@ export const Inline = forwardRef(function Inline(
|
|
|
36
43
|
<StyledInline
|
|
37
44
|
data-ui="Inline"
|
|
38
45
|
{...restProps}
|
|
39
|
-
$space={_getArrayProp(
|
|
46
|
+
$space={_getArrayProp(spacing)}
|
|
40
47
|
forwardedAs={as}
|
|
41
48
|
ref={ref as any}
|
|
42
49
|
>
|
|
@@ -44,4 +51,13 @@ export const Inline = forwardRef(function Inline(
|
|
|
44
51
|
</StyledInline>
|
|
45
52
|
)
|
|
46
53
|
})
|
|
47
|
-
|
|
54
|
+
InlineComponent.displayName = 'ForwardRef(Inline)'
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The `Inline` component is a layout utility for aligning and spacing items horizontally.
|
|
58
|
+
*
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
export const Inline = InlineComponent as unknown as <E extends ElementType = 'div'>(
|
|
62
|
+
props: InlineProps<E>,
|
|
63
|
+
) => React.JSX.Element
|
|
@@ -3,20 +3,24 @@ import {css, styled} from 'styled-components'
|
|
|
3
3
|
|
|
4
4
|
import {_getArrayProp} from '../../styles'
|
|
5
5
|
import {responsiveRadiusStyle, ResponsiveRadiusStyleProps} from '../../styles/internal'
|
|
6
|
-
import {Radius} from '../../types'
|
|
6
|
+
import {ElementType, Props, Radius} from '../../types'
|
|
7
7
|
import {Box} from '../box'
|
|
8
8
|
import {Text} from '../text'
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @public
|
|
12
12
|
*/
|
|
13
|
-
export interface
|
|
14
|
-
as?: React.ElementType | keyof React.JSX.IntrinsicElements
|
|
13
|
+
export interface KBDOwnProps {
|
|
15
14
|
fontSize?: number | number[]
|
|
16
15
|
padding?: number | number[]
|
|
17
16
|
radius?: Radius | Radius[]
|
|
18
17
|
}
|
|
19
18
|
|
|
19
|
+
/**
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export type KBDProps<E extends ElementType = 'kbd'> = Props<KBDOwnProps, E>
|
|
23
|
+
|
|
20
24
|
function kbdStyle() {
|
|
21
25
|
return css`
|
|
22
26
|
--card-bg-color: var(--card-kbd-bg-color);
|
|
@@ -37,13 +41,8 @@ function kbdStyle() {
|
|
|
37
41
|
|
|
38
42
|
const StyledKBD = styled.kbd<ResponsiveRadiusStyleProps>(responsiveRadiusStyle, kbdStyle)
|
|
39
43
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
*
|
|
43
|
-
* @public
|
|
44
|
-
*/
|
|
45
|
-
export const KBD = forwardRef(function KBD(
|
|
46
|
-
props: KBDProps & Omit<React.HTMLProps<HTMLElement>, 'as' | 'ref' | 'size'>,
|
|
44
|
+
const KBDComponent = forwardRef(function KBD(
|
|
45
|
+
props: KBDOwnProps & {as?: ElementType} & Omit<React.HTMLProps<HTMLElement>, 'as' | 'ref' | 'size'>,
|
|
47
46
|
ref: React.ForwardedRef<HTMLDivElement>,
|
|
48
47
|
) {
|
|
49
48
|
const {children, fontSize = 0, padding = 1, radius = 2, ...restProps} = props
|
|
@@ -58,4 +57,13 @@ export const KBD = forwardRef(function KBD(
|
|
|
58
57
|
</StyledKBD>
|
|
59
58
|
)
|
|
60
59
|
})
|
|
61
|
-
|
|
60
|
+
KBDComponent.displayName = 'ForwardRef(KBD)'
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Used to define some text as keyboard input.
|
|
64
|
+
*
|
|
65
|
+
* @public
|
|
66
|
+
*/
|
|
67
|
+
export const KBD = KBDComponent as unknown as <E extends ElementType = 'kbd'>(
|
|
68
|
+
props: KBDProps<E>,
|
|
69
|
+
) => React.JSX.Element
|
|
@@ -4,17 +4,16 @@ import {styled} from 'styled-components'
|
|
|
4
4
|
|
|
5
5
|
import {_getArrayProp} from '../../styles'
|
|
6
6
|
import {responsiveLabelFont, responsiveTextAlignStyle} from '../../styles/internal'
|
|
7
|
-
import {TextAlign} from '../../types'
|
|
7
|
+
import {ElementType, Props, TextAlign} from '../../types'
|
|
8
8
|
import {SpanWithTextOverflow} from '../../utils/spanWithTextOverflow'
|
|
9
9
|
import {labelBaseStyle} from './styles'
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @public
|
|
13
13
|
*/
|
|
14
|
-
export interface
|
|
14
|
+
export interface LabelOwnProps {
|
|
15
15
|
accent?: boolean
|
|
16
16
|
align?: TextAlign | TextAlign[]
|
|
17
|
-
as?: React.ElementType | keyof React.JSX.IntrinsicElements
|
|
18
17
|
muted?: boolean
|
|
19
18
|
size?: number | number[]
|
|
20
19
|
/**
|
|
@@ -26,6 +25,11 @@ export interface LabelProps {
|
|
|
26
25
|
weight?: ThemeFontWeightKey
|
|
27
26
|
}
|
|
28
27
|
|
|
28
|
+
/**
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
export type LabelProps<E extends ElementType = 'div'> = Props<LabelOwnProps, E>
|
|
32
|
+
|
|
29
33
|
const StyledLabel = styled.div<{
|
|
30
34
|
$accent?: boolean
|
|
31
35
|
$align: TextAlign[]
|
|
@@ -33,13 +37,8 @@ const StyledLabel = styled.div<{
|
|
|
33
37
|
$size: number[]
|
|
34
38
|
}>(responsiveLabelFont, responsiveTextAlignStyle, labelBaseStyle)
|
|
35
39
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
*
|
|
39
|
-
* @public
|
|
40
|
-
*/
|
|
41
|
-
export const Label = forwardRef(function Label(
|
|
42
|
-
props: LabelProps & Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'size'>,
|
|
40
|
+
const LabelComponent = forwardRef(function Label(
|
|
41
|
+
props: LabelOwnProps & {as?: ElementType} & Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'size'>,
|
|
43
42
|
ref: React.ForwardedRef<HTMLDivElement>,
|
|
44
43
|
) {
|
|
45
44
|
const {
|
|
@@ -76,4 +75,13 @@ export const Label = forwardRef(function Label(
|
|
|
76
75
|
</StyledLabel>
|
|
77
76
|
)
|
|
78
77
|
})
|
|
79
|
-
|
|
78
|
+
LabelComponent.displayName = 'ForwardRef(Label)'
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Typographic labels.
|
|
82
|
+
*
|
|
83
|
+
* @public
|
|
84
|
+
*/
|
|
85
|
+
export const Label = LabelComponent as unknown as <E extends ElementType = 'div'>(
|
|
86
|
+
props: LabelProps<E>,
|
|
87
|
+
) => React.JSX.Element
|
|
@@ -34,7 +34,7 @@ export default function SidePanelStory() {
|
|
|
34
34
|
</Box>
|
|
35
35
|
</Card>
|
|
36
36
|
<BoundaryElementProvider element={sidePanel}>
|
|
37
|
-
<Card borderLeft flex="none" ref={setSidePanel} style={{width: sidePanelWidth}}
|
|
37
|
+
<Card borderLeft flex="none" ref={setSidePanel} style={{width: sidePanelWidth}}>
|
|
38
38
|
<Stack padding={4} space={5}>
|
|
39
39
|
<Text muted size={1}>
|
|
40
40
|
Click the <code>reference</code> text below to toggle the popover.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** @jest-environment jsdom */
|
|
2
|
+
|
|
3
|
+
import {render} from '../../../../test'
|
|
4
|
+
import {Select} from './select'
|
|
5
|
+
import {selectStyle} from './styles'
|
|
6
|
+
|
|
7
|
+
jest.mock('./styles', () => {
|
|
8
|
+
const actual = jest.requireActual('./styles')
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
...actual,
|
|
12
|
+
selectStyle: {
|
|
13
|
+
...actual.selectStyle,
|
|
14
|
+
input: jest.fn(actual.selectStyle.input),
|
|
15
|
+
},
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
describe('primitives/select spacing', () => {
|
|
20
|
+
const mockedSelectInputStyle = jest.mocked(selectStyle.input)
|
|
21
|
+
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
mockedSelectInputStyle.mockClear()
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('should support `space` and `gap` with the same behavior', () => {
|
|
27
|
+
render(
|
|
28
|
+
<Select space={2}>
|
|
29
|
+
<option>Option A</option>
|
|
30
|
+
</Select>,
|
|
31
|
+
)
|
|
32
|
+
expect(mockedSelectInputStyle).toHaveBeenCalledWith(expect.objectContaining({$space: [2]}))
|
|
33
|
+
|
|
34
|
+
mockedSelectInputStyle.mockClear()
|
|
35
|
+
render(
|
|
36
|
+
<Select gap={2}>
|
|
37
|
+
<option>Option A</option>
|
|
38
|
+
</Select>,
|
|
39
|
+
)
|
|
40
|
+
expect(mockedSelectInputStyle).toHaveBeenCalledWith(expect.objectContaining({$space: [2]}))
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('should prefer `gap` over `space` when both are provided', () => {
|
|
44
|
+
render(
|
|
45
|
+
<Select gap={3} space={1}>
|
|
46
|
+
<option>Option A</option>
|
|
47
|
+
</Select>,
|
|
48
|
+
)
|
|
49
|
+
expect(mockedSelectInputStyle).toHaveBeenCalledWith(expect.objectContaining({$space: [3]}))
|
|
50
|
+
expect(mockedSelectInputStyle).not.toHaveBeenCalledWith(expect.objectContaining({$space: [1]}))
|
|
51
|
+
})
|
|
52
|
+
})
|
|
@@ -14,8 +14,12 @@ import {selectStyle} from './styles'
|
|
|
14
14
|
*/
|
|
15
15
|
export interface SelectProps {
|
|
16
16
|
fontSize?: number | number[]
|
|
17
|
+
gap?: number | number[]
|
|
17
18
|
padding?: number | number[]
|
|
18
19
|
radius?: Radius | Radius[]
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated Use `gap` instead. `space` will be removed in v4.
|
|
22
|
+
*/
|
|
19
23
|
space?: number | number[]
|
|
20
24
|
customValidity?: string
|
|
21
25
|
}
|
|
@@ -45,12 +49,14 @@ export const Select = forwardRef(function Select(
|
|
|
45
49
|
customValidity,
|
|
46
50
|
disabled,
|
|
47
51
|
fontSize = 2,
|
|
52
|
+
gap,
|
|
48
53
|
padding = 3,
|
|
49
54
|
radius = 2,
|
|
50
55
|
readOnly,
|
|
51
|
-
space = 3,
|
|
56
|
+
space: deprecated_space = 3,
|
|
52
57
|
...restProps
|
|
53
58
|
} = props
|
|
59
|
+
const spacing = gap === undefined ? deprecated_space : gap
|
|
54
60
|
|
|
55
61
|
const ref = useRef<HTMLSelectElement | null>(null)
|
|
56
62
|
|
|
@@ -70,7 +76,7 @@ export const Select = forwardRef(function Select(
|
|
|
70
76
|
$fontSize={_getArrayProp(fontSize)}
|
|
71
77
|
$padding={_getArrayProp(padding)}
|
|
72
78
|
$radius={_getArrayProp(radius)}
|
|
73
|
-
$space={_getArrayProp(
|
|
79
|
+
$space={_getArrayProp(spacing)}
|
|
74
80
|
disabled={disabled || readOnly}
|
|
75
81
|
ref={ref}
|
|
76
82
|
>
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** @jest-environment jsdom */
|
|
2
|
+
|
|
3
|
+
import {render} from '../../../../test'
|
|
4
|
+
import {Stack} from './stack'
|
|
5
|
+
import {responsiveStackSpaceStyle} from './styles'
|
|
6
|
+
|
|
7
|
+
jest.mock('./styles', () => {
|
|
8
|
+
const actual = jest.requireActual('./styles')
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
...actual,
|
|
12
|
+
responsiveStackSpaceStyle: jest.fn(actual.responsiveStackSpaceStyle),
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
describe('primitives/stack', () => {
|
|
17
|
+
const mockedResponsiveStackSpaceStyle = jest.mocked(responsiveStackSpaceStyle)
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
mockedResponsiveStackSpaceStyle.mockClear()
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('should support `space` and `gap` with the same behavior', () => {
|
|
23
|
+
render(
|
|
24
|
+
<Stack space={2}>
|
|
25
|
+
<span>One</span>
|
|
26
|
+
<span>Two</span>
|
|
27
|
+
</Stack>,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
expect(mockedResponsiveStackSpaceStyle).toHaveBeenCalledWith(
|
|
31
|
+
expect.objectContaining({$space: [2]}),
|
|
32
|
+
)
|
|
33
|
+
mockedResponsiveStackSpaceStyle.mockClear()
|
|
34
|
+
render(
|
|
35
|
+
<Stack gap={2}>
|
|
36
|
+
<span>One</span>
|
|
37
|
+
<span>Two</span>
|
|
38
|
+
</Stack>,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
expect(mockedResponsiveStackSpaceStyle).toHaveBeenCalledWith(
|
|
42
|
+
expect.objectContaining({$space: [2]}),
|
|
43
|
+
)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('should prefer `gap` over `space` when both are provided', () => {
|
|
47
|
+
render(
|
|
48
|
+
<Stack gap={3} space={1}>
|
|
49
|
+
<span>One</span>
|
|
50
|
+
<span>Two</span>
|
|
51
|
+
</Stack>,
|
|
52
|
+
)
|
|
53
|
+
expect(mockedResponsiveStackSpaceStyle).toHaveBeenCalledWith(
|
|
54
|
+
expect.objectContaining({$space: [3]}),
|
|
55
|
+
)
|
|
56
|
+
})
|
|
57
|
+
})
|