Skip to content

Commit 03e4404

Browse files
committed
checkbox improvement
1 parent 653692f commit 03e4404

6 files changed

Lines changed: 30 additions & 47 deletions

File tree

src/components/AwkGenerator.jsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useState } from "react";
2-
import { Card, PageHeader, CopyButton, CustomSelect, s } from "./shared/index.jsx";
2+
import { Card, PageHeader, CopyButton, CustomSelect, Checkbox, s } from "./shared/index.jsx";
33

44
export default function AwkGenerator() {
55
const [separator, setSeparator] = useState(",");
@@ -82,11 +82,9 @@ export default function AwkGenerator() {
8282
</div>
8383
</div>
8484

85-
<label style={{ display: "flex", alignItems: "center", gap: 7, cursor: "pointer", fontSize: "var(--sm)", color: useFilter ? "var(--green)" : "var(--text-muted)", userSelect: "none", marginBottom: useFilter ? "0.8rem" : 0 }}>
86-
<div onClick={() => setUseFilter((v) => !v)}
87-
style={{ width: 17, height: 17, border: `1px solid ${useFilter ? "var(--green)" : "var(--border-2)"}`, borderRadius: 3, background: useFilter ? "var(--green-bg)" : "var(--bg)", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 10, color: useFilter ? "var(--green)" : "transparent", fontFamily: "var(--font-mono)", fontWeight: 700, flexShrink: 0 }}></div>
88-
Enable row filter
89-
</label>
85+
<div style={{ marginBottom: useFilter ? "0.8rem" : 0 }}>
86+
<Checkbox checked={useFilter} onChange={() => setUseFilter((v) => !v)} label="Enable row filter" />
87+
</div>
9088

9189
{useFilter && (
9290
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 2fr", gap: 8, marginBottom: "1rem" }}>

src/components/ChmodCalculator.jsx

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useState } from "react";
2-
import { Card, PageHeader, s } from "./shared/index.jsx";
2+
import { Card, PageHeader, Checkbox, s } from "./shared/index.jsx";
33

44
export default function ChmodCalculator() {
55
const [bits, setBits] = useState({ ur: 0, uw: 0, ux: 0, gr: 0, gw: 0, gx: 0, or: 0, ow: 0, ox: 0 });
@@ -40,27 +40,11 @@ export default function ChmodCalculator() {
4040
{heading}
4141
</div>
4242
<div style={{ background: "var(--surface-2)", border: "1px solid var(--border)", borderRadius: 8, padding: "10px 13px" }}>
43-
{keys.map(({ key, label }) => {
44-
const isOn = bits[key];
45-
return (
46-
<div
47-
key={key}
48-
onClick={() => toggle(key)}
49-
style={{ display: "flex", alignItems: "center", gap: 9, padding: "6px 0", cursor: "pointer", userSelect: "none" }}
50-
>
51-
<div style={{
52-
width: 18, height: 18, border: `1px solid ${isOn ? "var(--green)" : "var(--border-2)"}`,
53-
borderRadius: 6, background: isOn ? "var(--green-bg)" : "var(--bg)",
54-
display: "flex", alignItems: "center", justifyContent: "center",
55-
flexShrink: 0, transition: "all 0.11s", fontFamily: "var(--font-mono)",
56-
fontSize: 11, fontWeight: 700, color: isOn ? "var(--green)" : "transparent",
57-
}}></div>
58-
<span style={{ fontFamily: "var(--font-mono)", fontSize: "var(--sm)", color: isOn ? "var(--green)" : "var(--text-muted)", transition: "color 0.11s" }}>
59-
{label}
60-
</span>
61-
</div>
62-
);
63-
})}
43+
{keys.map(({ key, label }) => (
44+
<div key={key} style={{ padding: "6px 0" }}>
45+
<Checkbox checked={!!bits[key]} onChange={() => toggle(key)} label={label} size={18} />
46+
</div>
47+
))}
6448
</div>
6549
</div>
6650
);

src/components/RegexTester.jsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useState, useMemo } from "react";
2-
import { Card, PageHeader, CopyButton, s } from "./shared/index.jsx";
2+
import { Card, PageHeader, CopyButton, Checkbox, s } from "./shared/index.jsx";
33

44
const FLAG_OPTS = [
55
{ key: "g", label: "Global", desc: "find all matches" },
@@ -86,13 +86,7 @@ export default function RegexTester() {
8686
{/* Flags */}
8787
<div style={{ display: "flex", gap: 14, flexWrap: "wrap", marginBottom: "1rem" }}>
8888
{FLAG_OPTS.map(({ key, label, desc }) => (
89-
<label key={key} onClick={() => toggleFlag(key)}
90-
style={{ display: "flex", alignItems: "center", gap: 7, cursor: "pointer", userSelect: "none",
91-
fontSize: "var(--sm)", color: flags[key] ? "var(--green)" : "var(--text-muted)" }}>
92-
<div style={{ width: 17, height: 17, border: `1px solid ${flags[key] ? "var(--green)" : "var(--border-2)"}`, borderRadius: 3, background: flags[key] ? "var(--green-bg)" : "var(--bg)", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 10, color: flags[key] ? "var(--green)" : "transparent", fontFamily: "var(--font-mono)", fontWeight: 700, flexShrink: 0 }}></div>
93-
<span style={{ fontFamily: "var(--font-mono)" }}>{key}</span>
94-
<span style={{ color: "var(--text-faint)", fontSize: "var(--xs)" }}>{desc}</span>
95-
</label>
89+
<Checkbox key={key} checked={flags[key]} onChange={() => toggleFlag(key)} label={key} description={`— ${desc}`} />
9690
))}
9791
</div>
9892

src/components/SedGenerator.jsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useState } from "react";
2-
import { Card, PageHeader, CopyButton, s } from "./shared/index.jsx";
2+
import { Card, PageHeader, CopyButton, Checkbox, s } from "./shared/index.jsx";
33

44
export default function SedGenerator() {
55
const [mode, setMode] = useState("substitute");
@@ -94,21 +94,13 @@ export default function SedGenerator() {
9494
{mode === "substitute" && (
9595
<div style={{ display: "flex", gap: 16, marginTop: "1rem", flexWrap: "wrap" }}>
9696
{[{ key: "g", label: "Global (-g)" }, { key: "i", label: "Case-insensitive (-I)" }, { key: "p", label: "Print matches (-p)" }, { key: "n", label: "Silent mode (-n)" }].map(({ key, label }) => (
97-
<label key={key} style={{ display: "flex", alignItems: "center", gap: 7, cursor: "pointer", fontSize: "var(--sm)", color: flags[key] ? "var(--green)" : "var(--text-muted)", userSelect: "none" }}>
98-
<div onClick={() => setFlags((f) => ({ ...f, [key]: !f[key] }))}
99-
style={{ width: 17, height: 17, border: `1px solid ${flags[key] ? "var(--green)" : "var(--border-2)"}`, borderRadius: 3, background: flags[key] ? "var(--green-bg)" : "var(--bg)", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 10, color: flags[key] ? "var(--green)" : "transparent", fontFamily: "var(--font-mono)", fontWeight: 700, flexShrink: 0 }}></div>
100-
{label}
101-
</label>
97+
<Checkbox key={key} checked={!!flags[key]} onChange={() => setFlags((f) => ({ ...f, [key]: !f[key] }))} label={label} />
10298
))}
10399
</div>
104100
)}
105101

106102
<div style={{ display: "flex", alignItems: "center", gap: 12, marginTop: "1rem" }}>
107-
<label style={{ display: "flex", alignItems: "center", gap: 7, cursor: "pointer", fontSize: "var(--sm)", color: inPlace ? "var(--green)" : "var(--text-muted)", userSelect: "none" }}>
108-
<div onClick={() => setInPlace((v) => !v)}
109-
style={{ width: 17, height: 17, border: `1px solid ${inPlace ? "var(--green)" : "var(--border-2)"}`, borderRadius: 3, background: inPlace ? "var(--green-bg)" : "var(--bg)", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 10, color: inPlace ? "var(--green)" : "transparent", fontFamily: "var(--font-mono)", fontWeight: 700, flexShrink: 0 }}></div>
110-
In-place edit (-i)
111-
</label>
103+
<Checkbox checked={inPlace} onChange={() => setInPlace((v) => !v)} label="In-place edit (-i)" />
112104
{inPlace && (
113105
<input value={backup} onChange={(e) => setBackup(e.target.value)} placeholder=".bak"
114106
style={{ ...s.monoInput, width: 100, fontSize: "var(--sm)" }} />

src/components/shared/index.jsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,19 @@ export function PresetRow({ presets, onSelect }) {
252252
);
253253
}
254254

255+
// Checkbox: dot-style toggle, clicking anywhere in the row toggles it
256+
export function Checkbox({ checked, onChange, label, description, size = 17 }) {
257+
return (
258+
<div onClick={onChange} style={{ display: "flex", alignItems: "center", gap: 7, cursor: "pointer", userSelect: "none", fontSize: "var(--sm)", color: checked ? "var(--green)" : "var(--text-muted)" }}>
259+
<div style={{ width: size, height: size, border: `1px solid ${checked ? "var(--green)" : "var(--border-2)"}`, borderRadius: 3, background: checked ? "var(--green-bg)" : "var(--bg)", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0, transition: "all 0.11s" }}>
260+
{checked && <div style={{ width: Math.round(size * 0.42), height: Math.round(size * 0.42), borderRadius: "50%", background: "var(--green)" }} />}
261+
</div>
262+
{label && <span style={{ fontFamily: "var(--font-mono)" }}>{label}</span>}
263+
{description && <span style={{ color: "var(--text-faint)", fontSize: "var(--xs)" }}>{description}</span>}
264+
</div>
265+
);
266+
}
267+
255268
export function Spinner() {
256269
return (
257270
<div style={{ width: 18, height: 18, border: "2px solid var(--border)", borderTopColor: "var(--green)", borderRadius: "50%", animation: "spin 0.7s linear infinite", display: "inline-block", flexShrink: 0 }} />

src/styles/global.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ body { visibility: var(--visibility, hidden); }
112112
--teal-bg: #e6f7f5;
113113
}
114114

115+
115116
html { font-size: 15px; }
116117

117118
html, body, #root {
@@ -147,6 +148,7 @@ input, select, textarea {
147148

148149
button { cursor: pointer; font-family: var(--font-sans); transition: filter 0.13s; will-change: filter; }
149150
button:not(:disabled):hover { filter: brightness(1.18); }
151+
[data-theme="light"] button:not(:disabled):hover { filter: brightness(0.90); }
150152
button:disabled { cursor: not-allowed; }
151153

152154
::-webkit-scrollbar { width: 6px; height: 6px; }

0 commit comments

Comments
 (0)