@sanity/ui 1.4.0 → 1.6.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/index.cjs.mjs +0 -2
- package/dist/index.d.ts +19 -34
- package/dist/index.esm.js +213 -189
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +211 -189
- package/dist/index.js.map +1 -1
- package/package.json +39 -39
- package/src/components/menu/__workshop__/menuButton.tsx +2 -0
- package/src/components/menu/menuButton.tsx +10 -0
- package/src/primitives/popover/__workshop__/AlignedStory.tsx +1 -0
- package/src/primitives/popover/__workshop__/SidePanelStory.tsx +86 -0
- package/src/primitives/popover/__workshop__/TestStory.tsx +30 -18
- package/src/primitives/popover/__workshop__/index.ts +3 -3
- package/src/primitives/popover/helpers.ts +32 -0
- package/src/primitives/popover/index.ts +0 -2
- package/src/primitives/popover/popover.tsx +124 -58
- package/src/primitives/popover/popoverCard.tsx +21 -50
- package/src/primitives/popover/types.ts +6 -8
- package/src/primitives/tooltip/tooltip.tsx +4 -4
- package/src/primitives/popover/__workshop__/PositionStory.tsx +0 -103
- package/src/primitives/popover/popover.test.tsx +0 -164
- package/src/primitives/popover/popoverContext.tsx +0 -9
- package/src/primitives/popover/popoverProvider.tsx +0 -29
- package/src/primitives/popover/useOnForcedUpdate.ts +0 -15
- package/src/primitives/popover/usePopover.ts +0 -24
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"source": "./src/index.ts",
|
|
@@ -49,46 +49,46 @@
|
|
|
49
49
|
"workshop:start": "http-server -a localhost -c-0 -p 1337 -s -P http://localhost:1337/index.html? dist"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@floating-ui/react-dom": "
|
|
53
|
-
"@sanity/color": "^2.2.
|
|
54
|
-
"@sanity/icons": "^2.
|
|
55
|
-
"csstype": "^3.1.
|
|
56
|
-
"framer-motion": "^10.
|
|
52
|
+
"@floating-ui/react-dom": "2.0.0",
|
|
53
|
+
"@sanity/color": "^2.2.5",
|
|
54
|
+
"@sanity/icons": "^2.3.1",
|
|
55
|
+
"csstype": "^3.1.2",
|
|
56
|
+
"framer-motion": "^10.12.16",
|
|
57
57
|
"react-refractor": "^2.1.7"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@babel/core": "^7.
|
|
61
|
-
"@babel/preset-env": "^7.
|
|
62
|
-
"@babel/preset-react": "^7.
|
|
63
|
-
"@babel/preset-typescript": "^7.
|
|
64
|
-
"@commitlint/cli": "^17.
|
|
65
|
-
"@commitlint/config-conventional": "^17.
|
|
60
|
+
"@babel/core": "^7.22.5",
|
|
61
|
+
"@babel/preset-env": "^7.22.5",
|
|
62
|
+
"@babel/preset-react": "^7.22.5",
|
|
63
|
+
"@babel/preset-typescript": "^7.22.5",
|
|
64
|
+
"@commitlint/cli": "^17.6.5",
|
|
65
|
+
"@commitlint/config-conventional": "^17.6.5",
|
|
66
66
|
"@juggle/resize-observer": "^3.4.0",
|
|
67
|
-
"@sanity/pkg-utils": "^2.2
|
|
68
|
-
"@sanity/semantic-release-preset": "^4.1.
|
|
67
|
+
"@sanity/pkg-utils": "^2.3.2",
|
|
68
|
+
"@sanity/semantic-release-preset": "^4.1.1",
|
|
69
69
|
"@sanity/ui-workshop": "^1.2.1",
|
|
70
|
-
"@testing-library/dom": "^9.
|
|
70
|
+
"@testing-library/dom": "^9.3.0",
|
|
71
71
|
"@testing-library/jest-dom": "^5.16.5",
|
|
72
72
|
"@testing-library/react": "^14.0.0",
|
|
73
|
-
"@types/jest": "^29.
|
|
73
|
+
"@types/jest": "^29.5.2",
|
|
74
74
|
"@types/jest-axe": "^3.5.5",
|
|
75
|
-
"@types/node": "^
|
|
76
|
-
"@types/react": "^18.
|
|
77
|
-
"@types/react-dom": "^18.
|
|
78
|
-
"@types/react-is": "^18.
|
|
75
|
+
"@types/node": "^20.2.5",
|
|
76
|
+
"@types/react": "^18.2.9",
|
|
77
|
+
"@types/react-dom": "^18.2.4",
|
|
78
|
+
"@types/react-is": "^18.2.0",
|
|
79
79
|
"@types/refractor": "^3.0.2",
|
|
80
80
|
"@types/styled-components": "^5.1.26",
|
|
81
|
-
"@types/testing-library__jest-dom": "^5.14.
|
|
82
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
83
|
-
"@typescript-eslint/parser": "^5.
|
|
81
|
+
"@types/testing-library__jest-dom": "^5.14.6",
|
|
82
|
+
"@typescript-eslint/eslint-plugin": "^5.59.9",
|
|
83
|
+
"@typescript-eslint/parser": "^5.59.9",
|
|
84
84
|
"commitizen": "^4.3.0",
|
|
85
|
-
"cypress": "^12.
|
|
86
|
-
"cypress-real-events": "^1.
|
|
85
|
+
"cypress": "^12.14.0",
|
|
86
|
+
"cypress-real-events": "^1.8.1",
|
|
87
87
|
"cz-conventional-changelog": "^3.3.0",
|
|
88
|
-
"esbuild": "^0.17.
|
|
88
|
+
"esbuild": "^0.17.19",
|
|
89
89
|
"esbuild-register": "^3.4.2",
|
|
90
|
-
"eslint": "^8.
|
|
91
|
-
"eslint-config-prettier": "^8.
|
|
90
|
+
"eslint": "^8.42.0",
|
|
91
|
+
"eslint-config-prettier": "^8.8.0",
|
|
92
92
|
"eslint-plugin-import": "^2.27.5",
|
|
93
93
|
"eslint-plugin-jsx-a11y": "^6.7.1",
|
|
94
94
|
"eslint-plugin-prettier": "^4.2.1",
|
|
@@ -96,22 +96,22 @@
|
|
|
96
96
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
97
97
|
"http-server": "^14.1.1",
|
|
98
98
|
"husky": "^8.0.3",
|
|
99
|
-
"jest": "^29.
|
|
100
|
-
"jest-axe": "^7.0.
|
|
101
|
-
"jest-environment-jsdom": "^29.
|
|
102
|
-
"lint-staged": "^13.
|
|
103
|
-
"module-alias": "^2.2.
|
|
99
|
+
"jest": "^29.5.0",
|
|
100
|
+
"jest-axe": "^7.0.1",
|
|
101
|
+
"jest-environment-jsdom": "^29.5.0",
|
|
102
|
+
"lint-staged": "^13.2.2",
|
|
103
|
+
"module-alias": "^2.2.3",
|
|
104
104
|
"npm-run-all": "^4.1.5",
|
|
105
|
-
"prettier": "^2.8.
|
|
105
|
+
"prettier": "^2.8.8",
|
|
106
106
|
"react": "^18.2.0",
|
|
107
107
|
"react-dom": "^18.2.0",
|
|
108
108
|
"react-is": "^18.2.0",
|
|
109
|
-
"rimraf": "^5.0.
|
|
110
|
-
"semantic-release": "^21.0.
|
|
109
|
+
"rimraf": "^5.0.1",
|
|
110
|
+
"semantic-release": "^21.0.3",
|
|
111
111
|
"start-server-and-test": "^2.0.0",
|
|
112
|
-
"styled-components": "^5.3.
|
|
113
|
-
"tsconfig-paths": "^4.
|
|
114
|
-
"typescript": "^5.
|
|
112
|
+
"styled-components": "^5.3.11",
|
|
113
|
+
"tsconfig-paths": "^4.2.0",
|
|
114
|
+
"typescript": "^5.1.3"
|
|
115
115
|
},
|
|
116
116
|
"peerDependencies": {
|
|
117
117
|
"react": "^18",
|
|
@@ -21,6 +21,7 @@ export interface MenuButtonProps {
|
|
|
21
21
|
id: string
|
|
22
22
|
menu?: React.ReactElement
|
|
23
23
|
onClose?: () => void
|
|
24
|
+
onOpen?: () => void
|
|
24
25
|
/**
|
|
25
26
|
* @deprecated Use `popover={{placement: 'top'}}` instead.
|
|
26
27
|
*/
|
|
@@ -59,6 +60,7 @@ export const MenuButton = forwardRef(function MenuButton(
|
|
|
59
60
|
id,
|
|
60
61
|
menu: menuProp,
|
|
61
62
|
onClose,
|
|
63
|
+
onOpen,
|
|
62
64
|
placement: deprecated_placement,
|
|
63
65
|
popoverScheme: deprecated_popoverScheme,
|
|
64
66
|
portal: deprecated_portal = true,
|
|
@@ -72,6 +74,14 @@ export const MenuButton = forwardRef(function MenuButton(
|
|
|
72
74
|
const [menuElements, setChildMenuElements] = useState<HTMLElement[]>([])
|
|
73
75
|
const openRef = useRef<boolean>(open)
|
|
74
76
|
|
|
77
|
+
// Notify consumers when the menu opens
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (onOpen && open && !openRef.current) {
|
|
80
|
+
onOpen()
|
|
81
|
+
}
|
|
82
|
+
}, [onOpen, open])
|
|
83
|
+
|
|
84
|
+
// Notify consumers when the menu closes
|
|
75
85
|
useEffect(() => {
|
|
76
86
|
if (onClose && !open && openRef.current) {
|
|
77
87
|
onClose()
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import {useSelect} from '@sanity/ui-workshop'
|
|
2
|
+
import {useCallback, useEffect, useRef, useState} from 'react'
|
|
3
|
+
import {BoundaryElementProvider} from '../../../utils'
|
|
4
|
+
import {Box} from '../../box'
|
|
5
|
+
import {Card} from '../../card'
|
|
6
|
+
import {Flex} from '../../flex'
|
|
7
|
+
import {Stack} from '../../stack'
|
|
8
|
+
import {Text} from '../../text'
|
|
9
|
+
import {Popover, PopoverProps, PopoverUpdateCallback} from '../popover'
|
|
10
|
+
|
|
11
|
+
const SIDE_PANEL_WIDTH = {
|
|
12
|
+
sm: 300,
|
|
13
|
+
md: 400,
|
|
14
|
+
lg: 500,
|
|
15
|
+
xl: 600,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default function SidePanelStory() {
|
|
19
|
+
const sidePanelWidth = useSelect('Side panel width', SIDE_PANEL_WIDTH, SIDE_PANEL_WIDTH.md)
|
|
20
|
+
const [sidePanel, setSidePanel] = useState<HTMLDivElement | null>(null)
|
|
21
|
+
const updateRef = useRef<PopoverUpdateCallback>()
|
|
22
|
+
|
|
23
|
+
useEffect(() => updateRef.current?.(), [sidePanelWidth])
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<Flex height="fill">
|
|
27
|
+
<Card flex={1}>
|
|
28
|
+
<Box padding={4}>
|
|
29
|
+
<Text>
|
|
30
|
+
This story shows that popovers respect their boundary when used in a side panel.
|
|
31
|
+
</Text>
|
|
32
|
+
</Box>
|
|
33
|
+
</Card>
|
|
34
|
+
<BoundaryElementProvider element={sidePanel}>
|
|
35
|
+
<Card borderLeft flex="none" ref={setSidePanel} style={{width: sidePanelWidth}} width={0}>
|
|
36
|
+
<Stack padding={4} space={5}>
|
|
37
|
+
<Text muted size={1}>
|
|
38
|
+
Click the <code>reference</code> text below to toggle the popover.
|
|
39
|
+
</Text>
|
|
40
|
+
|
|
41
|
+
<Card border padding={3}>
|
|
42
|
+
<Text size={1}>
|
|
43
|
+
Some editor <InlineObject updateRef={updateRef} />
|
|
44
|
+
</Text>
|
|
45
|
+
</Card>
|
|
46
|
+
</Stack>
|
|
47
|
+
</Card>
|
|
48
|
+
</BoundaryElementProvider>
|
|
49
|
+
</Flex>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function InlineObject(props: {updateRef?: PopoverProps['updateRef']}) {
|
|
54
|
+
const {updateRef} = props
|
|
55
|
+
const [open, setOpen] = useState(false)
|
|
56
|
+
|
|
57
|
+
const handleClick = useCallback(() => {
|
|
58
|
+
setOpen((prev) => !prev)
|
|
59
|
+
}, [])
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<Popover
|
|
63
|
+
content={
|
|
64
|
+
<Box padding={3}>
|
|
65
|
+
<Text size={1}>
|
|
66
|
+
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum
|
|
67
|
+
has been the industry's standard dummy text ever since the 1500s, when an unknown
|
|
68
|
+
printer took a galley of type and scrambled it to make a type specimen book. It has
|
|
69
|
+
survived not only five centuries, but also the leap into electronic typesetting,
|
|
70
|
+
remaining essentially unchanged. It was popularised in the 1960s with the release of
|
|
71
|
+
Letraset sheets containing Lorem Ipsum passages, and more recently with desktop
|
|
72
|
+
publishing software like Aldus PageMaker including versions of Lorem Ipsum.
|
|
73
|
+
</Text>
|
|
74
|
+
</Box>
|
|
75
|
+
}
|
|
76
|
+
constrainSize
|
|
77
|
+
open={open}
|
|
78
|
+
overflow="auto"
|
|
79
|
+
portal
|
|
80
|
+
width={0}
|
|
81
|
+
updateRef={updateRef}
|
|
82
|
+
>
|
|
83
|
+
<code onClick={handleClick}>reference</code>
|
|
84
|
+
</Popover>
|
|
85
|
+
)
|
|
86
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {useBoolean, useSelect, useText} from '@sanity/ui-workshop'
|
|
2
|
-
import {ReactElement, useState} from 'react'
|
|
1
|
+
import {useAction, useBoolean, useSelect, useText} from '@sanity/ui-workshop'
|
|
2
|
+
import {ReactElement, useRef, useState} from 'react'
|
|
3
3
|
import {
|
|
4
4
|
WORKSHOP_CONTAINER_WIDTH_OPTIONS,
|
|
5
5
|
WORKSHOP_PLACEMENT_OPTIONS,
|
|
@@ -10,10 +10,13 @@ import {Button} from '../../button'
|
|
|
10
10
|
import {Card} from '../../card'
|
|
11
11
|
import {Text} from '../../text'
|
|
12
12
|
import {Popover} from '../popover'
|
|
13
|
+
import {PopoverUpdateCallback} from '../types'
|
|
13
14
|
|
|
14
15
|
export default function TestStory(): ReactElement {
|
|
15
16
|
const [portalElement, setPortalElement] = useState<HTMLDivElement | null>(null)
|
|
16
17
|
const [boundaryElement, setBoundaryElement] = useState<HTMLDivElement | null>(null)
|
|
18
|
+
|
|
19
|
+
const mount = useBoolean('Mount', true)
|
|
17
20
|
const arrow = useBoolean('Arrow', true)
|
|
18
21
|
const constrainSize = useBoolean('Constrain size', true)
|
|
19
22
|
const matchReferenceWidth = useBoolean('Match reference width', false)
|
|
@@ -26,6 +29,10 @@ export default function TestStory(): ReactElement {
|
|
|
26
29
|
|
|
27
30
|
const text = useText('Text', 'Test')
|
|
28
31
|
|
|
32
|
+
const updateRef = useRef<PopoverUpdateCallback>()
|
|
33
|
+
|
|
34
|
+
const button = <Button text="reference" style={{width: referenceWide ? 300 : undefined}} />
|
|
35
|
+
|
|
29
36
|
return (
|
|
30
37
|
<Card
|
|
31
38
|
ref={setBoundaryElement}
|
|
@@ -56,22 +63,27 @@ export default function TestStory(): ReactElement {
|
|
|
56
63
|
<div style={{padding: '150vh'}}>
|
|
57
64
|
<PortalProvider element={portalElement}>
|
|
58
65
|
<BoundaryElementProvider element={boundaryElement}>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
66
|
+
{!mount && button}
|
|
67
|
+
{mount && (
|
|
68
|
+
<Popover
|
|
69
|
+
arrow={arrow}
|
|
70
|
+
content={<Text>{text}</Text>}
|
|
71
|
+
constrainSize={constrainSize}
|
|
72
|
+
fallbackPlacements={['left', 'bottom', 'right', 'top']}
|
|
73
|
+
matchReferenceWidth={matchReferenceWidth}
|
|
74
|
+
open={open}
|
|
75
|
+
overflow="hidden"
|
|
76
|
+
padding={3}
|
|
77
|
+
placement={placement}
|
|
78
|
+
portal
|
|
79
|
+
preventOverflow={preventOverflow}
|
|
80
|
+
radius={radius}
|
|
81
|
+
updateRef={updateRef}
|
|
82
|
+
width={width}
|
|
83
|
+
>
|
|
84
|
+
{button}
|
|
85
|
+
</Popover>
|
|
86
|
+
)}
|
|
75
87
|
</BoundaryElementProvider>
|
|
76
88
|
</PortalProvider>
|
|
77
89
|
</div>
|
|
@@ -41,9 +41,9 @@ export default defineScope({
|
|
|
41
41
|
component: lazy(() => import('./OpenOnMountStory')),
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
|
-
name: '
|
|
45
|
-
title: '
|
|
46
|
-
component: lazy(() => import('./
|
|
44
|
+
name: 'side-panel',
|
|
45
|
+
title: 'Side panel',
|
|
46
|
+
component: lazy(() => import('./SidePanelStory')),
|
|
47
47
|
},
|
|
48
48
|
],
|
|
49
49
|
})
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {Theme} from '../../theme'
|
|
2
|
+
import {DEFAULT_POPOVER_PADDING} from './constants'
|
|
3
|
+
import {PopoverWidth} from './types'
|
|
4
|
+
|
|
5
|
+
export function calcCurrentWidth(params: {
|
|
6
|
+
mediaIndex: number
|
|
7
|
+
theme: Theme
|
|
8
|
+
width: PopoverWidth[]
|
|
9
|
+
}): number | undefined {
|
|
10
|
+
const {mediaIndex, theme, width} = params
|
|
11
|
+
|
|
12
|
+
const w = width[mediaIndex]
|
|
13
|
+
const currentWidth: PopoverWidth | undefined = w === undefined ? width[width.length - 1] : w
|
|
14
|
+
|
|
15
|
+
return typeof currentWidth === 'number' ? theme.sanity.container[currentWidth] : undefined
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function calcMaxWidth(params: {
|
|
19
|
+
boundaryWidth: number | undefined
|
|
20
|
+
currentWidth: number | undefined
|
|
21
|
+
}): number | undefined {
|
|
22
|
+
const {boundaryWidth, currentWidth} = params
|
|
23
|
+
|
|
24
|
+
if (currentWidth === undefined && boundaryWidth === undefined) {
|
|
25
|
+
return undefined
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return Math.min(
|
|
29
|
+
currentWidth ?? Infinity,
|
|
30
|
+
(boundaryWidth || Infinity) - DEFAULT_POPOVER_PADDING * 2
|
|
31
|
+
)
|
|
32
|
+
}
|