Skip to content

Commit

Permalink
feat: dark mode (#15)
Browse files Browse the repository at this point in the history
* feat: add dark mode toggle

* feat: code editor to support dark mode

* feat: add more dark mode styling

* ignore some sonarqube rule

* ignore rule

* ignore sonar rule
  • Loading branch information
invisal authored Mar 2, 2024
1 parent cc64f29 commit 0c9fa73
Show file tree
Hide file tree
Showing 18 changed files with 247 additions and 94 deletions.
6 changes: 5 additions & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ sonar.organization=invisal
sonar.projectKey=invisal_libsql-studio
sonar.javascript.lcov.reportPaths=./coverage/lcov.info
sonar.coverage.exclusions=src/**/*.test.ts, src/**/*.tsx
sonar.sources=src/
sonar.sources=src/

sonar.issue.ignore.multicriteria=e1
sonar.issue.ignore.multicriteria.e1.ruleKey=typescript:S6848
sonar.issue.ignore.multicriteria.e1.resourceKey=*.tsx
44 changes: 25 additions & 19 deletions src/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
--color-table-grid: #eee;
--color-table-change: #f6e58d;
Expand All @@ -24,70 +24,76 @@
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;

--color-surface: #fff;
--color-surface-hover: #eee;

--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;

--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;

--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;

--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;

--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;

--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;

--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;

--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;

--radius: 0.5rem;
}

.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;


--color-surface: #1f1f1f;
--color-surface-hover: #3f3f3f;

--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;

--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;

--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;

--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;

--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;

--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;

--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;

--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;
}
}

@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
}
7 changes: 7 additions & 0 deletions src/components/code-preview/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function CodePreview({ code }: { code: string }) {
return (
<code className="p-2 bg-gray-200 dark:bg-gray-900 block overflow-x-auto w-full text-sm">
<pre>{code}</pre>
</code>
);
}
13 changes: 8 additions & 5 deletions src/components/main-connection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import InternalPubSub from "@/lib/internal-pubsub";
import { useRouter } from "next/navigation";
import { normalizeConnectionEndpoint } from "@/lib/validation";
import { SchemaProvider } from "@/context/SchemaProvider";
import ThemeProvider from "@/context/theme-provider";

function MainConnection({
credential,
Expand All @@ -30,11 +31,13 @@ function MainConnection({
}, [database]);

return (
<DatabaseDriverProvider driver={database}>
<SchemaProvider>
<DatabaseGui />
</SchemaProvider>
</DatabaseDriverProvider>
<ThemeProvider>
<DatabaseDriverProvider driver={database}>
<SchemaProvider>
<DatabaseGui />
</SchemaProvider>
</DatabaseDriverProvider>
</ThemeProvider>
);
}

Expand Down
7 changes: 4 additions & 3 deletions src/components/query-progress-log.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { MultipleQueryProgress } from "@/lib/multiple-query";
import { useEffect, useState } from "react";
import CodePreview from "./code-preview";

function formatTimeAgo(ms: number) {
if (ms < 1000) {
Expand Down Expand Up @@ -72,9 +73,9 @@ export default function QueryProgressLog({
ago.
</div>
)}
<code className="p-2 bg-yellow-50 block mt-2 overflow-x-auto w-full text-sm">
<pre>{detail.sql}</pre>
</code>

<div className="mt-3" />
<CodePreview code={detail.sql} />
</div>
);
})}
Expand Down
2 changes: 1 addition & 1 deletion src/components/schema-editor/ColumnDefaultValueInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export default function ColumnDefaultValueInput({
return (
<Popover>
<PopoverTrigger>
<div className="flex text-left shadow-sm py-2 px-3 rounded-md border w-[180px] h-full bg-white">
<div className="flex text-left shadow-sm py-2 px-3 rounded-md border w-[180px] h-full bg-background">
<div className="flex-grow">{display || "EMPTY STRING"}</div>
<div className="text-gray-400 flex items-center">
<ChevronsUpDown size={14} />
Expand Down
20 changes: 10 additions & 10 deletions src/components/schema-editor/SchemaEditorColumnList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ function ConflictClauseOptions({
}>) {
return (
<Select value={value} onValueChange={onChange}>
<SelectTrigger className="bg-white" disabled={disabled}>
<SelectTrigger className="bg-background" disabled={disabled}>
<SelectValue placeholder="Conflict" />
</SelectTrigger>
<SelectContent>
Expand Down Expand Up @@ -145,9 +145,9 @@ function ColumnItem({

let highlightClassName = "";
if (value.new === null) {
highlightClassName = "bg-red-50";
highlightClassName = "bg-red-50 dark:bg-red-800";
} else if (value.old === null) {
highlightClassName = "bg-green-100";
highlightClassName = "bg-green-100 dark:bg-green-800";
} else if (checkSchemaColumnChange(value)) {
highlightClassName = "bg-yellow-100";
}
Expand All @@ -165,23 +165,23 @@ function ColumnItem({
return (
<div className={"p-1 text-sm " + highlightClassName}>
<div className="flex">
<div className="mt-3 pl-2 w-[30px] text-red-600">
<div className="mt-3 pl-2 w-[30px] text-orange-600 dark:text-yellow-400">
{column.pk && <LucideKey size={15} />}
</div>
<div className="flex flex-col gap-1">
<div className={"flex p-1 gap-2"}>
<Input
autoFocus
value={column.name}
className={"w-[200px] bg-white"}
className={"w-[200px] bg-background"}
onChange={(e) => change({ name: e.currentTarget.value })}
/>
<Select
value={type}
onValueChange={(newType) => change({ type: newType })}
disabled={disabled}
>
<SelectTrigger className="w-[180px] bg-white">
<SelectTrigger className="w-[180px] bg-background">
<SelectValue placeholder="Select datatype" />
</SelectTrigger>
<SelectContent>
Expand Down Expand Up @@ -287,7 +287,7 @@ function ColumnItem({
});
}}
>
<SelectTrigger className="bg-white">
<SelectTrigger className="bg-background">
<SelectValue placeholder="Order" />
</SelectTrigger>
<SelectContent>
Expand Down Expand Up @@ -352,7 +352,7 @@ function ColumnItem({
<Input
disabled={disabled}
placeholder="Generate Expression"
className="font-mono bg-white"
className="font-mono bg-background"
onChange={(e) => {
change({
constraint: {
Expand All @@ -372,7 +372,7 @@ function ColumnItem({
});
}}
>
<SelectTrigger className="w-[100px] bg-white">
<SelectTrigger className="w-[100px] bg-background">
<SelectValue placeholder="Select datatype" />
</SelectTrigger>
<SelectContent>
Expand All @@ -397,7 +397,7 @@ function ColumnItem({
>
<Input
placeholder="Check Expression"
className="font-mono bg-white"
className="font-mono bg-background"
disabled={disabled}
value={column.constraint.checkExpression ?? ""}
onChange={(e) => {
Expand Down
27 changes: 25 additions & 2 deletions src/components/schema-sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@ import { buttonVariants } from "@/components/ui/button";
import { ScrollArea } from "@/components/ui/scroll-area";
import { cn } from "@/lib/utils";
import { openTabs } from "@/messages/openTabs";
import { LucideIcon, LucideSearch, Table2 } from "lucide-react";
import {
LucideIcon,
LucideSearch,
LucideSun,
LucideSunMoon,
Table2,
} from "lucide-react";
import { useCallback, useState } from "react";
import {
OpenContextMenuList,
openContextMenuFromEvent,
} from "@/messages/openContextMenu";
import { useSchema } from "@/context/SchemaProvider";
import { appVersion } from "@/env";
import { useTheme } from "@/context/theme-provider";

interface SchemaViewItemProps {
icon: LucideIcon;
Expand Down Expand Up @@ -60,6 +67,7 @@ export default function SchemaView() {
const { refresh, schema } = useSchema();
const [search, setSearch] = useState("");
const [selectedIndex, setSelectedIndex] = useState(-1);
const { theme, toggleTheme } = useTheme();

const prepareContextMenu = useCallback(
(tableName?: string) => {
Expand Down Expand Up @@ -106,7 +114,7 @@ export default function SchemaView() {
<div className="pt-2 px-2 flex h-10">
<div className="bg-secondary rounded overflow-hidden flex items-center ml-3 flex-grow">
<div className="text-sm px-2 h-full flex items-center">
<LucideSearch className="h-4 w-4 text-black" />
<LucideSearch className="h-4 w-4 text-black dark:text-white" />
</div>
<input
type="text"
Expand Down Expand Up @@ -149,6 +157,21 @@ export default function SchemaView() {
<span>LibSQL</span>
<strong>Studio</strong>
<span className="text-xs ml-2">v{appVersion}</span>
<div className="grow" />
<div
role="button"
className="px-2 flex items-center h-full -mr-2"
tabIndex={-1}
onClick={() => {
toggleTheme();
}}
>
{theme === "dark" ? (
<LucideSun className="w-4 h-4" />
) : (
<LucideSunMoon className="w-4 h-4" />
)}
</div>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { tags as t } from "@lezer/highlight";
import { createTheme } from "@uiw/codemirror-themes";
import CodeMirror, {
EditorView,
ReactCodeMirrorRef,
Expand All @@ -10,38 +8,7 @@ import { forwardRef, KeyboardEventHandler, useMemo } from "react";
import { defaultKeymap } from "@codemirror/commands";
import { keymap } from "@codemirror/view";
import { KEY_BINDING } from "@/lib/key-matcher";

const theme = createTheme({
theme: "light",
settings: {
background: "#FFFFFF",
foreground: "#000000",
caret: "#FBAC52",
selection: "#FFD420",
selectionMatch: "#FFD420",
gutterBackground: "#fff",
gutterForeground: "#4D4D4C",
gutterBorder: "transparent",
lineHighlight: "#00000012",
fontFamily:
'Menlo, Monaco, Consolas, "Andale Mono", "Ubuntu Mono", "Courier New", monospace',
},
styles: [
{ tag: [t.meta, t.comment], color: "#804000" },
{ tag: [t.keyword, t.strong], color: "#0000FF" },
{ tag: [t.number], color: "#FF0080" },
{ tag: [t.string], color: "#e17055" },
{ tag: [t.variableName], color: "#006600" },
{ tag: [t.escape], color: "#33CC33" },
{ tag: [t.tagName], color: "#1C02FF" },
{ tag: [t.heading], color: "#0C07FF" },
{ tag: [t.quote], color: "#000000" },
{ tag: [t.list], color: "#B90690" },
{ tag: [t.documentMeta], color: "#888888" },
{ tag: [t.function(t.variableName)], color: "#0000A2" },
{ tag: [t.definition(t.typeName), t.typeName], color: "#6D79DE" },
],
});
import useCodeEditorTheme from "./use-editor-theme";

interface SqlEditorProps {
value: string;
Expand All @@ -68,6 +35,8 @@ const SqlEditor = forwardRef<ReactCodeMirrorRef, SqlEditorProps>(
}: SqlEditorProps,
ref
) {
const theme = useCodeEditorTheme();

const keyExtensions = useMemo(() => {
return keymap.of([
{
Expand Down
Loading

0 comments on commit 0c9fa73

Please sign in to comment.