tamga-ui 0.6.0 → 0.7.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +133 -0
  2. package/dist/blocks/danger-zone.d.ts +54 -0
  3. package/dist/blocks/danger-zone.d.ts.map +1 -0
  4. package/dist/blocks/danger-zone.js +18 -0
  5. package/dist/blocks/index.d.ts +1 -0
  6. package/dist/blocks/index.d.ts.map +1 -1
  7. package/dist/blocks/index.js +1 -0
  8. package/dist/components/appearance.d.ts +91 -5
  9. package/dist/components/appearance.d.ts.map +1 -1
  10. package/dist/components/appearance.js +164 -18
  11. package/dist/components/button.d.ts +2 -1
  12. package/dist/components/button.d.ts.map +1 -1
  13. package/dist/components/button.js +1 -1
  14. package/dist/components/chrome.d.ts +10 -1
  15. package/dist/components/chrome.d.ts.map +1 -1
  16. package/dist/components/chrome.js +2 -2
  17. package/dist/components/date-picker.d.ts +142 -4
  18. package/dist/components/date-picker.d.ts.map +1 -1
  19. package/dist/components/date-picker.js +331 -40
  20. package/dist/components/disclosure.d.ts +37 -2
  21. package/dist/components/disclosure.d.ts.map +1 -1
  22. package/dist/components/disclosure.js +13 -3
  23. package/dist/components/display.d.ts +35 -6
  24. package/dist/components/display.d.ts.map +1 -1
  25. package/dist/components/display.js +21 -7
  26. package/dist/components/input.d.ts +2 -1
  27. package/dist/components/input.d.ts.map +1 -1
  28. package/dist/components/primitives.d.ts +3 -1
  29. package/dist/components/primitives.d.ts.map +1 -1
  30. package/dist/components/primitives.js +2 -2
  31. package/dist/fonts.css +1 -1
  32. package/dist/index.d.ts +2 -2
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +2 -2
  35. package/dist/kit.css +115 -3
  36. package/dist/lib/image.d.ts +2 -0
  37. package/dist/lib/image.d.ts.map +1 -1
  38. package/dist/lib/image.js +1 -1
  39. package/dist/lib/uyar.d.ts +2 -0
  40. package/dist/lib/uyar.d.ts.map +1 -0
  41. package/dist/lib/uyar.js +10 -0
  42. package/dist/styles.css +1 -1
  43. package/dist/theme.css +8 -1
  44. package/package.json +10 -12
@@ -1,12 +1,124 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useCallback, useMemo, useState } from "react";
3
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
4
  import { useDismiss } from "./a11y.js";
5
5
  import { cn } from "../lib/cn.js";
6
6
  import { dataProps } from "../lib/data-props.js";
7
+ import { uyar } from "../lib/uyar.js";
7
8
  import { Icon } from "./icon.js";
9
+ import { Select } from "./primitives.js";
8
10
  import { CaretLeft, CaretRight, CalendarPlus, Close } from "./icons.js";
9
- const iso = (y, m, d) => `${y}-${String(m + 1).padStart(2, "0")}-${String(d).padStart(2, "0")}`;
11
+ const p2 = (n) => String(n).padStart(2, "0");
12
+ export const varsayilanDilim = () => Intl.DateTimeFormat().resolvedOptions().timeZone;
13
+ const duvarBicim = new Map();
14
+ /** Bir anın `tz` dilimindeki duvar saati. */
15
+ function duvar(an, tz) {
16
+ let f = duvarBicim.get(tz);
17
+ if (!f) {
18
+ f = new Intl.DateTimeFormat("en-US", {
19
+ timeZone: tz,
20
+ year: "numeric",
21
+ month: "2-digit",
22
+ day: "2-digit",
23
+ hour: "2-digit",
24
+ minute: "2-digit",
25
+ hourCycle: "h23",
26
+ });
27
+ duvarBicim.set(tz, f);
28
+ }
29
+ const al = (parts, t) => Number(parts.find((p) => p.type === t)?.value ?? 0);
30
+ const parts = f.formatToParts(an);
31
+ return { y: al(parts, "year"), m: al(parts, "month") - 1, d: al(parts, "day"), h: al(parts, "hour") % 24, mi: al(parts, "minute") };
32
+ }
33
+ /** `tz` diliminin o andaki ofseti, dakika. */
34
+ function ofsetDk(an, tz) {
35
+ const w = duvar(an, tz);
36
+ return Math.round((Date.UTC(w.y, w.m, w.d, w.h, w.mi) - an.getTime()) / 60000 + an.getSeconds() / 60);
37
+ }
38
+ const SAAT_MS = 3600000;
39
+ /** Tahminin iki yanındaki ofsetler: bir geçiş yakındaysa öncesi ve sonrası, yoksa ikisi aynı. */
40
+ function ikiOfset(tahmin, tz) {
41
+ return { once: ofsetDk(new Date(tahmin - 15 * SAAT_MS), tz), sonra: ofsetDk(new Date(tahmin + 15 * SAAT_MS), tz) };
42
+ }
43
+ /**
44
+ * Bir duvar saatinin bu dilimde karşılık geldiği anlar, erken olan önce: sıfır
45
+ * (DST boşluğu), bir, ya da iki (sonbaharda iki kez yaşanan saat).
46
+ */
47
+ export function adaylar(w, tz) {
48
+ const tahmin = Date.UTC(w.y, w.m, w.d, w.h, w.mi);
49
+ const { once, sonra } = ikiOfset(tahmin, tz);
50
+ const out = [];
51
+ for (const o of once === sonra ? [once] : [once, sonra]) {
52
+ const t = new Date(tahmin - o * 60000);
53
+ if (ofsetDk(t, tz) === o)
54
+ out.push(t);
55
+ }
56
+ return out.sort((x, y) => x.getTime() - y.getTime());
57
+ }
58
+ /**
59
+ * Duvar saatinden an. Belirsiz saatte (sonbahar) SONRAKİ an, yani geçiş sonrası
60
+ * standart ofset. Boşlukta (ilkbahar, olmayan saat) önceki ofsetle kurulur, bu
61
+ * da saati İLERİ iter: 02:30 istenir, 03:30 döner. İki yarımkürede de aynı;
62
+ * New York ve Berlin için testte sabit.
63
+ */
64
+ export function anYap(w, tz) {
65
+ const a = adaylar(w, tz);
66
+ if (a.length)
67
+ return a[a.length - 1];
68
+ const tahmin = Date.UTC(w.y, w.m, w.d, w.h, w.mi);
69
+ return new Date(tahmin - ikiOfset(tahmin, tz).once * 60000);
70
+ }
71
+ /** Geçersiz girdi bileşeni düşürmez: dilim tarayıcınınkine, değer boşa düşer, konsol uyarır. */
72
+ function dilim(tz) {
73
+ const aday = tz ?? varsayilanDilim();
74
+ try {
75
+ new Intl.DateTimeFormat("en-US", { timeZone: aday });
76
+ return aday;
77
+ }
78
+ catch {
79
+ uyar(`timeZone "${aday}" is not a valid IANA zone; using the browser's.`);
80
+ return varsayilanDilim();
81
+ }
82
+ }
83
+ const GUN = /^\d{4}-\d{2}-\d{2}$/;
84
+ export function gunOku(v, ad) {
85
+ if (v === undefined)
86
+ return undefined;
87
+ if (GUN.test(v)) {
88
+ /* `2026-02-30` Date.UTC'de 2 Mart'a taşar; gidip gelince aynı kalan gün gerçek. */
89
+ const { y, m, d } = parcala(v);
90
+ const t = new Date(Date.UTC(y, m, d));
91
+ if (t.getUTCFullYear() === y && t.getUTCMonth() === m && t.getUTCDate() === d)
92
+ return v;
93
+ }
94
+ uyar(`DatePicker: ${ad} "${v}" is not a YYYY-MM-DD day; ignored.`);
95
+ return undefined;
96
+ }
97
+ function anOku(v, ad) {
98
+ if (!v)
99
+ return undefined;
100
+ const d = new Date(v);
101
+ if (!Number.isNaN(d.getTime()))
102
+ return d;
103
+ uyar(`DateTimePicker: ${ad} "${v}" is not an ISO instant; ignored.`);
104
+ return undefined;
105
+ }
106
+ const useGun = (v, ad) => useMemo(() => gunOku(v, ad), [v, ad]);
107
+ function isoWithOffset(an, tz) {
108
+ const w = duvar(an, tz);
109
+ const off = ofsetDk(an, tz);
110
+ const isaret = off >= 0 ? "+" : "-";
111
+ const mutlak = Math.abs(off);
112
+ return `${w.y}-${p2(w.m + 1)}-${p2(w.d)}T${p2(w.h)}:${p2(w.mi)}:00${isaret}${p2(Math.floor(mutlak / 60))}:${p2(mutlak % 60)}`;
113
+ }
114
+ const iso = (y, m, d) => `${y}-${p2(m + 1)}-${p2(d)}`;
115
+ const gunParcasi = (an, tz) => { const w = duvar(an, tz); return iso(w.y, w.m, w.d); };
116
+ const parcala = (d) => { const [y, m, g] = d.split("-").map(Number); return { y: y, m: m - 1, d: g }; };
117
+ const gunKaydir = (d, adim) => {
118
+ const { y, m, d: g } = parcala(d);
119
+ const t = new Date(Date.UTC(y, m, g + adim));
120
+ return iso(t.getUTCFullYear(), t.getUTCMonth(), t.getUTCDate());
121
+ };
10
122
  function monthMatrix(year, month, firstDay) {
11
123
  const first = new Date(Date.UTC(year, month, 1));
12
124
  const days = new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
@@ -33,35 +145,113 @@ function weekStart(locale) {
33
145
  }
34
146
  return 1;
35
147
  }
36
- export function Calendar({ locale, value, range, onSelect, labels, className, ...rest }) {
37
- const today = new Date();
38
- /* AÇILAN AY DEĞERİN AYI, bugünün ayı değil · ve bir süre bugünündü: başka bir
39
- aydan bir tarih verildiğinde takvim bu ayı açıyor, seçili gün hiç
40
- görünmüyor ve kullanıcı kendi verdiği tarihi arıyordu. Değer yoksa bugün. */
41
- const acilis = value ? new Date(`${value}T00:00:00`) : today;
42
- const [view, setView] = useState({ y: acilis.getFullYear(), m: acilis.getMonth() });
148
+ export function Calendar({ locale, timeZone, value: hamDeger, range, min: hamMin, max: hamMax, onSelect, labels, className, ...rest }) {
149
+ const tz = useMemo(() => dilim(timeZone), [timeZone]);
150
+ const value = useGun(hamDeger, "value");
151
+ const min = useGun(hamMin, "min");
152
+ const max = useGun(hamMax, "max");
153
+ /* ISO günler sözlük sırasıyla karşılaştırılıyor: `2026-04-05 < 2026-04-15`. */
154
+ const kapali = (d) => (min !== undefined && d < min) || (max !== undefined && d > max);
155
+ const bugun = gunParcasi(new Date(), tz);
156
+ /* AÇILAN AY DEĞERİN AYI, bugünün ayı değil. Değer yoksa bugün. */
157
+ const ayi = (d) => { const { y, m } = parcala(d); return { y, m }; };
158
+ const [view, setView] = useState(ayi(value ?? bugun));
159
+ const kok = useRef(null);
43
160
  const first = weekStart(locale);
44
161
  const cells = useMemo(() => monthMatrix(view.y, view.m, first), [view, first]);
45
- const monthName = new Intl.DateTimeFormat(locale, { month: "long", year: "numeric" }).format(new Date(Date.UTC(view.y, view.m, 1)));
162
+ const gorunenGunler = useMemo(() => cells.filter((d) => d !== null).map((d) => iso(view.y, view.m, d)), [cells, view]);
163
+ /* SEKME DURAĞI HEP GÖRÜNEN AYDA VE AÇIK BİR GÜNDE. `odak` yalnız tercihtir;
164
+ ay değişince ya da odak kapalı/görünmez olunca durak seçili güne, o da
165
+ yoksa ilk açık güne düşer · yoksa klavye ızgaraya hiç giremiyordu. */
166
+ const [odak, setOdak] = useState(value ?? bugun);
167
+ const gorunur = (d) => d !== undefined && d.startsWith(`${view.y}-${p2(view.m + 1)}`);
168
+ const etkinOdak = gorunur(odak) && !kapali(odak) ? odak
169
+ : gorunur(value) && !kapali(value) ? value
170
+ : gorunenGunler.find((d) => !kapali(d));
171
+ /* Dışarıdan değer değişince görünüm ve durak onunla eşleşiyor. */
172
+ const oncekiDeger = useRef(value);
173
+ useEffect(() => {
174
+ if (value === oncekiDeger.current)
175
+ return;
176
+ oncekiDeger.current = value;
177
+ if (value) {
178
+ setView(ayi(value));
179
+ setOdak(value);
180
+ }
181
+ }, [value]);
182
+ const monthName = new Intl.DateTimeFormat(locale, { month: "long", year: "numeric", timeZone: "UTC" }).format(new Date(Date.UTC(view.y, view.m, 1)));
46
183
  const dayNames = useMemo(() => {
47
- const fmt = new Intl.DateTimeFormat(locale, { weekday: "short" });
184
+ const fmt = new Intl.DateTimeFormat(locale, { weekday: "short", timeZone: "UTC" });
48
185
  /* 2024-01-07 bir Pazar; oradan hafta başına kaydırıyoruz. */
49
186
  return Array.from({ length: 7 }, (_, i) => fmt.format(new Date(Date.UTC(2024, 0, 7 + ((first + i) % 7)))));
50
187
  }, [locale, first]);
51
- /* BUGÜN İŞARETLİ, ve değildi: bir takvimde "hangi gün bugün" sorusu her
52
- zaman soruluyor, ve cevabı yoksa kullanıcı tarihi baştan sayıyor. */
53
- const bugun = iso(today.getFullYear(), today.getMonth(), today.getDate());
54
- const inRange = (d) => range?.from && range?.to ? d >= range.from && d <= range.to : false;
188
+ /* Günün erişilebilir adı tam tarih: oklar ay sınırını geçince ekran okuyucu ayı duysun. */
189
+ const tamTarih = useMemo(() => new Intl.DateTimeFormat(locale, { dateStyle: "long", timeZone: "UTC" }), [locale]);
190
+ const inRange = (d) => (range?.from && range?.to ? d >= range.from && d <= range.to : false);
55
191
  const isEdge = (d) => d === range?.from || d === range?.to || d === value;
56
- return (_jsxs("div", { ...dataProps(rest), className: cn("w-70", className), children: [_jsxs("div", { className: "mb-3 flex items-center gap-2", children: [_jsx("button", { type: "button", className: "tamga-icon-btn", "aria-label": labels.previousMonth, onClick: () => setView((v) => (v.m === 0 ? { y: v.y - 1, m: 11 } : { ...v, m: v.m - 1 })), children: _jsx(Icon, { icon: CaretLeft, size: "xs" }) }), _jsx("span", { className: "flex-1 text-center text-body font-medium text-ink", children: monthName }), _jsx("button", { type: "button", className: "tamga-icon-btn", "aria-label": labels.nextMonth, onClick: () => setView((v) => (v.m === 11 ? { y: v.y + 1, m: 0 } : { ...v, m: v.m + 1 })), children: _jsx(Icon, { icon: CaretRight, size: "xs" }) })] }), _jsxs("div", { className: "grid grid-cols-7 gap-px", children: [dayNames.map((d) => (_jsx("span", { className: "pb-1 text-center text-caption text-ink-faint", children: d }, d))), cells.map((d, i) => {
57
- if (d === null)
58
- return _jsx("span", {}, `x${i}`);
59
- const date = iso(view.y, view.m, d);
60
- return (_jsx("button", { type: "button",
61
- /* Seçili gün DOLGU alır: bir tarih bir değerdir, bir hedef değil;
62
- checkbox ile aynı gerekçe (Yasa 2). */
63
- className: "tamga-gun", "data-selected": isEdge(date), "data-today": date === bugun || undefined, "data-active": inRange(date) && !isEdge(date), "aria-pressed": isEdge(date), onClick: () => onSelect?.(date), children: d }, date));
64
- })] })] }));
192
+ const git = (hedef) => {
193
+ if (!hedef)
194
+ return;
195
+ setOdak(hedef);
196
+ setView(ayi(hedef));
197
+ /* Odak DOM'a yeni günün düğmesi çizildikten sonra, YALNIZ bu takvimin içinde. */
198
+ queueMicrotask(() => {
199
+ kok.current?.querySelector(`[data-gun="${hedef}"]`)?.focus();
200
+ });
201
+ };
202
+ /* Bir yönde ilk açık gün; 366 günde bulunamazsa yok. */
203
+ const kaydir = (d, adim) => {
204
+ let aday = d;
205
+ for (let i = 0; i < 366; i++) {
206
+ aday = gunKaydir(aday, adim);
207
+ if (!kapali(aday))
208
+ return aday;
209
+ }
210
+ return null;
211
+ };
212
+ const enYakinAcik = (d) => (!kapali(d) ? d : (kaydir(d, 1) ?? kaydir(d, -1)));
213
+ const tusla = (e) => {
214
+ if (!etkinOdak)
215
+ return;
216
+ const { y, m, d } = parcala(etkinOdak);
217
+ const haftaGunu = (new Date(Date.UTC(y, m, d)).getUTCDay() - first + 7) % 7;
218
+ const aySinirla = (yy, mm) => iso(yy, mm, Math.min(d, new Date(Date.UTC(yy, mm + 1, 0)).getUTCDate()));
219
+ const hedefler = {
220
+ ArrowRight: () => kaydir(etkinOdak, 1),
221
+ ArrowLeft: () => kaydir(etkinOdak, -1),
222
+ ArrowDown: () => kaydir(etkinOdak, 7),
223
+ ArrowUp: () => kaydir(etkinOdak, -7),
224
+ Home: () => enYakinAcik(gunKaydir(etkinOdak, -haftaGunu)),
225
+ End: () => enYakinAcik(gunKaydir(etkinOdak, 6 - haftaGunu)),
226
+ PageDown: () => enYakinAcik(m === 11 ? aySinirla(y + 1, 0) : aySinirla(y, m + 1)),
227
+ PageUp: () => enYakinAcik(m === 0 ? aySinirla(y - 1, 11) : aySinirla(y, m - 1)),
228
+ };
229
+ const hedef = hedefler[e.key];
230
+ if (!hedef)
231
+ return;
232
+ e.preventDefault();
233
+ git(hedef());
234
+ };
235
+ /* Ay düğmesi, o ay tümüyle aralığın dışındaysa kapanır. */
236
+ const oncekiKapali = min !== undefined && iso(view.y, view.m, 0) < min;
237
+ const sonrakiKapali = max !== undefined && iso(view.m === 11 ? view.y + 1 : view.y, (view.m + 1) % 12, 1) > max;
238
+ const satirlar = [];
239
+ for (let i = 0; i < cells.length; i += 7)
240
+ satirlar.push(cells.slice(i, i + 7));
241
+ return (_jsxs("div", { ref: kok, ...dataProps(rest), className: cn("w-70", className), children: [_jsxs("div", { className: "mb-3 flex items-center gap-2", children: [_jsx("button", { type: "button", className: "tamga-icon-btn", "aria-label": labels.previousMonth, disabled: oncekiKapali, onClick: () => setView((v) => (v.m === 0 ? { y: v.y - 1, m: 11 } : { ...v, m: v.m - 1 })), children: _jsx(Icon, { icon: CaretLeft, size: "xs" }) }), _jsx("span", { className: "flex-1 text-center text-body font-medium text-ink", children: monthName }), _jsx("button", { type: "button", className: "tamga-icon-btn", "aria-label": labels.nextMonth, disabled: sonrakiKapali, onClick: () => setView((v) => (v.m === 11 ? { y: v.y + 1, m: 0 } : { ...v, m: v.m + 1 })), children: _jsx(Icon, { icon: CaretRight, size: "xs" }) })] }), _jsxs("div", { role: "grid", "aria-label": monthName, className: "grid gap-px", onKeyDown: tusla, children: [_jsx("div", { role: "row", className: "grid grid-cols-7 gap-px", children: dayNames.map((d) => (_jsx("span", { role: "columnheader", className: "pb-1 text-center text-caption text-ink-faint", children: d }, d))) }), satirlar.map((satir, si) => (_jsx("div", { role: "row", className: "grid grid-cols-7 gap-px", children: satir.map((d, i) => {
242
+ if (d === null)
243
+ return _jsx("span", { role: "gridcell", "aria-hidden": "true" }, `x${i}`);
244
+ const date = iso(view.y, view.m, d);
245
+ const disi = kapali(date);
246
+ return (_jsx("button", { type: "button", role: "gridcell",
247
+ /* Seçili gün DOLGU alır: bir tarih bir değerdir, bir hedef değil;
248
+ checkbox ile aynı gerekçe (Yasa 2). */
249
+ className: "tamga-gun", "data-gun": date, "data-selected": isEdge(date), "data-today": date === bugun || undefined, "data-active": inRange(date) && !isEdge(date), "aria-selected": isEdge(date), "aria-label": tamTarih.format(new Date(`${date}T00:00:00Z`)), disabled: disi, tabIndex: date === etkinOdak ? 0 : -1, onFocus: () => setOdak(date), onClick: () => onSelect?.(date), children: d }, date));
250
+ }) }, si)))] })] }));
251
+ }
252
+ /* ── Ortak alan: salt okunur girdi + temizle/aç düğmeleri ── */
253
+ function Alan({ id, shown, placeholder, disabled, invalid, open, hasValue, labels, onToggle, onClear, }) {
254
+ return (_jsxs("span", { className: "relative flex items-center", children: [_jsx(Icon, { icon: CalendarPlus, size: "xs", className: "pointer-events-none absolute left-3 text-ink-faint" }), _jsx("input", { id: id, type: "text", readOnly: true, disabled: disabled, value: shown, placeholder: placeholder, onClick: () => !disabled && onToggle(), className: "tamga-input w-full cursor-pointer pr-16 pl-9", "aria-haspopup": "dialog", "aria-expanded": open, "aria-invalid": invalid || undefined }), _jsxs("span", { className: "absolute right-1.5 flex gap-0.5", children: [hasValue ? (_jsx("button", { type: "button", className: "tamga-mini-btn", "data-inset": "true", "aria-label": labels.clear, disabled: disabled, onClick: () => !disabled && onClear(), children: _jsx(Icon, { icon: Close, size: "xs" }) })) : null, _jsx("button", { type: "button", className: "tamga-mini-btn", "data-inset": "true", "aria-label": labels.open, disabled: disabled, onClick: () => !disabled && onToggle(), children: _jsx(Icon, { icon: CalendarPlus, size: "xs" }) })] })] }));
65
255
  }
66
256
  /**
67
257
  * Alan + açılan takvim.
@@ -70,25 +260,126 @@ export function Calendar({ locale, value, range, onSelect, labels, className, ..
70
260
  * demektir (`15/04/2026` · `04/15/2026` · `2026-04-15`) ve yanlış okunan bir
71
261
  * tarih sessizce yanlış veri üretir. Takvim tek doğru giriş yolu.
72
262
  */
73
- export function DatePicker({ locale, value, onChange, placeholder, labels, disabled = false, className, ...rest }) {
263
+ export function DatePicker({ id, locale, timeZone, value: hamDeger, onChange, placeholder, labels, min, max, invalid = false, disabled = false, className, ...rest }) {
74
264
  const [open, setOpen] = useState(false);
75
- /* TAKVİM DIŞARI TIKLAYINCA VE ESCAPE İLE KAPANIYOR, ve bir süre HİÇ
76
- kapanmıyordu: tek çıkış yolu bir tarih seçmekti, yani yanlışlıkla açan
77
- kişi ya bir tarih seçiyor ya da alanı yeniden tıklamayı buluyordu. Kutu
78
- tetiği de kapsıyor: tetiğe tıklama kendi anahtarına ulaşmalı, dışarı
79
- sayılmamalı. */
265
+ /* Takvim dışarı tıklayınca ve Escape ile kapanıyor; kutu tetiği de kapsıyor. */
80
266
  const kapat = useCallback(() => setOpen(false), []);
81
267
  const kutu = useDismiss(open, kapat);
268
+ const value = useGun(hamDeger, "value");
269
+ /* Gün UTC gece yarısı okunuyor (bkz. `DateISO`): tarayıcı dilimi günü kaydırmıyor. */
82
270
  const shown = value
83
- ? new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(new Date(`${value}T00:00:00Z`))
271
+ ? new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeZone: "UTC" }).format(new Date(`${value}T00:00:00Z`))
84
272
  : "";
85
- return (_jsxs("div", { ref: kutu, ...dataProps(rest), className: cn("relative", className), children: [_jsxs("span", { className: "relative flex items-center", children: [_jsx(Icon, { icon: CalendarPlus, size: "xs", className: "pointer-events-none absolute left-3 text-ink-faint" }), _jsx("input", { type: "text", readOnly: true, disabled: disabled, value: shown, placeholder: placeholder, onClick: () => !disabled && setOpen((v) => !v), className: "tamga-input w-full cursor-pointer pr-16 pl-9", "aria-haspopup": "dialog", "aria-expanded": open }), _jsxs("span", { className: "absolute right-1.5 flex gap-0.5", children: [value ? (_jsx("button", { type: "button", className: "tamga-mini-btn", "data-inset": "true", "aria-label": labels.clear, onClick: () => onChange?.(undefined), children: _jsx(Icon, { icon: Close, size: "xs" }) })) : null, _jsx("button", { type: "button", className: "tamga-mini-btn", "data-inset": "true", "aria-label": labels.open, onClick: () => setOpen((v) => !v), children: _jsx(Icon, { icon: CalendarPlus, size: "xs" }) })] })] }), open ? (_jsx("div", { className: "tamga-overlay absolute z-30 mt-2 p-3",
86
- /* TAKVİMİN TIKLAMASI SAYFAYA SIZMIYOR. Tüketen taraf alanı bir
87
- `<label>` ile sarınca (kitin `Field`i sarmıyor, elle yazılan sarıyor)
88
- takvimin boşluğuna her tıklama tarayıcı tarafından INPUT'A
89
- yönlendiriliyor, yani takvim kendi kendine açılıp kapanıyordu. */
90
- onClick: (e) => e.stopPropagation(), children: _jsx(Calendar, { locale: locale, value: value, labels: labels, onSelect: (d) => {
91
- onChange?.(d);
92
- setOpen(false);
93
- } }) })) : null] }));
273
+ return (_jsxs("div", { ref: kutu, ...dataProps(rest), className: cn("relative", className), children: [_jsx(Alan, { id: id, shown: shown, placeholder: placeholder, disabled: disabled, invalid: invalid, open: open, hasValue: Boolean(value), labels: labels, onToggle: () => setOpen((v) => !v), onClear: () => onChange?.(undefined) }), open ? (_jsx("div", { className: "tamga-overlay absolute z-30 mt-2 p-3", onClick: (e) => e.stopPropagation(), children: _jsx(Calendar, { locale: locale, timeZone: timeZone, value: value, min: min, max: max, labels: labels, onSelect: (d) => { onChange?.(d); setOpen(false); } }) })) : null] }));
274
+ }
275
+ /**
276
+ * Tarih + saat. AYRI BİR BİLEŞEN, `DatePicker`a bir prop değil: dönen değerin
277
+ * biçimi farklı (gün değil, dilimli bir an) ve bir prop'a göre tip değiştiren
278
+ * bir `onChange` çağıranı her kullanımda ikisini birden düşünmeye zorlardı.
279
+ *
280
+ * YAYILAN HER DEĞER [min, max] İÇİNDE: gün, saat, dakika ya da öğle değişince
281
+ * aday an sınırı deliyorsa en yakın geçerli saate kısılır ve seçimler ona
282
+ * çekilir. Gerekçe: docs/gerekce/01-form-ve-girdi.md
283
+ */
284
+ export function DateTimePicker({ id, locale, timeZone, value, onChange, placeholder, labels, min, max, minuteStep = 5, invalid = false, disabled = false, className, ...rest }) {
285
+ const tz = useMemo(() => dilim(timeZone), [timeZone]);
286
+ const [open, setOpen] = useState(false);
287
+ const kapat = useCallback(() => setOpen(false), []);
288
+ const kutu = useDismiss(open, kapat);
289
+ /* Sıfır ya da eksi adım sonsuz döngüydü; 1'e kısılıyor. */
290
+ const adim = Math.max(1, Math.floor(minuteStep) || 1);
291
+ const an = useMemo(() => anOku(value, "value"), [value]);
292
+ const w = an ? duvar(an, tz) : undefined;
293
+ const gun = w ? iso(w.y, w.m, w.d) : undefined;
294
+ const simdi = duvar(new Date(), tz);
295
+ /* Saat durumu değerden, değer yoksa şu andan: gün seçilir seçilmez anlamlı
296
+ bir saat çıksın, 00:00 değil. */
297
+ const [saat, setSaat] = useState(() => (w ?? simdi).h);
298
+ const [dakika, setDakika] = useState(() => (w ? w.mi : Math.floor(simdi.mi / adim) * adim));
299
+ useEffect(() => {
300
+ if (!w)
301
+ return;
302
+ setSaat(w.h);
303
+ setDakika(w.mi);
304
+ /* eslint-disable-next-line react-hooks/exhaustive-deps -- yalnız dışarıdan gelen değer */
305
+ }, [value, tz]);
306
+ const minAn = useMemo(() => anOku(min, "min"), [min]);
307
+ const maxAn = useMemo(() => anOku(max, "max"), [max]);
308
+ const minGun = minAn ? gunParcasi(minAn, tz) : undefined;
309
+ const maxGun = maxAn ? gunParcasi(maxAn, tz) : undefined;
310
+ /* Bir duvar saatinin [min, max] içindeki anları: dilimde var olan her aday
311
+ sayılır, yani belirsiz saatin iki yaşanışı da. */
312
+ const icinde = (t) => (!minAn || t.getTime() >= minAn.getTime()) && (!maxAn || t.getTime() <= maxAn.getTime());
313
+ const anlar = (g, h, mi) => {
314
+ const { y, m, d } = parcala(g);
315
+ return adaylar({ y, m, d, h, mi }, tz).filter(icinde);
316
+ };
317
+ const gecerli = (g, h, mi) => anlar(g, h, mi).length > 0;
318
+ /* Dakika ızgarası: adımın katları + (varsa) kayıtlı değerin ızgara dışı dakikası. */
319
+ const izgara = useMemo(() => {
320
+ const d = new Set();
321
+ for (let m = 0; m < 60; m += adim)
322
+ d.add(m);
323
+ if (w)
324
+ d.add(w.mi);
325
+ return [...d].sort((a, b) => a - b);
326
+ }, [adim, w?.mi]);
327
+ /* KISMA: istenen (saat, dakika) geçerli değilse ileri doğru ilk geçerli,
328
+ o da yoksa geri doğru ilk geçerli. Yayılan her değer aralık içinde. */
329
+ const kis = (g, h, mi) => {
330
+ if (gecerli(g, h, mi))
331
+ return { h, mi };
332
+ const adaylar = [];
333
+ for (let hh = 0; hh < 24; hh++)
334
+ for (const mm of izgara)
335
+ adaylar.push({ h: hh, mi: mm });
336
+ const sira = (a) => a.h * 60 + a.mi;
337
+ const istenen = h * 60 + mi;
338
+ return (adaylar.find((a) => sira(a) > istenen && gecerli(g, a.h, a.mi)) ??
339
+ [...adaylar].reverse().find((a) => sira(a) < istenen && gecerli(g, a.h, a.mi)) ??
340
+ null);
341
+ };
342
+ const yay = (g, h, mi) => {
343
+ if (!g)
344
+ return;
345
+ const k = kis(g, h, mi);
346
+ if (!k)
347
+ return;
348
+ setSaat(k.h);
349
+ setDakika(k.mi);
350
+ const secenekler = anlar(g, k.h, k.mi);
351
+ /* Belirsiz saatte dış değer kendi anını korur; aynı belirsiz saatin içinde
352
+ dakika değişince ofsetini korur (01:30-04:00 → 01:45-04:00); yoksa
353
+ sonraki (standart ofset). */
354
+ const belirsizde = an && w && adaylar(w, tz).length === 2 ? ofsetDk(an, tz) : undefined;
355
+ const secim = (an && secenekler.find((t) => t.getTime() === an.getTime())) ??
356
+ (belirsizde !== undefined ? secenekler.find((t) => ofsetDk(t, tz) === belirsizde) : undefined) ??
357
+ secenekler[secenekler.length - 1];
358
+ onChange?.(isoWithOffset(secim, tz));
359
+ };
360
+ /* Seçenekler: yalnız en az bir geçerli dakikası olan saatler, yalnız geçerli
361
+ dakikalar · artı kayıtlı değerin kendi saati ve dakikası, aralık dışında
362
+ kalsa da: kutu hep biçimli ve hep bir seçeneği gösteriyor. Gün yokken liste
363
+ tam, kutular kapalı: saat seçmek bugünü yayıyordu. */
364
+ const g = gun;
365
+ const saatler = open ? Array.from({ length: 24 }, (_, h) => h).filter((h) => !g || h === w?.h || izgara.some((mm) => gecerli(g, h, mm))) : [];
366
+ const dakikalar = open ? izgara.filter((mm) => !g || (w && saat === w.h && mm === w.mi) || gecerli(g, saat, mm)) : [];
367
+ /* 12/24 saat yerelin kararı; öğle sözcükleri Intl'den, yoksa labels'tan, o da
368
+ yoksa 24 saate düşülür · kit İngilizce yazmaz. */
369
+ const onIki = new Intl.DateTimeFormat(locale, { hour: "numeric" }).resolvedOptions().hour12 === true;
370
+ const donem = useMemo(() => {
371
+ if (!onIki)
372
+ return null;
373
+ const ad = (h) => new Intl.DateTimeFormat(locale, { hour: "numeric", hour12: true, timeZone: "UTC" })
374
+ .formatToParts(new Date(Date.UTC(2024, 0, 1, h)))
375
+ .find((p) => p.type === "dayPeriod")?.value;
376
+ const am = ad(9) ?? labels.am;
377
+ const pm = ad(21) ?? labels.pm;
378
+ return am && pm ? { am, pm } : null;
379
+ }, [locale, onIki, labels.am, labels.pm]);
380
+ const saatEtiketi = (h) => (donem ? String(h % 12 === 0 ? 12 : h % 12) : p2(h));
381
+ const shown = an ? new Intl.DateTimeFormat(locale, { dateStyle: "medium", timeStyle: "short", timeZone: tz }).format(an) : "";
382
+ return (_jsxs("div", { ref: kutu, ...dataProps(rest), className: cn("relative", className), children: [_jsx(Alan, { id: id, shown: shown, placeholder: placeholder, disabled: disabled, invalid: invalid, open: open, hasValue: Boolean(value), labels: labels, onToggle: () => setOpen((v) => !v), onClear: () => onChange?.(undefined) }), open ? (_jsxs("div", { className: "tamga-overlay absolute z-30 mt-2 p-3", onClick: (e) => e.stopPropagation(), children: [_jsx(Calendar, { locale: locale, timeZone: tz, value: gun, min: minGun, max: maxGun, labels: labels,
383
+ /* Gün seçilince takvim AÇIK KALIYOR: saat daha seçilecek. */
384
+ onSelect: (d) => yay(d, saat, dakika) }), _jsxs("div", { className: "mt-3 flex items-center gap-2 border-t border-line pt-3", children: [_jsx(Select, { "aria-label": labels.hour, placeholder: labels.hour, disabled: !g, value: String(saat), onChange: (v) => yay(g, Number(v), dakika), options: (donem ? saatler.filter((h) => (saat < 12 ? h < 12 : h >= 12)) : saatler).map((h) => ({ value: String(h), label: saatEtiketi(h) })) }), _jsx(Select, { "aria-label": labels.minute, placeholder: labels.minute, disabled: !g, value: String(dakika), onChange: (v) => yay(g, saat, Number(v)), options: dakikalar.map((m) => ({ value: String(m), label: p2(m) })) }), donem ? (_jsx(Select, { "aria-label": labels.period, placeholder: labels.period, disabled: !g, value: saat < 12 ? "am" : "pm", onChange: (v) => yay(g, v === "am" ? saat % 12 : (saat % 12) + 12, dakika), options: [{ value: "am", label: donem.am }, { value: "pm", label: donem.pm }] })) : null] })] })) : null] }));
94
385
  }
@@ -6,20 +6,55 @@ import type { IconGlyph } from "./icons.js";
6
6
  * Gerekçe: docs/gerekce/01-form-ve-girdi.md
7
7
  */
8
8
  /** Tek bir açılır bölüm. */
9
- export declare function Collapsible({ title, defaultOpen, icon, meta, className, children, ...rest }: {
10
- title: string;
9
+ export declare function Collapsible({ title, defaultOpen, open, onOpenChange, icon, meta, note, unmountOnClose, className, children, ...rest }: {
10
+ /**
11
+ * The head's text, or a node with text in it: "Accessibility · /pricing" with the path faint.
12
+ * It sits inside a `<button>`: no interactive or block elements in it. The accessible name is
13
+ * `title` and `meta` together. TR: Başlığın metni ya da içinde metin olan bir düğüm: yolu
14
+ * soluk "Erişilebilirlik · /fiyatlar". Bir `<button>`un içinde durur: içine etkileşimli ya da
15
+ * blok öğe konmaz. Erişilebilir ad `title` ve `meta` birlikte.
16
+ */
17
+ title: ReactNode;
11
18
  /**
12
19
  * The glyph at the head of the row, in the accent. It says what KIND of section this is before
13
20
  * the words are read. TR: Satırın başındaki glif, vurgu renginde. Sözcükler okunmadan önce bu
14
21
  * bölümün NE TÜR bir bölüm olduğunu söylüyor.
15
22
  */
16
23
  icon?: IconGlyph;
24
+ /** The starting state when the section keeps its own. Ignored once `open` is given. TR: Bölüm durumunu kendi tutuyorsa başlangıç. `open` verilince yok sayılır. */
17
25
  defaultOpen?: boolean;
26
+ /**
27
+ * Given, the section is controlled: this is the open state, and a click only reports through
28
+ * `onOpenChange` · the product decides, the way it decides whether to fetch when a row opens.
29
+ * Absent, the section keeps the state itself. React's own controlled/uncontrolled contract.
30
+ * TR: Verilirse bölüm kontrollü: açık durum budur, tık yalnız `onOpenChange` ile haber verir ·
31
+ * satır açılınca veri çekilip çekilmeyeceğine karar verdiği gibi kararı ürün verir. Verilmezse
32
+ * bölüm durumu kendi tutar. React'in kontrollü/kontrolsüz sözleşmesi.
33
+ */
34
+ open?: boolean;
35
+ /** Fires with the next state on click and keyboard, in both modes. TR: Tık ve klavyede sıradaki durumla ateşlenir, iki modda da. */
36
+ onOpenChange?: (open: boolean) => void;
18
37
  /**
19
38
  * The secondary text to the right of the title: a count, a state. TR: Başlığın sağındaki
20
39
  * ikincil metin: sayı, durum.
21
40
  */
22
41
  meta?: ReactNode;
42
+ /**
43
+ * A quiet line that stays visible when the section is CLOSED, between the head and the body,
44
+ * inside the same frame: why a measurement did not count, when it last ran. `children` hide;
45
+ * this does not. TR: Bölüm KAPALIYKEN de görünen sessiz satır, başlıkla gövde arasında, aynı
46
+ * çerçevede: bir ölçümün neden sayılmadığı, en son ne zaman koştuğu. `children` gizlenir; bu
47
+ * gizlenmez.
48
+ */
49
+ note?: ReactNode;
50
+ /**
51
+ * Off (default), the body stays in the DOM and is `hidden` when closed, so a search finds it and
52
+ * its state survives. On, the body is not rendered while closed · for a body that is heavy to
53
+ * mount or fetches on its own. TR: Kapalıyken (varsayılan) gövde DOM'da durur ve `hidden`dır;
54
+ * arama bulur, durumu yaşar. Açıkken gövde kapalıyken hiç çizilmez · kurulması ağır ya da kendi
55
+ * başına veri çeken bir gövde için.
56
+ */
57
+ unmountOnClose?: boolean;
23
58
  className?: string;
24
59
  children: ReactNode;
25
60
  /** `data-*` hooks pass through. TR: `data-*` kancaları geçiyor. */
@@ -1 +1 @@
1
- {"version":3,"file":"disclosure.d.ts","sourceRoot":"","sources":["../../src/components/disclosure.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C;;;;GAIG;AAEH,4BAA4B;AAC5B,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,WAAmB,EACnB,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,GAAG,IAAI,EACR,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;IACpB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BA4CA;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EACxB,IAAc,EACd,SAAS,EACT,QAAQ,EACR,GAAG,IAAI,EACR,EAAE;IACD;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;IACpB,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BASA"}
1
+ {"version":3,"file":"disclosure.d.ts","sourceRoot":"","sources":["../../src/components/disclosure.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C;;;;GAIG;AAEH,4BAA4B;AAC5B,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,WAAmB,EACnB,IAAI,EACJ,YAAY,EACZ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,cAAsB,EACtB,SAAS,EACT,QAAQ,EACR,GAAG,IAAI,EACR,EAAE;IACD;;;;;;OAMG;IACH,KAAK,EAAE,SAAS,CAAC;IACjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,mKAAmK;IACnK,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,oIAAoI;IACpI,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;IACpB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BA6DA;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EACxB,IAAc,EACd,SAAS,EACT,QAAQ,EACR,GAAG,IAAI,EACR,EAAE;IACD;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;IACpB,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BASA"}
@@ -11,10 +11,20 @@ import { CaretRight } from "./icons.js";
11
11
  * Gerekçe: docs/gerekce/01-form-ve-girdi.md
12
12
  */
13
13
  /** Tek bir açılır bölüm. */
14
- export function Collapsible({ title, defaultOpen = false, icon, meta, className, children, ...rest }) {
14
+ export function Collapsible({ title, defaultOpen = false, open, onOpenChange, icon, meta, note, unmountOnClose = false, className, children, ...rest }) {
15
15
  const id = useId();
16
- const [open, setOpen] = useState(defaultOpen);
17
- return (_jsxs("div", { ...dataProps(rest), className: cn("tamga-collapsible", className), "data-open": open || undefined, children: [_jsxs("button", { type: "button", className: "tamga-collapsible-head", "aria-expanded": open, "aria-controls": id, onClick: () => setOpen((v) => !v), children: [icon ? _jsx(Icon, { icon: icon, size: "base", className: "shrink-0 text-accent" }) : null, _jsx("span", { className: "min-w-0 flex-1 text-body font-bold text-ink", children: title }), meta ? _jsx("span", { className: "text-small text-ink-faint", children: meta }) : null, _jsx(Icon, { icon: CaretRight, size: "xs", weight: "bold", className: "shrink-0 transition-transform", style: { transform: open ? "rotate(90deg)" : undefined } })] }), _jsx("div", { id: id, hidden: !open, className: "tamga-collapsible-body", "data-indent": icon ? "true" : undefined, children: children })] }));
16
+ /* KONTROLLÜ Mİ: `open` verildiyse. İkisi birden verildiğinde `open` kazanır,
17
+ `defaultOpen` yalnız ilk çizimde bile okunmaz · React'in kalıbı. */
18
+ const kontrollu = open !== undefined;
19
+ const [ic, setIc] = useState(defaultOpen);
20
+ const acik = kontrollu ? open : ic;
21
+ const degistir = () => {
22
+ const sonraki = !acik;
23
+ onOpenChange?.(sonraki);
24
+ if (!kontrollu)
25
+ setIc(sonraki);
26
+ };
27
+ return (_jsxs("div", { ...dataProps(rest), className: cn("tamga-collapsible", className), "data-open": acik || undefined, children: [_jsxs("button", { type: "button", className: "tamga-collapsible-head", "aria-expanded": acik, "aria-controls": unmountOnClose && !acik ? undefined : id, "aria-describedby": note ? `${id}-not` : undefined, onClick: degistir, children: [icon ? _jsx(Icon, { icon: icon, size: "base", className: "shrink-0 text-accent" }) : null, _jsx("span", { className: "min-w-0 flex-1 text-body font-bold text-ink", children: title }), meta ? _jsx("span", { className: "text-small text-ink-faint", children: meta }) : null, _jsx(Icon, { icon: CaretRight, size: "xs", weight: "bold", className: "tamga-collapsible-caret shrink-0", style: { transform: acik ? "rotate(90deg)" : undefined } })] }), note ? (_jsx("div", { id: `${id}-not`, className: "tamga-collapsible-note", "data-indent": icon ? "true" : undefined, children: note })) : null, unmountOnClose && !acik ? null : (_jsx("div", { id: id, hidden: !acik, className: "tamga-collapsible-body", "data-indent": icon ? "true" : undefined, children: children }))] }));
18
28
  }
19
29
  /**
20
30
  * Açılır bölümler grubu.
@@ -140,12 +140,19 @@ export declare function Kbd({ children, inline, className, }: {
140
140
  className?: string;
141
141
  }): import("react").JSX.Element;
142
142
  /**
143
- * Sayaç rozeti: bir ikonun köşesindeki SAYI (`StatusChip` bir DURUM taşır).
144
- * `max` üstünde "+" ile kesiliyor, yoksa dört hane kutuyu şişirip altındaki
145
- * ikonu eziyor. Sıfır gösterilmiyor.
146
- *
147
- * Doküman: /docs/badge
143
+ * Kullanıcının kendi rengi için küçük işaret · Yasa 3'ün yazılı istisnası
144
+ * (bkz. `Tag swatch`). Tek başına dışa açık: tıklanabilir bir öneri satırı
145
+ * işareti bir `Button`un içine koyar, `Tag`i değil · kutu içinde kutu olmaz.
146
+ * Geçersiz renk (hex değil) HİÇ çizilmez: style'a kullanıcı verisi yalnız
147
+ * doğrulanmış bir hex olarak girer.
148
148
  */
149
+ export declare function ColorMark({ color, className, ...rest }: {
150
+ /** A hex colour (`#rgb`, `#rgba`, `#rrggbb`, `#rrggbbaa`). Anything else draws nothing. TR: Bir hex renk. Başka her şey hiçbir şey çizmez. */
151
+ color: string;
152
+ className?: string;
153
+ /** `data-*` hooks pass through. TR: `data-*` kancaları geçiyor. */
154
+ [k: `data-${string}`]: unknown;
155
+ }): import("react").JSX.Element | null;
149
156
  /**
150
157
  * Etiket rozeti · bir özelliğin durumu: BETA, YENİ, PRO.
151
158
  *
@@ -156,8 +163,23 @@ export declare function Kbd({ children, inline, className, }: {
156
163
  *
157
164
  * Gerekçe: docs/gerekce/06-isaret-ve-ton.md
158
165
  */
159
- export declare function Tag({ children, look, className, ...rest }: {
166
+ export declare function Tag({ children, look, swatch, className, ...rest }: {
160
167
  children: ReactNode;
168
+ /**
169
+ * The user's own colour for the label, as a hex (`#rrggbb`; `#rgb`, `#rgba`, `#rrggbbaa` too).
170
+ * Anything else draws no mark: user data reaches `style` only as a validated hex. A small mark before the text, nothing
171
+ * more: not a ground, not a text colour, and `aria-hidden` · the name carries the meaning, the
172
+ * colour is an identity mark. This is the one WRITTEN exception to Law 3 (colour is for
173
+ * deviation and interaction): the kit says nothing with it, it only carries the user's data.
174
+ * Never for status or severity · that is `StatusChip`. TR: Kullanıcının etikete verdiği renk,
175
+ * yalnız hex (`#rrggbb`; `#rgb`, `#rgba`, `#rrggbbaa` da); başka biçim hiç çizilmez,
176
+ * kullanıcı verisi `style`'a yalnız doğrulanmış hex olarak girer. Metnin önünde küçük bir
177
+ * işaret, fazlası değil: zemin değil, metin
178
+ * rengi değil, ve `aria-hidden` · anlamı ad taşıyor, renk bir kimlik işareti. Yasa 3'ün
179
+ * (renk sapma ve etkileşim içindir) tek YAZILI istisnası: kit bununla bir şey söylemiyor,
180
+ * yalnız kullanıcının verisini taşıyor. Durum ya da önem için asla · o `StatusChip`.
181
+ */
182
+ swatch?: string;
161
183
  /**
162
184
  * `dashed` not real yet (beta, coming), `solid` the loudest one, for what is new right now,
163
185
  * `outline` the quiet standing fact (a plan name, a tier). TR: `dashed` henüz gerçek değil
@@ -169,6 +191,13 @@ export declare function Tag({ children, look, className, ...rest }: {
169
191
  /** `data-*` hooks pass through. TR: `data-*` kancaları geçiyor. */
170
192
  [k: `data-${string}`]: unknown;
171
193
  }): import("react").JSX.Element;
194
+ /**
195
+ * Sayaç rozeti: bir ikonun köşesindeki SAYI (`StatusChip` bir DURUM taşır).
196
+ * `max` üstünde "+" ile kesiliyor, yoksa dört hane kutuyu şişirip altındaki
197
+ * ikonu eziyor. Sıfır gösterilmiyor.
198
+ *
199
+ * Doküman: /docs/badge
200
+ */
172
201
  export declare function Badge({ count, max, tone, dot, label, className, children, ...rest }: {
173
202
  /** The number. Not needed when `dot` is set. TR: Sayı. `dot` verildiğinde gerekmiyor. */
174
203
  count?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../src/components/display.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../src/components/display.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGpE,OAAO,KAAK,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAElE,OAAO,EAA4B,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAEzE,OAAO,EAAU,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAK9C;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,MAAe,EACf,KAAa,EACb,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD,KAAK,EAAE,SAAS,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,SAAS,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;IACjG;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAuCA;AAED;;;;;;GAMG;AACH,wBAAgB,GAAG,CAAC,EAClB,KAAK,EACL,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,MAAa,EACb,KAAK,EACL,IAAa,EACb,IAAI,EACJ,OAAO,EACP,OAAO,EACP,QAAQ,EACR,aAAa,EAAE,IAAkB,EACjC,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0HAA0H;IAC1H,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6FAA6F;IAC7F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,MAAM,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IACvB,sFAAsF;IACtF,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IACzB,uGAAuG;IACvG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2GAA2G;IAC3G,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,qFAAqF;IACrF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,gJAAgJ;IAChJ,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAqHA;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAA;CAAE,+BAMpI;AAED;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAC,EACnB,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAmDA;AAED;;;;;GAKG;AACH,wBAAgB,GAAG,CAAC,EAClB,QAAQ,EACR,MAAc,EACd,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BAEA;AAKD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD,8IAA8I;IAC9I,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,sCAGA;AAED;;;;;;;;;GASG;AACH,wBAAgB,GAAG,CAAC,EAClB,QAAQ,EACR,IAAgB,EAChB,MAAM,EACN,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAmBA;AAED;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,GAAQ,EACR,IAAe,EACf,GAAW,EACX,KAAK,EACL,SAAS,EACT,QAAQ,EACR,GAAG,IAAI,EACR,EAAE;IACD,yFAAyF;IACzF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAsCA;AAED;;;;GAIG;AACH,MAAM,MAAM,IAAI,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5E;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,OAAO,EACP,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD;;;;;OAKG;IACH,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IACvB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAyCA;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,MAAqC,EACrC,QAAc,EACd,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAsCA"}