tamga-ui 0.4.4 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +863 -0
- package/README.md +3 -1
- package/dist/blocks/count-row.d.ts +3 -8
- package/dist/blocks/count-row.d.ts.map +1 -1
- package/dist/blocks/count-row.js +3 -8
- package/dist/blocks/filter-bar.d.ts +42 -28
- package/dist/blocks/filter-bar.d.ts.map +1 -1
- package/dist/blocks/filter-bar.js +13 -5
- package/dist/blocks/index.d.ts +4 -17
- package/dist/blocks/index.d.ts.map +1 -1
- package/dist/blocks/index.js +4 -17
- package/dist/blocks/save-bar.d.ts +4 -12
- package/dist/blocks/save-bar.d.ts.map +1 -1
- package/dist/blocks/save-bar.js +4 -12
- package/dist/components/a11y.d.ts.map +1 -1
- package/dist/components/a11y.js +4 -15
- package/dist/components/advanced-input.d.ts +54 -48
- package/dist/components/advanced-input.d.ts.map +1 -1
- package/dist/components/advanced-input.js +64 -59
- package/dist/components/announcement.d.ts +34 -0
- package/dist/components/announcement.d.ts.map +1 -0
- package/dist/components/announcement.js +12 -0
- package/dist/components/appearance.d.ts +33 -1
- package/dist/components/appearance.d.ts.map +1 -1
- package/dist/components/appearance.js +78 -7
- package/dist/components/avatar.d.ts +28 -21
- package/dist/components/avatar.d.ts.map +1 -1
- package/dist/components/avatar.js +46 -22
- package/dist/components/badge.d.ts +54 -4
- package/dist/components/badge.d.ts.map +1 -1
- package/dist/components/badge.js +42 -9
- package/dist/components/bar.d.ts.map +1 -1
- package/dist/components/bar.js +4 -20
- package/dist/components/button.d.ts +15 -7
- package/dist/components/button.d.ts.map +1 -1
- package/dist/components/button.js +54 -8
- package/dist/components/chart.d.ts +5 -0
- package/dist/components/chart.d.ts.map +1 -1
- package/dist/components/chart.js +18 -11
- package/dist/components/checkbox.d.ts +23 -1
- package/dist/components/checkbox.d.ts.map +1 -1
- package/dist/components/checkbox.js +3 -4
- package/dist/components/chrome.d.ts +38 -54
- package/dist/components/chrome.d.ts.map +1 -1
- package/dist/components/chrome.js +55 -63
- package/dist/components/combobox.d.ts.map +1 -1
- package/dist/components/combobox.js +19 -3
- package/dist/components/data-table.d.ts +4 -4
- package/dist/components/data-table.d.ts.map +1 -1
- package/dist/components/data-table.js +15 -16
- package/dist/components/date-picker.d.ts.map +1 -1
- package/dist/components/date-picker.js +11 -4
- package/dist/components/disclosure.d.ts +17 -2
- package/dist/components/disclosure.d.ts.map +1 -1
- package/dist/components/disclosure.js +4 -8
- package/dist/components/display.d.ts +119 -94
- package/dist/components/display.d.ts.map +1 -1
- package/dist/components/display.js +103 -106
- package/dist/components/empty-state.d.ts +70 -52
- package/dist/components/empty-state.d.ts.map +1 -1
- package/dist/components/empty-state.js +40 -52
- package/dist/components/error-state.d.ts +21 -4
- package/dist/components/error-state.d.ts.map +1 -1
- package/dist/components/error-state.js +16 -6
- package/dist/components/file-upload.d.ts +45 -2
- package/dist/components/file-upload.d.ts.map +1 -1
- package/dist/components/file-upload.js +32 -7
- package/dist/components/gauge.d.ts +72 -9
- package/dist/components/gauge.d.ts.map +1 -1
- package/dist/components/gauge.js +52 -49
- package/dist/components/icons.d.ts +1 -1
- package/dist/components/icons.d.ts.map +1 -1
- package/dist/components/icons.js +4 -0
- package/dist/components/input.d.ts +21 -0
- package/dist/components/input.d.ts.map +1 -1
- package/dist/components/input.js +15 -1
- package/dist/components/layout.d.ts +47 -70
- package/dist/components/layout.d.ts.map +1 -1
- package/dist/components/layout.js +31 -73
- package/dist/components/link.d.ts +5 -10
- package/dist/components/link.d.ts.map +1 -1
- package/dist/components/live-scope.d.ts.map +1 -1
- package/dist/components/live-scope.js +5 -8
- package/dist/components/log-view.d.ts +32 -1
- package/dist/components/log-view.d.ts.map +1 -1
- package/dist/components/log-view.js +42 -15
- package/dist/components/number-input.d.ts +20 -2
- package/dist/components/number-input.d.ts.map +1 -1
- package/dist/components/number-input.js +32 -9
- package/dist/components/overlay.d.ts +69 -61
- package/dist/components/overlay.d.ts.map +1 -1
- package/dist/components/overlay.js +129 -78
- package/dist/components/pagination.d.ts.map +1 -1
- package/dist/components/pagination.js +12 -7
- package/dist/components/pie.d.ts.map +1 -1
- package/dist/components/pie.js +8 -7
- package/dist/components/primitives.d.ts +136 -6
- package/dist/components/primitives.d.ts.map +1 -1
- package/dist/components/primitives.js +73 -20
- package/dist/components/progress.d.ts +44 -9
- package/dist/components/progress.d.ts.map +1 -1
- package/dist/components/progress.js +21 -9
- package/dist/components/radio-group.d.ts.map +1 -1
- package/dist/components/radio-group.js +11 -12
- package/dist/components/rail-link.d.ts +17 -1
- package/dist/components/rail-link.d.ts.map +1 -1
- package/dist/components/rail-link.js +3 -3
- package/dist/components/rich-text.d.ts +8 -1
- package/dist/components/rich-text.d.ts.map +1 -1
- package/dist/components/rich-text.js +13 -19
- package/dist/components/says-bubble.d.ts +38 -0
- package/dist/components/says-bubble.d.ts.map +1 -0
- package/dist/components/says-bubble.js +6 -0
- package/dist/components/scroll-x.d.ts +23 -0
- package/dist/components/scroll-x.d.ts.map +1 -0
- package/dist/components/scroll-x.js +27 -0
- package/dist/components/section.d.ts +18 -1
- package/dist/components/section.d.ts.map +1 -1
- package/dist/components/section.js +12 -1
- package/dist/components/segmented.d.ts +17 -1
- package/dist/components/segmented.d.ts.map +1 -1
- package/dist/components/segmented.js +26 -6
- package/dist/components/skeleton.d.ts.map +1 -1
- package/dist/components/skeleton.js +1 -1
- package/dist/components/slider.d.ts +16 -2
- package/dist/components/slider.d.ts.map +1 -1
- package/dist/components/slider.js +12 -5
- package/dist/components/sparkline.d.ts +9 -2
- package/dist/components/sparkline.d.ts.map +1 -1
- package/dist/components/sparkline.js +9 -5
- package/dist/components/spinner.d.ts +16 -1
- package/dist/components/spinner.d.ts.map +1 -1
- package/dist/components/spinner.js +24 -1
- package/dist/components/square-picker.d.ts +4 -20
- package/dist/components/square-picker.d.ts.map +1 -1
- package/dist/components/square-picker.js +4 -20
- package/dist/components/stacked-bar.d.ts.map +1 -1
- package/dist/components/stacked-bar.js +5 -4
- package/dist/components/surface.d.ts +32 -3
- package/dist/components/surface.d.ts.map +1 -1
- package/dist/components/surface.js +11 -4
- package/dist/components/switch.d.ts +14 -1
- package/dist/components/switch.d.ts.map +1 -1
- package/dist/components/switch.js +2 -3
- package/dist/components/tabs.d.ts +35 -11
- package/dist/components/tabs.d.ts.map +1 -1
- package/dist/components/tabs.js +48 -5
- package/dist/components/timeline-strip.d.ts +28 -3
- package/dist/components/timeline-strip.d.ts.map +1 -1
- package/dist/components/timeline-strip.js +19 -8
- package/dist/components/tone.d.ts +51 -19
- package/dist/components/tone.d.ts.map +1 -1
- package/dist/components/tone.js +69 -15
- package/dist/components/tree-select.d.ts.map +1 -1
- package/dist/components/tree-select.js +10 -3
- package/dist/fonts/LICENSE-jetbrains-mono.txt +93 -0
- package/dist/fonts/LICENSE-onest.txt +93 -0
- package/dist/fonts/LICENSE-red-hat-display.txt +93 -0
- package/dist/fonts/jetbrains-mono-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/jetbrains-mono-latin-wght-normal.woff2 +0 -0
- package/dist/fonts/onest-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/onest-latin-wght-normal.woff2 +0 -0
- package/dist/fonts/red-hat-display-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/red-hat-display-latin-wght-normal.woff2 +0 -0
- package/dist/fonts.css +54 -0
- package/dist/index.d.ts +10 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -6
- package/dist/kit.css +3155 -648
- package/dist/lib/color.d.ts +8 -19
- package/dist/lib/color.d.ts.map +1 -1
- package/dist/lib/color.js +8 -19
- package/dist/lib/data-props.d.ts +4 -15
- package/dist/lib/data-props.d.ts.map +1 -1
- package/dist/lib/data-props.js +4 -15
- package/dist/lib/image.d.ts +4 -20
- package/dist/lib/image.d.ts.map +1 -1
- package/dist/lib/image.js +4 -20
- package/dist/lib/palette.d.ts +16 -20
- package/dist/lib/palette.d.ts.map +1 -1
- package/dist/lib/palette.js +136 -71
- package/dist/lib/scroll-lock.d.ts +4 -14
- package/dist/lib/scroll-lock.d.ts.map +1 -1
- package/dist/lib/scroll-lock.js +4 -14
- package/dist/patterns/app-shell.d.ts.map +1 -1
- package/dist/patterns/app-shell.js +4 -13
- package/dist/patterns/appearance-template.d.ts +20 -15
- package/dist/patterns/appearance-template.d.ts.map +1 -1
- package/dist/patterns/appearance-template.js +29 -8
- package/dist/patterns/list-template.d.ts.map +1 -1
- package/dist/patterns/list-template.js +1 -1
- package/dist/patterns/overview-template.d.ts.map +1 -1
- package/dist/patterns/overview-template.js +1 -1
- package/dist/patterns/settings-template.d.ts +1 -12
- package/dist/patterns/settings-template.d.ts.map +1 -1
- package/dist/patterns/settings-template.js +2 -2
- package/dist/patterns/shared.d.ts.map +1 -1
- package/dist/patterns/shared.js +8 -1
- package/dist/styles.css +2 -1
- package/dist/theme.css +94 -261
- package/package.json +3 -1
- package/dist/components/control-base.d.ts +0 -7
- package/dist/components/control-base.d.ts.map +0 -1
- package/dist/components/control-base.js +0 -6
|
@@ -5,7 +5,7 @@ import { cn } from "../lib/cn.js";
|
|
|
5
5
|
import { inputVariants } from "./input.js";
|
|
6
6
|
import { dataProps } from "../lib/data-props.js";
|
|
7
7
|
import { Icon } from "./icon.js";
|
|
8
|
-
import { Check, Close, Customize, Eye, EyeSlash, Search } from "./icons.js";
|
|
8
|
+
import { Check, Clock, Close, Copy, Customize, Eye, EyeSlash, Key, Search } from "./icons.js";
|
|
9
9
|
/* ------------------------------------------------------------------ *
|
|
10
10
|
* Gelişmiş girdiler.
|
|
11
11
|
*
|
|
@@ -17,20 +17,21 @@ import { Check, Close, Customize, Eye, EyeSlash, Search } from "./icons.js";
|
|
|
17
17
|
*
|
|
18
18
|
* Gerekçe: docs/gerekce/01-form-ve-girdi.md
|
|
19
19
|
*/
|
|
20
|
-
export function PasswordInput({ labels, invalid = false, className, ...props }) {
|
|
20
|
+
export function PasswordInput({ labels, strength, invalid = false, className, ...props }) {
|
|
21
21
|
const [shown, setShown] = useState(false);
|
|
22
|
-
|
|
22
|
+
const alan = (_jsxs("span", { className: "relative flex items-center", children: [_jsx("input", { type: shown ? "text" : "password", "aria-invalid": invalid || undefined, className: cn(inputVariants({ invalid }), "w-full pr-11", className), ...props }), _jsx("button", { type: "button", className: "tamga-field-btn", "aria-label": shown ? labels.hide : labels.show, "aria-pressed": shown, onClick: () => setShown((v) => !v), children: _jsx(Icon, { icon: shown ? EyeSlash : Eye, size: "xs" }) })] }));
|
|
23
|
+
if (!strength)
|
|
24
|
+
return alan;
|
|
25
|
+
const toplam = strength.of ?? 4;
|
|
26
|
+
const yanan = Math.max(0, Math.min(toplam, strength.value));
|
|
27
|
+
return (_jsxs("span", { className: "flex flex-col gap-2.5", children: [alan, _jsx("span", { className: "tamga-guc", style: { gridTemplateColumns: `repeat(${toplam}, 1fr)` }, children: Array.from({ length: toplam }, (_, i) => (_jsx("span", { "data-dolu": i < yanan || undefined }, i))) }), strength.note ? _jsx("span", { className: "text-small text-ink-faint", children: strength.note }) : null] }));
|
|
23
28
|
}
|
|
24
29
|
/**
|
|
25
|
-
* Maskeli sır
|
|
30
|
+
* Maskeli sır · API anahtarı, webhook secret. `PasswordInput`un kardeşi ama işi
|
|
31
|
+
* TERS: buraya yazılmıyor, okunup kopyalanıyor, o yüzden salt-okunur. Maske ilk
|
|
32
|
+
* ve son birkaç karakteri bırakıyor.
|
|
26
33
|
*
|
|
27
|
-
*
|
|
28
|
-
* buraya yazılmaz — okunur ve kopyalanır. O yüzden salt-okunur, ve asıl
|
|
29
|
-
* düğmesi kopyalama.
|
|
30
|
-
*
|
|
31
|
-
* Maske ilk ve son birkaç karakteri bırakıyor. Tamamen gizlemek, kullanıcının
|
|
32
|
-
* "hangi anahtar bu" sorusunu cevapsız bırakır; üç anahtarı olan biri
|
|
33
|
-
* hangisine baktığını bilemez.
|
|
34
|
+
* Gerekçe: docs/gerekce/01-form-ve-girdi.md
|
|
34
35
|
*/
|
|
35
36
|
export function SecretField({ value, labels, visibleChars = 4, className, ...rest }) {
|
|
36
37
|
const [shown, setShown] = useState(false);
|
|
@@ -57,24 +58,17 @@ export function SecretField({ value, labels, visibleChars = 4, className, ...res
|
|
|
57
58
|
window.clearTimeout(timer.current);
|
|
58
59
|
timer.current = window.setTimeout(() => setCopied("idle"), 1600);
|
|
59
60
|
}
|
|
60
|
-
return (_jsxs("span", { ...dataProps(rest), className: cn("
|
|
61
|
-
/* Salt-okunur bir alan yine de odaklanabilir olmalı: kullanıcı onu
|
|
62
|
-
seçip elle kopyalayabilsin. `disabled` bunu imkânsız kılardı. */
|
|
63
|
-
onFocus: (e) => e.currentTarget.select() }), _jsxs("span", { className: "absolute right-1.5 flex gap-0.5", children: [_jsx("button", { type: "button", className: "tamga-mini-btn", "aria-label": shown ? labels.hide : labels.reveal, "aria-pressed": shown, onClick: () => setShown((v) => !v), children: _jsx(Icon, { icon: shown ? EyeSlash : Eye, size: "xs" }) }), _jsx("button", { type: "button", className: "tamga-mini-btn", "aria-label": copied === "done" ? labels.copied : copied === "failed" ? labels.failed : labels.copy, onClick: copy, children: _jsx(Icon, { icon: copied === "done" ? Check : Customize, size: "xs" }) })] })] }));
|
|
61
|
+
return (_jsxs("span", { ...dataProps(rest), className: cn("flex flex-wrap items-center gap-2.5", className), children: [_jsxs("span", { className: "tamga-secret", children: [_jsx(Icon, { icon: Key, size: "xs", className: "shrink-0 text-ink-faint" }), _jsx("input", { readOnly: true, value: shown ? value : masked, onFocus: (e) => e.currentTarget.select() })] }), _jsx("button", { type: "button", className: "tamga-icon-btn", "aria-label": shown ? labels.hide : labels.reveal, "aria-pressed": shown, onClick: () => setShown((v) => !v), children: _jsx(Icon, { icon: shown ? EyeSlash : Eye, size: "sm" }) }), _jsxs("button", { type: "button", className: "tamga-btn", onClick: copy, children: [_jsx(Icon, { icon: copied === "done" ? Check : Copy, size: "xs" }), copied === "done" ? labels.copied : copied === "failed" ? labels.failed : labels.copy] })] }));
|
|
64
62
|
}
|
|
65
63
|
/**
|
|
66
|
-
* Etiket girdisi
|
|
67
|
-
*
|
|
68
|
-
* Enter ya da virgül bir etiketi kapatıyor; boşken Backspace sonuncuyu siliyor.
|
|
69
|
-
* İkincisi küçük görünür ama en çok kullanılan yoldur — yanlış yazılan bir
|
|
70
|
-
* etiketi silmek için fareye uzanmak, akışı kesen tek şeydir.
|
|
64
|
+
* Etiket girdisi · Enter ya da virgül bir etiketi kapatıyor, boşken Backspace
|
|
65
|
+
* sonuncuyu siliyor. Yinelenen etiket SESSİZCE yutuluyor, hata verilmiyor.
|
|
71
66
|
*
|
|
72
|
-
*
|
|
73
|
-
* yazmak bir hata değil, bir tekrardır, ve kullanıcı zaten istediğini almış
|
|
74
|
-
* olur.
|
|
67
|
+
* Gerekçe: docs/gerekce/01-form-ve-girdi.md
|
|
75
68
|
*/
|
|
76
69
|
export function TagsInput({ value, onChange, placeholder, labels, max, className, ...rest }) {
|
|
77
70
|
const [draft, setDraft] = useState("");
|
|
71
|
+
const [silinecek, setSilinecek] = useState(null);
|
|
78
72
|
const full = max !== undefined && value.length >= max;
|
|
79
73
|
function commit() {
|
|
80
74
|
const tag = draft.trim();
|
|
@@ -83,27 +77,42 @@ export function TagsInput({ value, onChange, placeholder, labels, max, className
|
|
|
83
77
|
return;
|
|
84
78
|
onChange([...value, tag]);
|
|
85
79
|
}
|
|
86
|
-
return (_jsxs("span", { ...dataProps(rest), className: cn("tamga-input h-auto min-h-10 w-full flex-wrap items-center gap-1.5 py-1.5", className), style: { display: "flex" }, children: [value.map((tag) => (_jsxs("span", { className: "tamga-
|
|
80
|
+
return (_jsxs("span", { ...dataProps(rest), className: cn("tamga-input h-auto min-h-10 w-full flex-wrap items-center gap-1.5 py-1.5", className), style: { display: "flex" }, children: [value.map((tag, i) => (_jsxs("span", { className: "tamga-token", "data-silinecek": i === silinecek || undefined, children: [tag, _jsx("button", { type: "button", "aria-label": labels.remove(tag), onClick: () => onChange(value.filter((x) => x !== tag)), className: "tamga-token-x", children: _jsx(Icon, { icon: Close, size: "xs" }) })] }, tag))), !full ? (_jsx("input", { value: draft, placeholder: value.length === 0 ? placeholder : undefined, onChange: (e) => {
|
|
81
|
+
setDraft(e.target.value);
|
|
82
|
+
setSilinecek(null);
|
|
83
|
+
}, onBlur: commit, onKeyDown: (e) => {
|
|
87
84
|
if (e.key === "Enter" || e.key === ",") {
|
|
88
85
|
e.preventDefault();
|
|
89
86
|
commit();
|
|
90
87
|
}
|
|
91
88
|
else if (e.key === "Backspace" && draft === "" && value.length > 0) {
|
|
92
|
-
|
|
89
|
+
/* İKİ ADIM: ilk Backspace son etiketi İŞARETLİYOR, ikincisi
|
|
90
|
+
siliyor. Tek adımlı hâlinde bir tuş fazla basan kişi
|
|
91
|
+
yazdığı etiketi silip fark etmiyordu; işaretli hâl o bir
|
|
92
|
+
karelik duraklamayı veriyor. Başka bir tuş işareti kaldırıyor. */
|
|
93
|
+
if (silinecek === value.length - 1) {
|
|
94
|
+
onChange(value.slice(0, -1));
|
|
95
|
+
setSilinecek(null);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
setSilinecek(value.length - 1);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
setSilinecek(null);
|
|
93
103
|
}
|
|
94
104
|
}, className: "min-w-24 flex-1 bg-transparent text-body text-ink outline-none" })) : null] }));
|
|
95
105
|
}
|
|
96
106
|
/**
|
|
97
|
-
* Çoklu seçim
|
|
107
|
+
* Çoklu seçim · aranabilir. `Combobox`tan ayrı olmasının sebebi görünüm değil
|
|
108
|
+
* DAVRANIŞ: çoklu seçimde liste seçince KAPANMIYOR. Seçilenler girdinin içinde
|
|
109
|
+
* çip olarak duruyor.
|
|
98
110
|
*
|
|
99
|
-
*
|
|
100
|
-
* görünüm değil DAVRANIŞ: tek seçimde liste seçince kapanır, çoklu seçimde
|
|
101
|
-
* KAPANMAZ — üç şey seçecek biri listeyi üç kez açmak zorunda kalmamalı.
|
|
102
|
-
*
|
|
103
|
-
* Seçilenler girdinin İÇİNDE çip olarak duruyor, altında ayrı bir listede
|
|
104
|
-
* değil: seçim ile seçilenler arasındaki mesafe arttıkça, kullanıcı neyi
|
|
105
|
-
* seçtiğini görmek için gözünü iki yere birden koymak zorunda kalır.
|
|
111
|
+
* Gerekçe: docs/gerekce/01-form-ve-girdi.md
|
|
106
112
|
*/
|
|
113
|
+
/* Kutuda yazıyla duran çip sayısı. Dördüncüden sonrası "+N": bir filtre
|
|
114
|
+
kutusunun iki satırı geçmemesi gerekiyor. */
|
|
115
|
+
const GORUNEN_CIP = 4;
|
|
107
116
|
export function MultiSelect({ options, value, onChange, placeholder, labels, className, ...rest }) {
|
|
108
117
|
const id = useId();
|
|
109
118
|
const [open, setOpen] = useState(false);
|
|
@@ -115,19 +124,11 @@ export function MultiSelect({ options, value, onChange, placeholder, labels, cla
|
|
|
115
124
|
function toggle(v) {
|
|
116
125
|
onChange(value.includes(v) ? value.filter((x) => x !== v) : [...value, v]);
|
|
117
126
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
* çalışıyordu; yazdıktan sonra listeye uzanıp tıklamak gerekiyordu, ve
|
|
124
|
-
* klavyeyle gezen biri seçim yapamıyordu.
|
|
125
|
-
*
|
|
126
|
-
* Enter vurgulanan seçeneği ekler/çıkarır, ve kutuyu boşaltır
|
|
127
|
-
* Ok tuşları vurguyu gezdirir
|
|
128
|
-
* Backspace kutu BOŞKEN son çipi kaldırır (yazarken silmeye karışmaz)
|
|
129
|
-
* Escape listeyi kapatır
|
|
130
|
-
*/
|
|
127
|
+
/* KLAVYE, ve onsuz bu kontrol yarım:
|
|
128
|
+
Enter vurgulanan seçeneği ekler/çıkarır, ve kutuyu boşaltır
|
|
129
|
+
Ok tuşları vurguyu gezdirir
|
|
130
|
+
Backspace kutu BOŞKEN son çipi kaldırır (yazarken silmeye karışmaz)
|
|
131
|
+
Escape listeyi kapatır */
|
|
131
132
|
function tus(e) {
|
|
132
133
|
if (e.key === "ArrowDown") {
|
|
133
134
|
e.preventDefault();
|
|
@@ -165,27 +166,31 @@ export function MultiSelect({ options, value, onChange, placeholder, labels, cla
|
|
|
165
166
|
onBlur: (e) => {
|
|
166
167
|
if (!box.current?.contains(e.relatedTarget))
|
|
167
168
|
setOpen(false);
|
|
168
|
-
}, children: [_jsxs("span", { className: "tamga-input relative h-auto min-h-10 w-full flex-wrap items-center gap-1.5 py-1.5", "data-leading": "true", style: { display: "flex" }, children: [_jsx(Icon, { icon: Search, size: "xs", "aria-hidden": true, className: "pointer-events-none absolute left-3 top-3 text-ink-faint" }), chosen.map((o) => (_jsxs("span", { className: "tamga-
|
|
169
|
+
}, children: [_jsxs("span", { className: "tamga-input relative h-auto min-h-10 w-full flex-wrap items-center gap-1.5 py-1.5", "data-leading": "true", style: { display: "flex" }, children: [_jsx(Icon, { icon: Search, size: "xs", "aria-hidden": true, className: "pointer-events-none absolute left-3 top-3 text-ink-faint" }), chosen.slice(0, GORUNEN_CIP).map((o) => (_jsxs("span", { className: "tamga-token", children: [o.label, _jsx("button", { type: "button", "aria-label": labels.remove(o.label), onClick: () => toggle(o.value), className: "tamga-token-x", children: _jsx(Icon, { icon: Close, size: "xs" }) })] }, o.value))), chosen.length > GORUNEN_CIP ? (_jsxs("span", { className: "tamga-token", "aria-hidden": true, children: ["+", chosen.length - GORUNEN_CIP] })) : null, _jsx("input", { value: query, placeholder: chosen.length === 0 ? placeholder : undefined, onChange: (e) => {
|
|
169
170
|
setQuery(e.target.value);
|
|
170
171
|
setActive(0);
|
|
171
172
|
setOpen(true);
|
|
172
|
-
}, onKeyDown: tus, onFocus: () => setOpen(true), role: "combobox", "aria-expanded": open, "aria-controls": id, "aria-label": labels.open, className: "min-w-24 flex-1 bg-transparent text-body text-ink outline-none" })] }), open ? (_jsx("div", { id: id, role: "listbox", "aria-multiselectable": true, className: "tamga-overlay absolute z-30 mt-2 max-h-64 w-full overflow-y-auto
|
|
173
|
+
}, onKeyDown: tus, onFocus: () => setOpen(true), role: "combobox", "aria-expanded": open, "aria-controls": id, "aria-label": labels.open, className: "min-w-24 flex-1 bg-transparent text-body text-ink outline-none" })] }), open ? (_jsx("div", { id: id, role: "listbox", "aria-multiselectable": true, className: "tamga-overlay tamga-menu absolute z-30 mt-2 max-h-64 w-full overflow-y-auto", children: shown.length === 0 ? (_jsx("p", { className: "px-4 py-3 text-small text-ink-faint", children: labels.empty })) : (shown.map(({ value: v, label: etiket, hint, ...rest }, i) => {
|
|
173
174
|
const on = value.includes(v);
|
|
174
175
|
return (_jsxs("button", { ...rest, type: "button", role: "option", "aria-selected": on, "data-selected": on, "data-active": i === active || undefined, className: "tamga-option w-full", onMouseEnter: () => setActive(i), onClick: () => toggle(v), children: [_jsx("span", { className: "flex-1 text-left", children: etiket }), hint ? _jsx("span", { className: "font-mono text-caption text-ink-faint", children: hint }) : null, on ? _jsx(Icon, { icon: Check, size: "xs" }) : null] }, v));
|
|
175
176
|
})) })) : null] }));
|
|
176
177
|
}
|
|
177
178
|
/**
|
|
178
|
-
* Zamanlama girdisi
|
|
179
|
+
* Zamanlama girdisi · "her N dakikada bir". NEDEN CRON DEĞİL: kürasyonlu
|
|
180
|
+
* seçenek, serbestlik değil. Aralıklar dakika olarak veriliyor, çevirisi
|
|
181
|
+
* çağıranın.
|
|
179
182
|
*
|
|
180
|
-
*
|
|
181
|
-
* için okunur, bir panel
|
|
182
|
-
* kullanıcısı için değildir — ve yanlış yazılan bir cron ifadesi hata
|
|
183
|
-
* vermez, sadece yanlış zamanda çalışır. Bu bileşen kürasyonlu bir liste
|
|
184
|
-
* sunuyor: kürasyonlu seçenek, serbestlik değil.
|
|
185
|
-
*
|
|
186
|
-
* Aralıklar dakika olarak veriliyor, çevirisi çağıranın: "5 dakika" ile
|
|
187
|
-
* "5 minutes" arasındaki farkı kit bilemez.
|
|
183
|
+
* Gerekçe: docs/gerekce/01-form-ve-girdi.md
|
|
188
184
|
*/
|
|
189
|
-
export function ScheduleInput({
|
|
190
|
-
|
|
185
|
+
export function ScheduleInput({ days, onDaysChange, from, to, onFromChange, onToChange, labels, summary, className, ...rest }) {
|
|
186
|
+
const secili = new Set(days);
|
|
187
|
+
const cevir = (g) => {
|
|
188
|
+
const next = new Set(secili);
|
|
189
|
+
if (next.has(g))
|
|
190
|
+
next.delete(g);
|
|
191
|
+
else
|
|
192
|
+
next.add(g);
|
|
193
|
+
onDaysChange([...next].sort((a, b) => a - b));
|
|
194
|
+
};
|
|
195
|
+
return (_jsxs("div", { ...dataProps(rest), className: cn("flex flex-col gap-4", className), children: [_jsx("div", { role: "group", "aria-label": labels.days, className: "flex flex-wrap gap-2", children: labels.dayNames.map((ad, g) => (_jsx("button", { type: "button", "aria-pressed": secili.has(g), onClick: () => cevir(g), className: "tamga-gun-btn", "data-on": secili.has(g) || undefined, children: ad }, ad))) }), _jsxs("div", { className: "flex flex-wrap items-center gap-2.5 text-body", children: [_jsx("span", { className: "font-semibold text-ink", children: labels.hours }), _jsx("input", { type: "time", value: from, onChange: (e) => onFromChange(e.target.value), "aria-label": labels.hours, className: "tamga-input tamga-sayi w-auto" }), _jsx("span", { className: "text-ink-faint", children: labels.between }), _jsx("input", { type: "time", value: to, onChange: (e) => onToChange(e.target.value), "aria-label": labels.between, className: "tamga-input tamga-sayi w-auto" }), labels.zone ? _jsx("span", { className: "text-ink-faint", children: labels.zone }) : null] }), _jsxs("p", { className: "tamga-ozet", children: [_jsx(Icon, { icon: Clock, size: "xs", weight: "bold", className: "text-accent" }), summary] })] }));
|
|
191
196
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { IconGlyph } from "./icons.js";
|
|
3
|
+
/**
|
|
4
|
+
* Duyuru şeridi · sayfanın en üstünde, tüm genişlikte.
|
|
5
|
+
*
|
|
6
|
+
* Gerekçe: docs/gerekce/05-yuzey-ve-kabuk.md
|
|
7
|
+
*/
|
|
8
|
+
export declare function Announcement({ look, icon, tag, title, children, action, className, ...rest }: {
|
|
9
|
+
/**
|
|
10
|
+
* `loud` the filled accent strip, for something the reader should ACT on (a campaign, a
|
|
11
|
+
* deadline). `quiet` the washed strip, for a standing condition that only needs to be READ
|
|
12
|
+
* ("you are in test mode"). TR: `loud` dolu vurgu şeridi · okuyanın bir şey YAPMASI gereken
|
|
13
|
+
* durum için (kampanya, son tarih). `quiet` yıkanmış şerit · yalnız OKUNMASI yeten, duran bir
|
|
14
|
+
* koşul için ("test modundasın").
|
|
15
|
+
*/
|
|
16
|
+
look?: "loud" | "quiet";
|
|
17
|
+
/** The glyph at the head of the strip. TR: Şeridin başındaki glif. */
|
|
18
|
+
icon?: IconGlyph;
|
|
19
|
+
/**
|
|
20
|
+
* A short word in a dark plate before the text, for the quiet strip: "TEST MODE", "BETA".
|
|
21
|
+
* It is the one place a mode names itself. TR: Sessiz şeritte metinden önce, koyu bir plaka
|
|
22
|
+
* içinde kısa bir sözcük: "TEST MODU", "BETA". Bir kipin kendi adını söylediği tek yer.
|
|
23
|
+
*/
|
|
24
|
+
tag?: string;
|
|
25
|
+
/** TR: Kalın ilk satır. Sessiz şeritte yok: orada tek bir cümle var. */
|
|
26
|
+
title?: string;
|
|
27
|
+
children: ReactNode;
|
|
28
|
+
/** The button or link at the end. TR: Sondaki düğme ya da bağlantı. */
|
|
29
|
+
action?: ReactNode;
|
|
30
|
+
className?: string;
|
|
31
|
+
/** `data-*` hooks pass through. TR: `data-*` kancaları geçiyor. */
|
|
32
|
+
[k: `data-${string}`]: unknown;
|
|
33
|
+
}): import("react").JSX.Element;
|
|
34
|
+
//# sourceMappingURL=announcement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"announcement.d.ts","sourceRoot":"","sources":["../../src/components/announcement.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAC3B,IAAa,EACb,IAAI,EACJ,GAAG,EACH,KAAK,EACL,QAAQ,EACR,MAAM,EACN,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,sEAAsE;IACtE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,CAAC;IACpB,uEAAuE;IACvE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAoBA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
import { dataProps } from "../lib/data-props.js";
|
|
4
|
+
import { Icon } from "./icon.js";
|
|
5
|
+
/**
|
|
6
|
+
* Duyuru şeridi · sayfanın en üstünde, tüm genişlikte.
|
|
7
|
+
*
|
|
8
|
+
* Gerekçe: docs/gerekce/05-yuzey-ve-kabuk.md
|
|
9
|
+
*/
|
|
10
|
+
export function Announcement({ look = "loud", icon, tag, title, children, action, className, ...rest }) {
|
|
11
|
+
return (_jsxs("div", { ...dataProps(rest), className: cn("tamga-announce", look === "loud" && "tamga-announce-loud", look === "quiet" && "tamga-announce-quiet", className), children: [icon ? _jsx(Icon, { icon: icon, size: "md", weight: "fill" }) : null, tag ? _jsx("span", { className: "tamga-announce-tag", children: tag }) : null, _jsxs("div", { className: "flex min-w-0 flex-1 basis-55 flex-col gap-0.5", children: [title ? _jsx("strong", { className: "font-display text-subhead", children: title }) : null, _jsx("span", { className: "text-small", children: children })] }), action] }));
|
|
12
|
+
}
|
|
@@ -36,12 +36,44 @@ export type ThemeChoice = "light" | "dark" | "system";
|
|
|
36
36
|
export declare function ThemeCards({ value, onChange, labels, className, ...rest }: {
|
|
37
37
|
value: ThemeChoice;
|
|
38
38
|
onChange: (next: ThemeChoice) => void;
|
|
39
|
-
/** The three names and the group's accessible name. TR: Üç ad ve kümenin erişilebilir adı. */
|
|
39
|
+
/** The three names, a one-line note under each, and the group's accessible name. TR: Üç ad, her birinin altındaki tek satır, ve kümenin erişilebilir adı. */
|
|
40
40
|
labels: {
|
|
41
41
|
light: string;
|
|
42
42
|
dark: string;
|
|
43
43
|
system: string;
|
|
44
44
|
group: string;
|
|
45
|
+
lightNote?: string;
|
|
46
|
+
darkNote?: string;
|
|
47
|
+
systemNote?: string;
|
|
48
|
+
};
|
|
49
|
+
className?: string;
|
|
50
|
+
/** `data-*` hooks pass through. TR: `data-*` kancaları geçiyor. */
|
|
51
|
+
[k: `data-${string}`]: unknown;
|
|
52
|
+
}): import("react").JSX.Element;
|
|
53
|
+
export type RailChoice = "narrow" | "wide" | "free";
|
|
54
|
+
/**
|
|
55
|
+
* Sidebar width picked from three little pictures of the panel.
|
|
56
|
+
* TR: Panelin üç küçük resminden seçilen kenar çubuğu genişliği.
|
|
57
|
+
*
|
|
58
|
+
* This was a `Segmented` of three words. On the same screen the theme was
|
|
59
|
+
* asked with pictures and this with words, and how much room a menu takes is
|
|
60
|
+
* the kind of thing you see rather than read.
|
|
61
|
+
* TR: Bu üç kelimelik bir `Segmented` idi. Aynı ekranda tema resimle, bu
|
|
62
|
+
* kelimeyle soruluyordu; oysa bir menünün ne kadar yer kapladığı okunacak
|
|
63
|
+
* değil görülecek bir şey.
|
|
64
|
+
*/
|
|
65
|
+
export declare function RailCards({ value, onChange, labels, className, ...rest }: {
|
|
66
|
+
value: RailChoice;
|
|
67
|
+
onChange: (next: RailChoice) => void;
|
|
68
|
+
/** The three names, a one-line note under each, and the group's accessible name. TR: Üç ad, her birinin altındaki tek satır, ve kümenin erişilebilir adı. */
|
|
69
|
+
labels: {
|
|
70
|
+
narrow: string;
|
|
71
|
+
wide: string;
|
|
72
|
+
free: string;
|
|
73
|
+
group: string;
|
|
74
|
+
narrowNote?: string;
|
|
75
|
+
wideNote?: string;
|
|
76
|
+
freeNote?: string;
|
|
45
77
|
};
|
|
46
78
|
className?: string;
|
|
47
79
|
/** `data-*` hooks pass through. TR: `data-*` kancaları geçiyor. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appearance.d.ts","sourceRoot":"","sources":["../../src/components/appearance.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"appearance.d.ts","sourceRoot":"","sources":["../../src/components/appearance.tsx"],"names":[],"mappings":"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"}
|
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useId, useRef, useState } from "react";
|
|
4
4
|
import { cn } from "../lib/cn.js";
|
|
5
|
+
import { makePalette } from "../lib/palette.js";
|
|
5
6
|
import { dataProps } from "../lib/data-props.js";
|
|
6
7
|
import { IMAGE_ACCEPT, prepareImage } from "../lib/image.js";
|
|
7
8
|
import { Alert } from "./primitives.js";
|
|
8
9
|
import { Button } from "./button.js";
|
|
10
|
+
import { Icon } from "./icon.js";
|
|
11
|
+
import { Check, Eyedropper } from "./icons.js";
|
|
9
12
|
/**
|
|
10
13
|
* Brand colour chosen from a few squares, or written by hand.
|
|
11
14
|
* TR: Birkaç kareden seçilen ya da elle yazılan marka rengi.
|
|
@@ -13,10 +16,59 @@ import { Button } from "./button.js";
|
|
|
13
16
|
export function ColorSwatches({ options, value, onChange, customLabel, custom = true, className, ...rest }) {
|
|
14
17
|
const secili = (hex) => hex.toLowerCase() === value.toLowerCase();
|
|
15
18
|
const hazirMi = options.some((o) => secili(o.hex));
|
|
16
|
-
return (_jsxs("span", { ...dataProps(rest), className: cn("flex flex-wrap items-center gap-3", className), children: [options.map(({ hex, label: etiket, ...rest }) => (_jsx("button", { ...rest, type: "button", className: "tamga-swatch", "data-selected": secili(hex), "aria-label": etiket, title: etiket, onClick: () => onChange(hex), children: _jsx(
|
|
19
|
+
return (_jsxs("span", { ...dataProps(rest), className: cn("flex flex-wrap items-center gap-3", className), children: [options.map(({ hex, label: etiket, ...rest }) => (_jsx("button", { ...rest, type: "button", className: "tamga-swatch", style: { background: hex, color: mürekkep(hex) }, "data-selected": secili(hex), "aria-pressed": secili(hex), "aria-label": etiket, title: etiket, onClick: () => onChange(hex), children: secili(hex) ? _jsx(Icon, { icon: Check, size: "base", weight: "bold" }) : null }, hex))), custom ? (_jsxs("label", { className: "tamga-swatch tamga-swatch-custom", "data-selected": !hazirMi, title: customLabel, style: hazirMi
|
|
20
|
+
? /* Hiçbir hazır renk seçili değilken kutu o rengi giyiyor;
|
|
21
|
+
seçiliyken damalı zemin "burada henüz bir renk yok" diyor. */
|
|
22
|
+
{ background: DAMA }
|
|
23
|
+
: { background: value, color: mürekkep(value) }, children: [_jsx("span", { className: "sr-only", children: customLabel }), _jsx(Icon, { icon: hazirMi ? Eyedropper : Check, size: "base", weight: "bold", style: hazirMi ? { color: "var(--color-ink)" } : undefined }), _jsx("input", { type: "color", value: hazirMi ? options[0].hex : value, onChange: (e) => onChange(e.target.value), className: "tamga-color-input", "aria-label": customLabel })] })) : null] }));
|
|
17
24
|
}
|
|
18
|
-
|
|
19
|
-
|
|
25
|
+
/* Damalı zemin: "burada renk yok". Kutunun kendisi bir renk olduğu için boş
|
|
26
|
+
hâlin de bir zemini olmak zorunda, ve düz bir gri yedinci bir renk gibi
|
|
27
|
+
okunuyordu. */
|
|
28
|
+
const DAMA = "repeating-linear-gradient(135deg, var(--color-hover) 0 6px, var(--color-sunk) 6px 12px)";
|
|
29
|
+
/**
|
|
30
|
+
* Ink that stays readable on a given fill.
|
|
31
|
+
* TR: Verilen dolgunun üstünde okunur kalan mürekkep.
|
|
32
|
+
*
|
|
33
|
+
* TOKEN DEĞİL, HESAP · ve önce token'dı: `--color-accent-ink`. Kusuru
|
|
34
|
+
* tarayıcıda göründü. Kutular SEÇİLEN ham rengi gösteriyor, token ise o an
|
|
35
|
+
* YÜRÜRLÜKTEKİ paletin mürekkebi; koyu temada antrasit marka seçilince palet
|
|
36
|
+
* vurguyu açıyor (#838c9d) ve mürekkebini koyulaştırıyor (#222326), oysa
|
|
37
|
+
* kutunun zemini hâlâ ham #3f4756. Sonuç koyunun üstünde koyu çentik: 1.4
|
|
38
|
+
* kontrast, yani görünmez.
|
|
39
|
+
*
|
|
40
|
+
* Cevap paletin kendisinde: o rengin PALETİ hangi mürekkebi seçiyorsa kutu da
|
|
41
|
+
* onu giyiyor. Eşik uydurmuyoruz, üreteci ikinci kez yazmıyoruz.
|
|
42
|
+
*/
|
|
43
|
+
const MUREKKEP = new Map();
|
|
44
|
+
function mürekkep(hex) {
|
|
45
|
+
const anahtar = hex.toLowerCase();
|
|
46
|
+
let m = MUREKKEP.get(anahtar);
|
|
47
|
+
if (m === undefined) {
|
|
48
|
+
m = makePalette(anahtar).light.accentInk;
|
|
49
|
+
MUREKKEP.set(anahtar, m);
|
|
50
|
+
}
|
|
51
|
+
return m;
|
|
52
|
+
}
|
|
53
|
+
/* Panelin yarısı: ray ve gövde. Bir tema kartı bunu bir kez çiziyor,
|
|
54
|
+
"Sistem" kartı iki kez · ikincisi çapraz kesilerek üstüne biniyor.
|
|
55
|
+
|
|
56
|
+
MİNYATÜR SABİT RENKLERLE, ve kitin tek istisnası bu. Seçenekler o an
|
|
57
|
+
yürürlükteki temayı değil SEÇİLİRSE ne olacağını gösteriyor; token
|
|
58
|
+
kullanılsaydı üçü de aynı görünürdü. Tek token: marka vurgusu, çünkü
|
|
59
|
+
önizlemenin yarısı o. */
|
|
60
|
+
function Yarim({ theme, clip = false }) {
|
|
61
|
+
return (_jsxs("span", { className: "tamga-theme-half", "data-theme": theme, "data-clip": clip || undefined, "aria-hidden": true, children: [_jsxs("span", { className: "tamga-theme-rail", children: [_jsx("span", { className: "tamga-theme-dot", "data-accent": "true", style: { width: "80%" } }), _jsx("span", { className: "tamga-theme-dot", style: { width: "100%" } }), _jsx("span", { className: "tamga-theme-dot", style: { width: "70%" } }), _jsx("span", { className: "tamga-theme-dot", style: { width: "60%" } })] }), _jsxs("span", { className: "tamga-theme-body", children: [_jsx("span", { className: "tamga-theme-line", "data-accent": "true", style: { width: "50%" } }), _jsx("span", { className: "tamga-theme-line", style: { width: "100%" } }), _jsx("span", { className: "tamga-theme-line", style: { width: "70%" } })] })] }));
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A miniature of the panel with a radio and a name under it.
|
|
65
|
+
* TR: Altında bir radyo ve bir ad duran panel minyatürü.
|
|
66
|
+
*
|
|
67
|
+
* Tema ve kenar çubuğu aynı soruyu soruyor ("hangisi olsun") ve ayrı
|
|
68
|
+
* çizilmişlerdi; ortak olan kap, farklı olan yalnız minyatürün içi.
|
|
69
|
+
*/
|
|
70
|
+
function OnizlemeKarti({ selected, onSelect, label, sub, children, }) {
|
|
71
|
+
return (_jsxs("button", { type: "button", role: "radio", "aria-checked": selected, tabIndex: selected ? 0 : -1, "data-selected": selected, className: "tamga-preview-card", onClick: onSelect, children: [_jsx("span", { className: "tamga-preview-box", children: children }), _jsxs("span", { className: "tamga-preview-foot", children: [_jsx("span", { className: "tamga-radio", "data-checked": selected, "aria-hidden": true }), _jsxs("span", { className: "tamga-preview-text", children: [_jsx("strong", { children: label }), sub ? _jsx("span", { children: sub }) : null] })] })] }));
|
|
20
72
|
}
|
|
21
73
|
/**
|
|
22
74
|
* Theme picked from three little pictures of the panel.
|
|
@@ -31,11 +83,30 @@ function Yarim({ theme }) {
|
|
|
31
83
|
*/
|
|
32
84
|
export function ThemeCards({ value, onChange, labels, className, ...rest }) {
|
|
33
85
|
const secenekler = [
|
|
34
|
-
{ deger: "light", ad: labels.light },
|
|
35
|
-
{ deger: "dark", ad: labels.dark },
|
|
36
|
-
{ deger: "system", ad: labels.system },
|
|
86
|
+
{ deger: "light", ad: labels.light, alt: labels.lightNote },
|
|
87
|
+
{ deger: "dark", ad: labels.dark, alt: labels.darkNote },
|
|
88
|
+
{ deger: "system", ad: labels.system, alt: labels.systemNote },
|
|
89
|
+
];
|
|
90
|
+
return (_jsx("div", { ...dataProps(rest), role: "radiogroup", "aria-label": labels.group, className: cn("tamga-preview-grid", className), children: secenekler.map((s) => (_jsx(OnizlemeKarti, { selected: value === s.deger, onSelect: () => onChange(s.deger), label: s.ad, sub: s.alt, children: _jsxs("span", { className: "tamga-theme-box", children: [_jsx(Yarim, { theme: s.deger === "dark" ? "dark" : "light" }), s.deger === "system" ? _jsx(Yarim, { theme: "dark", clip: true }) : null] }) }, s.deger))) }));
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Sidebar width picked from three little pictures of the panel.
|
|
94
|
+
* TR: Panelin üç küçük resminden seçilen kenar çubuğu genişliği.
|
|
95
|
+
*
|
|
96
|
+
* This was a `Segmented` of three words. On the same screen the theme was
|
|
97
|
+
* asked with pictures and this with words, and how much room a menu takes is
|
|
98
|
+
* the kind of thing you see rather than read.
|
|
99
|
+
* TR: Bu üç kelimelik bir `Segmented` idi. Aynı ekranda tema resimle, bu
|
|
100
|
+
* kelimeyle soruluyordu; oysa bir menünün ne kadar yer kapladığı okunacak
|
|
101
|
+
* değil görülecek bir şey.
|
|
102
|
+
*/
|
|
103
|
+
export function RailCards({ value, onChange, labels, className, ...rest }) {
|
|
104
|
+
const secenekler = [
|
|
105
|
+
{ deger: "wide", ad: labels.wide, alt: labels.wideNote },
|
|
106
|
+
{ deger: "narrow", ad: labels.narrow, alt: labels.narrowNote },
|
|
107
|
+
{ deger: "free", ad: labels.free, alt: labels.freeNote },
|
|
37
108
|
];
|
|
38
|
-
return (_jsx("div", { ...dataProps(rest), role: "radiogroup", "aria-label": labels.group, className: cn("
|
|
109
|
+
return (_jsx("div", { ...dataProps(rest), role: "radiogroup", "aria-label": labels.group, className: cn("tamga-preview-grid", className), children: secenekler.map((s) => (_jsx(OnizlemeKarti, { selected: value === s.deger, onSelect: () => onChange(s.deger), label: s.ad, sub: s.alt, children: _jsxs("span", { className: "tamga-rail-mini", "data-mode": s.deger, "aria-hidden": true, children: [_jsxs("span", { className: "tamga-rail-mini-rail", children: [_jsx("span", { "data-accent": "true" }), _jsx("span", {}), _jsx("span", {}), _jsx("span", {}), s.deger === "free" ? _jsx("span", { className: "tamga-rail-mini-toggle" }) : null] }), _jsxs("span", { className: "tamga-rail-mini-body", children: [_jsx("span", {}), _jsx("span", {})] })] }) }, s.deger))) }));
|
|
39
110
|
}
|
|
40
111
|
/**
|
|
41
112
|
* One image with a preview, a replace and a remove.
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import type { Tone } from "./tone.js";
|
|
1
2
|
/** Square, monochrome. Identity is text — color is reserved for health. */
|
|
2
|
-
export declare function Avatar({ name, size, src, bare, letters, ...rest }: {
|
|
3
|
+
export declare function Avatar({ name, size, src, bare, look, letters, status, ...rest }: {
|
|
3
4
|
name: string;
|
|
4
5
|
size?: number;
|
|
5
6
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
7
|
+
* The photo. Without it the tile carries initials; a photo that FAILS to load is the
|
|
8
|
+
* browser's broken-image mark, not the initials. TR: Fotoğraf. Yoksa karo baş harfleri
|
|
9
|
+
* taşıyor; yüklenEMEyen bir fotoğrafta baş harfler değil tarayıcının kırık görsel işareti
|
|
10
|
+
* kalıyor.
|
|
8
11
|
*/
|
|
9
12
|
src?: string;
|
|
10
13
|
/**
|
|
@@ -16,6 +19,14 @@ export declare function Avatar({ name, size, src, bare, letters, ...rest }: {
|
|
|
16
19
|
* düğmesi çıplak bir simge taşıyan bir araç çubuğunda tek başına farklı gösteriyordu.
|
|
17
20
|
*/
|
|
18
21
|
bare?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* `solid` the accent tile with light initials, `soft` the light tile with dark ones. Two, not
|
|
24
|
+
* a palette: an avatar is not a status, and a wall of differently coloured tiles reads as a
|
|
25
|
+
* legend nobody wrote. TR: `solid` vurgu karosu ve açık baş harfler, `soft` açık karo ve koyu
|
|
26
|
+
* harfler. İki tane, bir palet değil: avatar bir durum değil, ve farklı renkli karolardan
|
|
27
|
+
* oluşan bir duvar, kimsenin yazmadığı bir lejant gibi okunuyor.
|
|
28
|
+
*/
|
|
29
|
+
look?: "solid" | "soft";
|
|
19
30
|
/**
|
|
20
31
|
* How many initials to show. An avatar standing alone carries two, the least it takes to
|
|
21
32
|
* point at a person. But two do not fit in an OVERLAPPING stack: the tile above clips the
|
|
@@ -28,29 +39,25 @@ export declare function Avatar({ name, size, src, bare, letters, ...rest }: {
|
|
|
28
39
|
* harf ise yarım okunamaz. `AvatarStack` bu yüzden 1 geçiyor.
|
|
29
40
|
*/
|
|
30
41
|
letters?: 1 | 2;
|
|
42
|
+
/**
|
|
43
|
+
* A presence mark on the tile's bottom-right corner, in the tone's own colour. It is the ONE
|
|
44
|
+
* place colour is allowed on an avatar: the tile stays monochrome because identity is text,
|
|
45
|
+
* and this square is not identity but health. Absent by default · a mark on every avatar is
|
|
46
|
+
* a legend nobody wrote. TR: Karonun sağ alt köşesinde, tonun kendi rengiyle bir varlık
|
|
47
|
+
* işareti. Avatarda rengin izinli olduğu TEK yer: kimlik metin olduğu için karo tek renkli
|
|
48
|
+
* kalıyor, ve bu kare kimlik değil sağlık. Varsayılanı yok · her avatarda duran bir işaret,
|
|
49
|
+
* kimsenin yazmadığı bir lejant olurdu.
|
|
50
|
+
*/
|
|
51
|
+
status?: Tone;
|
|
31
52
|
/** `data-*` hooks pass through. TR: `data-*` kancaları geçiyor. */
|
|
32
53
|
[k: `data-${string}`]: unknown;
|
|
33
54
|
}): import("react").JSX.Element;
|
|
34
55
|
/**
|
|
35
|
-
* Üst üste binen ekip
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* birbirine yapışıp tek bir karışık blok olarak okunuyordu.
|
|
39
|
-
*
|
|
40
|
-
* Birincisi ÖRTÜŞME SABİTTİ — her boyutta 8px. Bir 24px karoda bu üçte bir
|
|
41
|
-
* demek, ve iki baş harften biri kapanıyor. Şimdi boyuna oranlı: dörtte bir,
|
|
42
|
-
* yani karo büyüdükçe örtüşme de büyüyor ama oran sabit kalıyor.
|
|
43
|
-
*
|
|
44
|
-
* İkincisi AYIRICI HALKA YOKTU. Avatarın kendi 1px kenarı yeterli sanılmıştı
|
|
45
|
-
* ve değildi: iki karo bitişince o kenarlar tek bir çizgi oluyor, ve
|
|
46
|
-
* hangisinin önde olduğu okunmuyor. Üstteki karonun etrafına ARKA PLAN
|
|
47
|
-
* RENGİNDE bir halka koyunca, üstteki alttakini gerçekten kesiyor.
|
|
56
|
+
* Üst üste binen ekip · örtüşme boyuna ORANLI (dörtte bir), ve üstteki karonun
|
|
57
|
+
* etrafında arka plan renginde bir AYIRICI HALKA var: onsuz bitişen 1px kenarlar
|
|
58
|
+
* tek çizgi oluyor. `surface` bu yüzden prop, halka zeminin rengi olmalı.
|
|
48
59
|
*
|
|
49
|
-
*
|
|
50
|
-
* olmalı. Varsayılan kart zemini (`--color-shell`), çünkü bir ekip listesi
|
|
51
|
-
* neredeyse her zaman bir kartın içindedir — ama sayfa zemininde duracaksa
|
|
52
|
-
* çağıran onu söyler. Bulanıklık yok: `0 0 0` yayılımsız bir halka, gölge
|
|
53
|
-
* değil.
|
|
60
|
+
* Gerekçe: docs/gerekce/05-yuzey-ve-kabuk.md
|
|
54
61
|
*/
|
|
55
62
|
export declare function AvatarStack({ names, extra, size, surface, ...rest }: {
|
|
56
63
|
names: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../src/components/avatar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../src/components/avatar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAWtC,2EAA2E;AAC3E,wBAAgB,MAAM,CAAC,EACrB,IAAI,EACJ,IAAS,EACT,GAAG,EACH,IAAY,EACZ,IAAc,EACd,OAAW,EACX,MAAM,EACN,GAAG,IAAI,EACR,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAChB;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BA0EA;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,KAAK,EACL,IAAS,EACT,OAA8B,EAC9B,GAAG,IAAI,EACR,EAAE;IACD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAuCA"}
|