@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
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
/** @jest-environment jsdom */
|
|
2
|
-
|
|
3
|
-
import {fireEvent, waitFor, screen} from '@testing-library/react'
|
|
4
|
-
import {startTransition, useCallback, useEffect, useMemo, useState} from 'react'
|
|
5
|
-
import {render} from '../../../test'
|
|
6
|
-
import {PopoverContext} from './popoverContext'
|
|
7
|
-
import {PopoverContextValue} from './types'
|
|
8
|
-
import {useOnForcedUpdate} from './useOnForcedUpdate'
|
|
9
|
-
import {usePopover} from './usePopover'
|
|
10
|
-
|
|
11
|
-
describe('components/toast', () => {
|
|
12
|
-
describe('usePopover', () => {
|
|
13
|
-
it('should get context value', async () => {
|
|
14
|
-
const log = jest.fn()
|
|
15
|
-
|
|
16
|
-
function Debug() {
|
|
17
|
-
const popover = usePopover()
|
|
18
|
-
|
|
19
|
-
log(popover)
|
|
20
|
-
|
|
21
|
-
return <>debug</>
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function Root() {
|
|
25
|
-
const value: PopoverContextValue = {
|
|
26
|
-
version: 0.0,
|
|
27
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
28
|
-
forceUpdate: () => {},
|
|
29
|
-
lastUpdateId: null,
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<PopoverContext.Provider value={value}>
|
|
34
|
-
<Debug />
|
|
35
|
-
</PopoverContext.Provider>
|
|
36
|
-
)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
render(<Root />)
|
|
40
|
-
|
|
41
|
-
expect(log.mock.calls[0][0].version).toBe(0.0)
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
it('should fail when no context value is provided', async () => {
|
|
45
|
-
const log = jest.fn()
|
|
46
|
-
|
|
47
|
-
function Debug() {
|
|
48
|
-
try {
|
|
49
|
-
usePopover()
|
|
50
|
-
} catch (err) {
|
|
51
|
-
log(err)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return null
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function Root() {
|
|
58
|
-
const value = undefined
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<PopoverContext.Provider value={value as any}>
|
|
62
|
-
<Debug />
|
|
63
|
-
</PopoverContext.Provider>
|
|
64
|
-
)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
render(<Root />)
|
|
68
|
-
|
|
69
|
-
expect(log.mock.calls[0][0].message).toEqual('usePopover(): missing context value')
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('should fail when context value is not compatible', async () => {
|
|
73
|
-
const log = jest.fn()
|
|
74
|
-
|
|
75
|
-
function Debug() {
|
|
76
|
-
try {
|
|
77
|
-
usePopover()
|
|
78
|
-
} catch (err) {
|
|
79
|
-
log(err)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return null
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function Root() {
|
|
86
|
-
// NOTE: we’re testing this because the context value may be a function in the future
|
|
87
|
-
const value = () => {
|
|
88
|
-
return {version: 1}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return (
|
|
92
|
-
<PopoverContext.Provider value={value as any}>
|
|
93
|
-
<Debug />
|
|
94
|
-
</PopoverContext.Provider>
|
|
95
|
-
)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
render(<Root />)
|
|
99
|
-
|
|
100
|
-
expect(log.mock.calls[0][0].message).toEqual(
|
|
101
|
-
'usePopover(): the context value is not compatible'
|
|
102
|
-
)
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
it('should trigger hook when forceUpdate is called', async () => {
|
|
106
|
-
const log = jest.fn()
|
|
107
|
-
const forcedCallback = jest.fn()
|
|
108
|
-
|
|
109
|
-
function Popover() {
|
|
110
|
-
useOnForcedUpdate(forcedCallback)
|
|
111
|
-
|
|
112
|
-
return null
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function Debug() {
|
|
116
|
-
const popover = usePopover()
|
|
117
|
-
|
|
118
|
-
useEffect(() => {
|
|
119
|
-
log(popover)
|
|
120
|
-
}, [popover])
|
|
121
|
-
|
|
122
|
-
const update = useCallback(() => {
|
|
123
|
-
popover.forceUpdate()
|
|
124
|
-
}, [popover])
|
|
125
|
-
|
|
126
|
-
return <button onClick={update}>Force position update</button>
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function Root() {
|
|
130
|
-
const [lastUpdateId, setLastUpdateId] = useState<string | null>(null)
|
|
131
|
-
const forceUpdate = useCallback(() => {
|
|
132
|
-
startTransition(() => {
|
|
133
|
-
setLastUpdateId('newid')
|
|
134
|
-
})
|
|
135
|
-
}, [])
|
|
136
|
-
const value: PopoverContextValue = useMemo(() => {
|
|
137
|
-
return {
|
|
138
|
-
version: 0.0,
|
|
139
|
-
forceUpdate,
|
|
140
|
-
lastUpdateId,
|
|
141
|
-
}
|
|
142
|
-
}, [forceUpdate, lastUpdateId])
|
|
143
|
-
|
|
144
|
-
return (
|
|
145
|
-
<PopoverContext.Provider value={value}>
|
|
146
|
-
<Debug />
|
|
147
|
-
<Popover />
|
|
148
|
-
</PopoverContext.Provider>
|
|
149
|
-
)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
render(<Root />)
|
|
153
|
-
|
|
154
|
-
fireEvent.click(screen.getByText('Force position update'))
|
|
155
|
-
|
|
156
|
-
await waitFor(() => {
|
|
157
|
-
expect(log).toHaveBeenCalledTimes(3)
|
|
158
|
-
expect(log.mock.calls[0][0].lastUpdateId).toBeNull()
|
|
159
|
-
expect(log.mock.calls[2][0].lastUpdateId).not.toBeNull()
|
|
160
|
-
expect(forcedCallback).toHaveBeenCalledTimes(1)
|
|
161
|
-
})
|
|
162
|
-
})
|
|
163
|
-
})
|
|
164
|
-
})
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import {createContext} from 'react'
|
|
2
|
-
import {globalScope} from '../../lib/globalScope'
|
|
3
|
-
import type {PopoverContextValue} from './types'
|
|
4
|
-
|
|
5
|
-
const key = Symbol.for('@sanity/ui/context/popover')
|
|
6
|
-
|
|
7
|
-
globalScope[key] = globalScope[key] || createContext<PopoverContextValue | null>(null)
|
|
8
|
-
|
|
9
|
-
export const PopoverContext: React.Context<PopoverContextValue | null> = globalScope[key]
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import React, {useState, useCallback, useMemo} from 'react'
|
|
2
|
-
import {PopoverContext} from './popoverContext'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @public
|
|
6
|
-
*/
|
|
7
|
-
export interface PopoverProviderProps {
|
|
8
|
-
children?: React.ReactNode
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @public
|
|
13
|
-
*/
|
|
14
|
-
export const PopoverProvider = ({children}: PopoverProviderProps): React.ReactElement => {
|
|
15
|
-
const [lastUpdateId, setUpdateId] = useState<string | null>(null)
|
|
16
|
-
|
|
17
|
-
const forceUpdate = useCallback(() => {
|
|
18
|
-
// Generate a new random ID
|
|
19
|
-
const newId = Math.random().toString(36).substr(2, 9)
|
|
20
|
-
setUpdateId(newId)
|
|
21
|
-
}, [])
|
|
22
|
-
|
|
23
|
-
const value = useMemo(
|
|
24
|
-
() => ({version: 0.0, lastUpdateId, forceUpdate}),
|
|
25
|
-
[lastUpdateId, forceUpdate]
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
return <PopoverContext.Provider value={value}>{children}</PopoverContext.Provider>
|
|
29
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import {useContext, useEffect} from 'react'
|
|
2
|
-
import {PopoverContext} from './popoverContext'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @public
|
|
6
|
-
*/
|
|
7
|
-
export const useOnForcedUpdate = (eventHandler: () => void): void => {
|
|
8
|
-
const contextValue = useContext(PopoverContext)
|
|
9
|
-
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
if (contextValue?.lastUpdateId !== null) {
|
|
12
|
-
eventHandler?.()
|
|
13
|
-
}
|
|
14
|
-
}, [contextValue?.lastUpdateId])
|
|
15
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import {useContext} from 'react'
|
|
2
|
-
import {isRecord} from '../../lib/isRecord'
|
|
3
|
-
import {PopoverContext} from './popoverContext'
|
|
4
|
-
import type {PopoverContextValue} from './types'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @public
|
|
8
|
-
*/
|
|
9
|
-
export function usePopover(): PopoverContextValue {
|
|
10
|
-
const value = useContext(PopoverContext)
|
|
11
|
-
|
|
12
|
-
if (!value) {
|
|
13
|
-
throw new Error('usePopover(): missing context value')
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// NOTE: This check is for future-compatiblity
|
|
17
|
-
// - If the value is not an object, it’s not compatible with the current version
|
|
18
|
-
// - If the value is an object, but doesn’t have `version: 0.0`, it’s not compatible with the current version
|
|
19
|
-
if (!isRecord(value) || value.version !== 0.0) {
|
|
20
|
-
throw new Error('usePopover(): the context value is not compatible')
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return value
|
|
24
|
-
}
|