refactor: ♻️ Rewrite entire preferences panel and emoji manager from scratch

This commit is contained in:
Jesse Wierzbinski 2025-04-30 01:44:16 +02:00
parent 0443a37508
commit 17bb75733c
No known key found for this signature in database
51 changed files with 1982 additions and 17 deletions

View file

@ -0,0 +1,37 @@
<template>
<div class="grid grid-cols-[minmax(0,1fr)_auto] gap-2 hover:bg-muted/40 duration-75 p-4">
<div class="flex flex-col gap-1">
<h3 class="text-sm font-semibold tracking-tight">{{ pref.options.name }}</h3>
<small v-if="pref.options.description" class="text-xs font-medium leading-none text-muted-foreground">{{
pref.options.description }}</small>
</div>
<div class="flex items-center justify-end">
<slot :value="value" :set-value="setValue" />
</div>
<slot name="extra" :value="value" :set-value="setValue" />
</div>
</template>
<script lang="ts" setup>
import type { Preference } from "../types";
const { pref } = defineProps<{
pref: Preference<any>;
}>();
const value = ref<any>(pref.options.defaultValue);
const setValue = (newValue: MaybeRef<any>) => {
value.value = toValue(newValue);
};
defineSlots<{
default(props: {
value: any;
setValue: (value: MaybeRef<any>) => void;
}): any;
extra(props: {
value: any;
setValue: (value: MaybeRef<any>) => void;
}): any;
}>();
</script>

View file

@ -0,0 +1,15 @@
<template>
<Base :pref="pref" v-slot="{ setValue, value }">
<Switch @update:model-value="setValue" :model-value="value" />
</Base>
</template>
<script lang="ts" setup>
import { Switch } from "~/components/ui/switch";
import type { BooleanPreference } from "../types";
import Base from "./base.vue";
const { pref } = defineProps<{
pref: BooleanPreference;
}>();
</script>

View file

@ -0,0 +1,34 @@
<template>
<Collapsible as-child>
<Base :pref="pref">
<template #default>
<CollapsibleTrigger as-child>
<Button variant="outline">
Open code
</Button>
</CollapsibleTrigger>
</template>
<template #extra="{ setValue, value }">
<CollapsibleContent class="col-span-2 mt-2">
<Textarea :rows="10" :model-value="value" @update:model-value="setValue" />
</CollapsibleContent>
</template>
</Base>
</Collapsible>
</template>
<script lang="ts" setup>
import { Button } from "~/components/ui/button";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "~/components/ui/collapsible";
import { Textarea } from "~/components/ui/textarea";
import type { CodePreference } from "../types";
import Base from "./base.vue";
const { pref } = defineProps<{
pref: CodePreference;
}>();
</script>

View file

@ -0,0 +1,39 @@
<template>
<Base :pref="pref" v-slot="{ setValue, value }">
<DropdownMenu>
<DropdownMenuTrigger as-child>
<Button variant="outline">
Pick
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent class="w-56">
<DropdownMenuCheckboxItem v-for="[option, title] in Object.entries(pref.options.options)" :key="option"
:model-value="value.includes(option)" @update:model-value="checked => {
if (checked) {
setValue([...value, option]);
} else {
setValue(value.filter((v: any) => v !== option));
}
}">
{{ title }}
</DropdownMenuCheckboxItem>
</DropdownMenuContent>
</DropdownMenu>
</Base>
</template>
<script lang="ts" setup>
import { Button } from "~/components/ui/button";
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuTrigger,
} from "~/components/ui/dropdown-menu";
import type { MultiSelectPreference } from "../types";
import Base from "./base.vue";
const { pref } = defineProps<{
pref: MultiSelectPreference<string>;
}>();
</script>

View file

@ -0,0 +1,27 @@
<template>
<Base :pref="pref" v-slot="{ setValue, value }">
<NumberField :model-value="value" @update:model-value="setValue" :min="pref.options.min" :max="pref.options.max" :step="pref.options.integer ? 1 : pref.options.step">
<NumberFieldContent>
<NumberFieldDecrement />
<NumberFieldInput />
<NumberFieldIncrement />
</NumberFieldContent>
</NumberField>
</Base>
</template>
<script lang="ts" setup>
import {
NumberField,
NumberFieldContent,
NumberFieldDecrement,
NumberFieldIncrement,
NumberFieldInput,
} from "~/components/ui/number-field";
import type { NumberPreference } from "../types";
import Base from "./base.vue";
const { pref } = defineProps<{
pref: NumberPreference;
}>();
</script>

View file

@ -0,0 +1,33 @@
<template>
<Base :pref="pref" v-slot="{ setValue, value }">
<Select :model-value="value" @update:model-value="setValue">
<SelectTrigger>
<SelectValue placeholder="Select an option" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem v-for="[val, title] in Object.entries(pref.options.options)" :value="val">
{{ title }}
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</Base>
</template>
<script lang="ts" setup>
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "~/components/ui/select";
import type { SelectPreference } from "../types";
import Base from "./base.vue";
const { pref } = defineProps<{
pref: SelectPreference<string>;
}>();
</script>

View file

@ -0,0 +1,15 @@
<template>
<Base :pref="pref" v-slot="{ setValue, value }">
<Input placeholder="Content here..." :model-value="value" @update:model-value="setValue" />
</Base>
</template>
<script lang="ts" setup>
import { Input } from "~/components/ui/input";
import type { TextPreference } from "../types";
import Base from "./base.vue";
const { pref } = defineProps<{
pref: TextPreference;
}>();
</script>

View file

@ -0,0 +1,34 @@
<template>
<Collapsible as-child>
<Base :pref="pref">
<template #default>
<CollapsibleTrigger as-child>
<Button variant="outline">
Edit URL
</Button>
</CollapsibleTrigger>
</template>
<template #extra="{ setValue, value }">
<CollapsibleContent class="col-span-2 mt-2">
<UrlInput placeholder="Type URL or domain here..." :model-value="value" @update:model-value="setValue" />
</CollapsibleContent>
</template>
</Base>
</Collapsible>
</template>
<script lang="ts" setup>
import { Button } from "~/components/ui/button";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "~/components/ui/collapsible";
import { Input, UrlInput } from "~/components/ui/input";
import type { TextPreference } from "../types";
import Base from "./base.vue";
const { pref } = defineProps<{
pref: TextPreference;
}>();
</script>