playroom 0.37.0 → 0.38.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 (80) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +4 -0
  3. package/package.json +18 -7
  4. package/src/Playroom/Box/Box.tsx +33 -0
  5. package/src/Playroom/Button/Button.css.ts +3 -2
  6. package/src/Playroom/Button/Button.tsx +0 -1
  7. package/src/Playroom/CodeEditor/CodeEditor.css.ts +5 -4
  8. package/src/Playroom/Frames/Frames.css.ts +21 -42
  9. package/src/Playroom/Frames/Frames.tsx +31 -28
  10. package/src/Playroom/FramesPanel/FramesPanel.css.ts +8 -24
  11. package/src/Playroom/FramesPanel/FramesPanel.tsx +34 -37
  12. package/src/Playroom/Heading/Heading.css.ts +2 -1
  13. package/src/Playroom/Inline/Inline.css.ts +22 -49
  14. package/src/Playroom/Inline/Inline.tsx +12 -16
  15. package/src/Playroom/Playroom.css.ts +2 -1
  16. package/src/Playroom/PreviewPanel/CopyButton.tsx +0 -1
  17. package/src/Playroom/PreviewPanel/PreviewPanel.tsx +2 -3
  18. package/src/Playroom/SettingsPanel/SettingsPanel.css.ts +12 -25
  19. package/src/Playroom/SettingsPanel/SettingsPanel.tsx +76 -73
  20. package/src/Playroom/Snippets/SearchField/SearchField.css.ts +2 -1
  21. package/src/Playroom/Snippets/SearchField/SearchField.tsx +3 -3
  22. package/src/Playroom/Snippets/Snippets.css.ts +4 -3
  23. package/src/Playroom/Snippets/Snippets.tsx +3 -3
  24. package/src/Playroom/Stack/Stack.css.ts +4 -6
  25. package/src/Playroom/Stack/Stack.tsx +4 -19
  26. package/src/Playroom/StatusMessage/StatusMessage.css.ts +2 -1
  27. package/src/Playroom/Toolbar/Toolbar.css.ts +35 -41
  28. package/src/Playroom/Toolbar/Toolbar.tsx +37 -36
  29. package/src/Playroom/ToolbarItem/ToolbarItem.css.ts +2 -1
  30. package/src/Playroom/ToolbarItem/ToolbarItem.tsx +1 -4
  31. package/src/Playroom/ToolbarPanel/ToolbarPanel.tsx +1 -7
  32. package/src/Playroom/icons/ChevronIcon.css.ts +1 -1
  33. package/src/Playroom/sprinkles.css.ts +9 -49
  34. package/src/Playroom/vars.css.ts +47 -0
  35. package/.changeset/README.md +0 -8
  36. package/.changeset/config.json +0 -11
  37. package/.editorconfig +0 -13
  38. package/.eslintignore +0 -4
  39. package/.eslintrc +0 -16
  40. package/.github/CODEOWNERS +0 -5
  41. package/.github/workflows/preview-site.yml +0 -42
  42. package/.github/workflows/release.yml +0 -41
  43. package/.github/workflows/snapshot.yml +0 -35
  44. package/.github/workflows/validate.yml +0 -63
  45. package/.husky/pre-commit +0 -4
  46. package/.nvmrc +0 -1
  47. package/.prettierignore +0 -4
  48. package/.prettierrc +0 -3
  49. package/cypress/e2e/editor.cy.js +0 -35
  50. package/cypress/e2e/keymaps.cy.js +0 -2025
  51. package/cypress/e2e/scope.cy.js +0 -16
  52. package/cypress/e2e/smoke.cy.js +0 -28
  53. package/cypress/e2e/snippets.cy.js +0 -117
  54. package/cypress/e2e/toolbar.cy.js +0 -52
  55. package/cypress/e2e/urlHandling.cy.js +0 -50
  56. package/cypress/projects/basic/components.js +0 -26
  57. package/cypress/projects/basic/playroom.config.js +0 -8
  58. package/cypress/projects/basic/snippets.js +0 -27
  59. package/cypress/projects/basic/useScope.js +0 -4
  60. package/cypress/projects/themed/components.js +0 -26
  61. package/cypress/projects/themed/playroom.config.js +0 -10
  62. package/cypress/projects/themed/serve.json +0 -3
  63. package/cypress/projects/themed/snippets.js +0 -22
  64. package/cypress/projects/themed/themes.js +0 -2
  65. package/cypress/projects/typescript/components/Bar.tsx +0 -13
  66. package/cypress/projects/typescript/components/Foo.tsx +0 -13
  67. package/cypress/projects/typescript/components/styles.ts +0 -4
  68. package/cypress/projects/typescript/components.ts +0 -2
  69. package/cypress/projects/typescript/playroom.config.js +0 -33
  70. package/cypress/projects/typescript/snippets.ts +0 -22
  71. package/cypress/projects/typescript/tsconfig.json +0 -18
  72. package/cypress/support/commands.js +0 -10
  73. package/cypress/support/e2e.js +0 -1
  74. package/cypress/support/utils.js +0 -236
  75. package/cypress/tsconfig.json +0 -9
  76. package/cypress.config.mjs +0 -7
  77. package/scripts/postCommitStatus.js +0 -50
  78. package/src/Playroom/Divider/Divider.css.ts +0 -16
  79. package/src/Playroom/Divider/Divider.tsx +0 -7
  80. package/tsconfig.json +0 -20
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # playroom
2
2
 
3
+ ## 0.38.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 7df36e3: Improve frame filtering UX.
8
+
9
+ - Allow users to select all checkboxes in a frame filter section, rather than automatically unselecting all checkboxes when all are selected.
10
+ - Rename the "Show all" button to "Clear" to reinforce the filtering pattern.
11
+
12
+ - 384810e: Use CSS gap and grid for layout spacing in Playroom UI.
13
+
14
+ ### Patch Changes
15
+
16
+ - a0724d2: Fixes a bug in the side panel exit animation that was causing the contents to vanish abruptly
17
+ - 934a017: Exclude irrelevant files from published package
18
+ - 92a0039: Fix Playroom UI icon centering
19
+ - 422a259: Remove `data-testid` attributes from UI elements
20
+
21
+ ## 0.37.1
22
+
23
+ ### Patch Changes
24
+
25
+ - 2b6d5c5: Update lz-string to 1.5.0, and removed unnecessary @types/lz-string
26
+
3
27
  ## 0.37.0
4
28
 
5
29
  ### Minor Changes
package/README.md CHANGED
@@ -208,6 +208,10 @@ Playroom supports loading [ESM](https://nodejs.org/api/esm.html#introduction) co
208
208
 
209
209
  If you are interested in integrating Playroom into Storybook, check out [storybook-addon-playroom](https://github.com/rbardini/storybook-addon-playroom).
210
210
 
211
+ ## Browser Support
212
+
213
+ Playroom is built to work on the latest stable versions of all major browsers. Some features may not work as expected in older browsers.
214
+
211
215
  ## License
212
216
 
213
217
  MIT.
package/package.json CHANGED
@@ -1,12 +1,20 @@
1
1
  {
2
2
  "name": "playroom",
3
- "version": "0.37.0",
3
+ "version": "0.38.0",
4
4
  "description": "Design with code, powered by your own component library",
5
5
  "main": "utils/index.js",
6
6
  "types": "utils/index.d.ts",
7
7
  "bin": {
8
8
  "playroom": "bin/cli.cjs"
9
9
  },
10
+ "files": [
11
+ "CHANGELOG.md",
12
+ ".babelrc",
13
+ "images",
14
+ "lib",
15
+ "src",
16
+ "utils"
17
+ ],
10
18
  "lint-staged": {
11
19
  "**/*.{js,ts,tsx}": [
12
20
  "eslint"
@@ -35,7 +43,6 @@
35
43
  "@types/base64-url": "^2.2.0",
36
44
  "@types/codemirror": "^5.60.5",
37
45
  "@types/lodash": "^4.14.191",
38
- "@types/lz-string": "^1.3.34",
39
46
  "@types/prettier": "^2.7.1",
40
47
  "@types/react": "^18.0.26",
41
48
  "@types/react-dom": "^18.0.9",
@@ -45,6 +52,7 @@
45
52
  "@vanilla-extract/webpack-plugin": "^2.3.6",
46
53
  "babel-loader": "^9.1.0",
47
54
  "classnames": "^2.3.2",
55
+ "clsx": "^2.1.1",
48
56
  "codemirror": "^5.65.10",
49
57
  "command-line-args": "^5.2.1",
50
58
  "command-line-usage": "^6.1.3",
@@ -59,7 +67,7 @@
59
67
  "intersection-observer": "^0.12.2",
60
68
  "localforage": "^1.10.0",
61
69
  "lodash": "^4.17.21",
62
- "lz-string": "^1.4.4",
70
+ "lz-string": "^1.5.0",
63
71
  "memoize-one": "^6.0.0",
64
72
  "mini-css-extract-plugin": "^2.7.2",
65
73
  "parse-prop-types": "^0.3.0",
@@ -70,6 +78,7 @@
70
78
  "re-resizable": "^6.9.9",
71
79
  "react-docgen-typescript": "^2.2.2",
72
80
  "react-helmet": "^6.1.0",
81
+ "react-transition-group": "^4.4.5",
73
82
  "react-use": "^17.4.0",
74
83
  "read-pkg-up": "^7.0.1",
75
84
  "scope-eval": "^1.0.0",
@@ -84,11 +93,13 @@
84
93
  "@actions/core": "^1.10.0",
85
94
  "@changesets/cli": "^2.25.2",
86
95
  "@octokit/rest": "^19.0.5",
96
+ "@testing-library/cypress": "^10.0.1",
87
97
  "@types/jest": "^29.2.4",
88
98
  "@types/react-helmet": "^6.1.6",
99
+ "@types/react-transition-group": "^4.4.10",
89
100
  "concurrently": "^7.6.0",
90
101
  "cypress": "^13.6.6",
91
- "eslint": "^8.44.0",
102
+ "eslint": "^8.56.0",
92
103
  "eslint-config-seek": "^11.3.1",
93
104
  "husky": "^8.0.2",
94
105
  "jest": "^29.3.1",
@@ -116,19 +127,19 @@
116
127
  "cypress:verify": "cypress verify",
117
128
  "start:basic": "./bin/cli.cjs start --config cypress/projects/basic/playroom.config.js",
118
129
  "build:basic": "./bin/cli.cjs build --config cypress/projects/basic/playroom.config.js",
119
- "serve:basic": "PORT=9000 serve --no-request-logging cypress/projects/basic/dist",
130
+ "serve:basic": "PORT=9000 serve --config ../serve.json --no-request-logging cypress/projects/basic/dist",
120
131
  "start:themed": "./bin/cli.cjs start --config cypress/projects/themed/playroom.config.js",
121
132
  "build:themed": "./bin/cli.cjs build --config cypress/projects/themed/playroom.config.js",
122
133
  "serve:themed": "PORT=9001 serve --config ../serve.json --no-request-logging cypress/projects/themed/dist",
123
134
  "start:typescript": "./bin/cli.cjs start --config cypress/projects/typescript/playroom.config.js",
124
135
  "build:typescript": "./bin/cli.cjs build --config cypress/projects/typescript/playroom.config.js",
125
- "serve:typescript": "PORT=9002 serve --no-request-logging cypress/projects/typescript/dist",
136
+ "serve:typescript": "PORT=9002 serve --config ../serve.json --no-request-logging cypress/projects/typescript/dist",
126
137
  "start:all": "concurrently 'npm:start:*(!all)'",
127
138
  "build:all": "concurrently 'npm:build:*(!all)'",
128
139
  "serve:all": "concurrently 'npm:serve:*(!all)'",
129
140
  "build-and-serve:all": "pnpm build:all && pnpm serve:all",
130
141
  "lint": "concurrently 'npm:lint:*'",
131
- "lint:eslint": "eslint --cache .",
142
+ "lint:eslint": "NODE_OPTIONS=--max_old_space_size=8192 eslint --cache .",
132
143
  "lint:prettier": "prettier --list-different '**/*.{js,md,ts,tsx}'",
133
144
  "lint:tsc": "tsc --noEmit",
134
145
  "lint:cypress": "tsc --project cypress/tsconfig.json",
@@ -0,0 +1,33 @@
1
+ import clsx, { type ClassValue } from 'clsx';
2
+ import type { AllHTMLAttributes, ElementType } from 'react';
3
+ import { sprinkles, type Sprinkles } from '../sprinkles.css';
4
+
5
+ interface BoxProps
6
+ extends Omit<
7
+ AllHTMLAttributes<HTMLElement>,
8
+ 'width' | 'height' | 'className' | 'data'
9
+ >,
10
+ Sprinkles {
11
+ className?: ClassValue;
12
+ component?: ElementType;
13
+ }
14
+
15
+ export const Box = ({
16
+ component = 'div',
17
+ className,
18
+ ...restProps
19
+ }: BoxProps) => {
20
+ const atomProps: Record<string, unknown> = {};
21
+
22
+ for (const key in restProps) {
23
+ if (sprinkles.properties.has(key as keyof Sprinkles)) {
24
+ atomProps[key] = restProps[key as keyof typeof restProps];
25
+ delete restProps[key as keyof typeof restProps];
26
+ }
27
+ }
28
+
29
+ const classes = clsx(className, sprinkles({ ...atomProps }));
30
+ const Component = component;
31
+
32
+ return <Component className={classes} {...restProps} />;
33
+ };
@@ -1,6 +1,7 @@
1
1
  import { style, createVar } from '@vanilla-extract/css';
2
2
  import { calc } from '@vanilla-extract/css-utils';
3
- import { sprinkles, vars, colorPaletteVars } from '../sprinkles.css';
3
+ import { sprinkles, colorPaletteVars } from '../sprinkles.css';
4
+ import { vars } from '../vars.css';
4
5
 
5
6
  export const reset = style([
6
7
  sprinkles({
@@ -78,7 +79,7 @@ export const positive = style({
78
79
  });
79
80
 
80
81
  export const iconContainer = style([
81
- sprinkles({ position: 'relative', paddingLeft: 'medium' }),
82
+ sprinkles({ position: 'relative', paddingLeft: 'small' }),
82
83
  {
83
84
  top: '1px',
84
85
  },
@@ -7,7 +7,6 @@ interface BaseProps {
7
7
  as?: ElementType;
8
8
  tone?: 'positive';
9
9
  icon?: ReactElement;
10
- 'data-testid'?: string;
11
10
  }
12
11
 
13
12
  interface ButtonProps
@@ -1,5 +1,6 @@
1
1
  import { style, globalStyle, keyframes, createVar } from '@vanilla-extract/css';
2
- import { vars, colorPaletteVars, sprinkles } from '../sprinkles.css';
2
+ import { colorPaletteVars, sprinkles } from '../sprinkles.css';
3
+ import { vars } from '../vars.css';
3
4
  import { toolbarItemSize } from '../ToolbarItem/ToolbarItem.css';
4
5
 
5
6
  const minimumLineNumberWidth = '50px';
@@ -296,9 +297,9 @@ globalStyle('.CodeMirror-dialog button', {
296
297
  appearance: 'none',
297
298
  font: vars.font.scale.standard,
298
299
  fontFamily: vars.font.family.standard,
299
- marginLeft: vars.space.medium,
300
- paddingTop: vars.space.medium,
301
- paddingBottom: vars.space.medium,
300
+ marginLeft: vars.space.small,
301
+ paddingTop: vars.space.small,
302
+ paddingBottom: vars.space.small,
302
303
  paddingLeft: vars.space.large,
303
304
  paddingRight: vars.space.large,
304
305
  alignSelf: 'center',
@@ -1,50 +1,29 @@
1
1
  import { style } from '@vanilla-extract/css';
2
2
  import { sprinkles } from '../sprinkles.css';
3
3
 
4
- export const root = style([
5
- sprinkles({
6
- height: 'full',
7
- width: 'full',
8
- whiteSpace: 'nowrap',
9
- display: 'flex',
10
- boxSizing: 'border-box',
11
- paddingY: 'gutter',
12
- paddingLeft: 'gutter',
13
- textAlign: 'center',
14
- }),
15
- {
16
- overflowX: 'auto',
17
- overflowY: 'hidden',
18
- // // Simulate centering when fewer frames than viewport width.
19
- '::before': {
20
- content: '""',
21
- flex: 1,
22
- },
23
- '::after': {
24
- content: '""',
25
- flex: 1,
26
- },
27
- },
28
- ]);
4
+ export const root = sprinkles({
5
+ height: 'full',
6
+ boxSizing: 'border-box',
7
+ display: 'flex',
8
+ padding: 'gutter',
9
+ textAlign: 'center',
10
+ overflow: 'auto',
11
+ });
29
12
 
30
- export const frameContainer = style([
31
- sprinkles({
32
- position: 'relative',
33
- height: 'full',
34
- textAlign: 'left',
35
- display: 'flex',
36
- flexDirection: 'column',
37
- paddingRight: 'gutter',
38
- }),
39
- {},
40
- ]);
13
+ export const frameContainer = sprinkles({
14
+ position: 'relative',
15
+ height: 'full',
16
+ textAlign: 'left',
17
+ display: 'flex',
18
+ flexDirection: 'column',
19
+ });
41
20
 
42
- export const frame = style([
43
- sprinkles({ position: 'relative', height: 'full', border: 0 }),
44
- {
45
- flexGrow: 1,
46
- },
47
- ]);
21
+ export const frame = sprinkles({
22
+ position: 'relative',
23
+ height: 'full',
24
+ border: 0,
25
+ flexGrow: 1,
26
+ });
48
27
 
49
28
  export const frameBorder = style([
50
29
  sprinkles({
@@ -9,6 +9,7 @@ import playroomConfig from '../../config';
9
9
  import frameSrc from './frameSrc';
10
10
 
11
11
  import * as styles from './Frames.css';
12
+ import { Box } from '../Box/Box';
12
13
 
13
14
  interface FramesProps {
14
15
  code: string;
@@ -34,36 +35,38 @@ export default function Frames({ code, themes, widths }: FramesProps) {
34
35
 
35
36
  return (
36
37
  <div ref={scrollingPanelRef} className={styles.root}>
37
- {frames.map((frame) => (
38
- <div
39
- key={`${frame.theme}_${frame.width}`}
40
- className={styles.frameContainer}
41
- >
42
- <div className={styles.frame}>
43
- <div className={styles.frameBorder} />
44
- <Iframe
45
- intersectionRootRef={scrollingPanelRef}
46
- src={frameSrc(
47
- { themeName: frame.theme, code: renderCode.current },
48
- playroomConfig
38
+ <Box display="flex" gap="gutter" marginX="auto">
39
+ {frames.map((frame) => (
40
+ <div
41
+ key={`${frame.theme}_${frame.width}`}
42
+ className={styles.frameContainer}
43
+ >
44
+ <div className={styles.frame}>
45
+ <div className={styles.frameBorder} />
46
+ <Iframe
47
+ intersectionRootRef={scrollingPanelRef}
48
+ src={frameSrc(
49
+ { themeName: frame.theme, code: renderCode.current },
50
+ playroomConfig
51
+ )}
52
+ className={styles.frame}
53
+ style={{ width: frame.width }}
54
+ data-testid="previewFrame"
55
+ />
56
+ </div>
57
+ <div className={styles.frameName} data-testid="frameName">
58
+ {frame.theme === '__PLAYROOM__NO_THEME__' ? (
59
+ <Text weight="strong">{frame.widthName}</Text>
60
+ ) : (
61
+ <Text>
62
+ <Strong>{frame.theme}</Strong>
63
+ {` \u2013 ${frame.widthName}`}
64
+ </Text>
49
65
  )}
50
- className={styles.frame}
51
- style={{ width: frame.width }}
52
- data-testid="previewFrame"
53
- />
66
+ </div>
54
67
  </div>
55
- <div className={styles.frameName} data-testid="frameName">
56
- {frame.theme === '__PLAYROOM__NO_THEME__' ? (
57
- <Text weight="strong">{frame.widthName}</Text>
58
- ) : (
59
- <Text>
60
- <Strong>{frame.theme}</Strong>
61
- {` \u2013 ${frame.widthName}`}
62
- </Text>
63
- )}
64
- </div>
65
- </div>
66
- ))}
68
+ ))}
69
+ </Box>
67
70
  </div>
68
71
  );
69
72
  }
@@ -1,20 +1,14 @@
1
1
  import { calc } from '@vanilla-extract/css-utils';
2
2
  import { globalStyle, style } from '@vanilla-extract/css';
3
- import { colorPaletteVars, sprinkles, vars } from '../sprinkles.css';
4
-
5
- export const title = sprinkles({
6
- display: 'flex',
7
- alignItems: 'center',
8
- justifyContent: 'space-between',
9
- marginBottom: 'medium',
10
- });
3
+ import { colorPaletteVars, sprinkles } from '../sprinkles.css';
4
+ import { vars } from '../vars.css';
11
5
 
12
6
  export const reset = style([
13
7
  sprinkles({
14
8
  position: 'relative',
15
9
  font: 'small',
16
10
  border: 0,
17
- padding: 'medium',
11
+ padding: 'small',
18
12
  appearance: 'none',
19
13
  }),
20
14
  {
@@ -22,7 +16,7 @@ export const reset = style([
22
16
  backgroundColor: 'transparent',
23
17
  outline: 'none',
24
18
  textDecoration: 'underline',
25
- margin: calc(vars.space.medium).negate().toString(),
19
+ margin: calc(vars.space.small).negate().toString(),
26
20
  '::before': {
27
21
  content: '""',
28
22
  position: 'absolute',
@@ -46,18 +40,9 @@ export const reset = style([
46
40
  },
47
41
  ]);
48
42
 
49
- export const label = style([
50
- sprinkles({
51
- position: 'relative',
52
- display: 'flex',
53
- alignItems: 'center',
54
- cursor: 'pointer',
55
- userSelect: 'none',
56
- }),
57
- {
58
- height: calc(vars.grid).multiply(9).toString(),
59
- },
60
- ]);
43
+ export const label = sprinkles({
44
+ cursor: 'pointer',
45
+ });
61
46
 
62
47
  const checkboxSize = '20px';
63
48
  export const checkbox = style([
@@ -67,7 +52,6 @@ export const checkbox = style([
67
52
  left: 0,
68
53
  right: 0,
69
54
  opacity: 0,
70
- pointerEvents: 'none',
71
55
  }),
72
56
  {
73
57
  height: checkboxSize,
@@ -83,8 +67,8 @@ export const fakeCheckbox = style([
83
67
  justifyContent: 'center',
84
68
  position: 'relative',
85
69
  borderRadius: 'large',
86
- marginRight: 'large',
87
70
  padding: checkboxPadding,
71
+ pointerEvents: 'none',
88
72
  }),
89
73
  {
90
74
  flexGrow: 0,
@@ -5,9 +5,11 @@ import { ToolbarPanel } from '../ToolbarPanel/ToolbarPanel';
5
5
  import { StoreContext } from '../../StoreContext/StoreContext';
6
6
  import { Stack } from '../Stack/Stack';
7
7
  import { Text } from '../Text/Text';
8
+ import { Helmet } from 'react-helmet';
9
+ import { Inline } from '../Inline/Inline';
10
+ import { Box } from '../Box/Box';
8
11
 
9
12
  import * as styles from './FramesPanel.css';
10
- import { Helmet } from 'react-helmet';
11
13
 
12
14
  const getTitle = (title: string | undefined) => {
13
15
  if (title) {
@@ -45,48 +47,47 @@ interface FrameHeadingProps {
45
47
  children: ReactNode;
46
48
  }
47
49
  const FrameHeading = ({ showReset, onReset, children }: FrameHeadingProps) => (
48
- <div className={styles.title}>
49
- <Heading level="3">{children}</Heading>
50
- {showReset && <ResetButton onClick={onReset}>Show all</ResetButton>}
51
- </div>
50
+ <Inline space="none" alignY="center">
51
+ <Box flexGrow={1}>
52
+ <Heading level="3">{children}</Heading>
53
+ </Box>
54
+ {showReset && <ResetButton onClick={onReset}>Clear</ResetButton>}
55
+ </Inline>
52
56
  );
53
57
 
54
58
  interface FrameOptionProps<Option> {
55
59
  option: Option;
56
60
  selected: boolean;
57
61
  visible: Option[];
58
- available: Option[];
59
62
  onChange: (options?: Option[]) => void;
60
63
  }
61
64
  function FrameOption<Option>({
62
65
  option,
63
66
  selected,
64
67
  visible,
65
- available,
66
68
  onChange,
67
69
  }: FrameOptionProps<Option>) {
68
70
  return (
69
71
  <label className={styles.label}>
70
- <input
71
- type="checkbox"
72
- checked={selected}
73
- className={styles.checkbox}
74
- onChange={(ev) => {
75
- if (ev.target.checked) {
76
- const newVisiblePreference = [...visible, option];
77
- const isOriginalList =
78
- JSON.stringify(newVisiblePreference.sort()) ===
79
- JSON.stringify([...available].sort());
80
- onChange(isOriginalList ? undefined : newVisiblePreference);
81
- } else {
82
- onChange(visible.filter((p) => p !== option));
83
- }
84
- }}
85
- />
86
- <div className={styles.fakeCheckbox}>
87
- <Checkmark />
88
- </div>
89
- <Text truncate>{String(option)}</Text>
72
+ <Inline space="large" alignY="center">
73
+ <input
74
+ type="checkbox"
75
+ checked={selected}
76
+ className={styles.checkbox}
77
+ onChange={(event) => {
78
+ if (event.target.checked) {
79
+ const newVisiblePreference = [...visible, option];
80
+ onChange(newVisiblePreference);
81
+ } else {
82
+ onChange(visible.filter((p) => p !== option));
83
+ }
84
+ }}
85
+ />
86
+ <div className={styles.fakeCheckbox}>
87
+ <Checkmark />
88
+ </div>
89
+ <Text truncate>{String(option)}</Text>
90
+ </Inline>
90
91
  </label>
91
92
  );
92
93
  }
@@ -112,10 +113,10 @@ export default ({ availableWidths, availableThemes }: FramesPanelProps) => {
112
113
  <title>{displayedTitle}</title>
113
114
  </Helmet>
114
115
  )}
115
- <ToolbarPanel data-testid="frame-panel">
116
+ <ToolbarPanel>
116
117
  <Stack space="xxxlarge">
117
118
  <label>
118
- <Stack space="medium">
119
+ <Stack space="small">
119
120
  <Heading level="3">Title</Heading>
120
121
  <input
121
122
  type="text"
@@ -133,21 +134,19 @@ export default ({ availableWidths, availableThemes }: FramesPanelProps) => {
133
134
  </Stack>
134
135
  </label>
135
136
 
136
- <div data-testid="widthsPreferences">
137
+ <Stack space="xlarge">
137
138
  <FrameHeading
138
139
  showReset={hasFilteredWidths}
139
140
  onReset={() => dispatch({ type: 'resetVisibleWidths' })}
140
141
  >
141
142
  Widths
142
143
  </FrameHeading>
143
-
144
144
  {availableWidths.map((option) => (
145
145
  <FrameOption
146
146
  key={option}
147
147
  option={option}
148
148
  selected={hasFilteredWidths && visibleWidths.includes(option)}
149
149
  visible={visibleWidths}
150
- available={availableWidths}
151
150
  onChange={(newWidths) => {
152
151
  if (newWidths) {
153
152
  dispatch({
@@ -160,24 +159,22 @@ export default ({ availableWidths, availableThemes }: FramesPanelProps) => {
160
159
  }}
161
160
  />
162
161
  ))}
163
- </div>
162
+ </Stack>
164
163
 
165
164
  {hasThemes ? (
166
- <div data-testid="themePreferences">
165
+ <Stack space="xlarge">
167
166
  <FrameHeading
168
167
  showReset={hasFilteredThemes}
169
168
  onReset={() => dispatch({ type: 'resetVisibleThemes' })}
170
169
  >
171
170
  Themes
172
171
  </FrameHeading>
173
-
174
172
  {availableThemes.map((option) => (
175
173
  <FrameOption
176
174
  key={option}
177
175
  option={option}
178
176
  selected={hasFilteredThemes && visibleThemes.includes(option)}
179
177
  visible={visibleThemes}
180
- available={availableThemes}
181
178
  onChange={(newThemes) => {
182
179
  if (newThemes) {
183
180
  dispatch({
@@ -190,7 +187,7 @@ export default ({ availableWidths, availableThemes }: FramesPanelProps) => {
190
187
  }}
191
188
  />
192
189
  ))}
193
- </div>
190
+ </Stack>
194
191
  ) : null}
195
192
  </Stack>
196
193
  </ToolbarPanel>
@@ -1,4 +1,5 @@
1
- import { sprinkles, vars, colorPaletteVars } from '../sprinkles.css';
1
+ import { sprinkles, colorPaletteVars } from '../sprinkles.css';
2
+ import { vars } from '../vars.css';
2
3
  import { style } from '@vanilla-extract/css';
3
4
 
4
5
  export const base = style([