messing around with ui
This commit is contained in:
Binary file not shown.
@ -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": {
|
||||||
|
@ -1 +0,0 @@
|
|||||||
|
|
@ -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>
|
||||||
|
BIN
frontend/src/assets/fonts/Manrope-VariableFont_wght.ttf
Normal file
BIN
frontend/src/assets/fonts/Manrope-VariableFont_wght.ttf
Normal file
Binary file not shown.
37
frontend/src/components/ImageViewer.tsx
Normal file
37
frontend/src/components/ImageViewer.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
@ -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;
|
||||||
|
@ -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")],
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user