mirror of
https://github.com/Ku6epXBOCTuK/easy-png-tools.git
synced 2026-11-13 17:08:20 +00:00
refactor: separate components
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from "svelte";
|
||||
|
||||
interface Props {
|
||||
children?: Snippet;
|
||||
size?: "sm" | "large";
|
||||
}
|
||||
let { children, size = "large" }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div class="checker-canvas checker-canvas--{size}">
|
||||
{#if children}
|
||||
{@render children()}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.checker-canvas {
|
||||
position: relative;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
overflow: hidden;
|
||||
background-color: var(--color-text);
|
||||
background-image:
|
||||
linear-gradient(45deg, var(--color-checker-main) 25%, transparent 25%),
|
||||
linear-gradient(-45deg, var(--color-checker-main) 25%, transparent 25%),
|
||||
linear-gradient(45deg, transparent 75%, var(--color-checker-main) 75%),
|
||||
linear-gradient(-45deg, transparent 75%, var(--color-checker-main) 75%);
|
||||
background-size: var(--space-xl) var(--space-xl);
|
||||
background-position:
|
||||
0 0,
|
||||
0 calc(var(--space-xl) / 2),
|
||||
calc(var(--space-xl) / 2) calc(-1 * var(--space-xl) / 2),
|
||||
calc(-1 * var(--space-xl) / 2) 0;
|
||||
}
|
||||
|
||||
.checker-canvas--sm {
|
||||
min-height: var(--size-preview-canvas-min-height-s);
|
||||
}
|
||||
|
||||
.checker-canvas--large {
|
||||
min-height: var(--size-preview-canvas-min-height-l);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,55 @@
|
||||
<script lang="ts">
|
||||
import { Copy } from "@lucide/svelte";
|
||||
import { t } from "$lib/i18n/t";
|
||||
import IconButton from "$lib/components/ui/IconButton.svelte";
|
||||
|
||||
interface Props {
|
||||
code: string;
|
||||
lang?: string;
|
||||
copyable?: boolean;
|
||||
oncopy?: () => void;
|
||||
}
|
||||
let { code, lang, copyable = false, oncopy }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div class="code-block">
|
||||
{#if lang}<span class="code-lang">{lang}</span>{/if}
|
||||
<pre class="code-pre"><code>{code}</code></pre>
|
||||
{#if copyable}
|
||||
<div class="code-copy">
|
||||
<IconButton
|
||||
icon={Copy}
|
||||
label={t("textResult.copy")}
|
||||
onclick={() => oncopy?.()}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.code-block {
|
||||
position: relative;
|
||||
border: var(--size-border) solid var(--color-border);
|
||||
border-radius: var(--radius-m);
|
||||
background: var(--color-background);
|
||||
padding: var(--space-m) var(--space-l);
|
||||
}
|
||||
.code-lang {
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--font-size-s);
|
||||
text-transform: uppercase;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
.code-pre {
|
||||
margin: 0;
|
||||
overflow: auto;
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--font-size-s);
|
||||
color: var(--color-text);
|
||||
}
|
||||
.code-copy {
|
||||
position: absolute;
|
||||
top: var(--space-s);
|
||||
right: var(--space-s);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,32 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from "svelte";
|
||||
import MonoLabel from "./MonoLabel.svelte";
|
||||
|
||||
interface Props {
|
||||
label: string;
|
||||
children: Snippet;
|
||||
}
|
||||
let { label, children }: Props = $props();
|
||||
</script>
|
||||
|
||||
<figure class="image-card">
|
||||
<MonoLabel>{label}</MonoLabel>
|
||||
<div class="image-canvas">{@render children()}</div>
|
||||
</figure>
|
||||
|
||||
<style>
|
||||
.image-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-s);
|
||||
margin: 0;
|
||||
border: var(--size-border) solid var(--color-border);
|
||||
border-radius: var(--radius-m);
|
||||
padding: var(--space-m);
|
||||
background: var(--color-panel);
|
||||
}
|
||||
.image-canvas {
|
||||
border-radius: var(--radius-m);
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,24 @@
|
||||
<script lang="ts">
|
||||
import MetaRow from "./MetaRow.svelte";
|
||||
|
||||
interface Props {
|
||||
items: { caption: string; value: string }[];
|
||||
}
|
||||
let { items }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div class="meta-list">
|
||||
{#each items as item (item.caption)}
|
||||
<MetaRow caption={item.caption} value={item.value} />
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.meta-list {
|
||||
border-top: var(--size-border) solid var(--color-border);
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: var(--space-m);
|
||||
padding-top: var(--space-l);
|
||||
display: grid;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,31 @@
|
||||
<script lang="ts">
|
||||
interface Props {
|
||||
caption: string;
|
||||
value: string;
|
||||
}
|
||||
let { caption, value }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div class="meta-row">
|
||||
<span class="meta-caption">{caption}</span>
|
||||
<b class="meta-value">{value}</b>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.meta-row {
|
||||
gap: var(--space-s);
|
||||
display: grid;
|
||||
}
|
||||
.meta-caption {
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--font-size-s);
|
||||
color: var(--color-text-muted);
|
||||
line-height: normal;
|
||||
}
|
||||
.meta-value {
|
||||
margin-top: var(--space-s);
|
||||
line-height: normal;
|
||||
font: var(--font-size-s) var(--font-mono);
|
||||
color: var(--color-text);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,29 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from "svelte";
|
||||
|
||||
interface Props {
|
||||
accent?: boolean;
|
||||
children?: Snippet;
|
||||
}
|
||||
|
||||
let { accent = false, children }: Props = $props();
|
||||
</script>
|
||||
|
||||
<span class="mono-label" class:accent>
|
||||
{#if children}
|
||||
{@render children()}
|
||||
{/if}
|
||||
</span>
|
||||
|
||||
<style>
|
||||
.mono-label {
|
||||
font: normal var(--font-size-s) var(--font-mono);
|
||||
letter-spacing: var(--space-text-l);
|
||||
color: var(--color-text-muted);
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.accent {
|
||||
color: var(--color-accent);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,31 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from "svelte";
|
||||
import MonoLabel from "./MonoLabel.svelte";
|
||||
|
||||
interface Props {
|
||||
label: string;
|
||||
children: Snippet;
|
||||
}
|
||||
let { label, children }: Props = $props();
|
||||
</script>
|
||||
|
||||
<div class="setting-group">
|
||||
<MonoLabel>{label}</MonoLabel>
|
||||
<div class="setting-control">{@render children()}</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.setting-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-xl);
|
||||
padding: var(--space-m) var(--space-xl);
|
||||
border-bottom: var(--size-border) solid var(--color-border);
|
||||
}
|
||||
.setting-control {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-m);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,21 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from "svelte";
|
||||
|
||||
interface Props {
|
||||
children: Snippet;
|
||||
}
|
||||
let { children }: Props = $props();
|
||||
</script>
|
||||
|
||||
<footer class="settings-footer">{@render children()}</footer>
|
||||
|
||||
<style>
|
||||
.settings-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: var(--space-m);
|
||||
padding: var(--space-l) var(--space-xl);
|
||||
border-top: var(--size-border) solid var(--color-border);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,91 @@
|
||||
<script lang="ts">
|
||||
import { Ellipsis, GripVertical, X } from "@lucide/svelte";
|
||||
import IconButton from "$lib/components/ui/IconButton.svelte";
|
||||
import { t } from "$lib/i18n/t";
|
||||
import type { Snippet } from "svelte";
|
||||
|
||||
interface Props {
|
||||
index: number;
|
||||
title?: string;
|
||||
type?: string;
|
||||
tools?: Snippet;
|
||||
children?: Snippet;
|
||||
onremove?: () => void;
|
||||
}
|
||||
|
||||
let { index, title, type, tools, children, onremove }: Props = $props();
|
||||
</script>
|
||||
|
||||
<article class="step-card">
|
||||
<div class="step-index">{index.toString().padStart(2, "0")}</div>
|
||||
<GripVertical size={16} class="drag" aria-hidden="true" />
|
||||
<div class="step-body">
|
||||
<div class="step-heading">
|
||||
<div class="step-heading-text">
|
||||
{#if type}<span class="step-type">{type}</span>{/if}
|
||||
{#if title}<h2 class="step-title">{title}</h2>{/if}
|
||||
</div>
|
||||
<div class="step-tools">
|
||||
{#if tools}{@render tools()}{/if}
|
||||
<IconButton
|
||||
icon={X}
|
||||
label={t("chain.removeStepAria")}
|
||||
variant="clear"
|
||||
size="s"
|
||||
onclick={() => onremove?.()}
|
||||
/>
|
||||
<Ellipsis size={17} />
|
||||
</div>
|
||||
</div>
|
||||
{#if children}
|
||||
{@render children()}
|
||||
{/if}
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<style>
|
||||
.step-card {
|
||||
display: grid;
|
||||
grid-template-columns: var(--size-step-index) var(--size-step-grip) 1fr;
|
||||
min-height: var(--size-step-min-height);
|
||||
border: var(--size-border) solid var(--color-border);
|
||||
background: var(--color-panel);
|
||||
}
|
||||
.step-index {
|
||||
font: var(--font-size-s) var(--font-mono);
|
||||
color: var(--color-main);
|
||||
padding: var(--space-xl) 0 0px var(--space-xl);
|
||||
}
|
||||
.step-body {
|
||||
padding: var(--space-xl) var(--space-xl) var(--space-xl);
|
||||
}
|
||||
.step-heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-xl);
|
||||
border-color: var(--color-border);
|
||||
}
|
||||
.step-type {
|
||||
color: var(--color-text-muted);
|
||||
font: var(--font-size-s) var(--font-mono);
|
||||
letter-spacing: var(--space-text-xl);
|
||||
}
|
||||
.step-title {
|
||||
margin: var(--space-s) 0 var(--space-xl);
|
||||
font: 600 var(--font-size-m) var(--font-mono);
|
||||
color: var(--color-text);
|
||||
}
|
||||
.step-tools {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--space-l);
|
||||
}
|
||||
.step-card :global(.drag) {
|
||||
margin-top: var(--space-xl);
|
||||
color: var(--color-border);
|
||||
}
|
||||
.step-body > :not(.step-heading) {
|
||||
padding: var(--space-l);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user