mirror of
https://github.com/Ku6epXBOCTuK/easy-png-tools.git
synced 2026-09-14 13:36:36 +00:00
feat: css audit fixes
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
<footer class="preview-footer">
|
||||
<span>easy-png-tools <b class="version">v2.4.0</b></span>
|
||||
<span>© 2024</span>
|
||||
</footer>
|
||||
|
||||
<style>
|
||||
.preview-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
padding: 16px clamp(20px, 4vw, 64px);
|
||||
border-top: 1px solid var(--line);
|
||||
font: 10px var(--font-mono);
|
||||
letter-spacing: 0.08em;
|
||||
color: var(--muted);
|
||||
}
|
||||
.preview-footer .version {
|
||||
color: var(--blue);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,37 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from "svelte";
|
||||
|
||||
interface Props {
|
||||
settings: Snippet;
|
||||
preview: Snippet;
|
||||
}
|
||||
|
||||
let { settings, preview }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div class="ws">
|
||||
<section class="ws-settings">{@render settings()}</section>
|
||||
{@render preview()}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.ws {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.05fr) minmax(520px, 0.95fr);
|
||||
align-items: start;
|
||||
gap: 56px;
|
||||
max-width: none;
|
||||
margin: auto;
|
||||
padding: 60px clamp(24px, 4vw, 72px) 72px;
|
||||
}
|
||||
.ws-settings {
|
||||
min-width: 0;
|
||||
}
|
||||
@media (max-width: 800px) {
|
||||
.ws {
|
||||
grid-template-columns: 1fr;
|
||||
gap: var(--ws-gap-mobile);
|
||||
padding: 36px 16px 48px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,57 +0,0 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from "svelte";
|
||||
|
||||
interface Props {
|
||||
settings: Snippet;
|
||||
preview: Snippet;
|
||||
columns?: string;
|
||||
gap?: string;
|
||||
padding?: string;
|
||||
maxWidth?: string;
|
||||
stickyTop?: string;
|
||||
padMobile?: string;
|
||||
gapMobile?: string;
|
||||
}
|
||||
|
||||
let {
|
||||
settings,
|
||||
preview,
|
||||
columns = "minmax(0, 1fr) minmax(0, 1.1fr)",
|
||||
gap = "40px",
|
||||
padding = "48px clamp(24px, 4vw, 72px) 72px",
|
||||
maxWidth = "1680px",
|
||||
stickyTop = "84px",
|
||||
padMobile = "32px 16px 48px",
|
||||
gapMobile = "24px",
|
||||
}: Props = $props();
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="ws"
|
||||
style="--ws-cols:{columns};--ws-gap:{gap};--ws-pad:{padding};--ws-max:{maxWidth};--ws-sticky:{stickyTop};--ws-pad-mobile:{padMobile};--ws-gap-mobile:{gapMobile};"
|
||||
>
|
||||
<section class="ws-settings">{@render settings()}</section>
|
||||
{@render preview()}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.ws {
|
||||
display: grid;
|
||||
grid-template-columns: var(--ws-cols);
|
||||
align-items: start;
|
||||
gap: var(--ws-gap);
|
||||
max-width: var(--ws-max);
|
||||
margin: auto;
|
||||
padding: var(--ws-pad);
|
||||
}
|
||||
.ws-settings {
|
||||
min-width: 0;
|
||||
}
|
||||
@media (max-width: 800px) {
|
||||
.ws {
|
||||
grid-template-columns: 1fr;
|
||||
gap: var(--ws-gap-mobile);
|
||||
padding: var(--ws-pad-mobile);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { page } from "$app/stores";
|
||||
import { page } from "$app/state";
|
||||
import Footer from "$lib/components/kit/Footer.svelte";
|
||||
import TopBar from "$lib/components/kit/TopBar.svelte";
|
||||
import { Link2 } from "@lucide/svelte";
|
||||
import "$lib/styles/design2.css";
|
||||
import type { Snippet } from "svelte";
|
||||
|
||||
@@ -31,14 +31,8 @@
|
||||
}
|
||||
});
|
||||
|
||||
let crumb = $derived(toCrumb($page.url.pathname));
|
||||
let status = $derived(toStatus($page.url.pathname));
|
||||
|
||||
const FOOTER_NOTE: Record<string, string> = {
|
||||
"/preview/tools/linear-gradient-png": "gradient tool · local-only",
|
||||
"/preview/tools/remove-background-png": "background remover · local-only",
|
||||
};
|
||||
let footerNote = $derived(FOOTER_NOTE[$page.url.pathname] ?? "pipeline is local-only");
|
||||
let crumb = $derived(toCrumb(page.url.pathname));
|
||||
let status = $derived(toStatus(page.url.pathname));
|
||||
|
||||
const CRUMB: Record<string, string> = {
|
||||
"/preview/demo": "WORKSPACE",
|
||||
@@ -55,7 +49,12 @@
|
||||
};
|
||||
|
||||
function toCrumb(path: string): string {
|
||||
return "/ " + (CRUMB[path] ?? path.split("/").filter(Boolean).pop()?.toUpperCase() ?? "PREVIEW");
|
||||
return (
|
||||
"/ " +
|
||||
(CRUMB[path] ??
|
||||
path.split("/").filter(Boolean).pop()?.toUpperCase() ??
|
||||
"PREVIEW")
|
||||
);
|
||||
}
|
||||
|
||||
function toStatus(path: string): string {
|
||||
@@ -66,30 +65,16 @@
|
||||
<main class="preview-root" data-theme={theme}>
|
||||
<TopBar {theme} {crumb} {status} ontoggle={toggle} />
|
||||
{@render children()}
|
||||
{#if $page.url.pathname !== "/preview/list-tools"}
|
||||
<footer class="preview-footer">
|
||||
<span>easy-png-tools <b>v2.4.0</b></span>
|
||||
<span
|
||||
>{#if footerNote === "pipeline is local-only"}<Link2 size={13} /> {/if}{footerNote}</span
|
||||
>
|
||||
<span>© 2024</span>
|
||||
</footer>
|
||||
{/if}
|
||||
<Footer />
|
||||
</main>
|
||||
|
||||
<style>
|
||||
.preview-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
padding: 16px clamp(20px, 4vw, 64px);
|
||||
border-top: 1px solid var(--line);
|
||||
font: 10px var(--font-mono);
|
||||
letter-spacing: 0.08em;
|
||||
color: var(--muted);
|
||||
}
|
||||
.preview-footer .version {
|
||||
color: var(--blue);
|
||||
main {
|
||||
background-color: var(--background);
|
||||
background-image:
|
||||
linear-gradient(#dce2e7 1px, #0000 1px),
|
||||
linear-gradient(90deg, #dce2e7 1px, #0000 1px);
|
||||
background-size: 32px 32px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
<script lang="ts">
|
||||
import { Settings2, ChevronDown, Plus, SlidersHorizontal } from "@lucide/svelte";
|
||||
import WorkspaceLayout from "$lib/components/kit/WorkspaceLayout.svelte";
|
||||
import WorkspaceHeader from "./WorkspaceHeader.svelte";
|
||||
import SectionLabel from "$lib/components/kit/SectionLabel.svelte";
|
||||
import StepCard from "$lib/components/kit/StepCard.svelte";
|
||||
import Badge from "$lib/components/kit/Badge.svelte";
|
||||
import FieldGrid from "$lib/components/kit/FieldGrid.svelte";
|
||||
import ColorField from "$lib/components/kit/ColorField.svelte";
|
||||
import SliderField from "$lib/components/kit/SliderField.svelte";
|
||||
import Segmented from "$lib/components/kit/Segmented.svelte";
|
||||
import ToggleRow from "$lib/components/kit/ToggleRow.svelte";
|
||||
import DownloadButton from "$lib/components/kit/DownloadButton.svelte";
|
||||
import FieldGrid from "$lib/components/kit/FieldGrid.svelte";
|
||||
import IconButton from "$lib/components/kit/IconButton.svelte";
|
||||
import MetaList from "$lib/components/kit/MetaList.svelte";
|
||||
import PageGrid from "$lib/components/kit/PageGrid.svelte";
|
||||
import PipelineFooter from "$lib/components/kit/PipelineFooter.svelte";
|
||||
import PreviewStack from "$lib/components/kit/PreviewStack.svelte";
|
||||
import PreviewTile from "$lib/components/kit/PreviewTile.svelte";
|
||||
import DownloadButton from "$lib/components/kit/DownloadButton.svelte";
|
||||
import MetaList from "$lib/components/kit/MetaList.svelte";
|
||||
import IconButton from "$lib/components/kit/IconButton.svelte";
|
||||
import PipelineFooter from "$lib/components/kit/PipelineFooter.svelte";
|
||||
import SectionLabel from "$lib/components/kit/SectionLabel.svelte";
|
||||
import Segmented from "$lib/components/kit/Segmented.svelte";
|
||||
import SliderField from "$lib/components/kit/SliderField.svelte";
|
||||
import StepCard from "$lib/components/kit/StepCard.svelte";
|
||||
import ToggleRow from "$lib/components/kit/ToggleRow.svelte";
|
||||
import {
|
||||
ChevronDown,
|
||||
Plus,
|
||||
Settings2,
|
||||
SlidersHorizontal,
|
||||
} from "@lucide/svelte";
|
||||
import WorkspaceHeader from "./WorkspaceHeader.svelte";
|
||||
|
||||
let gradColor = $state("#DCEBFF");
|
||||
let direction = $state(135);
|
||||
@@ -59,14 +64,7 @@
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
</svelte:head>
|
||||
|
||||
<WorkspaceLayout
|
||||
columns="minmax(0, 1.05fr) minmax(520px, 0.95fr)"
|
||||
gap="56px"
|
||||
padding="60px clamp(24px, 4vw, 72px) 72px"
|
||||
maxWidth="1200px"
|
||||
stickyTop="24px"
|
||||
padMobile="36px 16px 48px"
|
||||
>
|
||||
<PageGrid>
|
||||
{#snippet settings()}
|
||||
<WorkspaceHeader
|
||||
eyebrowA="PNG PROCESSING"
|
||||
@@ -76,9 +74,16 @@
|
||||
file={{ name: "source.png", size: "1.8 MB" }}
|
||||
/>
|
||||
|
||||
<SectionLabel label="PROCESSING PIPELINE" title="4 active steps" meta="• LIVE" unwrapActions>
|
||||
<SectionLabel
|
||||
label="PROCESSING PIPELINE"
|
||||
title="4 active steps"
|
||||
meta="• LIVE"
|
||||
unwrapActions
|
||||
>
|
||||
{#snippet actions()}
|
||||
<button class="add-btn" onclick={() => {}}><Plus size={15} /> Add tool</button>
|
||||
<button class="add-btn" onclick={() => {}}
|
||||
><Plus size={15} /> Add tool</button
|
||||
>
|
||||
{/snippet}
|
||||
</SectionLabel>
|
||||
|
||||
@@ -92,27 +97,27 @@
|
||||
{#snippet tools()}
|
||||
<Badge tone="success" check>AUTO</Badge>
|
||||
{/snippet}
|
||||
<FieldGrid>
|
||||
<ColorField label="COLOR" chevron bind:value={gradColor} />
|
||||
<SliderField
|
||||
label="DIRECTION"
|
||||
bind:value={direction}
|
||||
min={0}
|
||||
max={360}
|
||||
suffix=" °"
|
||||
/>
|
||||
<div class="control-block">
|
||||
<label>OPACITY <output>{opacity}%</output></label>
|
||||
<Segmented
|
||||
bind:value={opacity}
|
||||
options={[
|
||||
{ value: "100", label: "100" },
|
||||
{ value: "75", label: "75" },
|
||||
{ value: "50", label: "50" },
|
||||
{ value: "25", label: "25" },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<FieldGrid>
|
||||
<ColorField label="COLOR" chevron bind:value={gradColor} />
|
||||
<SliderField
|
||||
label="DIRECTION"
|
||||
bind:value={direction}
|
||||
min={0}
|
||||
max={360}
|
||||
suffix=" °"
|
||||
/>
|
||||
<div class="control-block">
|
||||
<label>OPACITY <output>{opacity}%</output></label>
|
||||
<Segmented
|
||||
bind:value={opacity}
|
||||
options={[
|
||||
{ value: "100", label: "100" },
|
||||
{ value: "75", label: "75" },
|
||||
{ value: "50", label: "50" },
|
||||
{ value: "25", label: "25" },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</FieldGrid>
|
||||
</StepCard>
|
||||
|
||||
@@ -125,8 +130,8 @@
|
||||
{#snippet tools()}
|
||||
<Badge tone="success" check>AUTO</Badge>
|
||||
{/snippet}
|
||||
<div class="transform-note">
|
||||
<SlidersHorizontal size={15} /> Automatic subject detection enabled
|
||||
<div class="transform-note">
|
||||
<SlidersHorizontal size={15} /> Automatic subject detection enabled
|
||||
</div>
|
||||
</StepCard>
|
||||
|
||||
@@ -134,15 +139,15 @@
|
||||
{#snippet tools()}
|
||||
<Badge tone="success" check>AUTO</Badge>
|
||||
{/snippet}
|
||||
<FieldGrid compact>
|
||||
<SliderField
|
||||
label="WIDTH"
|
||||
bind:value={outlineWidth}
|
||||
min={0}
|
||||
max={8}
|
||||
suffix=" px"
|
||||
/>
|
||||
<ColorField label="COLOR" dark bind:value={outlineColor} />
|
||||
<FieldGrid compact>
|
||||
<SliderField
|
||||
label="WIDTH"
|
||||
bind:value={outlineWidth}
|
||||
min={0}
|
||||
max={8}
|
||||
suffix=" px"
|
||||
/>
|
||||
<ColorField label="COLOR" dark bind:value={outlineColor} />
|
||||
</FieldGrid>
|
||||
</StepCard>
|
||||
|
||||
@@ -155,15 +160,18 @@
|
||||
{#snippet tools()}
|
||||
<Badge tone="success" check>AUTO</Badge>
|
||||
{/snippet}
|
||||
<FieldGrid compact>
|
||||
<SliderField
|
||||
label="RADIUS"
|
||||
bind:value={radius}
|
||||
min={0}
|
||||
max={48}
|
||||
suffix=" px"
|
||||
/>
|
||||
<ToggleRow label="Preserve aspect ratio" bind:checked={preserveAspect} />
|
||||
<FieldGrid compact>
|
||||
<SliderField
|
||||
label="RADIUS"
|
||||
bind:value={radius}
|
||||
min={0}
|
||||
max={48}
|
||||
suffix=" px"
|
||||
/>
|
||||
<ToggleRow
|
||||
label="Preserve aspect ratio"
|
||||
bind:checked={preserveAspect}
|
||||
/>
|
||||
</FieldGrid>
|
||||
</StepCard>
|
||||
</div>
|
||||
@@ -178,10 +186,7 @@
|
||||
<button class="history-toggle" onclick={() => {}}>
|
||||
Hide intermediate <ChevronDown size={15} />
|
||||
</button>
|
||||
<DownloadButton
|
||||
label="Download result"
|
||||
onclick={() => {}}
|
||||
/>
|
||||
<DownloadButton label="Download result" onclick={() => {}} />
|
||||
<MetaList
|
||||
items={[
|
||||
{ caption: "DIMENSIONS", value: "1200 × 800 px" },
|
||||
@@ -199,17 +204,17 @@
|
||||
|
||||
<PreviewStack pad="16px 0">
|
||||
{#each previewTiles as tile (tile.label)}
|
||||
<PreviewTile label={tile.label} caption={tile.caption}>
|
||||
<div
|
||||
class="ph"
|
||||
class:active={tile.active}
|
||||
style="background:{tile.bg}; border-radius:{tile.radius ??
|
||||
'0'}; box-shadow:{tile.ring ?? 'none'};"
|
||||
>
|
||||
<span class="sample-icon">PNG</span>
|
||||
<span>easy-png-tools</span>
|
||||
</div>
|
||||
</PreviewTile>
|
||||
<PreviewTile label={tile.label} caption={tile.caption}>
|
||||
<div
|
||||
class="ph"
|
||||
class:active={tile.active}
|
||||
style="background:{tile.bg}; border-radius:{tile.radius ??
|
||||
'0'}; box-shadow:{tile.ring ?? 'none'};"
|
||||
>
|
||||
<span class="sample-icon">PNG</span>
|
||||
<span>easy-png-tools</span>
|
||||
</div>
|
||||
</PreviewTile>
|
||||
{/each}
|
||||
</PreviewStack>
|
||||
|
||||
@@ -218,7 +223,7 @@
|
||||
</p>
|
||||
</section>
|
||||
{/snippet}
|
||||
</WorkspaceLayout>
|
||||
</PageGrid>
|
||||
|
||||
<style>
|
||||
.add-btn {
|
||||
@@ -301,4 +306,3 @@
|
||||
line-height: 1.5;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user