Skip to content

Commit 5007515

Browse files
authoredOct 24, 2024··
feat: add options page (#22)
1 parent cc06d10 commit 5007515

29 files changed

+755
-14
lines changed
 

‎.changeset/poor-needles-watch.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"gregmat-buddy": minor
3+
---
4+
5+
added options page

‎components.json

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"$schema": "https://shadcn-svelte.com/schema.json",
3+
"style": "default",
4+
"tailwind": {
5+
"config": "tailwind.config.ts",
6+
"css": "src/entrypoints/options/app.css",
7+
"baseColor": "slate"
8+
},
9+
"aliases": {
10+
"components": "@/components",
11+
"utils": "@/utils"
12+
},
13+
"typescript": true
14+
}

‎package.json

+6-1
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,20 @@
2222
"@types/vimeo__player": "^2.18.3",
2323
"@wxt-dev/module-svelte": "^1.0.1",
2424
"autoprefixer": "^10.4.20",
25+
"bits-ui": "^0.21.16",
26+
"clsx": "^2.1.1",
2527
"svelte": "^4.2.19",
2628
"svelte-check": "^3.8.6",
29+
"tailwind-merge": "^2.5.4",
30+
"tailwind-variants": "^0.2.1",
2731
"tailwindcss": "^3.4.14",
2832
"tslib": "^2.8.0",
2933
"typescript": "^5.6.3",
3034
"wxt": "^0.19.13"
3135
},
3236
"dependencies": {
3337
"@vimeo/player": "^2.24.0",
34-
"fast-glob": "^3.3.2"
38+
"fast-glob": "^3.3.2",
39+
"lucide-svelte": "^0.453.0"
3540
}
3641
}

‎pnpm-lock.yaml

+126
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/components/option/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Root from "./option.svelte";
2+
3+
export {
4+
Root,
5+
//
6+
Root as Option,
7+
};

‎src/components/option/option.svelte

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<script lang="ts">
2+
import { Label } from "@/components/ui/label";
3+
import { Switch } from "@/components/ui/switch";
4+
import * as Tooltip from "@/components/ui/tooltip";
5+
import { CircleHelp } from "lucide-svelte";
6+
7+
export let id: string;
8+
export let handler: (id: string, checked: boolean) => void;
9+
export let checked: boolean = false;
10+
export let tooltip: string = "";
11+
12+
let isInitialLoad = true;
13+
14+
$: if (!isInitialLoad) {
15+
handler(id, checked);
16+
} else {
17+
isInitialLoad = false;
18+
}
19+
</script>
20+
21+
<div class="px-2 flex justify-between">
22+
<Label for={id} class="my-auto"><slot /></Label>
23+
<div class="flex gap-2 items-center">
24+
{#if tooltip !== ""}
25+
<Tooltip.Root>
26+
<Tooltip.Trigger>
27+
<CircleHelp size={20} class="stroke-gray-400 dark:stroke-zinc-400" />
28+
</Tooltip.Trigger>
29+
<Tooltip.Content>
30+
<p>{tooltip}</p>
31+
</Tooltip.Content>
32+
</Tooltip.Root>
33+
{/if}
34+
<Switch {id} bind:checked />
35+
</div>
36+
</div>

‎src/components/ui/label/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Root from "./label.svelte";
2+
3+
export {
4+
Root,
5+
//
6+
Root as Label,
7+
};

‎src/components/ui/label/label.svelte

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<script lang="ts">
2+
import { Label as LabelPrimitive } from "bits-ui";
3+
import { cn } from "@/utils";
4+
5+
type $$Props = LabelPrimitive.Props;
6+
type $$Events = LabelPrimitive.Events;
7+
8+
let className: $$Props["class"] = undefined;
9+
export { className as class };
10+
</script>
11+
12+
<LabelPrimitive.Root
13+
class={cn(
14+
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
15+
className,
16+
)}
17+
{...$$restProps}
18+
on:mousedown
19+
>
20+
<slot />
21+
</LabelPrimitive.Root>

‎src/components/ui/switch/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Root from "./switch.svelte";
2+
3+
export {
4+
Root,
5+
//
6+
Root as Switch,
7+
};
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<script lang="ts">
2+
import { Switch as SwitchPrimitive } from "bits-ui";
3+
import { cn } from "@/utils";
4+
5+
type $$Props = SwitchPrimitive.Props;
6+
type $$Events = SwitchPrimitive.Events;
7+
8+
let className: $$Props["class"] = undefined;
9+
export let checked: $$Props["checked"] = undefined;
10+
export { className as class };
11+
</script>
12+
13+
<SwitchPrimitive.Root
14+
bind:checked
15+
class={cn(
16+
"focus-visible:ring-ring focus-visible:ring-offset-background data-[state=checked]:bg-primary data-[state=unchecked]:bg-input peer inline-flex h-[24px] w-[44px] shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
17+
className,
18+
)}
19+
{...$$restProps}
20+
on:click
21+
on:keydown
22+
>
23+
<SwitchPrimitive.Thumb
24+
class={cn(
25+
"bg-background pointer-events-none block h-5 w-5 rounded-full shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0",
26+
)}
27+
/>
28+
</SwitchPrimitive.Root>

‎src/components/ui/tabs/index.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Tabs as TabsPrimitive } from "bits-ui";
2+
import Content from "./tabs-content.svelte";
3+
import List from "./tabs-list.svelte";
4+
import Trigger from "./tabs-trigger.svelte";
5+
6+
const Root = TabsPrimitive.Root;
7+
8+
export {
9+
Root,
10+
Content,
11+
List,
12+
Trigger,
13+
//
14+
Root as Tabs,
15+
Content as TabsContent,
16+
List as TabsList,
17+
Trigger as TabsTrigger,
18+
};
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<script lang="ts">
2+
import { Tabs as TabsPrimitive } from "bits-ui";
3+
import { cn } from "@/utils";
4+
5+
type $$Props = TabsPrimitive.ContentProps;
6+
7+
let className: $$Props["class"] = undefined;
8+
export let value: $$Props["value"];
9+
export { className as class };
10+
</script>
11+
12+
<TabsPrimitive.Content
13+
class={cn(
14+
"ring-offset-background focus-visible:ring-ring mt-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
15+
className,
16+
)}
17+
{value}
18+
{...$$restProps}
19+
>
20+
<slot />
21+
</TabsPrimitive.Content>
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<script lang="ts">
2+
import { Tabs as TabsPrimitive } from "bits-ui";
3+
import { cn } from "@/utils";
4+
5+
type $$Props = TabsPrimitive.ListProps;
6+
7+
let className: $$Props["class"] = undefined;
8+
export { className as class };
9+
</script>
10+
11+
<TabsPrimitive.List
12+
class={cn(
13+
"bg-muted text-muted-foreground inline-flex h-10 items-center justify-center rounded-md p-1",
14+
className,
15+
)}
16+
{...$$restProps}
17+
>
18+
<slot />
19+
</TabsPrimitive.List>
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<script lang="ts">
2+
import { Tabs as TabsPrimitive } from "bits-ui";
3+
import { cn } from "@/utils";
4+
5+
type $$Props = TabsPrimitive.TriggerProps;
6+
type $$Events = TabsPrimitive.TriggerEvents;
7+
8+
let className: $$Props["class"] = undefined;
9+
export let value: $$Props["value"];
10+
export { className as class };
11+
</script>
12+
13+
<TabsPrimitive.Trigger
14+
class={cn(
15+
"ring-offset-background focus-visible:ring-ring data-[state=active]:bg-background data-[state=active]:text-foreground inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm",
16+
className,
17+
)}
18+
{value}
19+
{...$$restProps}
20+
on:click
21+
>
22+
<slot />
23+
</TabsPrimitive.Trigger>

‎src/components/ui/tooltip/index.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Tooltip as TooltipPrimitive } from "bits-ui";
2+
import Content from "./tooltip-content.svelte";
3+
4+
const Root = TooltipPrimitive.Root;
5+
const Trigger = TooltipPrimitive.Trigger;
6+
7+
export {
8+
Root,
9+
Trigger,
10+
Content,
11+
//
12+
Root as Tooltip,
13+
Content as TooltipContent,
14+
Trigger as TooltipTrigger,
15+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<script lang="ts">
2+
import { Tooltip as TooltipPrimitive } from "bits-ui";
3+
import { cn, flyAndScale } from "@/utils";
4+
5+
type $$Props = TooltipPrimitive.ContentProps;
6+
7+
let className: $$Props["class"] = undefined;
8+
export let sideOffset: $$Props["sideOffset"] = 4;
9+
export let transition: $$Props["transition"] = flyAndScale;
10+
export let transitionConfig: $$Props["transitionConfig"] = {
11+
y: 8,
12+
duration: 150,
13+
};
14+
export { className as class };
15+
</script>
16+
17+
<TooltipPrimitive.Content
18+
{transition}
19+
{transitionConfig}
20+
{sideOffset}
21+
class={cn(
22+
"bg-popover text-popover-foreground z-50 overflow-hidden rounded-md border px-3 py-1.5 text-sm shadow-md",
23+
className,
24+
)}
25+
{...$$restProps}
26+
>
27+
<slot />
28+
</TooltipPrimitive.Content>

‎src/entrypoints/content/prefs.ts

+12-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
import { VIMEO_SELECTOR } from "@/constants";
2-
import { seenBanners, vimeoPlaybackRate } from "@/utils/storage";
2+
import {
3+
config as config_store,
4+
seenBanners,
5+
vimeoPlaybackRate,
6+
} from "@/utils/storage";
37
import Player from "@vimeo/player";
48

5-
export function vimeoChanges() {
9+
export async function vimeoChanges() {
10+
const config = await config_store.getValue();
11+
if (!config.playbackRate) return;
12+
613
window.addEventListener("vimeoAdded", async () => {
714
const iframe = document.querySelector(VIMEO_SELECTOR);
815

@@ -19,6 +26,9 @@ export function vimeoChanges() {
1926
}
2027

2128
export async function removeBanner() {
29+
const config = await config_store.getValue();
30+
if (!config.banner) return;
31+
2232
const banner = document.querySelector(".px-3.py-3.mx-auto.max-w-7xl");
2333
if (!banner) return;
2434

‎src/entrypoints/gregmat.content/vocab-mountain.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
import { config as config_store } from "@/utils/storage";
12
export async function main() {
3+
addStats();
4+
5+
const config = await config_store.getValue();
6+
if (!config.vocabMountain) return;
7+
28
registerKeybinds();
39
showKeybinds();
4-
addStats();
510
}
611

712
function eventGenerator(key: KeyboardEvent["key"]) {

‎src/entrypoints/options/App.svelte

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<script lang="ts">
2+
import * as Tabs from "@/components/ui/tabs";
3+
import { Option } from "@/components/option";
4+
import { config as config_store } from "@/utils/storage";
5+
6+
let local_config: { [key: string]: boolean } = {};
7+
8+
function handler(id: string, checked: boolean) {
9+
local_config[id] = checked;
10+
// @ts-ignore 2345
11+
config_store.setValue(local_config);
12+
}
13+
14+
async function get_options() {
15+
const config = await config_store.getValue();
16+
local_config = config;
17+
const options = {
18+
general: [
19+
{
20+
id: "banner",
21+
tooltip:
22+
"Automatically dismisses a banner after you dismiss it for the first time!",
23+
text: "Automatically remove banner",
24+
checked: config.banner,
25+
},
26+
{
27+
id: "playbackRate",
28+
text: "Persist video playback speed",
29+
tooltip: "",
30+
checked: config.playbackRate,
31+
},
32+
],
33+
gregmat: [
34+
{
35+
id: "vocabMountain",
36+
text: "Enable vocab mountain keybinds",
37+
tooltip: "Includes gre and toefl vocab mountain",
38+
checked: config.vocabMountain,
39+
},
40+
],
41+
prepswift: [
42+
{
43+
id: "prepswiftStats",
44+
text: "Show prepswift completion stats",
45+
tooltip: "Shows total time and lectures completed",
46+
checked: config.prepswiftStats,
47+
},
48+
],
49+
} as const;
50+
51+
return options;
52+
}
53+
</script>
54+
55+
<main class="h-lvh dark:bg-black dark:text-white">
56+
<div class="h-lvh grid place-items-center">
57+
<Tabs.Root value="general" class="w-[400px]">
58+
<Tabs.List class="w-[400px]">
59+
<Tabs.Trigger value="general" class="w-full">General</Tabs.Trigger>
60+
<Tabs.Trigger value="gregmat" class="w-full">GregMat</Tabs.Trigger>
61+
<Tabs.Trigger value="prepswift" class="w-full">PrepSwift</Tabs.Trigger>
62+
</Tabs.List>
63+
{#await get_options() then options}
64+
{#each Object.entries(options) as [cat, val]}
65+
<Tabs.Content value={cat}>
66+
<div
67+
class="flex flex-col gap-2 font-mono text-gray-800 dark:text-gray-200"
68+
>
69+
{#each val as option}
70+
<Option
71+
id={option.id}
72+
{handler}
73+
tooltip={option.tooltip}
74+
checked={option.checked}
75+
>
76+
{option.text}
77+
</Option>
78+
{/each}
79+
</div>
80+
</Tabs.Content>
81+
{/each}
82+
{/await}
83+
</Tabs.Root>
84+
</div>
85+
</main>

‎src/entrypoints/options/app.css

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
4+
5+
@layer base {
6+
:root {
7+
--background: 0 0% 100%;
8+
--foreground: 222.2 84% 4.9%;
9+
10+
--muted: 210 40% 96.1%;
11+
--muted-foreground: 215.4 16.3% 46.9%;
12+
13+
--popover: 0 0% 100%;
14+
--popover-foreground: 222.2 84% 4.9%;
15+
16+
--card: 0 0% 100%;
17+
--card-foreground: 222.2 84% 4.9%;
18+
19+
--border: 214.3 31.8% 91.4%;
20+
--input: 214.3 31.8% 91.4%;
21+
22+
--primary: 222.2 47.4% 11.2%;
23+
--primary-foreground: 210 40% 98%;
24+
25+
--secondary: 210 40% 96.1%;
26+
--secondary-foreground: 222.2 47.4% 11.2%;
27+
28+
--accent: 210 40% 96.1%;
29+
--accent-foreground: 222.2 47.4% 11.2%;
30+
31+
--destructive: 0 72.2% 50.6%;
32+
--destructive-foreground: 210 40% 98%;
33+
34+
--ring: 222.2 84% 4.9%;
35+
36+
--radius: 0.5rem;
37+
}
38+
39+
.dark {
40+
--background: 222.2 84% 4.9%;
41+
--foreground: 210 40% 98%;
42+
43+
--muted: 217.2 32.6% 17.5%;
44+
--muted-foreground: 215 20.2% 65.1%;
45+
46+
--popover: 222.2 84% 4.9%;
47+
--popover-foreground: 210 40% 98%;
48+
49+
--card: 222.2 84% 4.9%;
50+
--card-foreground: 210 40% 98%;
51+
52+
--border: 217.2 32.6% 17.5%;
53+
--input: 217.2 32.6% 17.5%;
54+
55+
--primary: 210 40% 98%;
56+
--primary-foreground: 222.2 47.4% 11.2%;
57+
58+
--secondary: 217.2 32.6% 17.5%;
59+
--secondary-foreground: 210 40% 98%;
60+
61+
--accent: 217.2 32.6% 17.5%;
62+
--accent-foreground: 210 40% 98%;
63+
64+
--destructive: 0 62.8% 30.6%;
65+
--destructive-foreground: 210 40% 98%;
66+
67+
--ring: 212.7 26.8% 83.9%;
68+
}
69+
}
70+
71+
@layer base {
72+
* {
73+
@apply border-border;
74+
}
75+
body {
76+
@apply bg-background text-foreground;
77+
}
78+
}

‎src/entrypoints/options/index.html

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>GregMat Buddy | Preferences</title>
7+
<meta
8+
name="manifest.default_icon"
9+
content="{
10+
16: '/icon/16.png',
11+
24: '/icon/24.png',
12+
48: '/icon/48.png',
13+
96: '/icon/96.png',
14+
128: '/icon/128.png'
15+
}"
16+
/>
17+
</head>
18+
<body class="min-h-max">
19+
<div id="app"></div>
20+
<script type="module" src="./main.ts"></script>
21+
</body>
22+
</html>

‎src/entrypoints/options/main.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import "./app.css";
2+
import App from "./App.svelte";
3+
4+
const app = new App({
5+
target: document.getElementById("app")!,
6+
});
7+
8+
export default app;

‎src/entrypoints/popup/App.svelte

+8-3
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,16 @@
88
</a>
99
</div>
1010

11+
<p>All the best!</p>
12+
13+
<p class="read-the-docs">
14+
<a target="_blank" href="/options.html">Extension Options</a> - Configure your
15+
Preferences
16+
</p>
17+
1118
<p class="read-the-docs">
1219
Found a bug or have a feature request?
13-
<a href={import.meta.env.VITE_GITHUB_URL + "/issues/new/choose"}>
14-
Open an Issue
15-
</a>
20+
<a href={import.meta.env.VITE_GITHUB_URL + "/issues"}> Open an Issue </a>
1621
</p>
1722

1823
<p>

‎src/entrypoints/prepswift.content/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { waitForElement, registerUrl } from "@/utils";
2+
import { config as config_store } from "@/utils/storage";
23

34
export default defineContentScript({
45
matches: ["*://*.prepswift.com/*"],
@@ -9,6 +10,9 @@ export default defineContentScript({
910
});
1011

1112
async function main() {
13+
const config = await config_store.getValue();
14+
if (!config.prepswiftStats) return;
15+
1216
await waitForElement(".htmlContent");
1317
const container = document.querySelector("div[class='space-y-6 my-10']");
1418
const header = document.querySelector(".htmlContent");

‎src/utils/index.ts

+63
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,66 @@
1+
import { type ClassValue, clsx } from "clsx";
2+
import { twMerge } from "tailwind-merge";
3+
import { cubicOut } from "svelte/easing";
4+
import type { TransitionConfig } from "svelte/transition";
5+
6+
export function cn(...inputs: ClassValue[]) {
7+
return twMerge(clsx(inputs));
8+
}
9+
10+
type FlyAndScaleParams = {
11+
y?: number;
12+
x?: number;
13+
start?: number;
14+
duration?: number;
15+
};
16+
17+
export const flyAndScale = (
18+
node: Element,
19+
params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 }
20+
): TransitionConfig => {
21+
const style = getComputedStyle(node);
22+
const transform = style.transform === "none" ? "" : style.transform;
23+
24+
const scaleConversion = (
25+
valueA: number,
26+
scaleA: [number, number],
27+
scaleB: [number, number]
28+
) => {
29+
const [minA, maxA] = scaleA;
30+
const [minB, maxB] = scaleB;
31+
32+
const percentage = (valueA - minA) / (maxA - minA);
33+
const valueB = percentage * (maxB - minB) + minB;
34+
35+
return valueB;
36+
};
37+
38+
const styleToString = (
39+
style: Record<string, number | string | undefined>
40+
): string => {
41+
return Object.keys(style).reduce((str, key) => {
42+
if (style[key] === undefined) return str;
43+
return str + `${key}:${style[key]};`;
44+
}, "");
45+
};
46+
47+
return {
48+
duration: params.duration ?? 200,
49+
delay: 0,
50+
css: (t) => {
51+
const y = scaleConversion(t, [0, 1], [params.y ?? 5, 0]);
52+
const x = scaleConversion(t, [0, 1], [params.x ?? 0, 0]);
53+
const scale = scaleConversion(t, [0, 1], [params.start ?? 0.95, 1]);
54+
55+
return styleToString({
56+
transform: `${transform} translate3d(${x}px, ${y}px, 0) scale(${scale})`,
57+
opacity: t,
58+
});
59+
},
60+
easing: cubicOut,
61+
};
62+
};
63+
164
export function waitForElement(selector: string) {
265
return new Promise((resolve) => {
366
if (document.querySelector(selector)) {

‎src/utils/storage.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,25 @@
11
export const vimeoPlaybackRate = storage.defineItem<number>(
22
"local:vimeoPlaybackRate",
3-
{ fallback: 1 },
3+
{ fallback: 1 }
44
);
55

66
export const seenBanners = storage.defineItem<string[]>("local:seenBanners", {
77
fallback: [],
88
});
9+
10+
type ConfigType = {
11+
banner: boolean;
12+
playbackRate: boolean;
13+
vocabMountain: boolean;
14+
prepswiftStats: boolean;
15+
};
16+
17+
export const config = storage.defineItem<ConfigType>("local:config", {
18+
fallback: {
19+
banner: true,
20+
playbackRate: true,
21+
vocabMountain: true,
22+
prepswiftStats: true,
23+
},
24+
version: 1,
25+
});

‎tailwind.config.ts

+57-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,63 @@
1+
import { fontFamily } from "tailwindcss/defaultTheme";
12
import type { Config } from "tailwindcss";
23

3-
export default {
4+
const config: Config = {
45
content: ["./src/**/*.{html,js,svelte,ts}"],
5-
6+
safelist: ["dark"],
67
theme: {
7-
extend: {},
8+
container: {
9+
center: true,
10+
padding: "2rem",
11+
screens: {
12+
"2xl": "1400px",
13+
},
14+
},
15+
extend: {
16+
colors: {
17+
border: "hsl(var(--border) / <alpha-value>)",
18+
input: "hsl(var(--input) / <alpha-value>)",
19+
ring: "hsl(var(--ring) / <alpha-value>)",
20+
background: "hsl(var(--background) / <alpha-value>)",
21+
foreground: "hsl(var(--foreground) / <alpha-value>)",
22+
primary: {
23+
DEFAULT: "hsl(var(--primary) / <alpha-value>)",
24+
foreground: "hsl(var(--primary-foreground) / <alpha-value>)",
25+
},
26+
secondary: {
27+
DEFAULT: "hsl(var(--secondary) / <alpha-value>)",
28+
foreground: "hsl(var(--secondary-foreground) / <alpha-value>)",
29+
},
30+
destructive: {
31+
DEFAULT: "hsl(var(--destructive) / <alpha-value>)",
32+
foreground: "hsl(var(--destructive-foreground) / <alpha-value>)",
33+
},
34+
muted: {
35+
DEFAULT: "hsl(var(--muted) / <alpha-value>)",
36+
foreground: "hsl(var(--muted-foreground) / <alpha-value>)",
37+
},
38+
accent: {
39+
DEFAULT: "hsl(var(--accent) / <alpha-value>)",
40+
foreground: "hsl(var(--accent-foreground) / <alpha-value>)",
41+
},
42+
popover: {
43+
DEFAULT: "hsl(var(--popover) / <alpha-value>)",
44+
foreground: "hsl(var(--popover-foreground) / <alpha-value>)",
45+
},
46+
card: {
47+
DEFAULT: "hsl(var(--card) / <alpha-value>)",
48+
foreground: "hsl(var(--card-foreground) / <alpha-value>)",
49+
},
50+
},
51+
borderRadius: {
52+
lg: "var(--radius)",
53+
md: "calc(var(--radius) - 2px)",
54+
sm: "calc(var(--radius) - 4px)",
55+
},
56+
fontFamily: {
57+
sans: [...fontFamily.sans],
58+
},
59+
},
860
},
61+
};
962

10-
plugins: [require("@tailwindcss/typography")],
11-
} as Config;
63+
export default config;

‎tsconfig.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
{
22
"extends": "./.wxt/tsconfig.json",
33
"compilerOptions": {
4-
"useDefineForClassFields": true
4+
"useDefineForClassFields": true,
5+
"baseUrl": ".",
6+
"paths": {
7+
"@/*": ["src/*"]
8+
}
59
}
610
}

‎wxt.config.ts

+8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { defineConfig } from "wxt";
2+
import path from "path";
23

34
export default defineConfig({
45
srcDir: "src",
@@ -7,4 +8,11 @@ export default defineConfig({
78
name: "GregMat Buddy",
89
permissions: ["storage"],
910
},
11+
vite: () => ({
12+
resolve: {
13+
alias: {
14+
"@/": path.resolve("./src/"),
15+
},
16+
},
17+
}),
1018
});

0 commit comments

Comments
 (0)
Please sign in to comment.