mirror of
https://github.com/Ku6epXBOCTuK/easy-png-tools.git
synced 2026-11-13 17:08:20 +00:00
fix: select mode via segmented button in split by parts
This commit is contained in:
@@ -135,6 +135,8 @@
|
|||||||
|
|
||||||
## UI и качество
|
## UI и качество
|
||||||
|
|
||||||
|
- [ ] split to parts - посмотреть вариант с toggle component - может будет
|
||||||
|
удобнее чем sectioned buttons
|
||||||
- [ ] неудобно настраивать ползунками, некоторые инструменты удобнее настроить
|
- [ ] неудобно настраивать ползунками, некоторые инструменты удобнее настроить
|
||||||
через drag-n-drop. звучит сложно, но надо придумать процесс
|
через drag-n-drop. звучит сложно, но надо придумать процесс
|
||||||
- [ ] просмотр картинки в оригинальном размере, и возможно с зумом отдельных
|
- [ ] просмотр картинки в оригинальном размере, и возможно с зумом отдельных
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Control from "./Control.svelte";
|
||||||
|
import Segmented from "$lib/components/ui/Segmented.svelte";
|
||||||
|
import { optionLabel } from "$lib/i18n/schema-tool-strings";
|
||||||
|
import type { FieldSpec, SegmentedSpec } from "$lib/registry-schema";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
label: string;
|
||||||
|
value: unknown;
|
||||||
|
spec: FieldSpec;
|
||||||
|
toolId: string;
|
||||||
|
fieldId: string;
|
||||||
|
onchange?: (value: string) => void;
|
||||||
|
}
|
||||||
|
let { label, value, spec, toolId, fieldId, onchange }: Props = $props();
|
||||||
|
|
||||||
|
const sp = $derived(spec as SegmentedSpec);
|
||||||
|
const current = $derived(
|
||||||
|
typeof value === "string" && sp.options.some((o) => o.value === value)
|
||||||
|
? value
|
||||||
|
: sp.default,
|
||||||
|
);
|
||||||
|
const options = $derived(
|
||||||
|
sp.options.map((o) => ({
|
||||||
|
value: o.value,
|
||||||
|
label: optionLabel(toolId, fieldId, o.value, o.label),
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Control {label}>
|
||||||
|
<Segmented {options} value={current} onchange={(v) => onchange?.(v)} />
|
||||||
|
</Control>
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
import ColorsControl from "$lib/components/fields/schema/ColorsControl.svelte";
|
import ColorsControl from "$lib/components/fields/schema/ColorsControl.svelte";
|
||||||
import RangeControl from "$lib/components/fields/schema/RangeControl.svelte";
|
import RangeControl from "$lib/components/fields/schema/RangeControl.svelte";
|
||||||
import SelectControl from "$lib/components/fields/schema/SelectControl.svelte";
|
import SelectControl from "$lib/components/fields/schema/SelectControl.svelte";
|
||||||
|
import SegmentedControl from "$lib/components/fields/schema/SegmentedControl.svelte";
|
||||||
import TextControl from "$lib/components/fields/schema/TextControl.svelte";
|
import TextControl from "$lib/components/fields/schema/TextControl.svelte";
|
||||||
import OffsetControl from "$lib/components/fields/schema/OffsetControl.svelte";
|
import OffsetControl from "$lib/components/fields/schema/OffsetControl.svelte";
|
||||||
import PositionControl from "$lib/components/fields/schema/PositionControl.svelte";
|
import PositionControl from "$lib/components/fields/schema/PositionControl.svelte";
|
||||||
@@ -42,6 +43,7 @@
|
|||||||
"color-pair": ColorPairControl,
|
"color-pair": ColorPairControl,
|
||||||
colors: ColorsControl,
|
colors: ColorsControl,
|
||||||
select: SelectControl,
|
select: SelectControl,
|
||||||
|
segmented: SegmentedControl,
|
||||||
checkbox: CheckboxControl,
|
checkbox: CheckboxControl,
|
||||||
text: TextControl,
|
text: TextControl,
|
||||||
dimension: DimensionField,
|
dimension: DimensionField,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ function selectOptions(
|
|||||||
const spec = (
|
const spec = (
|
||||||
field as { spec?: { kind?: string; options?: SelectOption[] } }
|
field as { spec?: { kind?: string; options?: SelectOption[] } }
|
||||||
).spec;
|
).spec;
|
||||||
if (spec?.kind !== "select") continue;
|
if (spec?.kind !== "select" && spec?.kind !== "segmented") continue;
|
||||||
for (const option of spec.options ?? []) result.push({ fieldId, option });
|
for (const option of spec.options ?? []) result.push({ fieldId, option });
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -50,6 +50,15 @@ export interface SelectSpec<V extends string = string> extends FieldSpecBase {
|
|||||||
options: { value: V; label: string }[];
|
options: { value: V; label: string }[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** То же, что select, но рендерится кнопками-сегментами (выбор в 1 клик). */
|
||||||
|
export interface SegmentedSpec<
|
||||||
|
V extends string = string,
|
||||||
|
> extends FieldSpecBase {
|
||||||
|
kind: "segmented";
|
||||||
|
default: V;
|
||||||
|
options: { value: V; label: string }[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface TextSpec extends FieldSpecBase {
|
export interface TextSpec extends FieldSpecBase {
|
||||||
kind: "text";
|
kind: "text";
|
||||||
default: string;
|
default: string;
|
||||||
@@ -214,6 +223,7 @@ export const fieldSpecs = {
|
|||||||
slider: {} as SliderSpec,
|
slider: {} as SliderSpec,
|
||||||
color: {} as ColorSpec,
|
color: {} as ColorSpec,
|
||||||
select: {} as SelectSpec,
|
select: {} as SelectSpec,
|
||||||
|
segmented: {} as SegmentedSpec,
|
||||||
text: {} as TextSpec,
|
text: {} as TextSpec,
|
||||||
checkbox: {} as CheckboxSpec,
|
checkbox: {} as CheckboxSpec,
|
||||||
dimension: {} as DimensionSpec,
|
dimension: {} as DimensionSpec,
|
||||||
@@ -277,6 +287,11 @@ export const field = {
|
|||||||
select: <V extends string>(s: Omit<SelectSpec<V>, "kind">): Field<V> => ({
|
select: <V extends string>(s: Omit<SelectSpec<V>, "kind">): Field<V> => ({
|
||||||
spec: { kind: "select", ...s },
|
spec: { kind: "select", ...s },
|
||||||
}),
|
}),
|
||||||
|
segmented: <V extends string>(
|
||||||
|
s: Omit<SegmentedSpec<V>, "kind">,
|
||||||
|
): Field<V> => ({
|
||||||
|
spec: { kind: "segmented", ...s },
|
||||||
|
}),
|
||||||
text: (s: Omit<TextSpec, "kind">): Field<string> => ({
|
text: (s: Omit<TextSpec, "kind">): Field<string> => ({
|
||||||
spec: { kind: "text", ...s },
|
spec: { kind: "text", ...s },
|
||||||
}),
|
}),
|
||||||
@@ -576,6 +591,7 @@ export function sanitizeSchemaParams<P>(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "select":
|
case "select":
|
||||||
|
case "segmented":
|
||||||
out[key] =
|
out[key] =
|
||||||
typeof raw === "string" && spec.options.some((o) => o.value === raw)
|
typeof raw === "string" && spec.options.some((o) => o.value === raw)
|
||||||
? raw
|
? raw
|
||||||
|
|||||||
@@ -446,7 +446,7 @@ interface SplitPartsParams {
|
|||||||
|
|
||||||
export const splitPartsSchema = toolSchema<SplitPartsParams>(
|
export const splitPartsSchema = toolSchema<SplitPartsParams>(
|
||||||
{
|
{
|
||||||
mode: field.select({
|
mode: field.segmented({
|
||||||
label: "fields.splitMode",
|
label: "fields.splitMode",
|
||||||
default: "grid",
|
default: "grid",
|
||||||
options: [
|
options: [
|
||||||
|
|||||||
Reference in New Issue
Block a user