@sanity/ui 2.0.0-beta.9 → 2.0.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.
Files changed (35) hide show
  1. package/LICENSE +1 -1
  2. package/dist/index.esm.js +53 -30
  3. package/dist/index.esm.js.map +1 -1
  4. package/dist/index.js +53 -30
  5. package/dist/index.js.map +1 -1
  6. package/dist/theme.d.ts +12 -1
  7. package/dist/theme.esm.js +99 -78
  8. package/dist/theme.esm.js.map +1 -1
  9. package/dist/theme.js +99 -78
  10. package/dist/theme.js.map +1 -1
  11. package/package.json +2 -2
  12. package/src/core/__workshop__/fontsPlugin.tsx +48 -8
  13. package/src/core/components/dialog/dialog.tsx +1 -1
  14. package/src/core/components/dialog/styles.ts +2 -2
  15. package/src/core/components/toast/toast.tsx +17 -2
  16. package/src/core/components/toast/toastProvider.tsx +20 -3
  17. package/src/core/constants.ts +22 -3
  18. package/src/core/primitives/button/button.tsx +10 -12
  19. package/src/core/primitives/heading/styles.ts +4 -0
  20. package/src/core/primitives/popover/popoverCard.tsx +7 -2
  21. package/src/core/primitives/switch/styles.ts +5 -0
  22. package/src/core/primitives/textInput/__workshop__/plain.tsx +1 -1
  23. package/src/core/primitives/textInput/__workshop__/states.tsx +10 -2
  24. package/src/core/primitives/tooltip/tooltipCard.tsx +9 -3
  25. package/src/core/styles/input/textInputStyle.ts +33 -2
  26. package/src/core/theme/__workshop__/debug/story.tsx +65 -28
  27. package/src/theme/build/buildColorTheme.test.ts +2 -2
  28. package/src/theme/defaults/colorTokens.ts +90 -72
  29. package/src/theme/defaults/config.ts +1 -1
  30. package/src/theme/getScopedTheme.ts +1 -0
  31. package/src/theme/system/color/state.ts +6 -0
  32. package/src/theme/system/theme.ts +9 -1
  33. package/src/theme/system/v0/color/color.ts +0 -1
  34. package/src/theme/versioning/getTheme_v2.ts +2 -1
  35. package/src/theme/versioning/v2_v0.ts +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/ui",
3
- "version": "2.0.0-beta.9",
3
+ "version": "2.0.0",
4
4
  "sideEffects": false,
5
5
  "types": "./dist/index.d.ts",
6
6
  "source": "./exports/index.ts",
@@ -72,7 +72,7 @@
72
72
  },
73
73
  "dependencies": {
74
74
  "@floating-ui/react-dom": "^2.0.4",
75
- "@sanity/color": "3.0.0-beta.9",
75
+ "@sanity/color": "^3.0.0",
76
76
  "@sanity/icons": "^2.7.0",
77
77
  "csstype": "^3.1.2",
78
78
  "framer-motion": "^10.16.5",
@@ -3,20 +3,60 @@ import {createGlobalStyle} from 'styled-components'
3
3
 
4
4
  const GlobalStyle = createGlobalStyle`
5
5
  @font-face {
6
- font-family: 'Inter';
6
+ font-family: Inter;
7
7
  font-style: normal;
8
- font-weight: 100 900;
8
+ font-weight: 400;
9
9
  font-display: swap;
10
- src: url('https://rsms.me/inter/font-files/InterVariable.woff2?v=4.0') format('woff2');
11
- font-named-instance: 'Regular';
10
+ src: url('https://studio-static.sanity.io/Inter-Regular.woff2') format('woff2');
12
11
  }
13
12
  @font-face {
14
- font-family: 'Inter';
13
+ font-family: Inter;
15
14
  font-style: italic;
16
- font-weight: 100 900;
15
+ font-weight: 400;
17
16
  font-display: swap;
18
- src: url('https://rsms.me/inter/font-files/InterVariable-Italic.woff2?v=4.0') format('woff2');
19
- font-named-instance: 'Italic';
17
+ src: url('https://studio-static.sanity.io/Inter-Italic.woff2') format('woff2');
18
+ }
19
+ @font-face {
20
+ font-family: Inter;
21
+ font-style: normal;
22
+ font-weight: 500;
23
+ font-display: swap;
24
+ src: url('https://studio-static.sanity.io/Inter-Medium.woff2') format('woff2');
25
+ }
26
+ @font-face {
27
+ font-family: Inter;
28
+ font-style: italic;
29
+ font-weight: 500;
30
+ font-display: swap;
31
+ src: url('https://studio-static.sanity.io/Inter-MediumItalic.woff2') format('woff2');
32
+ }
33
+ @font-face {
34
+ font-family: Inter;
35
+ font-style: normal;
36
+ font-weight: 600;
37
+ font-display: swap;
38
+ src: url('https://studio-static.sanity.io/Inter-SemiBold.woff2') format('woff2');
39
+ }
40
+ @font-face {
41
+ font-family: Inter;
42
+ font-style: italic;
43
+ font-weight: 600;
44
+ font-display: swap;
45
+ src: url('https://studio-static.sanity.io/Inter-SemiBoldItalic.woff2') format('woff2');
46
+ }
47
+ @font-face {
48
+ font-family: Inter;
49
+ font-style: normal;
50
+ font-weight: 700;
51
+ font-display: swap;
52
+ src: url('https://studio-static.sanity.io/Inter-Bold.woff2') format('woff2');
53
+ }
54
+ @font-face {
55
+ font-family: Inter;
56
+ font-style: italic;
57
+ font-weight: 700;
58
+ font-display: swap;
59
+ src: url('https://studio-static.sanity.io/Inter-BoldItalic.woff2') format('woff2');
20
60
  }
21
61
  `
22
62
 
@@ -394,6 +394,7 @@ export const Dialog = forwardRef(function Dialog(
394
394
  <Portal __unstable_name={portalProp}>
395
395
  <Root
396
396
  {...restProps}
397
+ $animate={animate}
397
398
  $padding={padding}
398
399
  $position={position}
399
400
  aria-labelledby={labelId}
@@ -406,7 +407,6 @@ export const Dialog = forwardRef(function Dialog(
406
407
  ref={ref}
407
408
  role="dialog"
408
409
  zOffset={zOffset}
409
- animate={animate}
410
410
  >
411
411
  <div ref={preDivRef} tabIndex={0} />
412
412
  <DialogCard
@@ -41,11 +41,11 @@ export function responsiveDialogPositionStyle(
41
41
  * @internal
42
42
  */
43
43
  export interface AnimationDialogStyleProps {
44
- animate: boolean
44
+ $animate: boolean
45
45
  }
46
46
 
47
47
  export function animationDialogStyle(props: AnimationDialogStyleProps): ReturnType<typeof css> {
48
- if (!props.animate) return css``
48
+ if (!props.$animate) return css``
49
49
 
50
50
  return css`
51
51
  @keyframes zoomIn {
@@ -1,7 +1,9 @@
1
1
  import {CloseIcon} from '@sanity/icons'
2
2
  import {ThemeColorToneKey} from '@sanity/ui/theme'
3
3
  import styled from 'styled-components'
4
+ import {POPOVER_MOTION_CONTENT_OPACITY_PROPERTY} from '../../constants'
4
5
  import {Box, Button, Card, Flex, Stack, Text} from '../../primitives'
6
+ import type {ButtonTone} from '../../types'
5
7
 
6
8
  /**
7
9
  * @public
@@ -20,17 +22,28 @@ const STATUS_CARD_TONE: {[key: string]: ThemeColorToneKey} = {
20
22
  warning: 'caution',
21
23
  success: 'positive',
22
24
  info: 'primary',
23
- }
25
+ } as const
26
+
27
+ const BUTTON_TONE = {
28
+ error: 'critical',
29
+ warning: 'caution',
30
+ success: 'positive',
31
+ info: 'primary',
32
+ } satisfies {[key: string]: ButtonTone}
24
33
 
25
34
  const ROLES = {
26
35
  error: 'alert',
27
36
  warning: 'alert',
28
37
  success: 'alert',
29
38
  info: 'alert',
30
- }
39
+ } as const
31
40
 
32
41
  const Root = styled(Card)`
33
42
  pointer-events: all;
43
+ & > * {
44
+ opacity: var(${POPOVER_MOTION_CONTENT_OPACITY_PROPERTY}, 1);
45
+ will-change: opacity;
46
+ }
34
47
  `
35
48
 
36
49
  const TextBox = styled(Flex)`
@@ -49,6 +62,7 @@ export function Toast(
49
62
  ): React.ReactElement {
50
63
  const {closable, description, onClose, radius = 3, title, status, ...restProps} = props
51
64
  const cardTone = status ? STATUS_CARD_TONE[status] : 'default'
65
+ const buttonTone = status ? BUTTON_TONE[status] : 'default'
52
66
  const role = status ? ROLES[status] : 'status'
53
67
 
54
68
  return (
@@ -84,6 +98,7 @@ export function Toast(
84
98
  icon={CloseIcon}
85
99
  mode="bleed"
86
100
  padding={2}
101
+ tone={buttonTone}
87
102
  onClick={onClose}
88
103
  style={{verticalAlign: 'top'}}
89
104
  />
@@ -1,6 +1,7 @@
1
1
  import {AnimatePresence, motion} from 'framer-motion'
2
2
  import {useCallback, useEffect, useMemo, useRef, useState, startTransition} from 'react'
3
3
  import styled from 'styled-components'
4
+ import {POPOVER_MOTION_CONTENT_OPACITY_PROPERTY} from '../../constants'
4
5
  import {useMounted} from '../../hooks/useMounted'
5
6
  import {Box} from '../../primitives'
6
7
  import {Layer} from '../../utils'
@@ -132,9 +133,25 @@ export function ToastProvider(props: ToastProviderProps): React.ReactElement {
132
133
  <AnimatePresence initial={false}>
133
134
  {state.map(({dismiss, id, params}) => (
134
135
  <motion.div
135
- animate={{opacity: 1, y: 0, scale: 1}}
136
- exit={{opacity: 0, scale: 0.5, transition: {duration: 0.2}}}
137
- initial={{opacity: 0, y: 32, scale: 0.25}}
136
+ animate={{
137
+ opacity: [0, 1, 1],
138
+ [POPOVER_MOTION_CONTENT_OPACITY_PROPERTY as string]: [0, 0, 1],
139
+ y: 0,
140
+ scale: 1,
141
+ }}
142
+ exit={{
143
+ opacity: [1, 1, 0],
144
+ [POPOVER_MOTION_CONTENT_OPACITY_PROPERTY as string]: [1, 0, 0],
145
+ scale: 0.5,
146
+ transition: {duration: 0.2},
147
+ }}
148
+ initial={{
149
+ opacity: 0,
150
+ [POPOVER_MOTION_CONTENT_OPACITY_PROPERTY as string]: 0,
151
+ y: 32,
152
+ scale: 0.25,
153
+ willChange: 'transform',
154
+ }}
138
155
  key={id}
139
156
  layout="position"
140
157
  transition={{type: 'spring', damping: 30, stiffness: 400}}
@@ -10,6 +10,11 @@ export const EMPTY_ARRAY: never[] = []
10
10
  */
11
11
  export const EMPTY_RECORD: Record<string, never> = {}
12
12
 
13
+ /**
14
+ * @internal
15
+ */
16
+ export const POPOVER_MOTION_CONTENT_OPACITY_PROPERTY = '--motion-content-opacity'
17
+
13
18
  /**
14
19
  * Shared `framer-motion` variants used by `Popover` and `Tooltip` components.
15
20
  * @internal
@@ -20,9 +25,23 @@ export const POPOVER_MOTION_PROPS: {
20
25
  exit: Variant
21
26
  transition: Transition
22
27
  } = {
23
- initial: {opacity: 0.5, scale: 0.97},
24
- animate: {opacity: 1, scale: 1},
25
- exit: {opacity: 0, scale: 0.97},
28
+ initial: {
29
+ opacity: 0.5,
30
+ [POPOVER_MOTION_CONTENT_OPACITY_PROPERTY as string]: 0,
31
+ scale: 0.97,
32
+ willChange: 'transform',
33
+ },
34
+ animate: {
35
+ opacity: [null, 1, 1],
36
+ [POPOVER_MOTION_CONTENT_OPACITY_PROPERTY as string]: [null, null, 1],
37
+ scale: 1,
38
+ },
39
+ exit: {
40
+ // @ts-expect-error -- passing null a second time is valid: https://github.com/framer/motion/blob/b9ce4c42914c3916ea523609c5b032dfc72718bb/packages/framer-motion/src/animation/utils/keyframes.ts#L34C22-L34C22
41
+ opacity: [null, null, 0],
42
+ [POPOVER_MOTION_CONTENT_OPACITY_PROPERTY as string]: [null, 0, 0],
43
+ scale: 0.97,
44
+ },
26
45
  transition: {duration: 0.4, type: 'spring'},
27
46
  }
28
47
 
@@ -72,7 +72,7 @@ export const Button = forwardRef(function Button(
72
72
  iconRight,
73
73
  justify: justifyProp = 'center',
74
74
  loading,
75
- mode = 'ghost',
75
+ mode = 'default',
76
76
  padding: paddingProp = 3,
77
77
  paddingX: paddingXProp,
78
78
  paddingY: paddingYProp,
@@ -149,17 +149,15 @@ export const Button = forwardRef(function Button(
149
149
  )}
150
150
 
151
151
  {text && (
152
- <Box flex={iconRight ? 1 : undefined}>
153
- <Text
154
- muted={muted}
155
- align={textAlign}
156
- size={fontSize}
157
- textOverflow="ellipsis"
158
- weight={button.textWeight}
159
- >
160
- {text}
161
- </Text>
162
- </Box>
152
+ <Text
153
+ muted={muted}
154
+ align={textAlign}
155
+ size={fontSize}
156
+ textOverflow="ellipsis"
157
+ weight={button.textWeight}
158
+ >
159
+ {text}
160
+ </Text>
163
161
  )}
164
162
 
165
163
  {iconRight && (
@@ -46,6 +46,10 @@ export function headingBaseStyle(props: HeadingStyleProps & ThemeProps): ReturnT
46
46
  }
47
47
  }
48
48
 
49
+ & strong {
50
+ font-weight: ${font.heading.weights.bold};
51
+ }
52
+
49
53
  & svg {
50
54
  /* Certain popular CSS libraries changes the defaults for SVG display */
51
55
  /* Make sure SVGs are rendered as inline elements */
@@ -3,7 +3,7 @@ import {ThemeColorSchemeKey} from '@sanity/ui/theme'
3
3
  import {MotionProps, motion} from 'framer-motion'
4
4
  import React, {CSSProperties, forwardRef, memo, useMemo} from 'react'
5
5
  import styled from 'styled-components'
6
- import {POPOVER_MOTION_PROPS} from '../../constants'
6
+ import {POPOVER_MOTION_CONTENT_OPACITY_PROPERTY, POPOVER_MOTION_PROPS} from '../../constants'
7
7
  import {BoxOverflow, CardTone, Placement, PopoverMargins, Radius} from '../../types'
8
8
  import {Arrow, useLayer} from '../../utils'
9
9
  import {Card, CardProps} from '../card'
@@ -22,6 +22,10 @@ const MotionCard = styled(motion(Card))`
22
22
  flex-direction: column;
23
23
  width: max-content;
24
24
  min-width: min-content;
25
+ & > * {
26
+ opacity: var(${POPOVER_MOTION_CONTENT_OPACITY_PROPERTY}, 1);
27
+ will-change: opacity;
28
+ }
25
29
  `
26
30
 
27
31
  /**
@@ -99,9 +103,10 @@ export const PopoverCard = memo(
99
103
  top: y,
100
104
  width,
101
105
  zIndex,
106
+ willChange: animate ? 'transform' : undefined,
102
107
  ...style,
103
108
  }),
104
- [originX, originY, strategy, style, width, x, y, zIndex],
109
+ [animate, originX, originY, strategy, style, width, x, y, zIndex],
105
110
  )
106
111
 
107
112
  const arrowStyle: CSSProperties = useMemo(
@@ -102,6 +102,11 @@ export function switchRepresentationStyles(props: ThemeProps): ReturnType<typeof
102
102
  --switch-bg-color: ${color.input.default.readOnly.border};
103
103
  --switch-fg-color: ${color.input.default.readOnly.bg};
104
104
  }
105
+
106
+ input:checked[data-read-only]:disabled + && {
107
+ --switch-bg-color: ${color.input.default.readOnly.fg};
108
+ --switch-fg-color: ${color.input.default.readOnly.bg};
109
+ }
105
110
  `
106
111
  }
107
112
 
@@ -62,7 +62,7 @@ function TextInputTest(props: {inputRef: React.Ref<HTMLInputElement>}) {
62
62
  ) as IconSymbol
63
63
  const padding = useSelect('Padding', WORKSHOP_SPACE_OPTIONS, 3, 'Props')
64
64
  const placeholder = useText('Placeholder', '', 'Props') || undefined
65
- const radius = useSelect('Radius', WORKSHOP_RADIUS_OPTIONS, 0, 'Props')
65
+ const radius = useSelect('Radius', WORKSHOP_RADIUS_OPTIONS, 2, 'Props')
66
66
  const readOnly = useBoolean('Read only', false, 'Props')
67
67
  const space = useSelect('Space', WORKSHOP_SPACE_OPTIONS, 3, 'Props')
68
68
  const weight = useSelect('Weight', WORKSHOP_FONT_WEIGHT_OPTIONS, '', 'Props') || undefined
@@ -1,7 +1,8 @@
1
1
  import {Container, Flex, Stack, Text, TextInput} from '@sanity/ui'
2
- import {useAction} from '@sanity/ui-workshop'
2
+ import {useAction, useBoolean} from '@sanity/ui-workshop'
3
3
 
4
4
  export default function StatesStory() {
5
+ const invalid = useBoolean('Invalid', false, 'Props')
5
6
  const onChange = useAction('onChange')
6
7
 
7
8
  return (
@@ -12,7 +13,12 @@ export default function StatesStory() {
12
13
  <Text size={1} weight="medium">
13
14
  <label htmlFor="enabled-example">Enabled (default)</label>
14
15
  </Text>
15
- <TextInput id="enabled-example" onChange={onChange} value="This is some text" />
16
+ <TextInput
17
+ customValidity={invalid ? 'invalid' : undefined}
18
+ id="enabled-example"
19
+ onChange={onChange}
20
+ value="This is some text"
21
+ />
16
22
  </Stack>
17
23
 
18
24
  <Stack space={3}>
@@ -20,6 +26,7 @@ export default function StatesStory() {
20
26
  <label htmlFor="disabled-example">Disabled</label>
21
27
  </Text>
22
28
  <TextInput
29
+ customValidity={invalid ? 'invalid' : undefined}
23
30
  disabled
24
31
  id="disabled-example"
25
32
  onChange={onChange}
@@ -32,6 +39,7 @@ export default function StatesStory() {
32
39
  <label htmlFor="read-only-example">Read-only</label>
33
40
  </Text>
34
41
  <TextInput
42
+ customValidity={invalid ? 'invalid' : undefined}
35
43
  id="read-only-example"
36
44
  readOnly
37
45
  onChange={onChange}
@@ -2,7 +2,7 @@ import {ThemeColorSchemeKey} from '@sanity/ui/theme'
2
2
  import {MotionProps, motion} from 'framer-motion'
3
3
  import React, {CSSProperties, forwardRef, memo, useMemo} from 'react'
4
4
  import styled from 'styled-components'
5
- import {POPOVER_MOTION_PROPS} from '../../constants'
5
+ import {POPOVER_MOTION_CONTENT_OPACITY_PROPERTY, POPOVER_MOTION_PROPS} from '../../constants'
6
6
  import {Placement, Radius} from '../../types'
7
7
  import {Arrow} from '../../utils'
8
8
  import {Card, CardProps} from '../card'
@@ -12,7 +12,12 @@ import {
12
12
  DEFAULT_TOOLTIP_ARROW_WIDTH,
13
13
  } from './constants'
14
14
 
15
- const MotionCard = styled(motion(Card))``
15
+ const MotionCard = styled(motion(Card))`
16
+ & > * {
17
+ opacity: var(${POPOVER_MOTION_CONTENT_OPACITY_PROPERTY}, 1);
18
+ will-change: opacity;
19
+ }
20
+ `
16
21
 
17
22
  /**
18
23
  * @internal
@@ -57,9 +62,10 @@ export const TooltipCard = memo(
57
62
  () => ({
58
63
  originX,
59
64
  originY,
65
+ willChange: animate ? 'transform' : undefined,
60
66
  ...style,
61
67
  }),
62
- [originX, originY, style],
68
+ [animate, originX, originY, style],
63
69
  )
64
70
 
65
71
  const arrowStyle: CSSProperties = useMemo(
@@ -195,9 +195,10 @@ export function textInputRepresentationStyle(
195
195
  }
196
196
 
197
197
  /* disabled */
198
- *:disabled + & {
198
+ *:not(:invalid):disabled + & {
199
199
  --card-bg-color: ${color.input.default.disabled.bg} !important;
200
200
  --card-fg-color: ${color.input.default.disabled.fg} !important;
201
+ --card-icon-color: ${color.input.default.disabled.fg} !important;
201
202
 
202
203
  &[data-border] {
203
204
  --input-box-shadow: ${focusRingBorderStyle({
@@ -207,12 +208,30 @@ export function textInputRepresentationStyle(
207
208
  }
208
209
  }
209
210
 
211
+ *:invalid:disabled + & {
212
+ --card-bg-color: ${color.input.invalid.disabled.bg} !important;
213
+ --card-fg-color: ${color.input.invalid.disabled.fg} !important;
214
+ --card-icon-color: ${color.input.invalid.disabled.fg} !important;
215
+
216
+ &[data-border] {
217
+ --input-box-shadow: ${focusRingBorderStyle({
218
+ color: color.input.invalid.disabled.border,
219
+ width: input.border.width,
220
+ })};
221
+ }
222
+ }
223
+
210
224
  /* readOnly */
211
- *:read-only + & {
225
+ *:not(:invalid):read-only + & {
212
226
  --card-bg-color: ${color.input.default.readOnly.bg} !important;
213
227
  --card-fg-color: ${color.input.default.readOnly.fg} !important;
214
228
  }
215
229
 
230
+ *:invalid:read-only + & {
231
+ --card-bg-color: ${color.input.invalid.readOnly.bg} !important;
232
+ --card-fg-color: ${color.input.invalid.readOnly.fg} !important;
233
+ }
234
+
216
235
  /* hovered */
217
236
  @media (hover: hover) {
218
237
  *:not(:disabled):not(:read-only):not(:invalid):hover + & {
@@ -220,12 +239,24 @@ export function textInputRepresentationStyle(
220
239
  --card-fg-color: ${color.input.default.hovered.fg};
221
240
  }
222
241
 
242
+ *:invalid:not(:disabled):not(:read-only):hover + & {
243
+ --card-bg-color: ${color.input.invalid.hovered.bg};
244
+ --card-fg-color: ${color.input.invalid.hovered.fg};
245
+ }
246
+
223
247
  *:not(:disabled):not(:read-only):not(:invalid):not(:focus):hover + &[data-border] {
224
248
  --input-box-shadow: ${focusRingBorderStyle({
225
249
  color: color.input.default.hovered.border,
226
250
  width: input.border.width,
227
251
  })};
228
252
  }
253
+
254
+ *:invalid:not(:disabled):not(:read-only):not(:focus):hover + &[data-border] {
255
+ --input-box-shadow: ${focusRingBorderStyle({
256
+ color: color.input.invalid.hovered.border,
257
+ width: input.border.width,
258
+ })};
259
+ }
229
260
  }
230
261
  }
231
262
  `
@@ -1,3 +1,4 @@
1
+ import {CropIcon} from '@sanity/icons'
1
2
  import {
2
3
  THEME_COLOR_BUTTON_MODES,
3
4
  THEME_COLOR_CARD_TONES,
@@ -8,6 +9,7 @@ import {
8
9
  ThemeColorScheme_v2,
9
10
  ThemeColorState_v2,
10
11
  } from '@sanity/ui/theme'
12
+ import {useBoolean} from '@sanity/ui-workshop'
11
13
  import {CSSProperties} from 'react'
12
14
  import {Badge, Box, Flex, KBD, Stack, Text} from '../../../primitives'
13
15
  import {useRootTheme} from '../../useRootTheme'
@@ -27,17 +29,23 @@ export default function DebugStory() {
27
29
  function DebugScheme(props: {scheme: ThemeColorScheme_v2}) {
28
30
  const {scheme} = props
29
31
 
32
+ const button = useBoolean('Button', false, 'Props') || false
33
+ const selectable = useBoolean('Selectable', false, 'Props') || false
34
+
30
35
  return (
31
36
  <Box flex={1} style={{backgroundColor: scheme.default.bg}}>
32
37
  {THEME_COLOR_CARD_TONES.map((tone) => (
33
- <DebugCard card={scheme[tone]} key={tone} />
38
+ <DebugCard card={scheme[tone]} features={{button, selectable}} key={tone} />
34
39
  ))}
35
40
  </Box>
36
41
  )
37
42
  }
38
43
 
39
- function DebugCard(props: {card: ThemeColorCard_v2}) {
40
- const {card} = props
44
+ function DebugCard(props: {
45
+ card: ThemeColorCard_v2
46
+ features: {button: boolean; selectable: boolean}
47
+ }) {
48
+ const {card, features} = props
41
49
 
42
50
  // card.avatar
43
51
  // card.backdrop
@@ -56,27 +64,44 @@ function DebugCard(props: {card: ThemeColorCard_v2}) {
56
64
  return (
57
65
  <Box style={getStateVars(card)}>
58
66
  <DebugState />
59
- <Stack padding={2} space={1}>
60
- {THEME_COLOR_BUTTON_MODES.map((mode) => (
61
- <Stack key={mode} space={1}>
62
- {THEME_COLOR_STATE_TONES.map((stateTone) => (
63
- <Flex key={stateTone} gap={1}>
64
- {/* {mode} */}
65
- {THEME_COLOR_STATES.map((state) => (
66
- <Box
67
- flex={1}
68
- key={state}
69
- style={getStateVars(card.button[mode][stateTone][state])}
70
- >
71
- <DebugState />
72
- {/* {state} */}
73
- </Box>
74
- ))}
75
- </Flex>
76
- ))}
77
- </Stack>
78
- ))}
79
- </Stack>
67
+
68
+ {features.button && (
69
+ <Stack padding={2} space={1}>
70
+ {THEME_COLOR_BUTTON_MODES.map((mode) => (
71
+ <Stack key={mode} space={1}>
72
+ {THEME_COLOR_STATE_TONES.map((stateTone) => (
73
+ <Flex key={stateTone} gap={1}>
74
+ {/* {mode} */}
75
+ {THEME_COLOR_STATES.map((state) => (
76
+ <Box
77
+ flex={1}
78
+ key={state}
79
+ style={getStateVars(card.button[mode][stateTone][state])}
80
+ >
81
+ <DebugState />
82
+ </Box>
83
+ ))}
84
+ </Flex>
85
+ ))}
86
+ </Stack>
87
+ ))}
88
+ </Stack>
89
+ )}
90
+
91
+ {features.selectable && (
92
+ <Stack padding={2} space={1}>
93
+ {THEME_COLOR_STATE_TONES.map((stateTone) => (
94
+ <Flex key={stateTone} gap={1}>
95
+ {/* {mode} */}
96
+ {THEME_COLOR_STATES.map((state) => (
97
+ <Box flex={1} key={state} style={getStateVars(card.selectable[stateTone][state])}>
98
+ <DebugState />
99
+ </Box>
100
+ ))}
101
+ </Flex>
102
+ ))}
103
+ </Stack>
104
+ )}
80
105
  </Box>
81
106
  )
82
107
  }
@@ -89,7 +114,12 @@ function DebugState() {
89
114
  space={3}
90
115
  style={{border: '1px solid var(--card-border-color)'}}
91
116
  >
92
- <Text size={1}>Text</Text>
117
+ <Flex gap={3}>
118
+ <Text size={1}>Text</Text>
119
+ <Text size={1}>
120
+ <CropIcon />
121
+ </Text>
122
+ </Flex>
93
123
  <Text muted size={1}>
94
124
  Muted
95
125
  </Text>
@@ -116,13 +146,20 @@ function DebugState() {
116
146
 
117
147
  function getStateVars(state: ThemeColorState_v2) {
118
148
  return {
149
+ '--card-accent-fg-color': state.accent.fg,
150
+
151
+ '--card-code-bg-color': state.code.bg,
152
+ '--card-code-fg-color': state.code.fg,
153
+
119
154
  '--card-bg-color': state.bg,
155
+
120
156
  '--card-border-color': state.border,
157
+
121
158
  '--card-fg-color': state.fg,
122
- '--card-accent-fg-color': state.accent.fg,
159
+
160
+ '--card-icon-color': state.icon,
161
+
123
162
  '--card-muted-fg-color': state.muted.fg,
124
- '--card-code-bg-color': state.code.bg,
125
- '--card-code-fg-color': state.code.fg,
126
163
 
127
164
  '--card-kbd-bg-color': state.kbd.bg,
128
165
  '--card-kbd-border-color': state.kbd.border,
@@ -65,7 +65,7 @@ test('buildColorTheme: base', () => {
65
65
  light: {
66
66
  transparent: {
67
67
  bg: 'gray/50',
68
- fg: 'gray/600',
68
+ fg: 'gray/800',
69
69
  },
70
70
  default: {
71
71
  bg: 'white',
@@ -79,7 +79,7 @@ test('buildColorTheme: base', () => {
79
79
  dark: {
80
80
  transparent: {
81
81
  bg: 'black',
82
- fg: 'gray/400',
82
+ fg: 'gray/200',
83
83
  },
84
84
  default: {
85
85
  bg: 'gray/950',