@sanity/ui 0.37.14 → 0.37.17

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/ui",
3
- "version": "0.37.14",
3
+ "version": "0.37.17",
4
4
  "sideEffects": false,
5
5
  "source": "./src/index.ts",
6
6
  "exports": {
@@ -72,5 +72,5 @@
72
72
  "publishConfig": {
73
73
  "access": "public"
74
74
  },
75
- "gitHead": "7e3169ea708addc044669028bc627c00318a1236"
75
+ "gitHead": "8a8dde772a715b8349b199f8e89c27b709cfe51a"
76
76
  }
@@ -24,7 +24,7 @@ export function dialogStyle({theme}: ThemeProps): CSSObject {
24
24
  alignItems: 'center',
25
25
  justifyContent: 'center',
26
26
  outline: 'none',
27
- background: color.shadow.penumbra,
27
+ background: color.shadow.umbra,
28
28
  }
29
29
  }
30
30
 
@@ -1,4 +1,12 @@
1
- import React, {cloneElement, forwardRef, useCallback, useEffect, useMemo, useState} from 'react'
1
+ import React, {
2
+ cloneElement,
3
+ forwardRef,
4
+ useCallback,
5
+ useEffect,
6
+ useMemo,
7
+ useRef,
8
+ useState,
9
+ } from 'react'
2
10
  import {usePopper} from 'react-popper'
3
11
  import styled, {css} from 'styled-components'
4
12
  import {EMPTY_RECORD} from '../../constants'
@@ -137,7 +145,7 @@ export const Popover = forwardRef(function Popover(
137
145
  const [popperElement, setPopperElement] = useState<HTMLElement | null>(null)
138
146
  const [arrowElement, setArrowElement] = useState<HTMLElement | null>(null)
139
147
  const popperReferenceElement = referenceElementProp || referenceElement
140
- const width = useArrayProp(widthProp)
148
+ const width = useArrayProp(matchReferenceWidth ? 'auto' : widthProp)
141
149
 
142
150
  const modifiers = usePopoverModifiers({
143
151
  allowedAutoPlacements,
@@ -188,14 +196,23 @@ export const Popover = forwardRef(function Popover(
188
196
 
189
197
  const popoverStyle = useMemo(() => ({...style, ...styles.popper}), [style, styles])
190
198
 
199
+ const updateTimeoutRef = useRef<NodeJS.Timeout | null>(null)
200
+
191
201
  useEffect(() => {
192
- if (forceUpdate) {
193
- try {
194
- forceUpdate()
195
- } catch (_) {
196
- // ignore caught error
197
- }
202
+ if (updateTimeoutRef.current) {
203
+ clearTimeout(updateTimeoutRef.current)
204
+ updateTimeoutRef.current = null
198
205
  }
206
+
207
+ updateTimeoutRef.current = setTimeout(() => {
208
+ if (forceUpdate) {
209
+ try {
210
+ forceUpdate()
211
+ } catch (_) {
212
+ // ignore caught error
213
+ }
214
+ }
215
+ }, 0)
199
216
  }, [content, forceUpdate, open, popperReferenceElement])
200
217
 
201
218
  if (disabled) {
@@ -80,6 +80,7 @@ export const TextArea = forwardRef(function TextArea(
80
80
  {...restProps}
81
81
  $fontSize={useArrayProp(fontSize)}
82
82
  $padding={useArrayProp(padding)}
83
+ $scheme={rootTheme.scheme}
83
84
  $space={useArrayProp(0)}
84
85
  $tone={rootTheme.tone}
85
86
  $weight={weight}
@@ -89,6 +90,7 @@ export const TextArea = forwardRef(function TextArea(
89
90
  <Presentation
90
91
  $border={border}
91
92
  $radius={useArrayProp(radius)}
93
+ $scheme={rootTheme.scheme}
92
94
  $tone={rootTheme.tone}
93
95
  data-tone={rootTheme.tone}
94
96
  />
@@ -1,4 +1,4 @@
1
- import {Box, Card, Container, Stack, Text, TextInput} from '@sanity/ui'
1
+ import {Box, Card, Container, Flex, Stack, Text, TextInput} from '@sanity/ui'
2
2
  import {useBoolean} from '@sanity/ui-workshop'
3
3
  import React from 'react'
4
4
 
@@ -10,114 +10,231 @@ export default function TonesStory() {
10
10
  const criticalTone = useBoolean('Critical', true)
11
11
 
12
12
  return (
13
- <Container width={1}>
14
- <Stack padding={[3, 4, 5]} space={4}>
15
- <Card padding={3}>
16
- <TextInput
17
- placeholder="default"
18
- prefix={
19
- <Box padding={3}>
20
- <Text>prefix</Text>
21
- </Box>
22
- }
23
- suffix={
24
- <Box padding={3}>
25
- <Text>suffix</Text>
26
- </Box>
27
- }
28
- />
29
- </Card>
13
+ <Card height="fill" tone="transparent">
14
+ <Flex align="center" height="fill" justify="center">
15
+ <Container width={1}>
16
+ <Flex>
17
+ <Card flex={1} scheme="light">
18
+ <Stack padding={[3, 4, 5]} space={4}>
19
+ <Card padding={3}>
20
+ <TextInput
21
+ placeholder="default"
22
+ prefix={
23
+ <Box padding={3}>
24
+ <Text>prefix</Text>
25
+ </Box>
26
+ }
27
+ suffix={
28
+ <Box padding={3}>
29
+ <Text>suffix</Text>
30
+ </Box>
31
+ }
32
+ />
33
+ </Card>
30
34
 
31
- {transparentTone && (
32
- <Card padding={3} tone="transparent">
33
- <TextInput
34
- placeholder="transparent"
35
- prefix={
36
- <Box padding={3}>
37
- <Text>prefix</Text>
38
- </Box>
39
- }
40
- suffix={
41
- <Box padding={3}>
42
- <Text>suffix</Text>
43
- </Box>
44
- }
45
- />
46
- </Card>
47
- )}
35
+ {transparentTone && (
36
+ <Card padding={3} tone="transparent">
37
+ <TextInput
38
+ placeholder="transparent"
39
+ prefix={
40
+ <Box padding={3}>
41
+ <Text>prefix</Text>
42
+ </Box>
43
+ }
44
+ suffix={
45
+ <Box padding={3}>
46
+ <Text>suffix</Text>
47
+ </Box>
48
+ }
49
+ />
50
+ </Card>
51
+ )}
48
52
 
49
- {primaryTone && (
50
- <Card padding={3} tone="primary">
51
- <TextInput
52
- placeholder="primary"
53
- prefix={
54
- <Box padding={3}>
55
- <Text>prefix</Text>
56
- </Box>
57
- }
58
- suffix={
59
- <Box padding={3}>
60
- <Text>suffix</Text>
61
- </Box>
62
- }
63
- />
64
- </Card>
65
- )}
53
+ {primaryTone && (
54
+ <Card padding={3} tone="primary">
55
+ <TextInput
56
+ placeholder="primary"
57
+ prefix={
58
+ <Box padding={3}>
59
+ <Text>prefix</Text>
60
+ </Box>
61
+ }
62
+ suffix={
63
+ <Box padding={3}>
64
+ <Text>suffix</Text>
65
+ </Box>
66
+ }
67
+ />
68
+ </Card>
69
+ )}
66
70
 
67
- {positiveTone && (
68
- <Card padding={3} tone="positive">
69
- <TextInput
70
- placeholder="positive"
71
- prefix={
72
- <Box padding={3}>
73
- <Text>prefix</Text>
74
- </Box>
75
- }
76
- suffix={
77
- <Box padding={3}>
78
- <Text>suffix</Text>
79
- </Box>
80
- }
81
- />
82
- </Card>
83
- )}
71
+ {positiveTone && (
72
+ <Card padding={3} tone="positive">
73
+ <TextInput
74
+ placeholder="positive"
75
+ prefix={
76
+ <Box padding={3}>
77
+ <Text>prefix</Text>
78
+ </Box>
79
+ }
80
+ suffix={
81
+ <Box padding={3}>
82
+ <Text>suffix</Text>
83
+ </Box>
84
+ }
85
+ />
86
+ </Card>
87
+ )}
84
88
 
85
- {cautionTone && (
86
- <Card padding={3} tone="caution">
87
- <TextInput
88
- placeholder="caution"
89
- prefix={
90
- <Box padding={3}>
91
- <Text>prefix</Text>
92
- </Box>
93
- }
94
- suffix={
95
- <Box padding={3}>
96
- <Text>suffix</Text>
97
- </Box>
98
- }
99
- />
100
- </Card>
101
- )}
89
+ {cautionTone && (
90
+ <Card padding={3} tone="caution">
91
+ <TextInput
92
+ placeholder="caution"
93
+ prefix={
94
+ <Box padding={3}>
95
+ <Text>prefix</Text>
96
+ </Box>
97
+ }
98
+ suffix={
99
+ <Box padding={3}>
100
+ <Text>suffix</Text>
101
+ </Box>
102
+ }
103
+ />
104
+ </Card>
105
+ )}
102
106
 
103
- {criticalTone && (
104
- <Card padding={3} tone="critical">
105
- <TextInput
106
- placeholder="critical"
107
- prefix={
108
- <Box padding={3}>
109
- <Text>prefix</Text>
110
- </Box>
111
- }
112
- suffix={
113
- <Box padding={3}>
114
- <Text>suffix</Text>
115
- </Box>
116
- }
117
- />
118
- </Card>
119
- )}
120
- </Stack>
121
- </Container>
107
+ {criticalTone && (
108
+ <Card padding={3} tone="critical">
109
+ <TextInput
110
+ placeholder="critical"
111
+ prefix={
112
+ <Box padding={3}>
113
+ <Text>prefix</Text>
114
+ </Box>
115
+ }
116
+ suffix={
117
+ <Box padding={3}>
118
+ <Text>suffix</Text>
119
+ </Box>
120
+ }
121
+ />
122
+ </Card>
123
+ )}
124
+ </Stack>
125
+ </Card>
126
+ <Card flex={1} scheme="dark">
127
+ <Stack padding={[3, 4, 5]} space={4}>
128
+ <Card padding={3}>
129
+ <TextInput
130
+ placeholder="default"
131
+ prefix={
132
+ <Box padding={3}>
133
+ <Text>prefix</Text>
134
+ </Box>
135
+ }
136
+ suffix={
137
+ <Box padding={3}>
138
+ <Text>suffix</Text>
139
+ </Box>
140
+ }
141
+ />
142
+ </Card>
143
+
144
+ {transparentTone && (
145
+ <Card padding={3} tone="transparent">
146
+ <TextInput
147
+ placeholder="transparent"
148
+ prefix={
149
+ <Box padding={3}>
150
+ <Text>prefix</Text>
151
+ </Box>
152
+ }
153
+ suffix={
154
+ <Box padding={3}>
155
+ <Text>suffix</Text>
156
+ </Box>
157
+ }
158
+ />
159
+ </Card>
160
+ )}
161
+
162
+ {primaryTone && (
163
+ <Card padding={3} tone="primary">
164
+ <TextInput
165
+ placeholder="primary"
166
+ prefix={
167
+ <Box padding={3}>
168
+ <Text>prefix</Text>
169
+ </Box>
170
+ }
171
+ suffix={
172
+ <Box padding={3}>
173
+ <Text>suffix</Text>
174
+ </Box>
175
+ }
176
+ />
177
+ </Card>
178
+ )}
179
+
180
+ {positiveTone && (
181
+ <Card padding={3} tone="positive">
182
+ <TextInput
183
+ placeholder="positive"
184
+ prefix={
185
+ <Box padding={3}>
186
+ <Text>prefix</Text>
187
+ </Box>
188
+ }
189
+ suffix={
190
+ <Box padding={3}>
191
+ <Text>suffix</Text>
192
+ </Box>
193
+ }
194
+ />
195
+ </Card>
196
+ )}
197
+
198
+ {cautionTone && (
199
+ <Card padding={3} tone="caution">
200
+ <TextInput
201
+ placeholder="caution"
202
+ prefix={
203
+ <Box padding={3}>
204
+ <Text>prefix</Text>
205
+ </Box>
206
+ }
207
+ suffix={
208
+ <Box padding={3}>
209
+ <Text>suffix</Text>
210
+ </Box>
211
+ }
212
+ />
213
+ </Card>
214
+ )}
215
+
216
+ {criticalTone && (
217
+ <Card padding={3} tone="critical">
218
+ <TextInput
219
+ placeholder="critical"
220
+ prefix={
221
+ <Box padding={3}>
222
+ <Text>prefix</Text>
223
+ </Box>
224
+ }
225
+ suffix={
226
+ <Box padding={3}>
227
+ <Text>suffix</Text>
228
+ </Box>
229
+ }
230
+ />
231
+ </Card>
232
+ )}
233
+ </Stack>
234
+ </Card>
235
+ </Flex>
236
+ </Container>
237
+ </Flex>
238
+ </Card>
122
239
  )
123
240
  }
@@ -214,7 +214,9 @@ export const TextInput = forwardRef(function TextInput(
214
214
  $hasPrefix={$hasPrefix}
215
215
  $hasSuffix={$hasSuffix}
216
216
  $radius={radius}
217
+ $scheme={rootTheme.scheme}
217
218
  $tone={rootTheme.tone}
219
+ data-scheme={rootTheme.scheme}
218
220
  data-tone={rootTheme.tone}
219
221
  >
220
222
  {icon && (
@@ -243,7 +245,7 @@ export const TextInput = forwardRef(function TextInput(
243
245
  iconRight,
244
246
  padding,
245
247
  radius,
246
- rootTheme.tone,
248
+ rootTheme,
247
249
  $hasClearButton,
248
250
  $hasPrefix,
249
251
  $hasSuffix,
@@ -334,12 +336,14 @@ export const TextInput = forwardRef(function TextInput(
334
336
  <InputRoot>
335
337
  <Input
336
338
  data-as="input"
339
+ data-scheme={rootTheme.scheme}
337
340
  data-tone={rootTheme.tone}
338
341
  {...restProps}
339
342
  $fontSize={fontSize}
340
343
  $iconLeft={$hasIcon}
341
344
  $iconRight={$hasIconRight || $hasClearButton}
342
345
  $padding={padding}
346
+ $scheme={rootTheme.scheme}
343
347
  $space={space}
344
348
  $tone={rootTheme.tone}
345
349
  $weight={weight}
@@ -1,9 +1,10 @@
1
1
  import {Box, Button, Card, Flex, Text, Tooltip} from '@sanity/ui'
2
- import {useSelect} from '@sanity/ui-workshop'
2
+ import {useSelect, useText} from '@sanity/ui-workshop'
3
3
  import React from 'react'
4
4
  import {WORKSHOP_PLACEMENT_OPTIONS} from '../../../__workshop__/constants'
5
5
 
6
6
  export default function PropsStory() {
7
+ const content = useText('Content', 'Tooltip content')
7
8
  const placement = useSelect('Placement', WORKSHOP_PLACEMENT_OPTIONS, 'top')
8
9
 
9
10
  return (
@@ -12,7 +13,7 @@ export default function PropsStory() {
12
13
  <Tooltip
13
14
  content={
14
15
  <Box padding={2}>
15
- <Text size={1}>Tooltip content</Text>
16
+ <Text size={1}>{content}</Text>
16
17
  </Box>
17
18
  }
18
19
  placement={placement}
@@ -1,4 +1,4 @@
1
- import React, {cloneElement, forwardRef, useCallback, useEffect, useState} from 'react'
1
+ import React, {cloneElement, forwardRef, useCallback, useEffect, useRef, useState} from 'react'
2
2
  import {usePopper} from 'react-popper'
3
3
  import styled from 'styled-components'
4
4
  import {useArrayProp, useForwardedRef} from '../../hooks'
@@ -118,14 +118,23 @@ export const Tooltip = forwardRef(function Tooltip(
118
118
  }
119
119
  }, [isOpen, referenceElement])
120
120
 
121
+ const updateTimeoutRef = useRef<NodeJS.Timeout | null>(null)
122
+
121
123
  useEffect(() => {
122
- if (forceUpdate) {
123
- try {
124
- forceUpdate()
125
- } catch (_) {
126
- // ignore caught error
127
- }
124
+ if (updateTimeoutRef.current) {
125
+ clearTimeout(updateTimeoutRef.current)
126
+ updateTimeoutRef.current = null
128
127
  }
128
+
129
+ updateTimeoutRef.current = setTimeout(() => {
130
+ if (forceUpdate) {
131
+ try {
132
+ forceUpdate()
133
+ } catch (_) {
134
+ // ignore caught error
135
+ }
136
+ }
137
+ }, 0)
129
138
  }, [forceUpdate, content])
130
139
 
131
140
  // Close when `disabled` changes to `true`
@@ -1,5 +1,5 @@
1
1
  import {css, CSSObject, FlattenSimpleInterpolation} from 'styled-components'
2
- import {ThemeFontWeightKey} from '../../theme'
2
+ import {ThemeColorSchemeKey, ThemeFontWeightKey} from '../../theme'
3
3
  import {CardTone} from '../../types'
4
4
  import {focusRingBorderStyle, focusRingStyle} from '../focusRing'
5
5
  import {rem, _responsive} from '../helpers'
@@ -10,6 +10,7 @@ import {ThemeProps} from '../types'
10
10
  */
11
11
  export interface TextInputInputStyleProps {
12
12
  $fontSize: number[]
13
+ $scheme: ThemeColorSchemeKey
13
14
  $tone: CardTone
14
15
  $weight?: ThemeFontWeightKey
15
16
  }
@@ -21,6 +22,7 @@ export interface TextInputRepresentationStyleProps {
21
22
  $border?: boolean
22
23
  $hasPrefix?: boolean
23
24
  $hasSuffix?: boolean
25
+ $scheme: ThemeColorSchemeKey
24
26
  $tone: CardTone
25
27
  }
26
28
 
@@ -39,7 +41,7 @@ export function textInputRootStyle(): FlattenSimpleInterpolation {
39
41
  export function textInputBaseStyle(
40
42
  props: TextInputInputStyleProps & ThemeProps
41
43
  ): FlattenSimpleInterpolation {
42
- const {theme, $tone, $weight} = props
44
+ const {theme, $scheme, $tone, $weight} = props
43
45
  const font = theme.sanity.fonts.text
44
46
  const color = theme.sanity.color.input
45
47
 
@@ -79,7 +81,7 @@ export function textInputBaseStyle(
79
81
  color: var(--input-placeholder-color);
80
82
  }
81
83
 
82
- &[data-tone='${$tone}'] {
84
+ &[data-scheme='${$scheme}'][data-tone='${$tone}'] {
83
85
  --input-fg-color: ${color.default.enabled.fg};
84
86
  --input-placeholder-color: ${color.default.enabled.placeholder};
85
87
 
@@ -127,7 +129,7 @@ export function textInputFontSizeStyle(props: TextInputInputStyleProps & ThemePr
127
129
  export function textInputRepresentationStyle(
128
130
  props: TextInputRepresentationStyleProps & ThemeProps
129
131
  ): FlattenSimpleInterpolation {
130
- const {$border, $hasPrefix, $hasSuffix, $tone, theme} = props
132
+ const {$border, $hasPrefix, $hasSuffix, $scheme, $tone, theme} = props
131
133
  const {focusRing, input} = theme.sanity
132
134
  const color = theme.sanity.color.input
133
135
 
@@ -151,7 +153,7 @@ export function textInputRepresentationStyle(
151
153
  border-top-right-radius: ${$hasSuffix ? 0 : undefined};
152
154
  border-bottom-right-radius: ${$hasSuffix ? 0 : undefined};
153
155
 
154
- &[data-tone='${$tone}'] {
156
+ &[data-scheme='${$scheme}'][data-tone='${$tone}'] {
155
157
  --card-bg-color: ${color.default.enabled.bg};
156
158
  --card-fg-color: ${color.default.enabled.fg};
157
159
 
@@ -17,18 +17,19 @@ const NEUTRAL_TONES = ['default', 'transparent']
17
17
  export const color = createColorTheme({
18
18
  base: ({dark, name}) => {
19
19
  if (name === 'default') {
20
- const skeletonFrom = dark ? hues.gray[900].hex : hues.gray[100].hex
20
+ const tints = hues.gray
21
+ const skeletonFrom = dark ? tints[900].hex : tints[100].hex
21
22
 
22
23
  return {
23
24
  fg: dark ? white.hex : black.hex,
24
25
  bg: dark ? black.hex : white.hex,
25
- border: hues.gray[dark ? 800 : 200].hex,
26
+ border: tints[dark ? 800 : 200].hex,
26
27
  focusRing: hues.blue[dark ? 500 : 500].hex,
27
28
  shadow: {
28
- outline: rgba(hues.gray[500].hex, 0.4),
29
- umbra: rgba(dark ? black.hex : hues.gray[500].hex, 0.2),
30
- penumbra: rgba(dark ? black.hex : hues.gray[500].hex, 0.14),
31
- ambient: rgba(dark ? black.hex : hues.gray[500].hex, 0.12),
29
+ outline: rgba(tints[500].hex, 0.4),
30
+ umbra: dark ? rgba(tints[950].hex, 0.4) : rgba(tints[500].hex, 0.2),
31
+ penumbra: dark ? rgba(tints[950].hex, 0.28) : rgba(tints[500].hex, 0.14),
32
+ ambient: dark ? rgba(tints[950].hex, 0.24) : rgba(tints[500].hex, 0.12),
32
33
  },
33
34
  skeleton: {
34
35
  from: skeletonFrom,
@@ -47,10 +48,10 @@ export const color = createColorTheme({
47
48
  border: tints[dark ? 800 : 300].hex,
48
49
  focusRing: hues.blue[500].hex,
49
50
  shadow: {
50
- outline: rgba(tints[500].hex, dark ? 0.2 : 0.4),
51
- umbra: rgba(dark ? black.hex : tints[500].hex, 0.2),
52
- penumbra: rgba(dark ? black.hex : tints[500].hex, 0.14),
53
- ambient: rgba(dark ? black.hex : tints[500].hex, 0.12),
51
+ outline: rgba(tints[500].hex, 0.4),
52
+ umbra: dark ? rgba(tints[900].hex, 0.4) : rgba(tints[500].hex, 0.2),
53
+ penumbra: dark ? rgba(tints[900].hex, 0.28) : rgba(tints[500].hex, 0.14),
54
+ ambient: dark ? rgba(tints[900].hex, 0.24) : rgba(tints[500].hex, 0.12),
54
55
  },
55
56
  skeleton: {
56
57
  from: skeletonFrom,
@@ -68,10 +69,10 @@ export const color = createColorTheme({
68
69
  border: tints[dark ? 800 : 200].hex,
69
70
  focusRing: tints[500].hex,
70
71
  shadow: {
71
- outline: rgba(tints[500].hex, dark ? 0.2 : 0.4),
72
- umbra: rgba(dark ? black.hex : tints[500].hex, 0.2),
73
- penumbra: rgba(dark ? black.hex : tints[500].hex, 0.14),
74
- ambient: rgba(dark ? black.hex : tints[500].hex, 0.12),
72
+ outline: rgba(tints[500].hex, 0.4),
73
+ umbra: dark ? rgba(tints[900].hex, 0.4) : rgba(tints[500].hex, 0.2),
74
+ penumbra: dark ? rgba(tints[900].hex, 0.28) : rgba(tints[500].hex, 0.14),
75
+ ambient: dark ? rgba(tints[900].hex, 0.24) : rgba(tints[500].hex, 0.12),
75
76
  },
76
77
  skeleton: {
77
78
  from: skeletonFrom,