kopia lustrzana https://github.com/zhengkyl/qrframe
add rendered pixels toggles
rodzic
f7961a816f
commit
0688bce67b
|
@ -1,5 +1,6 @@
|
|||
import { Button } from "@kobalte/core/button";
|
||||
import type { JSX } from "solid-js";
|
||||
import { ToggleButton as KToggleButton } from "@kobalte/core/toggle-button";
|
||||
|
||||
type Props = {
|
||||
class?: string;
|
||||
|
@ -18,3 +19,21 @@ export function FlatButton(props: Props) {
|
|||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
type ToggleProps = {
|
||||
value: boolean;
|
||||
onClick: () => void;
|
||||
children: JSX.Element;
|
||||
};
|
||||
|
||||
export function ToggleButton(props: ToggleProps) {
|
||||
return (
|
||||
<KToggleButton
|
||||
class="px-3 py-2 border rounded-md text-fore-subtle data-[pressed]:(bg-fore-base/10 text-fore-base) hover:bg-fore-base/10"
|
||||
pressed={props.value}
|
||||
onChange={props.onClick}
|
||||
>
|
||||
{props.children}
|
||||
</KToggleButton>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { ToggleGroup } from "@kobalte/core/toggle-group";
|
|||
import { type JSX } from "solid-js";
|
||||
|
||||
type Props = {
|
||||
value: string;
|
||||
value?: string;
|
||||
setValue: (v: string) => void;
|
||||
children: JSX.Element;
|
||||
};
|
||||
|
@ -11,7 +11,6 @@ export function ButtonGroup(props: Props) {
|
|||
return (
|
||||
<ToggleGroup
|
||||
class="border rounded-md flex"
|
||||
defaultValue={props.value}
|
||||
value={props.value}
|
||||
onChange={(v) => v && props.setValue(v)}
|
||||
>
|
||||
|
|
|
@ -18,10 +18,11 @@ export function ModeTextInput(props: Props) {
|
|||
<div class="flex flex-col gap-2">
|
||||
<textarea
|
||||
class="bg-back-subtle min-h-[80px] px-3 py-2 rounded-md border focus:(outline-none ring-2 ring-fore-base ring-offset-2 ring-offset-back-base)"
|
||||
value={props.input}
|
||||
onInput={(e) => onInput(e.target.value)}
|
||||
onChange={(e) => props.setInput(e.target.value)}
|
||||
></textarea>
|
||||
>
|
||||
{props.input}
|
||||
</textarea>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-sm">Encoding</span>
|
||||
<Select
|
||||
|
|
|
@ -10,7 +10,7 @@ export default function QRCode(props: any) {
|
|||
.ecl(props.ecl)
|
||||
.mask(new Mask(props.mask))
|
||||
.mode(props.mode);
|
||||
const renderOptions = new RenderOptions()
|
||||
let renderOptions = new RenderOptions()
|
||||
.finder_pattern(props.finderPattern)
|
||||
.finder_roundness(props.finderRoundness)
|
||||
.margin(props.margin)
|
||||
|
@ -18,6 +18,12 @@ export default function QRCode(props: any) {
|
|||
.foreground(props.foreground)
|
||||
.background(props.background);
|
||||
|
||||
props.renderedPixels.forEach((v: boolean, i: number) => {
|
||||
if (!v) {
|
||||
renderOptions = renderOptions.toggle_render_type(1 + 2 * i);
|
||||
}
|
||||
});
|
||||
|
||||
return get_svg(props.input, svgOptions, renderOptions);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,30 +1,35 @@
|
|||
import { For, Show, createMemo, createSignal, type JSX } from "solid-js";
|
||||
import { clientOnly } from "@solidjs/start";
|
||||
import init, { ECL, FinderPattern, Mode } from "fuqr";
|
||||
import init, { ECL, FinderPattern, Mode, Module } from "fuqr";
|
||||
|
||||
import { ButtonGroup, ButtonGroupItem } from "~/components/ButtonGroup";
|
||||
import { ModeTextInput } from "~/components/ModeTextInput";
|
||||
import { NumberInput } from "~/components/NumberInput";
|
||||
import { ColorInput } from "~/components/ColorInput";
|
||||
import { ToggleButton } from "~/components/Button";
|
||||
import { createStore } from "solid-js/store";
|
||||
|
||||
const QRCode = clientOnly(async () => {
|
||||
await init();
|
||||
return import("../components/QRCode");
|
||||
});
|
||||
|
||||
export default function Home() {
|
||||
const ECL_VALUE = {
|
||||
Low: ECL.Low,
|
||||
Medium: ECL.Medium,
|
||||
Quartile: ECL.Quartile,
|
||||
High: ECL.High,
|
||||
};
|
||||
const ECL_VALUE = {
|
||||
Low: ECL.Low,
|
||||
Medium: ECL.Medium,
|
||||
Quartile: ECL.Quartile,
|
||||
High: ECL.High,
|
||||
};
|
||||
|
||||
const MODE_NAME = {
|
||||
[Mode.Numeric]: "Numeric",
|
||||
[Mode.Alphanumeric]: "Alphanumeric",
|
||||
[Mode.Byte]: "Byte",
|
||||
};
|
||||
const MODE_NAME = {
|
||||
[Mode.Numeric]: "Numeric",
|
||||
[Mode.Alphanumeric]: "Alphanumeric",
|
||||
[Mode.Byte]: "Byte",
|
||||
};
|
||||
|
||||
const MODULES = ["Data", "Finder", "Alignment", "Timing", "Format", "Version"];
|
||||
|
||||
export default function Home() {
|
||||
const [minVersion, setMinVersion] = createSignal(1);
|
||||
const [margin, setMargin] = createSignal(2);
|
||||
const [ecl, setEcl] = createSignal<keyof typeof ECL_VALUE>("Low");
|
||||
|
@ -41,6 +46,10 @@ export default function Home() {
|
|||
const [input, setInput] = createSignal("Greetings traveler");
|
||||
const [mode, setMode] = createSignal(Mode.Byte);
|
||||
|
||||
const [renderedPixels, setRenderedPixels] = createStore(
|
||||
MODULES.map(() => true)
|
||||
);
|
||||
|
||||
// TODO TEMPORARY FIX TO PREVENT CRASHING UNTIL I ADD SIZE ADJUSTMENT TO FUQR
|
||||
const version = createMemo(() =>
|
||||
min_version(input(), mode(), minVersion(), ECL_VALUE[ecl()])
|
||||
|
@ -83,9 +92,9 @@ export default function Home() {
|
|||
<main class="text-center max-w-screen-lg mx-auto my-16 p-4">
|
||||
<div class="flex gap-4 flex-wrap">
|
||||
<div class="flex flex-col gap-2 flex-1">
|
||||
{/* <textarea class="bg-back-subtle min-h-[80px] px-3 py-2 rounded-md border focus:(outline-none ring-2 ring-fore-base ring-offset-2 ring-offset-back-base)"></textarea> */}
|
||||
<ModeTextInput
|
||||
input={input()}
|
||||
// textarea does not have a controlled value, input is only default value
|
||||
input={"Greetings travelers"}
|
||||
setInput={setInput}
|
||||
mode={MODE_NAME[mode()]}
|
||||
setMode={setMode}
|
||||
|
@ -171,6 +180,24 @@ export default function Home() {
|
|||
<Row title="Background">
|
||||
<ColorInput color={background()} setColor={setBackground} />
|
||||
</Row>
|
||||
|
||||
<div class="flex mt-2">
|
||||
<span class="w-30 text-left text-sm flex-shrink-0">
|
||||
Rendered pixels
|
||||
</span>
|
||||
<div class="flex flex-wrap gap-2 text-sm leading-tight">
|
||||
<For each={renderedPixels}>
|
||||
{(value, i) => (
|
||||
<ToggleButton
|
||||
value={value}
|
||||
onClick={() => setRenderedPixels(i(), !value)}
|
||||
>
|
||||
{MODULES[i()]}
|
||||
</ToggleButton>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1 min-w-200px">
|
||||
<Show
|
||||
|
@ -195,6 +222,7 @@ export default function Home() {
|
|||
moduleSize={moduleScale()}
|
||||
foreground={foreground()}
|
||||
background={background()}
|
||||
renderedPixels={renderedPixels}
|
||||
/>
|
||||
</Show>
|
||||
</div>
|
||||
|
@ -207,7 +235,7 @@ function Row(props: { title: string; children: JSX.Element }) {
|
|||
// clicking <label/> sometimes selects first button
|
||||
return (
|
||||
<div class="flex items-center">
|
||||
<span class="w-40 text-left text-sm">{props.title}</span>
|
||||
<span class="w-30 text-left text-sm flex-shrink-0">{props.title}</span>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
|
|
Ładowanie…
Reference in New Issue