Skip to content

Commit

Permalink
Basic palette selector (updated) (ekzhang#81)
Browse files Browse the repository at this point in the history
* Basic palette selector

* Minor styling and text updates

* Fix lint issues

---------

Co-authored-by: Cveinnt <wuws.vincent@gmail.com>
  • Loading branch information
2 people authored and kahnwong committed Apr 13, 2024
1 parent b52d6c5 commit 61ec400
Show file tree
Hide file tree
Showing 5 changed files with 237 additions and 19 deletions.
3 changes: 3 additions & 0 deletions src/lib/settings.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { persisted } from "svelte-persisted-store";
import { type ThemeName, defaultTheme } from "./ui/themes";

export type SettingsStore = {
name: string;
theme: ThemeName;
};

/** A persisted store for settings of the current user. */
export const settings = persisted<SettingsStore>("sshx-settings-store", {
name: "",
theme: defaultTheme,
});
5 changes: 4 additions & 1 deletion src/lib/ui/ChooseName.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
let value = "";
function handleSubmit() {
settings.set({ ...settings, name: value });
settings.update((curSettings) => ({
...curSettings,
name: value,
}));
}
</script>

Expand Down
60 changes: 48 additions & 12 deletions src/lib/ui/Settings.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<script lang="ts">
import { settings } from "$lib/settings";
import { ChevronDownIcon } from "svelte-feather-icons";
import OverlayMenu from "./OverlayMenu.svelte";
import themes, { defaultTheme, type ThemeName } from "./themes";
export let open: boolean;
Expand All @@ -12,6 +14,20 @@
initialized = true;
nameValue = $settings.name;
}
let selectedTheme: ThemeName; // Bound to the settings input.
if (Object.hasOwn(themes, $settings.theme)) {
selectedTheme = $settings.theme;
} else {
selectedTheme = defaultTheme;
}
function handleThemeChange() {
settings.update((curSettings) => ({
...curSettings,
theme: selectedTheme,
}));
}
</script>

<OverlayMenu
Expand All @@ -21,23 +37,26 @@
{open}
on:close
>
<div class="flex flex-col gap-2">
<div class="flex flex-col gap-4">
<div class="item">
<div class="flex-1">
<p class="font-medium mb-2">Name</p>
<p class="text-sm text-zinc-400">
How you appear to other users online.
Choose how you appear to other users.
</p>
</div>
<div>
<input
class="w-52 px-3 py-1.5 rounded-md bg-zinc-700 outline-none focus:ring-2 focus:ring-indigo-500"
class="input-common"
placeholder="Your name"
bind:value={nameValue}
maxlength="50"
on:input={() => {
if (nameValue.length >= 2) {
settings.set({ ...$settings, name: nameValue });
settings.update((curSettings) => ({
...curSettings,
name: nameValue,
}));
}
}}
/>
Expand All @@ -46,19 +65,30 @@
<div class="item">
<div class="flex-1">
<p class="font-medium mb-2">Color palette</p>
<p class="text-sm text-zinc-400">Color scheme for text in terminals.</p>
<p class="text-sm text-zinc-400">Color theme for text in terminals.</p>
</div>
<div class="relative">
<ChevronDownIcon
class="absolute top-[11px] right-2.5 w-4 h-4 text-zinc-400"
/>
<select
class="input-common !pr-5"
bind:value={selectedTheme}
on:change={handleThemeChange}
>
{#each Object.keys(themes) as themeName (themeName)}
<option value={themeName}>{themeName}</option>
{/each}
</select>
</div>
<div class="text-red-500">Coming soon</div>
</div>
<div class="item">
<!-- <div class="item">
<div class="flex-1">
<p class="font-medium mb-2">Cursor style</p>
<p class="text-sm text-zinc-400">
How live cursors should be displayed.
</p>
<p class="text-sm text-zinc-400">Style of live cursors.</p>
</div>
<div class="text-red-500">Coming soon</div>
</div>
</div> -->
</div>

<!-- svelte-ignore missing-declaration -->
Expand All @@ -71,6 +101,12 @@

<style lang="postcss">
.item {
@apply bg-zinc-800/25 rounded-lg p-4 flex gap-4 flex-col sm:flex-row;
@apply bg-zinc-800/25 rounded-lg p-4 flex gap-4 flex-col sm:flex-row items-start;
}
.input-common {
@apply w-52 px-3 py-2 text-sm rounded-md bg-transparent hover:bg-white/5;
@apply border border-zinc-700 outline-none focus:ring-2 focus:ring-indigo-500/50;
@apply appearance-none transition-colors;
}
</style>
14 changes: 11 additions & 3 deletions src/lib/ui/XTerm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,12 @@
import type { Terminal } from "sshx-xterm";
import { Buffer } from "buffer";
import themes from "./themes";
import themes, { defaultTheme } from "./themes";
import CircleButton from "./CircleButton.svelte";
import CircleButtons from "./CircleButtons.svelte";
import { settings } from "$lib/settings";
import { TypeAheadAddon } from "$lib/typeahead";
const theme = themes.defaultDark;
/** Used to determine Cmd versus Ctrl keyboard shortcuts. */
const isMac = browser && navigator.platform.startsWith("Mac");
Expand All @@ -68,6 +67,15 @@
export let termEl: HTMLDivElement = null as any; // suppress "missing prop" warning
let term: Terminal | null = null;
$: theme = Object.hasOwn(themes, $settings.theme)
? themes[$settings.theme]
: themes[defaultTheme];
$: if (term) {
// If the theme changes, update existing terminals' appearance.
term.options.theme = theme;
}
let loaded = false;
let focused = false;
let currentTitle = "Remote Terminal";
Expand Down
174 changes: 171 additions & 3 deletions src/lib/ui/themes.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ITheme } from "sshx-xterm";

/** VSCode default dark theme, from https://glitchbone.github.io/vscode-base16-term/. */
export const defaultDark: ITheme = {
const defaultDark: ITheme = {
foreground: "#d8d8d8",
background: "#181818",

Expand All @@ -27,7 +27,7 @@ export const defaultDark: ITheme = {
};

/** Hybrid theme from https://terminal.sexy/, using Alacritty export format. */
export const hybrid: ITheme = {
const hybrid: ITheme = {
foreground: "#c5c8c6",
background: "#1d1f21",

Expand All @@ -50,4 +50,172 @@ export const hybrid: ITheme = {
brightWhite: "#c5c8c6",
};

export default { defaultDark, hybrid };
/** Below themes are converted from https://github.com/alacritty/alacritty-theme/. */
const rosePine: ITheme = {
foreground: "#e0def4",
background: "#191724",

cursor: "#524f67",

black: "#26233a",
red: "#eb6f92",
green: "#31748f",
yellow: "#f6c177",
blue: "#9ccfd8",
magenta: "#c4a7e7",
cyan: "#ebbcba",
white: "#e0def4",

brightBlack: "#6e6a86",
brightRed: "#eb6f92",
brightGreen: "#31748f",
brightYellow: "#f6c177",
brightBlue: "#9ccfd8",
brightMagenta: "#c4a7e7",
brightCyan: "#ebbcba",
brightWhite: "#e0def4",
};

const ubuntu: ITheme = {
foreground: "#eeeeec",
background: "#300a24",
black: "#2e3436",
red: "#cc0000",
green: "#4e9a06",
yellow: "#c4a000",
blue: "#3465a4",
magenta: "#75507b",
cyan: "#06989a",
white: "#d3d7cf",
brightBlack: "#555753",
brightRed: "#ef2929",
brightGreen: "#8ae234",
brightYellow: "#fce94f",
brightBlue: "#729fcf",
brightMagenta: "#ad7fa8",
brightCyan: "#34e2e2",
brightWhite: "#eeeeec",
};

const dracula: ITheme = {
foreground: "#f8f8f2",
background: "#282a36",
black: "#000000",
red: "#ff5555",
green: "#50fa7b",
yellow: "#f1fa8c",
blue: "#bd93f9",
magenta: "#ff79c6",
cyan: "#8be9fd",
white: "#bbbbbb",
brightBlack: "#555555",
brightRed: "#ff5555",
brightGreen: "#50fa7b",
brightYellow: "#f1fa8c",
brightBlue: "#caa9fa",
brightMagenta: "#ff79c6",
brightCyan: "#8be9fd",
brightWhite: "#ffffff",
};

const githubDark: ITheme = {
foreground: "#d1d5da",
background: "#24292e",
black: "#586069",
red: "#ea4a5a",
green: "#34d058",
yellow: "#ffea7f",
blue: "#2188ff",
magenta: "#b392f0",
cyan: "#39c5cf",
white: "#d1d5da",
brightBlack: "#959da5",
brightRed: "#f97583",
brightGreen: "#85e89d",
brightYellow: "#ffea7f",
brightBlue: "#79b8ff",
brightMagenta: "#b392f0",
brightCyan: "#56d4dd",
brightWhite: "#fafbfc",
};

const gruvboxDark: ITheme = {
foreground: "#ebdbb2",
background: "#282828",
black: "#282828",
red: "#cc241d",
green: "#98971a",
yellow: "#d79921",
blue: "#458588",
magenta: "#b16286",
cyan: "#689d6a",
white: "#a89984",
brightBlack: "#928374",
brightRed: "#fb4934",
brightGreen: "#b8bb26",
brightYellow: "#fabd2f",
brightBlue: "#83a598",
brightMagenta: "#d3869b",
brightCyan: "#8ec07c",
brightWhite: "#ebdbb2",
};

const solarizedDark: ITheme = {
foreground: "#839496",
background: "#002b36",
black: "#073642",
red: "#dc322f",
green: "#859900",
yellow: "#b58900",
blue: "#268bd2",
magenta: "#d33682",
cyan: "#2aa198",
white: "#eee8d5",
brightBlack: "#002b36",
brightRed: "#cb4b16",
brightGreen: "#586e75",
brightYellow: "#657b83",
brightBlue: "#839496",
brightMagenta: "#6c71c4",
brightCyan: "#93a1a1",
brightWhite: "#fdf6e3",
};

const tokyoNight: ITheme = {
foreground: "#a9b1d6",
background: "#1a1b26",
black: "#32344a",
red: "#f7768e",
green: "#9ece6a",
yellow: "#e0af68",
blue: "#7aa2f7",
magenta: "#ad8ee6",
cyan: "#449dab",
white: "#787c99",
brightBlack: "#444b6a",
brightRed: "#ff7a93",
brightGreen: "#b9f27c",
brightYellow: "#ff9e64",
brightBlue: "#7da6ff",
brightMagenta: "#bb9af7",
brightCyan: "#0db9d7",
brightWhite: "#acb0d0",
};

const themes = {
"VS Code Dark": defaultDark,
Hybrid: hybrid,
"Rosé Pine": rosePine,
Ubuntu: ubuntu,
Dracula: dracula,
"GitHub Dark": githubDark,
"Gruvbox Dark": gruvboxDark,
"Solarized Dark": solarizedDark,
"Tokyo Night": tokyoNight,
};

export type ThemeName = keyof typeof themes;

export const defaultTheme: ThemeName = "VS Code Dark";

export default themes;

0 comments on commit 61ec400

Please sign in to comment.