playroom 0.36.0 → 0.37.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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # playroom
2
2
 
3
+ ## 0.37.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 94c75f8: Add "Find", "Find and replace", and "Jump to line" functionality.
8
+
9
+ Keybindings for these new commands are:
10
+
11
+ - `Cmd + F` / `Ctrl + F` - Find
12
+ - `Cmd + Option + F` / `Ctrl + Alt + F` - Find and replace
13
+ - `Cmd + G` / `Ctrl + G` - Jump to line
14
+
15
+ ### Patch Changes
16
+
17
+ - 71f694a: Fix issue with "Toggle comment" command commenting certain code outside JSX tags with incorrect syntax.
18
+
3
19
  ## 0.36.0
4
20
 
5
21
  ### Minor Changes
@@ -3,6 +3,7 @@ import {
3
3
  typeCode,
4
4
  assertCodePaneContains,
5
5
  loadPlayroom,
6
+ cmdPlus,
6
7
  selectNextWords,
7
8
  selectNextLines,
8
9
  selectNextCharacters,
@@ -11,14 +12,13 @@ import {
11
12
  moveToEndOfLine,
12
13
  moveBy,
13
14
  moveByWords,
15
+ assertCodePaneSearchMatchesCount,
16
+ findInCode,
17
+ replaceInCode,
18
+ jumpToLine,
14
19
  } from '../support/utils';
15
20
  import { isMac } from '../../src/utils/formatting';
16
21
 
17
- const cmdPlus = (keyCombo) => {
18
- const platformSpecificKey = isMac() ? 'cmd' : 'ctrl';
19
- return `${platformSpecificKey}+${keyCombo}`;
20
- };
21
-
22
22
  describe('Keymaps', () => {
23
23
  describe('swapLine', () => {
24
24
  beforeEach(() => {
@@ -350,6 +350,163 @@ describe('Keymaps', () => {
350
350
  });
351
351
  });
352
352
 
353
+ describe('find and replace', () => {
354
+ beforeEach(() => {
355
+ loadPlayroom(`
356
+ <div>First line</div>
357
+ <div>Second line</div>
358
+ <div>Third line</div>
359
+ `);
360
+ });
361
+
362
+ it('should find all occurrences of search term', () => {
363
+ findInCode('div');
364
+
365
+ assertCodePaneSearchMatchesCount(6);
366
+
367
+ cy.focused().type('{esc}');
368
+
369
+ typeCode('c');
370
+
371
+ assertCodePaneContains(dedent`
372
+ <c>First line</div>
373
+ <div>Second line</div>
374
+ <div>Third line</div>
375
+ `);
376
+ });
377
+
378
+ it('should replace and skip occurrences of search term correctly', () => {
379
+ replaceInCode('div', 'span');
380
+
381
+ // replace occurrence
382
+ cy.get('.CodeMirror-dialog button').contains('Yes').click();
383
+
384
+ assertCodePaneContains(dedent`
385
+ <span>First line</div>
386
+ <div>Second line</div>
387
+ <div>Third line</div>
388
+ `);
389
+
390
+ // ignore occurrence
391
+ cy.get('.CodeMirror-dialog button').contains('No').click();
392
+
393
+ assertCodePaneContains(dedent`
394
+ <span>First line</div>
395
+ <div>Second line</div>
396
+ <div>Third line</div>
397
+ `);
398
+
399
+ // replace occurrence
400
+ cy.get('.CodeMirror-dialog button').contains('Yes').click();
401
+
402
+ assertCodePaneContains(dedent`
403
+ <span>First line</div>
404
+ <span>Second line</div>
405
+ <div>Third line</div>
406
+ `);
407
+
408
+ // replace all remaining occurrences
409
+ cy.get('.CodeMirror-dialog button').contains('All').click();
410
+
411
+ assertCodePaneContains(dedent`
412
+ <span>First line</span>
413
+ <span>Second line</span>
414
+ <span>Third line</span>
415
+ `);
416
+
417
+ typeCode('c');
418
+
419
+ assertCodePaneContains(dedent`
420
+ <span>First line</span>
421
+ <span>Second line</spanc>
422
+ <span>Third line</span>
423
+ `);
424
+ });
425
+
426
+ it('should back out of replace correctly', () => {
427
+ replaceInCode('div');
428
+
429
+ typeCode('{esc}');
430
+
431
+ assertCodePaneContains(dedent`
432
+ <div>First line</div>
433
+ <div>Second line</div>
434
+ <div>Third line</div>
435
+ `);
436
+
437
+ typeCode('c');
438
+
439
+ assertCodePaneContains(dedent`
440
+ c<div>First line</div>
441
+ <div>Second line</div>
442
+ <div>Third line</div>
443
+ `);
444
+ });
445
+ });
446
+
447
+ describe('jump to line', () => {
448
+ beforeEach(() => {
449
+ loadPlayroom(`
450
+ <div>First line</div>
451
+ <div>Second line</div>
452
+ <div>Third line</div>
453
+ <div>Forth line</div>
454
+ <div>Fifth line</div>
455
+ <div>Sixth line</div>
456
+ <div>Seventh line</div>
457
+ `);
458
+ });
459
+
460
+ it('should jump to line number correctly', () => {
461
+ const line = 6;
462
+ jumpToLine(line);
463
+
464
+ typeCode('c');
465
+
466
+ assertCodePaneContains(dedent`
467
+ <div>First line</div>
468
+ <div>Second line</div>
469
+ <div>Third line</div>
470
+ <div>Forth line</div>
471
+ <div>Fifth line</div>
472
+ c<div>Sixth line</div>
473
+ <div>Seventh line</div>
474
+ `);
475
+
476
+ typeCode('{backspace}');
477
+
478
+ const nextLine = 2;
479
+ jumpToLine(nextLine);
480
+
481
+ typeCode('c');
482
+
483
+ assertCodePaneContains(dedent`
484
+ <div>First line</div>
485
+ c<div>Second line</div>
486
+ <div>Third line</div>
487
+ <div>Forth line</div>
488
+ <div>Fifth line</div>
489
+ <div>Sixth line</div>
490
+ <div>Seventh line</div>
491
+ `);
492
+ });
493
+
494
+ it('should jump to line and column number correctly', () => {
495
+ jumpToLine('6:10');
496
+ typeCode('a');
497
+
498
+ assertCodePaneContains(dedent`
499
+ <div>First line</div>
500
+ <div>Second line</div>
501
+ <div>Third line</div>
502
+ <div>Forth line</div>
503
+ <div>Fifth line</div>
504
+ <div>Sixtha line</div>
505
+ <div>Seventh line</div>
506
+ `);
507
+ });
508
+ });
509
+
353
510
  describe('toggleComment', () => {
354
511
  const blockStarter = `
355
512
  <div>First line</div>
@@ -412,7 +569,7 @@ describe('Keymaps', () => {
412
569
  >
413
570
  Text
414
571
  </button>
415
- `);
572
+ `);
416
573
 
417
574
  moveBy(0, 2);
418
575
 
@@ -429,6 +586,76 @@ describe('Keymaps', () => {
429
586
  </button>
430
587
  `);
431
588
  });
589
+
590
+ it('block - expression slot outside tags', () => {
591
+ loadPlayroom(`
592
+ {testFn('test')}
593
+ <div>First line</div>
594
+ <div>Second line</div>
595
+ <div>Third line</div>
596
+ `);
597
+
598
+ executeToggleCommentCommand();
599
+
600
+ assertCodePaneContains(dedent`
601
+ {/* {testFn('test')} */}
602
+ <div>First line</div>
603
+ <div>Second line</div>
604
+ <div>Third line</div>
605
+ `);
606
+ });
607
+
608
+ it('line - inside multi-line expression slot outside tags', () => {
609
+ loadPlayroom(`
610
+ {
611
+ testFn('test')
612
+ }
613
+ <div>First line</div>
614
+ <div>Second line</div>
615
+ <div>Third line</div>
616
+ `);
617
+
618
+ moveBy(0, 1);
619
+
620
+ executeToggleCommentCommand();
621
+
622
+ assertCodePaneContains(dedent`
623
+ {
624
+ // testFn('test')
625
+ }
626
+ <div>First line</div>
627
+ <div>Second line</div>
628
+ <div>Third line</div>
629
+ `);
630
+ });
631
+
632
+ it('line - full line expression slot inside tags', () => {
633
+ loadPlayroom(`
634
+ <div
635
+ prop1="prop1"
636
+ {...props}
637
+ >
638
+ First line
639
+ </div>
640
+ <div>Second line</div>
641
+ <div>Third line</div>
642
+ `);
643
+
644
+ moveBy(0, 2);
645
+
646
+ executeToggleCommentCommand();
647
+
648
+ assertCodePaneContains(dedent`
649
+ <div
650
+ prop1="prop1"
651
+ // {...props}
652
+ >
653
+ First line
654
+ </div>
655
+ <div>Second line</div>
656
+ <div>Third line</div>
657
+ `);
658
+ });
432
659
  });
433
660
 
434
661
  describe('should wrap a single line selection in a comment', () => {
@@ -1391,7 +1618,7 @@ describe('Keymaps', () => {
1391
1618
  });
1392
1619
  });
1393
1620
 
1394
- describe('for an selection beginning during opening comment syntax', () => {
1621
+ describe('for a selection beginning during opening comment syntax', () => {
1395
1622
  it('block', () => {
1396
1623
  loadPlayroom(`
1397
1624
  <div>
@@ -5,6 +5,11 @@ import dedent from 'dedent';
5
5
  import { createUrl } from '../../utils';
6
6
  import { isMac } from '../../src/utils/formatting';
7
7
 
8
+ export const cmdPlus = (keyCombo) => {
9
+ const platformSpecificKey = isMac() ? 'cmd' : 'ctrl';
10
+ return `${platformSpecificKey}+${keyCombo}`;
11
+ };
12
+
8
13
  const getCodeEditor = () =>
9
14
  cy.get('.CodeMirror-code').then((editor) => cy.wrap(editor));
10
15
 
@@ -182,3 +187,50 @@ export const loadPlayroom = (initialCode) => {
182
187
  indexedDB.deleteDatabase(storageKey);
183
188
  });
184
189
  };
190
+
191
+ const typeInSearchField = (text) =>
192
+ cy.get('.CodeMirror-search-field').type(text);
193
+
194
+ /**
195
+ * @param {string} term
196
+ */
197
+ export const findInCode = (term) => {
198
+ // Wait necessary to ensure code pane is focussed
199
+ cy.wait(500); // eslint-disable-line @finsit/cypress/no-unnecessary-waiting
200
+ typeCode(`{${cmdPlus('f')}}`);
201
+
202
+ typeInSearchField(`${term}{enter}`);
203
+ };
204
+
205
+ /**
206
+ * @param {string} term
207
+ * @param {string} [replaceWith]
208
+ */
209
+ export const replaceInCode = (term, replaceWith) => {
210
+ // Wait necessary to ensure code pane is focussed
211
+ cy.wait(500); // eslint-disable-line @finsit/cypress/no-unnecessary-waiting
212
+ typeCode(`{${cmdPlus('alt+f')}}`);
213
+ typeInSearchField(`${term}{enter}`);
214
+ if (replaceWith) {
215
+ typeInSearchField(`${replaceWith}{enter}`);
216
+ }
217
+ };
218
+
219
+ /**
220
+ * @param {number} line
221
+ */
222
+ export const jumpToLine = (line) => {
223
+ // Wait necessary to ensure code pane is focussed
224
+ cy.wait(500); // eslint-disable-line @finsit/cypress/no-unnecessary-waiting
225
+ typeCode(`{${cmdPlus('g')}}`);
226
+ typeCode(`${line}{enter}`);
227
+ };
228
+
229
+ /**
230
+ * @param {number} lines
231
+ */
232
+ export const assertCodePaneSearchMatchesCount = (lines) => {
233
+ getCodeEditor().within(() =>
234
+ cy.get('.cm-searching').should('have.length', lines)
235
+ );
236
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playroom",
3
- "version": "0.36.0",
3
+ "version": "0.37.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",
@@ -86,6 +86,7 @@
86
86
  "@octokit/rest": "^19.0.5",
87
87
  "@types/jest": "^29.2.4",
88
88
  "@types/react-helmet": "^6.1.6",
89
+ "concurrently": "^7.6.0",
89
90
  "cypress": "^13.6.6",
90
91
  "eslint": "^8.44.0",
91
92
  "eslint-config-seek": "^11.3.1",
@@ -122,11 +123,11 @@
122
123
  "start:typescript": "./bin/cli.cjs start --config cypress/projects/typescript/playroom.config.js",
123
124
  "build:typescript": "./bin/cli.cjs build --config cypress/projects/typescript/playroom.config.js",
124
125
  "serve:typescript": "PORT=9002 serve --no-request-logging cypress/projects/typescript/dist",
125
- "start:all": "pnpm run '/^start:(?!all)/'",
126
- "build:all": "pnpm run '/^build:(?!all)/'",
127
- "serve:all": "pnpm run '/^serve:(?!all)/'",
126
+ "start:all": "concurrently 'npm:start:*(!all)'",
127
+ "build:all": "concurrently 'npm:build:*(!all)'",
128
+ "serve:all": "concurrently 'npm:serve:*(!all)'",
128
129
  "build-and-serve:all": "pnpm build:all && pnpm serve:all",
129
- "lint": "pnpm run '/^lint:.*/'",
130
+ "lint": "concurrently 'npm:lint:*'",
130
131
  "lint:eslint": "eslint --cache .",
131
132
  "lint:prettier": "prettier --list-different '**/*.{js,md,ts,tsx}'",
132
133
  "lint:tsc": "tsc --noEmit",
@@ -1,5 +1,6 @@
1
- import { style, globalStyle, keyframes } from '@vanilla-extract/css';
1
+ import { style, globalStyle, keyframes, createVar } from '@vanilla-extract/css';
2
2
  import { vars, colorPaletteVars, sprinkles } from '../sprinkles.css';
3
+ import { toolbarItemSize } from '../ToolbarItem/ToolbarItem.css';
3
4
 
4
5
  const minimumLineNumberWidth = '50px';
5
6
 
@@ -224,3 +225,100 @@ globalStyle('.cm-s-neo .cm-variable', {
224
225
  globalStyle('.cm-s-neo .cm-number', {
225
226
  color: colorPaletteVars.code.number,
226
227
  });
228
+
229
+ globalStyle('.CodeMirror-dialog', {
230
+ paddingLeft: vars.space.xlarge,
231
+ paddingRight: vars.space.xlarge,
232
+ minHeight: toolbarItemSize,
233
+ borderBottom: `1px solid ${colorPaletteVars.border.standard}`,
234
+ display: 'flex',
235
+ alignItems: 'center',
236
+ });
237
+
238
+ const searchOffset = createVar();
239
+ globalStyle('.CodeMirror-scroll', {
240
+ transform: `translateY(${searchOffset})`,
241
+ transition: vars.transition.fast,
242
+ });
243
+
244
+ globalStyle('.dialog-opened .CodeMirror-scroll', {
245
+ vars: {
246
+ [searchOffset]: `${toolbarItemSize}px`,
247
+ },
248
+ });
249
+
250
+ globalStyle('.dialog-opened .CodeMirror-lines', {
251
+ paddingBottom: searchOffset,
252
+ });
253
+
254
+ globalStyle('.CodeMirror-dialog input', {
255
+ font: vars.font.scale.large,
256
+ fontFamily: vars.font.family.code,
257
+ height: vars.touchableSize,
258
+ flexGrow: 1,
259
+ });
260
+
261
+ globalStyle('.CodeMirror-search-hint', {
262
+ display: 'none',
263
+ });
264
+
265
+ globalStyle('.CodeMirror-search-label', {
266
+ display: 'flex',
267
+ alignItems: 'center',
268
+ minHeight: vars.touchableSize,
269
+ font: vars.font.scale.large,
270
+ fontFamily: vars.font.family.code,
271
+ });
272
+
273
+ globalStyle('.CodeMirror-search-field', {
274
+ paddingLeft: vars.space.xlarge,
275
+ });
276
+
277
+ globalStyle('label.CodeMirror-search-label', {
278
+ flexGrow: 1,
279
+ });
280
+
281
+ globalStyle('.dialog-opened.cm-s-neo .CodeMirror-selected', {
282
+ background: colorPaletteVars.background.search,
283
+ });
284
+
285
+ globalStyle('.cm-overlay.cm-searching', {
286
+ paddingTop: 2,
287
+ paddingBottom: 2,
288
+ background: colorPaletteVars.background.selection,
289
+ });
290
+
291
+ globalStyle('.CodeMirror-dialog button:first-of-type', {
292
+ marginLeft: vars.space.xlarge,
293
+ });
294
+
295
+ globalStyle('.CodeMirror-dialog button', {
296
+ appearance: 'none',
297
+ font: vars.font.scale.standard,
298
+ fontFamily: vars.font.family.standard,
299
+ marginLeft: vars.space.medium,
300
+ paddingTop: vars.space.medium,
301
+ paddingBottom: vars.space.medium,
302
+ paddingLeft: vars.space.large,
303
+ paddingRight: vars.space.large,
304
+ alignSelf: 'center',
305
+ display: 'block',
306
+ background: 'none',
307
+ borderRadius: vars.radii.large,
308
+ cursor: 'pointer',
309
+ border: '1px solid currentColor',
310
+ });
311
+
312
+ globalStyle('.CodeMirror-dialog button:focus', {
313
+ color: colorPaletteVars.foreground.accent,
314
+ boxShadow: colorPaletteVars.shadows.focus,
315
+ outline: 'none',
316
+ });
317
+
318
+ globalStyle('.CodeMirror-dialog button:focus:hover', {
319
+ background: colorPaletteVars.background.selection,
320
+ });
321
+
322
+ globalStyle('.CodeMirror-dialog button:hover', {
323
+ background: colorPaletteVars.background.transparent,
324
+ });
@@ -2,6 +2,7 @@ import { useRef, useContext, useEffect, useCallback } from 'react';
2
2
  import { useDebouncedCallback } from 'use-debounce';
3
3
  import type { Editor } from 'codemirror';
4
4
  import 'codemirror/lib/codemirror.css';
5
+ import 'codemirror/addon/dialog/dialog.css';
5
6
  import 'codemirror/theme/neo.css';
6
7
 
7
8
  import {
@@ -26,6 +27,10 @@ import 'codemirror/addon/edit/closetag';
26
27
  import 'codemirror/addon/edit/closebrackets';
27
28
  import 'codemirror/addon/hint/show-hint';
28
29
  import 'codemirror/addon/hint/xml-hint';
30
+ import 'codemirror/addon/dialog/dialog';
31
+ import 'codemirror/addon/search/jump-to-line';
32
+ import 'codemirror/addon/search/search';
33
+ import 'codemirror/addon/search/searchcursor';
29
34
  import 'codemirror/addon/selection/active-line';
30
35
  import 'codemirror/addon/fold/foldcode';
31
36
  import 'codemirror/addon/fold/foldgutter';
@@ -117,6 +122,17 @@ export const CodeEditor = ({ code, onChange, previewCode, hints }: Props) => {
117
122
  e.preventDefault();
118
123
  dispatch({ type: 'toggleToolbar', payload: { panel: 'snippets' } });
119
124
  }
125
+
126
+ // Prevent browser keyboard shortcuts when the search/replace input is focused
127
+ if (
128
+ cmdOrCtrl &&
129
+ document.activeElement?.classList.contains(
130
+ 'CodeMirror-search-field'
131
+ ) &&
132
+ e.key === 'f'
133
+ ) {
134
+ e.preventDefault();
135
+ }
120
136
  }
121
137
  };
122
138
 
@@ -259,6 +275,14 @@ export const CodeEditor = ({ code, onChange, previewCode, hints }: Props) => {
259
275
  [`${keymapModifierKey}-D`]: selectNextOccurrence,
260
276
  [`Shift-${keymapModifierKey}-,`]: wrapInTag,
261
277
  [`${keymapModifierKey}-/`]: toggleComment,
278
+ [`${keymapModifierKey}-F`]: 'findPersistent',
279
+ [`${keymapModifierKey}-Alt-F`]: 'replace',
280
+ [`${keymapModifierKey}-G`]: 'jumpToLine',
281
+ ['Alt-G']: false, // override default keybinding
282
+ ['Alt-F']: false, // override default keybinding
283
+ ['Shift-Ctrl-R']: false, // override default keybinding
284
+ ['Cmd-Option-F']: false, // override default keybinding
285
+ ['Shift-Cmd-Option-F']: false, // override default keybinding
262
286
  [`Shift-${keymapModifierKey}-C`]: () => {
263
287
  dispatch({
264
288
  type: 'copyToClipboard',
@@ -198,6 +198,19 @@ function getUpdatedContent(existingContent: string, range: TagRange) {
198
198
 
199
199
  type CommentType = 'line' | 'block';
200
200
 
201
+ const isOnlyWhitespace = (input: string) => /^\s+$/.test(input);
202
+
203
+ const isFullExpressionSlot = (tokens: CodeMirror.Token[]) => {
204
+ const formattedLineTokens = tokens.filter(
205
+ (token) => token.type !== 'comment' && !isOnlyWhitespace(token.string)
206
+ );
207
+
208
+ return (
209
+ formattedLineTokens.at(0)?.string === '{' &&
210
+ formattedLineTokens.at(-1)?.string === '}'
211
+ );
212
+ };
213
+
201
214
  interface TagRange {
202
215
  from: CodeMirror.Position;
203
216
  to: CodeMirror.Position;
@@ -219,7 +232,9 @@ const determineCommentType = (
219
232
  (token) => token.type === 'attribute'
220
233
  );
221
234
 
222
- const isJavaScriptMode = cm.getModeAt(from).name === 'javascript';
235
+ const isJavaScriptMode =
236
+ cm.getModeAt(new Pos(from.line, 0)).name === 'javascript';
237
+
223
238
  const isInlineComment = cm
224
239
  .getLine(from.line)
225
240
  .trimStart()
@@ -228,6 +243,10 @@ const determineCommentType = (
228
243
  cm.getLine(from.line).trimStart().startsWith(BLOCK_COMMENT_START) &&
229
244
  cm.getLine(to.line).trimEnd().endsWith(BLOCK_COMMENT_END);
230
245
 
246
+ if (!isBlockComment && isFullExpressionSlot(lineTokens)) {
247
+ return isJavaScriptMode ? 'block' : 'line';
248
+ }
249
+
231
250
  if (isInlineComment) {
232
251
  return 'line';
233
252
  }
@@ -25,12 +25,15 @@ const getKeyBindings = () => {
25
25
  const shiftKeySymbol = isMac() ? '⇧' : 'Shift';
26
26
 
27
27
  return {
28
+ Find: [metaKeySymbol, 'F'],
29
+ 'Find and replace': [metaKeySymbol, altKeySymbol, 'F'],
28
30
  'Toggle comment': [metaKeySymbol, '/'],
29
31
  'Wrap selection in tag': [metaKeySymbol, shiftKeySymbol, ','],
30
32
  'Format code': [metaKeySymbol, 'S'],
31
33
  'Insert snippet': [metaKeySymbol, 'K'],
32
34
  'Copy Playroom link': [metaKeySymbol, shiftKeySymbol, 'C'],
33
35
  'Select next occurrence': [metaKeySymbol, 'D'],
36
+ 'Jump to line number': [metaKeySymbol, 'G'],
34
37
  'Swap line up': [altKeySymbol, '↑'],
35
38
  'Swap line down': [altKeySymbol, '↓'],
36
39
  'Duplicate line up': [shiftKeySymbol, altKeySymbol, '↑'],
@@ -49,7 +49,8 @@ export const light = {
49
49
  neutral: originalPalette.gray2,
50
50
  surface: originalPalette.white,
51
51
  body: originalPalette.gray1,
52
- selection: originalPalette.blue0,
52
+ selection: transparentize(0.85, originalPalette.blue1),
53
+ search: darken(0.15, originalPalette.blue0),
53
54
  },
54
55
  border: {
55
56
  standard: originalPalette.gray2,
@@ -143,14 +144,15 @@ export const dark = {
143
144
  positive: seekPalette.mint[500],
144
145
  },
145
146
  background: {
146
- transparent: 'rgba(0, 0, 0, .15)',
147
+ transparent: 'rgba(255, 255, 255, .07)',
147
148
  accent: seekPalette.blue[500],
148
149
  positive: mix(0.6, seekPalette.grey[900], seekPalette.mint[500]),
149
150
  critical: mix(0.7, seekPalette.grey[900], seekPalette.red[600]),
150
151
  neutral: seekPalette.grey[800],
151
152
  surface: seekPalette.grey[900],
152
153
  body: darken(0.03, seekPalette.grey[900]),
153
- selection: transparentize(0.85, seekPalette.blue[600]),
154
+ selection: transparentize(0.75, seekPalette.blue[600]),
155
+ search: transparentize(0.25, seekPalette.blue[600]),
154
156
  },
155
157
  border: {
156
158
  standard: seekPalette.grey[800],
@@ -75,6 +75,7 @@ export const colorPaletteVars = createThemeContract({
75
75
  surface: null,
76
76
  body: null,
77
77
  selection: null,
78
+ search: null,
78
79
  },
79
80
  border: {
80
81
  standard: null,