messing around with ui

This commit is contained in:
2025-02-23 20:02:06 +01:00
parent df16298b1f
commit 1fc1079484
8 changed files with 79 additions and 50 deletions

Binary file not shown.

View File

@ -20,6 +20,7 @@
"@tauri-apps/api": "^2", "@tauri-apps/api": "^2",
"@tauri-apps/plugin-dialog": "~2", "@tauri-apps/plugin-dialog": "~2",
"@tauri-apps/plugin-opener": "^2", "@tauri-apps/plugin-opener": "^2",
"clsx": "^2.1.1",
"solid-js": "^1.9.3" "solid-js": "^1.9.3"
}, },
"devDependencies": { "devDependencies": {

View File

@ -1 +0,0 @@

View File

@ -1,8 +1,7 @@
import { FolderPicker } from "./components/FolderPicker"; import { createSignal } from "solid-js";
import { listen } from "@tauri-apps/api/event";
import { createEffect, createSignal } from "solid-js";
import { Search } from "@kobalte/core/search"; import { Search } from "@kobalte/core/search";
import { IconSearch, IconRefresh } from "@tabler/icons-solidjs"; import { IconSearch, IconRefresh } from "@tabler/icons-solidjs";
import clsx from "clsx";
type Emoji = { type Emoji = {
emoji: string; emoji: string;
@ -10,7 +9,6 @@ type Emoji = {
}; };
function App() { function App() {
const [latestImage, setLatestImage] = createSignal<string | null>(null);
const [options, setOptions] = createSignal<Emoji[]>([]); const [options, setOptions] = createSignal<Emoji[]>([]);
const [emoji, setEmoji] = createSignal<Emoji | null>(null); const [emoji, setEmoji] = createSignal<Emoji | null>(null);
@ -28,35 +26,8 @@ function App() {
); );
}; };
createEffect(() => {
// Listen for PNG processing events
const unlisten = listen("png-processed", (event) => {
console.log("Received processed PNG");
const base64Data = event.payload as string;
setLatestImage(`data:image/png;base64,${base64Data}`);
});
return () => {
unlisten.then((fn) => fn()); // Cleanup listener
};
});
return ( return (
<main class="container pt-8"> <main class="container px-4 pt-2 pb-4">
<h1>hello???</h1>
<FolderPicker />
{latestImage() && (
<div class="mt-4">
<h3>Latest Processed Image:</h3>
<img
src={latestImage() || undefined}
alt="Latest processed"
class="max-w-md"
/>
</div>
)}
<Search <Search
triggerMode="focus" triggerMode="focus"
options={options()} options={options()}
@ -66,39 +37,50 @@ function App() {
optionLabel="name" optionLabel="name"
placeholder="Search an emoji…" placeholder="Search an emoji…"
itemComponent={(props) => ( itemComponent={(props) => (
<Search.Item item={props.item} class="search__item"> <Search.Item
<Search.ItemLabel>{props.item.rawValue.emoji}</Search.ItemLabel> item={props.item}
class={clsx(
"text-2xl leading-none text-gray-900 rounded-md p-2 select-none outline-none grid justify-items-center w-[calc(20%-5px)] box-border",
"hover:bg-gray-100 ui-highlighted:bg-gray-100 ui-highlighted:shadow-[inset_0_0_0_2px_rgb(2,132,199)] ui-disabled:text-gray-400 ui-disabled:opacity-50 ui-disabled:pointer-events-none"
)}
>
<Search.ItemLabel class="mx-[-100px]">
{props.item.rawValue.emoji}
</Search.ItemLabel>
</Search.Item> </Search.Item>
)} )}
> >
<Search.Control class="search__control" aria-label="Emoji"> <Search.Control
class="inline-flex justify-between w-full rounded-md text-base leading-none outline-none bg-white border border-gray-200 text-gray-900 transition-colors duration-250 ui-invalid::border-red-500 ui-invalid::text-red-500"
aria-label="Emoji"
>
<Search.Indicator <Search.Indicator
class="search__indicator" class="appearance-none inline-flex justify-center items-center w-auto outline-none rounded-l-md px-2.5 bg-gray-100 border-r border-gray-200 text-gray-900 text-base leading-none transition-colors duration-250"
loadingComponent={ loadingComponent={
<Search.Icon class="load__icon"> <Search.Icon class="h-5 w-5 grid justify-items-center flex-none">
<IconRefresh class="spin__icon" /> <IconRefresh class="m-auto animate-spin" />
</Search.Icon> </Search.Icon>
} }
> >
<Search.Icon class="search__icon"> <Search.Icon class="h-5 w-5 grid justify-items-center flex-none">
<IconSearch class="center__icon" /> <IconSearch class="m-auto" />
</Search.Icon> </Search.Icon>
</Search.Indicator> </Search.Indicator>
<Search.Input class="search__input" /> <Search.Input class="appearance-none inline-flex w-full min-h-[40px] pl-4 text-base bg-transparent rounded-l-md outline-none placeholder:text-gray-600" />
</Search.Control> </Search.Control>
<Search.Portal> <Search.Portal>
<Search.Content <Search.Content
class="search__content" class="bg-white rounded-md border border-gray-200 shadow-md origin-[var(--kb-search-content-transform-origin)] w-[var(--kb-popper-anchor-width)] data-[expanded]:animate-contentShow"
onCloseAutoFocus={(e) => e.preventDefault()} onCloseAutoFocus={(e) => e.preventDefault()}
> >
<Search.Listbox class="search__listbox" /> <Search.Listbox class="overflow-y-auto max-h-[360px] p-2 flex flex-row justify-start flex-wrap gap-1.5 leading-none focus:outline-none" />
<Search.NoResult class="search__no_result"> <Search.NoResult class="text-center p-2 pb-6 m-auto text-gray-600">
😬 No emoji found 😬 No emoji found
</Search.NoResult> </Search.NoResult>
</Search.Content> </Search.Content>
</Search.Portal> </Search.Portal>
</Search> </Search>
<div class="result__content"> <div class="mt-4 text-base leading-none">
Emoji selected: {emoji()?.emoji} {emoji()?.name} Emoji selected: {emoji()?.emoji} {emoji()?.name}
</div> </div>
</main> </main>

View File

@ -0,0 +1,37 @@
import { createEffect, createSignal } from "solid-js";
import { listen } from "@tauri-apps/api/event";
import { FolderPicker } from "./FolderPicker";
export function ImageViewer() {
const [latestImage, setLatestImage] = createSignal<string | null>(null);
createEffect(() => {
// Listen for PNG processing events
const unlisten = listen("png-processed", (event) => {
console.log("Received processed PNG");
const base64Data = event.payload as string;
setLatestImage(`data:image/png;base64,${base64Data}`);
});
return () => {
unlisten.then((fn) => fn()); // Cleanup listener
};
});
return (
<div>
<FolderPicker />
{latestImage() && (
<div class="mt-4">
<h3>Latest Processed Image:</h3>
<img
src={latestImage() || undefined}
alt="Latest processed"
class="max-w-md"
/>
</div>
)}
</div>
);
}

View File

@ -2,13 +2,19 @@
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
@font-face {
font-family: "Manrope";
src: url("./assets/fonts/Manrope-VariableFont_wght.ttf") format("truetype");
font-weight: 100 900;
font-display: swap;
}
:root { :root {
@apply bg-neutral-50 text-black rounded-xl; @apply bg-neutral-50 text-black rounded-xl;
font-family: Inter, Avenir, Helvetica, Arial, sans-serif; font-family: Manrope, sans-serif;
font-size: 16px; font-size: 16px;
line-height: 24px; line-height: 24px;
font-weight: 400; font-weight: 500;
font-synthesis: none; font-synthesis: none;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;

View File

@ -2,7 +2,11 @@
export default { export default {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: { theme: {
extend: {}, extend: {
fontFamily: {
sans: ["Manrope", "sans-serif"],
},
},
}, },
plugins: [require("@kobalte/tailwindcss")], plugins: [require("@kobalte/tailwindcss")],
}; };