diff --git a/src/components/searchable-select.tsx b/src/components/searchable-select.tsx index d7d3605..63128eb 100644 --- a/src/components/searchable-select.tsx +++ b/src/components/searchable-select.tsx @@ -42,6 +42,7 @@ export function SearchableSelect({ }: SearchableSelectProps) { const [open, setOpen] = React.useState(false); const [searchQuery, setSearchQuery] = React.useState(""); + const [justSelected, setJustSelected] = React.useState(false); const selectedOption = React.useMemo( () => options.find((option) => option.value === value), @@ -57,13 +58,27 @@ export function SearchableSelect({ const handleSelect = React.useCallback( (optionValue: string) => { + setJustSelected(true); onValueChange?.(optionValue); - setOpen(false); - setSearchQuery(""); + + setTimeout(() => { + setOpen(false); + setSearchQuery(""); + + setTimeout(() => setJustSelected(false), 300); + }, 10); }, [onValueChange], ); + const handleMouseEnter = React.useCallback( + (optionValue: string) => { + if (justSelected) return; + onPreview?.(optionValue); + }, + [onPreview, justSelected], + ); + return ( @@ -105,7 +120,7 @@ export function SearchableSelect({ "bg-accent text-accent-foreground", )} onClick={() => handleSelect(option.value)} - onMouseEnter={() => onPreview?.(option.value)} + onMouseEnter={() => handleMouseEnter(option.value)} > {option.label} diff --git a/src/utils/custom/dark-squared.json b/src/utils/custom/dark-squared.json new file mode 100644 index 0000000..79f68d7 --- /dev/null +++ b/src/utils/custom/dark-squared.json @@ -0,0 +1,368 @@ +{ + "$schema": "vscode://schemas/color-theme", + "name": "dark-squared", + "colors": { + "editor.background": "#0e0e0e", + "tab.activeBackground": "#1c1c1c", + "tab.inactiveBackground": "#0e0e0e", + "editorGroupHeader.tabsBackground": "#0C0C0C", + "minimap.background": "#1f1f1f", + "sideBar.background": "#181818", + "sideBarSectionHeader.background": "#101010", + "statusBarItem.remoteBackground": "#0C0C0C", + "toolbar.activeBackground": "#101010", + "activityBar.background": "#161616", + "statusBar.background": "#1c1c1c", + "menu.background": "#222222", + "editor.lineHighlightBackground": "#1f1f1f", + "editor.lineHighlightBorder": "#252525", + "titleBar.activeBackground": "#1c1c1c", + "breadcrumb.background": "#000000", + "breadcrumbPicker.background": "#141414", + "actionBar.toggledBackground": "#383a49", + "activityBarBadge.background": "#007ACC", + "checkbox.border": "#6B6B6B", + "editor.foreground": "#D4D4D4", + "editor.inactiveSelectionBackground": "#3A3D41", + "editor.selectionHighlightBackground": "#ADD6FF26", + "editorIndentGuide.activeBackground1": "#707070", + "editorIndentGuide.background1": "#404040", + "input.placeholderForeground": "#A6A6A6", + "list.activeSelectionIconForeground": "#FFF", + "list.dropBackground": "#383B3D", + "menu.border": "#454545", + "menu.foreground": "#CCCCCC", + "menu.selectionBackground": "#0078d4", + "menu.separatorBackground": "#454545", + "ports.iconRunningProcessForeground": "#369432", + "sideBarSectionHeader.border": "#ccc3", + "sideBarTitle.foreground": "#BBBBBB", + "statusBarItem.remoteForeground": "#FFF", + "tab.lastPinnedBorder": "#ccc3", + "tab.selectedBackground": "#222222", + "tab.selectedForeground": "#ffffffa0", + "terminal.inactiveSelectionBackground": "#3A3D41", + "widget.border": "#303031" + }, + "semanticHighlighting": true, + "semanticTokenColors": { + "customLiteral": "#DCDCAA", + "newOperator": "#C586C0", + "numberLiteral": "#b5cea8", + "stringLiteral": "#ce9178" + }, + "tokenColors": [ + { + "scope": [ + "meta.embedded", + "source.groovy.embedded", + "string meta.image.inline.markdown", + "variable.legacy.builtin.python" + ], + "settings": { "foreground": "#D4D4D4" } + }, + { "scope": "emphasis", "settings": { "fontStyle": "italic" } }, + { "scope": "strong", "settings": { "fontStyle": "bold" } }, + { "scope": "header", "settings": { "foreground": "#000080" } }, + { "scope": "comment", "settings": { "foreground": "#6A9955" } }, + { "scope": "constant.language", "settings": { "foreground": "#569cd6" } }, + { + "scope": [ + "constant.numeric", + "variable.other.enummember", + "keyword.operator.plus.exponent", + "keyword.operator.minus.exponent" + ], + "settings": { "foreground": "#b5cea8" } + }, + { "scope": "constant.regexp", "settings": { "foreground": "#646695" } }, + { "scope": "entity.name.tag", "settings": { "foreground": "#569cd6" } }, + { + "scope": ["entity.name.tag.css", "entity.name.tag.less"], + "settings": { "foreground": "#d7ba7d" } + }, + { + "scope": "entity.other.attribute-name", + "settings": { "foreground": "#9cdcfe" } + }, + { + "scope": [ + "entity.other.attribute-name.class.css", + "source.css entity.other.attribute-name.class", + "entity.other.attribute-name.id.css", + "entity.other.attribute-name.parent-selector.css", + "entity.other.attribute-name.parent.less", + "source.css entity.other.attribute-name.pseudo-class", + "entity.other.attribute-name.pseudo-element.css", + "source.css.less entity.other.attribute-name.id", + "entity.other.attribute-name.scss" + ], + "settings": { "foreground": "#d7ba7d" } + }, + { "scope": "invalid", "settings": { "foreground": "#f44747" } }, + { "scope": "markup.underline", "settings": { "fontStyle": "underline" } }, + { + "scope": "markup.bold", + "settings": { "fontStyle": "bold", "foreground": "#569cd6" } + }, + { + "scope": "markup.heading", + "settings": { "fontStyle": "bold", "foreground": "#569cd6" } + }, + { "scope": "markup.italic", "settings": { "fontStyle": "italic" } }, + { + "scope": "markup.strikethrough", + "settings": { "fontStyle": "strikethrough" } + }, + { "scope": "markup.inserted", "settings": { "foreground": "#b5cea8" } }, + { "scope": "markup.deleted", "settings": { "foreground": "#ce9178" } }, + { "scope": "markup.changed", "settings": { "foreground": "#569cd6" } }, + { + "scope": "punctuation.definition.quote.begin.markdown", + "settings": { "foreground": "#6A9955" } + }, + { + "scope": "punctuation.definition.list.begin.markdown", + "settings": { "foreground": "#6796e6" } + }, + { "scope": "markup.inline.raw", "settings": { "foreground": "#ce9178" } }, + { + "scope": "punctuation.definition.tag", + "settings": { "foreground": "#808080" } + }, + { + "scope": ["meta.preprocessor", "entity.name.function.preprocessor"], + "settings": { "foreground": "#569cd6" } + }, + { + "scope": "meta.preprocessor.string", + "settings": { "foreground": "#ce9178" } + }, + { + "scope": "meta.preprocessor.numeric", + "settings": { "foreground": "#b5cea8" } + }, + { + "scope": "meta.structure.dictionary.key.python", + "settings": { "foreground": "#9cdcfe" } + }, + { "scope": "meta.diff.header", "settings": { "foreground": "#569cd6" } }, + { "scope": "storage", "settings": { "foreground": "#569cd6" } }, + { "scope": "storage.type", "settings": { "foreground": "#569cd6" } }, + { + "scope": ["storage.modifier", "keyword.operator.noexcept"], + "settings": { "foreground": "#569cd6" } + }, + { + "scope": ["string", "meta.embedded.assembly"], + "settings": { "foreground": "#ce9178" } + }, + { "scope": "string.tag", "settings": { "foreground": "#ce9178" } }, + { "scope": "string.value", "settings": { "foreground": "#ce9178" } }, + { "scope": "string.regexp", "settings": { "foreground": "#d16969" } }, + { + "scope": [ + "punctuation.definition.template-expression.begin", + "punctuation.definition.template-expression.end", + "punctuation.section.embedded" + ], + "settings": { "foreground": "#569cd6" } + }, + { + "scope": ["meta.template.expression"], + "settings": { "foreground": "#d4d4d4" } + }, + { + "scope": [ + "support.type.vendored.property-name", + "support.type.property-name", + "source.css variable", + "source.coffee.embedded" + ], + "settings": { "foreground": "#9cdcfe" } + }, + { "scope": "keyword", "settings": { "foreground": "#569cd6" } }, + { "scope": "keyword.control", "settings": { "foreground": "#569cd6" } }, + { "scope": "keyword.operator", "settings": { "foreground": "#d4d4d4" } }, + { + "scope": [ + "keyword.operator.new", + "keyword.operator.expression", + "keyword.operator.cast", + "keyword.operator.sizeof", + "keyword.operator.alignof", + "keyword.operator.typeid", + "keyword.operator.alignas", + "keyword.operator.instanceof", + "keyword.operator.logical.python", + "keyword.operator.wordlike" + ], + "settings": { "foreground": "#569cd6" } + }, + { "scope": "keyword.other.unit", "settings": { "foreground": "#b5cea8" } }, + { + "scope": [ + "punctuation.section.embedded.begin.php", + "punctuation.section.embedded.end.php" + ], + "settings": { "foreground": "#569cd6" } + }, + { + "scope": "support.function.git-rebase", + "settings": { "foreground": "#9cdcfe" } + }, + { + "scope": "constant.sha.git-rebase", + "settings": { "foreground": "#b5cea8" } + }, + { + "scope": [ + "storage.modifier.import.java", + "variable.language.wildcard.java", + "storage.modifier.package.java" + ], + "settings": { "foreground": "#d4d4d4" } + }, + { "scope": "variable.language", "settings": { "foreground": "#569cd6" } }, + { + "scope": [ + "entity.name.function", + "support.function", + "support.constant.handlebars", + "source.powershell variable.other.member", + "entity.name.operator.custom-literal" + ], + "settings": { "foreground": "#DCDCAA" } + }, + { + "scope": [ + "support.class", + "support.type", + "entity.name.type", + "entity.name.namespace", + "entity.other.attribute", + "entity.name.scope-resolution", + "entity.name.class", + "storage.type.numeric.go", + "storage.type.byte.go", + "storage.type.boolean.go", + "storage.type.string.go", + "storage.type.uintptr.go", + "storage.type.error.go", + "storage.type.rune.go", + "storage.type.cs", + "storage.type.generic.cs", + "storage.type.modifier.cs", + "storage.type.variable.cs", + "storage.type.annotation.java", + "storage.type.generic.java", + "storage.type.java", + "storage.type.object.array.java", + "storage.type.primitive.array.java", + "storage.type.primitive.java", + "storage.type.token.java", + "storage.type.groovy", + "storage.type.annotation.groovy", + "storage.type.parameters.groovy", + "storage.type.generic.groovy", + "storage.type.object.array.groovy", + "storage.type.primitive.array.groovy", + "storage.type.primitive.groovy" + ], + "settings": { "foreground": "#4EC9B0" } + }, + { + "scope": [ + "meta.type.cast.expr", + "meta.type.new.expr", + "support.constant.math", + "support.constant.dom", + "support.constant.json", + "entity.other.inherited-class", + "punctuation.separator.namespace.ruby" + ], + "settings": { "foreground": "#4EC9B0" } + }, + { + "scope": [ + "keyword.control", + "source.cpp keyword.operator.new", + "keyword.operator.delete", + "keyword.other.using", + "keyword.other.directive.using", + "keyword.other.operator", + "entity.name.operator" + ], + "settings": { "foreground": "#C586C0" } + }, + { + "scope": [ + "variable", + "meta.definition.variable.name", + "support.variable", + "entity.name.variable", + "constant.other.placeholder" + ], + "settings": { "foreground": "#9CDCFE" } + }, + { + "scope": ["variable.other.constant", "variable.other.enummember"], + "settings": { "foreground": "#4FC1FF" } + }, + { + "scope": ["meta.object-literal.key"], + "settings": { "foreground": "#9CDCFE" } + }, + { + "scope": [ + "support.constant.property-value", + "support.constant.font-name", + "support.constant.media-type", + "support.constant.media", + "constant.other.color.rgb-value", + "constant.other.rgb-value", + "support.constant.color" + ], + "settings": { "foreground": "#CE9178" } + }, + { + "scope": [ + "punctuation.definition.group.regexp", + "punctuation.definition.group.assertion.regexp", + "punctuation.definition.character-class.regexp", + "punctuation.character.set.begin.regexp", + "punctuation.character.set.end.regexp", + "keyword.operator.negation.regexp", + "support.other.parenthesis.regexp" + ], + "settings": { "foreground": "#CE9178" } + }, + { + "scope": [ + "constant.character.character-class.regexp", + "constant.other.character-class.set.regexp", + "constant.other.character-class.regexp", + "constant.character.set.regexp" + ], + "settings": { "foreground": "#d16969" } + }, + { + "scope": ["keyword.operator.or.regexp", "keyword.control.anchor.regexp"], + "settings": { "foreground": "#DCDCAA" } + }, + { + "scope": "keyword.operator.quantifier.regexp", + "settings": { "foreground": "#d7ba7d" } + }, + { + "scope": ["constant.character", "constant.other.option"], + "settings": { "foreground": "#569cd6" } + }, + { + "scope": "constant.character.escape", + "settings": { "foreground": "#d7ba7d" } + }, + { "scope": "entity.name.label", "settings": { "foreground": "#C8C8C8" } } + ], + "type": "dark" +} diff --git a/src/utils/themes.ts b/src/utils/themes.ts index 93b947e..b2ffc18 100644 --- a/src/utils/themes.ts +++ b/src/utils/themes.ts @@ -1,6 +1,7 @@ import { ThemeInput } from "shiki"; import horizonTheme from "./custom/horizon.json"; import shadesOfPurpleTheme from "./custom/shades-of-purple.json"; +import darkSquaredTheme from "./custom/dark-squared.json"; type ShadCnKeys = | "background" @@ -113,6 +114,29 @@ export const THEME_MAP: Record = { ring: "#0078d4", }, }, + "dark-squared": { + ui: { + background: "#0e0e0e", + foreground: "#D4D4D4", + card: "#252526", + "card-foreground": "#D4D4D4", + popover: "#252526", + "popover-foreground": "#D4D4D4", + primary: "#007ACC", + "primary-foreground": "#ffffff", + secondary: "#0078d4", + "secondary-foreground": "#ffffff", + muted: "#383a49", + "muted-foreground": "#A6A6A6", + accent: "#4EC9B0", + "accent-foreground": "#ffffff", + destructive: "#f44747", + border: "#454545", + input: "#3A3D41", + ring: "#0078d4", + }, + theme: darkSquaredTheme as ThemeInput, + }, "everforest-dark": { ui: { background: "#2d353b",