tamga-ui 0.5.4 → 0.5.6

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 CHANGED
@@ -5,6 +5,73 @@ Versions follow [semver](https://semver.org/). Through `0.x`, breaking changes m
5
5
 
6
6
  > 🇹🇷 Türkçe için [tamga.org.tr/tr](https://tamga.org.tr/tr).
7
7
 
8
+ ## 0.5.6
9
+
10
+ > A calendar can be closed, a chosen file reaches the screen that asked for it, and the rail
11
+ > answers the mouse.
12
+
13
+ ### Added
14
+
15
+ - **`FilterBar.onFile`** · the file itself, and `null` when it is removed. The drawer's file
16
+ section let someone pick a file and then dropped it: `values` holds strings, so only the NAME
17
+ was ever written, and the thing the screen has to parse or upload existed nowhere. One product
18
+ had already moved its import button out of the drawer because of this. The name still lands in
19
+ `values[fileSearchKey]`, so the chip is unchanged.
20
+
21
+ ### Changed
22
+
23
+ - **`FilterBar` no longer names file formats; `fileAccept` does.** The picker hardcoded
24
+ `.xlsx,.xls,.csv`, which is one product's vocabulary living in a library: the same drawer may
25
+ want a photo or a PDF. Pass `fileAccept` to get the old behaviour back.
26
+
27
+ ### Fixed
28
+
29
+ - **`DatePicker` closes on an outside click and on Escape.** The only way out of an open calendar
30
+ was to pick a date: someone who opened it by accident either chose a date they did not want or
31
+ discovered that clicking the field again closed it. The kit already had the dismissal the other
32
+ overlays use, and this one component never called it.
33
+
34
+ - **A click inside the calendar no longer escapes to the page.** Wrap the field in a `<label>`, the
35
+ way a form usually is, and every click on the calendar's own padding was forwarded by the browser
36
+ to the labelled input, which toggled the calendar underneath the pointer. The kit's own `Field`
37
+ points at its control rather than wrapping it, so this only ever bit hand written markup, and it
38
+ bit it silently.
39
+
40
+ - **A rail row without an address now shows a pointer.** `.tamga-rail-link` left the cursor to the
41
+ browser: a row carrying `href` is an `<a>` and gets the pointing hand for free, while the same row
42
+ in a shell whose screens are state is a `<button>` and kept the arrow. One control, two cursors,
43
+ and every such product patched it from the outside.
44
+
45
+ - **A narrow rail shows where one group ends and the next begins.** `NavEntry.section` drew its
46
+ heading only on a wide rail, which is right — a heading is unreadable in a 40px box — but nothing
47
+ took its place, so a rail that narrowed turned "start" and the three tools into one undivided
48
+ column. The group change is now a line, the same divider the brand mark already sits above.
49
+
50
+ ## 0.5.5
51
+
52
+ > A page title finds its size, a shell can be driven by state instead of addresses, and the
53
+ > current rail row stands on the brand.
54
+
55
+ ### Added
56
+
57
+ - **`AppShell` entries can carry an action instead of an address.** `NavEntry.href` was required and
58
+ the active row was found by comparing paths, which is right for a web panel and wrong for a
59
+ desktop app, where a screen is state and there is no URL. An entry may now give `onSelect`, and
60
+ `activePath` is then matched against its `key`. One of the two is required; nothing changes for an
61
+ entry that has a path.
62
+
63
+ - **`AppShell.mainClassName`** — a state class on the content surface, for something the shell
64
+ cannot know: a window-wide drop target marking its edge, say. Layout stays the kit's; without it
65
+ a product had to draw the whole shell by hand to reach that one edge.
66
+
67
+ ### Changed
68
+
69
+ - **A page title is 24px, not 40px.** `PageBand` drew its heading at `--text-display-lg`, which is
70
+ the reference design's own size for a marketing-width page. In a dense panel — a table under the
71
+ title, a filter bar above it — it took the room the data needed and read as a banner rather than a
72
+ heading. The scale now reads 16 section · 18 dialog · 24 page · 30 KPI, and the two token comments
73
+ that still called 18px "page titles" and 30px "KPI numbers only" were corrected with it.
74
+
8
75
  ## 0.5.4
9
76
 
10
77
  > An empty filter drawer no longer advertises itself, and a tile's icon reads as a glyph.
@@ -127,11 +127,33 @@ export type FilterBarProps = {
127
127
  searchKey?: string;
128
128
  /** The key for search-by-file if this screen has it; without it the section is not drawn. TR: Dosyayla arama bu ekranda varsa anahtarı; yoksa bölüm hiç çizilmiyor. */
129
129
  fileSearchKey?: string;
130
+ /**
131
+ * The chosen FILE, and `null` when it is removed. TR: Seçilen DOSYANIN kendisi, kaldırılınca
132
+ * `null`.
133
+ *
134
+ * `values` holds strings, so the file section could only ever write the file's NAME there, and
135
+ * the thing the screen has to read, parse or upload existed nowhere. Given this, the name still
136
+ * lands in `values[fileSearchKey]` for the chip; the `File` comes here. TR: `values` dizgi
137
+ * tutuyor, yani dosya bölümü oraya ancak dosyanın ADINI yazabiliyordu ve ekranın okuyacağı,
138
+ * ayrıştıracağı ya da göndereceği şey hiçbir yerde yoktu. Verildiğinde ad yine çipe gidiyor,
139
+ * `File` buraya geliyor.
140
+ */
141
+ onFile?: (file: File | null) => void;
142
+ /**
143
+ * What the picker accepts: `".xlsx,.csv"`, `"image/*"`. TR: Seçicinin kabul ettiği tür:
144
+ * `".xlsx,.csv"`, `"image/*"`.
145
+ *
146
+ * The kit named the formats itself for a while (`.xlsx,.xls,.csv`), which is a product's
147
+ * vocabulary living in a library: the same drawer may want a photo or a PDF. TR: Kit bir süre
148
+ * türleri kendi sayıyordu; o bir ürünün sözlüğünün kütüphanede yaşamasıdır · aynı çekmece bir
149
+ * fotoğraf ya da PDF de isteyebilir.
150
+ */
151
+ fileAccept?: string;
130
152
  /** A screen-specific button on the filter row, beside "All filters". TR: Filtre satırına, "Tüm filtreler"in yanına giren ekrana özel düğme. */
131
153
  extra?: ReactNode;
132
154
  /** For `DatePicker`'s calendar: "tr-TR", "en-GB". TR: `DatePicker`ın takvimi için: "tr-TR", "en-GB". */
133
155
  locale?: string;
134
156
  labels: FilterBarLabels;
135
157
  };
136
- export declare function FilterBar({ values, onChange, top, drawer, optionSource, searchKey, fileSearchKey, extra, locale, labels, }: FilterBarProps): import("react").JSX.Element;
158
+ export declare function FilterBar({ values, onChange, top, drawer, optionSource, searchKey, fileSearchKey, onFile, fileAccept, extra, locale, labels, }: FilterBarProps): import("react").JSX.Element;
137
159
  //# sourceMappingURL=filter-bar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"filter-bar.d.ts","sourceRoot":"","sources":["../../src/blocks/filter-bar.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"filter-bar.d.ts","sourceRoot":"","sources":["../../src/blocks/filter-bar.tsx"],"names":[],"mappings":"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"}
@@ -46,7 +46,7 @@ function FieldControl({ field, values, write, optionSource, locale, labels, }) {
46
46
  }
47
47
  return (_jsx(Input, { full: true, value: values[field.key] ?? "", onChange: (e) => write(field.key, e.target.value) }));
48
48
  }
49
- export function FilterBar({ values, onChange, top, drawer, optionSource = {}, searchKey = "q", fileSearchKey, extra, locale = "en-GB", labels, }) {
49
+ export function FilterBar({ values, onChange, top, drawer, optionSource = {}, searchKey = "q", fileSearchKey, onFile, fileAccept, extra, locale = "en-GB", labels, }) {
50
50
  const [drawerOpen, setDrawerOpen] = useState(false);
51
51
  const formId = useId();
52
52
  const active = Object.entries(values).filter(([, v]) => v);
@@ -78,5 +78,14 @@ export function FilterBar({ values, onChange, top, drawer, optionSource = {}, se
78
78
  return (_jsxs("div", { className: "tamga-card tamga-card-open flex flex-col gap-3.5 p-4", children: [_jsxs("div", { className: "tamga-filter-row", children: [_jsxs("label", { className: "flex min-w-0 shrink grow-[2] basis-75 flex-col gap-1.5", children: [_jsx("span", { className: "text-small font-bold text-ink-faint", children: labels.search }), _jsxs("span", { className: "relative flex items-center", children: [_jsx(Icon, { icon: Search, size: "xs", "aria-hidden": true, className: "pointer-events-none absolute left-2.5 text-ink-faint" }), _jsx(Input, { type: "search", full: true, leading: true, placeholder: labels.search, value: values[searchKey] ?? "", onChange: (e) => write(searchKey, e.target.value) })] })] }), top.map((field) => (_jsxs(Fragment, { children: [field.break ? _jsx("span", { "aria-hidden": true, className: "h-0 basis-full" }) : null, _jsxs("div", { className: `flex min-w-0 shrink grow flex-col gap-1.5 ${field.kind === "dateRange" ? "basis-80" : "basis-40 tamga-filter-cap"}`, children: [_jsx("span", { className: "text-small font-bold text-ink-faint", children: field.label }), _jsx(FieldControl, { field: field, values: values, write: write, optionSource: optionSource, locale: locale, labels: labels })] })] }, field.key))), drawer.length > 0 && (_jsxs(Button, { className: "ml-auto", onClick: () => setDrawerOpen(true), children: [_jsx(Icon, { icon: Customize, size: "xs" }), labels.allFilters, hiddenActive > 0 && (_jsx("span", { className: "tamga-count ml-1 tabular-nums", children: hiddenActive }))] })), extra] }), active.length > 0 && (_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [active.map(([key, value]) => (_jsxs("span", { className: "tamga-token", children: [_jsxs("span", { className: "font-normal text-ink-faint", children: [labelFor(key), ":"] }), value, _jsx("button", { type: "button", className: "tamga-token-x", "aria-label": labels.remove(labelFor(key)), onClick: () => write(key, ""), children: _jsx(Icon, { icon: Close, size: "xs" }) })] }, key))), _jsx(Button, { variant: "link", size: "sm", onClick: () => onChange({}), children: labels.clearAll })] })), _jsx(Sheet, { open: drawerOpen, onClose: () => setDrawerOpen(false), title: labels.allFilters, closeLabel: labels.calendar.clear, footer: _jsxs(_Fragment, { children: [_jsx(Button, { type: "button", onClick: () => onChange({}), children: labels.clear }), _jsx(Button, { type: "submit", form: formId, variant: "primary", children: labels.apply })] }), children: _jsxs("form", { id: formId, onSubmit: (e) => {
79
79
  e.preventDefault();
80
80
  setDrawerOpen(false);
81
- }, className: "flex flex-col", children: [drawer.map((group) => (_jsxs("div", { className: "flex flex-col gap-3.5 border-b border-dashed border-line py-4.5 last:border-b-0", children: [_jsx("p", { className: "text-caption font-extrabold uppercase tracking-label text-ink-faint", children: group.title }), _jsx("div", { className: "grid gap-3 sm:grid-cols-[repeat(2,minmax(0,1fr))]", children: group.fields.map((field) => (_jsxs("div", { className: `flex flex-col gap-1.5 ${field.kind === "dateRange" ? "sm:col-span-2" : ""}`, children: [_jsx("span", { className: "text-small text-ink-soft", children: field.label }), _jsx(FieldControl, { field: field, values: values, write: write, optionSource: optionSource, locale: locale, labels: labels })] }, field.key))) })] }, group.title))), fileSearchKey && labels.fileSearch && (_jsxs("div", { children: [_jsx("p", { className: "mb-3 text-micro font-semibold uppercase tracking-wide text-ink-faint", children: labels.fileSearch.title }), _jsx("p", { className: "mb-3 text-small leading-relaxed text-ink-soft", children: labels.fileSearch.help }), values[fileSearchKey] ? (_jsxs("span", { className: "flex items-center gap-2", children: [_jsx("span", { className: "truncate text-small text-ink", children: values[fileSearchKey] }), _jsx(Button, { type: "button", size: "sm", onClick: () => write(fileSearchKey, ""), children: labels.fileSearch.remove })] })) : (_jsxs("label", { className: `${buttonVariants({})} cursor-pointer`, children: [_jsx(Icon, { icon: Upload, size: "xs" }), labels.fileSearch.choose, _jsx("input", { type: "file", accept: ".xlsx,.xls,.csv", className: "sr-only", onChange: (e) => write(fileSearchKey, e.target.files?.[0]?.name ?? "") })] }))] }))] }) })] }));
81
+ }, className: "flex flex-col", children: [drawer.map((group) => (_jsxs("div", { className: "flex flex-col gap-3.5 border-b border-dashed border-line py-4.5 last:border-b-0", children: [_jsx("p", { className: "text-caption font-extrabold uppercase tracking-label text-ink-faint", children: group.title }), _jsx("div", { className: "grid gap-3 sm:grid-cols-[repeat(2,minmax(0,1fr))]", children: group.fields.map((field) => (_jsxs("div", { className: `flex flex-col gap-1.5 ${field.kind === "dateRange" ? "sm:col-span-2" : ""}`, children: [_jsx("span", { className: "text-small text-ink-soft", children: field.label }), _jsx(FieldControl, { field: field, values: values, write: write, optionSource: optionSource, locale: locale, labels: labels })] }, field.key))) })] }, group.title))), fileSearchKey && labels.fileSearch && (_jsxs("div", { children: [_jsx("p", { className: "mb-3 text-micro font-semibold uppercase tracking-wide text-ink-faint", children: labels.fileSearch.title }), _jsx("p", { className: "mb-3 text-small leading-relaxed text-ink-soft", children: labels.fileSearch.help }), values[fileSearchKey] ? (_jsxs("span", { className: "flex items-center gap-2", children: [_jsx("span", { className: "truncate text-small text-ink", children: values[fileSearchKey] }), _jsx(Button, { type: "button", size: "sm", onClick: () => {
82
+ write(fileSearchKey, "");
83
+ onFile?.(null);
84
+ }, children: labels.fileSearch.remove })] })) : (_jsxs("label", { className: `${buttonVariants({})} cursor-pointer`, children: [_jsx(Icon, { icon: Upload, size: "xs" }), labels.fileSearch.choose, _jsx("input", { type: "file", accept: fileAccept, className: "sr-only", onChange: (e) => {
85
+ /* AD ÇİPE, DOSYA ÇAĞIRANA: ikisi ayrı şey ve blok bir
86
+ süre yalnız birincisini veriyordu. */
87
+ const dosya = e.target.files?.[0] ?? null;
88
+ write(fileSearchKey, dosya?.name ?? "");
89
+ onFile?.(dosya);
90
+ } })] }))] }))] }) })] }));
82
91
  }
@@ -18,4 +18,12 @@ export declare function useListKeys({ open, containerRef, onClose, }: {
18
18
  containerRef: React.RefObject<HTMLElement | null>;
19
19
  onClose: () => void;
20
20
  }): void;
21
+ /**
22
+ * Closes a popup when the pointer goes down outside it, or on Escape.
23
+ *
24
+ * Shared, because an overlay nobody can dismiss is a trap rather than a style:
25
+ * `DatePicker` kept its own open state and had none of this. The returned ref
26
+ * marks what counts as "inside", and that includes the trigger.
27
+ */
28
+ export declare function useDismiss<T extends HTMLElement = HTMLDivElement>(open: boolean, close: () => void): import("react").RefObject<T | null>;
21
29
  //# sourceMappingURL=a11y.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"a11y.d.ts","sourceRoot":"","sources":["../../src/components/a11y.ts"],"names":[],"mappings":"AAkCA;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,WAAW,EAAE,IAAI,EAAE,OAAO,uCA0DhE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,YAAY,EACZ,OAAO,GACR,EAAE;IACD,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAClD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,QA0DA"}
1
+ {"version":3,"file":"a11y.d.ts","sourceRoot":"","sources":["../../src/components/a11y.ts"],"names":[],"mappings":"AAkCA;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,WAAW,EAAE,IAAI,EAAE,OAAO,uCA0DhE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,YAAY,EACZ,OAAO,GACR,EAAE;IACD,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAClD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,QA0DA;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,WAAW,GAAG,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,uCAgBlG"}
@@ -152,3 +152,29 @@ export function useListKeys({ open, containerRef, onClose, }) {
152
152
  return () => root.removeEventListener("keydown", onKey);
153
153
  }, [open, containerRef, onClose]);
154
154
  }
155
+ /**
156
+ * Closes a popup when the pointer goes down outside it, or on Escape.
157
+ *
158
+ * Shared, because an overlay nobody can dismiss is a trap rather than a style:
159
+ * `DatePicker` kept its own open state and had none of this. The returned ref
160
+ * marks what counts as "inside", and that includes the trigger.
161
+ */
162
+ export function useDismiss(open, close) {
163
+ const box = useRef(null);
164
+ useEffect(() => {
165
+ if (!open)
166
+ return;
167
+ const away = (e) => {
168
+ if (box.current && !box.current.contains(e.target))
169
+ close();
170
+ };
171
+ const esc = (e) => e.key === "Escape" && close();
172
+ document.addEventListener("mousedown", away);
173
+ document.addEventListener("keydown", esc);
174
+ return () => {
175
+ document.removeEventListener("mousedown", away);
176
+ document.removeEventListener("keydown", esc);
177
+ };
178
+ }, [open, close]);
179
+ return box;
180
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../src/components/date-picker.tsx"],"names":[],"mappings":"AAQA;;;;GAIG;AAEH,0CAA0C;AAC1C,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAE7B,MAAM,MAAM,SAAS,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,EAAE,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAgCzD,wBAAgB,QAAQ,CAAC,EACvB,MAAM,EACN,KAAK,EACL,KAAK,EACL,QAAQ,EACR,MAAM,EACN,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,MAAM,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAmFA;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,QAAQ,EACR,WAAW,EACX,MAAM,EACN,QAAgB,EAChB,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,KAAK,IAAI,CAAC;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BA0DA"}
1
+ {"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../src/components/date-picker.tsx"],"names":[],"mappings":"AASA;;;;GAIG;AAEH,0CAA0C;AAC1C,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAE7B,MAAM,MAAM,SAAS,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,EAAE,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAgCzD,wBAAgB,QAAQ,CAAC,EACvB,MAAM,EACN,KAAK,EACL,KAAK,EACL,QAAQ,EACR,MAAM,EACN,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,MAAM,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAmFA;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,QAAQ,EACR,WAAW,EACX,MAAM,EACN,QAAgB,EAChB,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,KAAK,IAAI,CAAC;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAClF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAwEA"}
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useMemo, useState } from "react";
3
+ import { useCallback, useMemo, useState } from "react";
4
+ import { useDismiss } from "./a11y.js";
4
5
  import { cn } from "../lib/cn.js";
5
6
  import { dataProps } from "../lib/data-props.js";
6
7
  import { Icon } from "./icon.js";
@@ -71,10 +72,22 @@ export function Calendar({ locale, value, range, onSelect, labels, className, ..
71
72
  */
72
73
  export function DatePicker({ locale, value, onChange, placeholder, labels, disabled = false, className, ...rest }) {
73
74
  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ı. */
80
+ const kapat = useCallback(() => setOpen(false), []);
81
+ const kutu = useDismiss(open, kapat);
74
82
  const shown = value
75
83
  ? new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(new Date(`${value}T00:00:00Z`))
76
84
  : "";
77
- return (_jsxs("div", { ...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", children: _jsx(Calendar, { locale: locale, value: value, labels: labels, onSelect: (d) => {
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) => {
78
91
  onChange?.(d);
79
92
  setOpen(false);
80
93
  } }) })) : null] }));
@@ -78,7 +78,7 @@ export function CellActions({ className, children, align = "end", ...props
78
78
  * Doküman: /docs/page-band
79
79
  */
80
80
  export function PageBand({ eyebrow, title, subtitle, actions, className, ...rest }) {
81
- return (_jsxs("div", { ...dataProps(rest), className: cn("flex flex-wrap items-end gap-4", className), children: [_jsxs("div", { className: "min-w-0 flex-1 basis-65", children: [eyebrow ? (_jsx("p", { className: "mb-1.5 text-small font-semibold text-ink-faint", children: eyebrow })) : null, _jsx("h1", { className: "flex flex-wrap items-center gap-x-3 gap-y-1.5 font-display text-display-lg leading-tight font-extrabold text-ink", children: title }), subtitle ? _jsx("p", { className: "mt-1.5 text-body text-ink-soft", children: subtitle }) : null] }), actions ? _jsx("div", { className: "ml-auto flex flex-wrap items-center gap-2", children: actions }) : null] }));
81
+ return (_jsxs("div", { ...dataProps(rest), className: cn("flex flex-wrap items-end gap-4", className), children: [_jsxs("div", { className: "min-w-0 flex-1 basis-65", children: [eyebrow ? (_jsx("p", { className: "mb-1.5 text-small font-semibold text-ink-faint", children: eyebrow })) : null, _jsx("h1", { className: "flex flex-wrap items-center gap-x-3 gap-y-1.5 font-display text-display-sm leading-tight font-extrabold text-ink", children: title }), subtitle ? _jsx("p", { className: "mt-1.5 text-body text-ink-soft", children: subtitle }) : null] }), actions ? _jsx("div", { className: "ml-auto flex flex-wrap items-center gap-2", children: actions }) : null] }));
82
82
  }
83
83
  /**
84
84
  * Gezinen bağlantı. `Button variant="link"` DEĞİL: o bir `<button>`, yani orta
@@ -1,4 +1,10 @@
1
1
  import type { Tone } from "./tone.js";
2
+ /**
3
+ * Katman düzlemi · 6 piksel, sayfanın ulaşabildiği 4 pikselin ötesi. Perde
4
+ * yalnız `Dialog` ve `Sheet`te; `Tooltip` bir etiket, hiç yükselmiyor.
5
+ *
6
+ * Gerekçe: docs/gerekce/07-katman-ve-diyalog.md
7
+ */
2
8
  export type MenuItem = {
3
9
  kind?: "item";
4
10
  label: string;
@@ -1 +1 @@
1
- {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/components/overlay.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/components/overlay.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAatC;;;;;GAKG;AAIH,MAAM,MAAM,QAAQ,GAChB;IACE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACD;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAErC,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,KAAK,EACL,KAAe,EACf,KAAW,EACX,OAAe,EACf,WAAe,EACf,WAAmB,EACnB,WAAmB,EACnB,GAAG,IAAI,EACR,EAAE;IACD,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;;;;OAYG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BA6FA;AAID,wBAAgB,OAAO,CAAC,EACtB,OAAO,EACP,KAAK,EACL,QAAQ,EACR,MAAM,EACN,KAAW,EACX,KAAe,EACf,OAAe,EACf,YAAY,EACZ,UAAU,EACV,GAAG,IAAI,EACR,EAAE;IACD,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IACxB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BA4CA;AAID,QAAA,MAAM,UAAU;aACd,GAAG,EAAE,yDAAyD;aAC9D,MAAM,EAAE,sDAAsD;aAC9D,IAAI,EAAE,uDAAuD;aAC7D,KAAK,EAAE,sDAAsD;CACrD,CAAC;AAwBX;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,SAAoB,EACpB,KAAW,EACX,IAAW,EACX,QAAQ,EACR,GAAG,IAAI,EACR,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,OAAO,UAAU,CAAC;IACpC;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BA6HA;AAID,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC;AAE7B,wBAAgB,KAAK,CAAC,EACpB,IAAgB,EAChB,KAAK,EACL,WAAW,EACX,MAAM,EACN,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,GAAG,IAAI,EACR,EAAE;IACD,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BA8EA;AAED;;;GAGG;AACH,QAAA,MAAM,OAAO;aACX,WAAW,EAAE,yBAAyB;aACtC,UAAU,EAAE,0BAA0B;aACtC,cAAc,EAAE,4BAA4B;aAC5C,aAAa,EAAE,6BAA6B;CACpC,CAAC;AAEX,wBAAgB,aAAa,CAAC,EAC5B,QAAsB,EACtB,QAAQ,EACR,GAAG,IAAI,EACR,EAAE;IACD,QAAQ,CAAC,EAAE,MAAM,OAAO,OAAO,CAAC;IAChC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAQA;AAID;;;;;;GAMG;AACH,QAAA,MAAM,eAAe;aACnB,EAAE,EAAE,UAAU;aACd,EAAE,EAAE,WAAW;aACf,IAAI,EAAE,uBAAuB;aAC7B,IAAI,EAAE,YAAY;CACV,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,eAAe,CAAC;AAkEtD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,OAAO,EACP,SAAS,EACT,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,UAAU,EACV,IAAe,EACf,IAAY,EACZ,eAAuB,GACxB,EAAE;IACD,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC5B;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;;;;;;;;;OAYG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,+BAuBA;AAED,wBAAgB,MAAM,CAAC,EACrB,IAAI,EACJ,OAAO,EACP,KAAK,EACL,QAAQ,EACR,MAAM,EACN,OAAe,EACf,UAAU,EACV,IAAW,EACX,GAAG,IAAI,EACR,EAAE;IACD,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAuBA"}
@@ -9,34 +9,9 @@ import { Close } from "./icons.js";
9
9
  import { SkeletonOptions, SkeletonPanel } from "./skeleton.js";
10
10
  import { Kbd } from "./display.js";
11
11
  import { Button } from "./button.js";
12
- import { useFocusTrap, useListKeys } from "./a11y.js";
12
+ import { useDismiss, useFocusTrap, useListKeys } from "./a11y.js";
13
13
  import { MiniButton } from "./button.js";
14
14
  import { useScrollLock } from "../lib/scroll-lock.js";
15
- /**
16
- * Katman düzlemi · 6 piksel, sayfanın ulaşabildiği 4 pikselin ötesi. Perde
17
- * yalnız `Dialog` ve `Sheet`te; `Tooltip` bir etiket, hiç yükselmiyor.
18
- *
19
- * Gerekçe: docs/gerekce/07-katman-ve-diyalog.md
20
- */
21
- function useDismiss(open, close) {
22
- const box = useRef(null);
23
- useEffect(() => {
24
- if (!open)
25
- return;
26
- const away = (e) => {
27
- if (box.current && !box.current.contains(e.target))
28
- close();
29
- };
30
- const esc = (e) => e.key === "Escape" && close();
31
- document.addEventListener("mousedown", away);
32
- document.addEventListener("keydown", esc);
33
- return () => {
34
- document.removeEventListener("mousedown", away);
35
- document.removeEventListener("keydown", esc);
36
- };
37
- }, [open, close]);
38
- return box;
39
- }
40
15
  export function DropdownMenu({ trigger, items, align = "start", width = 200, loading = false, loadingRows = 4, openOnHover = false, defaultOpen = false, ...rest }) {
41
16
  const [open, setOpen] = useState(defaultOpen);
42
17
  const box = useDismiss(open, () => setOpen(false));
package/dist/fonts.css CHANGED
@@ -1,4 +1,4 @@
1
- /*! tamga-ui 0.5.4 · MIT · https://tamga.org.tr */
1
+ /*! tamga-ui 0.5.6 · MIT · https://tamga.org.tr */
2
2
  @font-face {
3
3
  font-family: "Red Hat Display";
4
4
  font-style: normal;
package/dist/kit.css CHANGED
@@ -1,4 +1,4 @@
1
- /*! tamga-ui 0.5.4 · MIT · https://tamga.org.tr */
1
+ /*! tamga-ui 0.5.6 · MIT · https://tamga.org.tr */
2
2
  :root {
3
3
 
4
4
  --overlay-gap: 8px;
@@ -383,6 +383,8 @@
383
383
  .tamga-rail-link {
384
384
  position: relative;
385
385
  display: flex;
386
+
387
+ cursor: pointer;
386
388
  height: 40px;
387
389
 
388
390
  width: 52px;
@@ -440,9 +442,9 @@
440
442
 
441
443
  .tamga-rail-link[data-active="true"] {
442
444
  background: var(--color-shell);
443
- border-color: var(--color-edge-strong);
445
+ border-color: var(--color-accent-shadow);
444
446
  transform: translate(-1px, -1px);
445
- box-shadow: 3px 3px 0 var(--color-edge-strong);
447
+ box-shadow: 3px 3px 0 var(--color-accent-shadow);
446
448
  }
447
449
 
448
450
  .tamga-rail-link[data-active="true"] svg {
@@ -451,7 +453,7 @@
451
453
 
452
454
  .tamga-rail-link[data-active="true"]:active {
453
455
  transform: translate(2px, 2px);
454
- box-shadow: 0 0 0 var(--color-edge-strong);
456
+ box-shadow: 0 0 0 var(--color-accent-shadow);
455
457
  }
456
458
 
457
459
  .tamga-btn:not(:disabled):active,
@@ -8,8 +8,23 @@ import { type LinkComponent } from "./shared.js";
8
8
  * yönlendiriciyi tanımaz. Gerekçe: docs/adr/0004-sablon-katmani.md
9
9
  */
10
10
  export type NavEntry = {
11
+ /**
12
+ * The entry's identity. With `onSelect` it is also what `activePath` is compared against.
13
+ * TR: Girişin kimliği. `onSelect` ile birlikte `activePath`in karşılaştırıldığı değer de bu.
14
+ */
11
15
  key: string;
12
- href: string;
16
+ /**
17
+ * Where the entry goes. A desktop app has no addresses: it gives `onSelect` instead, and one of
18
+ * the two is required.
19
+ * TR: Girişin gittiği yer. Masaüstü uygulamasının adresi yok; onun yerine `onSelect` veriyor ve
20
+ * ikisinden biri zorunlu.
21
+ */
22
+ href?: string;
23
+ /**
24
+ * Runs instead of navigating. For a shell whose screens are state, not addresses.
25
+ * TR: Gezinmenin yerine koşuyor · ekranları adres değil durum olan bir kabuk için.
26
+ */
27
+ onSelect?: () => void;
13
28
  /** The translated label. In the tooltip on a narrow rail, on the row itself on a wide one. TR: Çevrilmiş etiket. Dar rayda ipucunda, geniş rayda satırın kendisinde. */
14
29
  label: string;
15
30
  icon: ComponentProps<typeof Icon>["icon"];
@@ -24,8 +39,8 @@ export type NavEntry = {
24
39
  * ve boş bir grup kurmak mümkün hâle gelirdi. Düz listede o iki sorun da yok: grup başlığı
25
40
  * verinin bir alanı, ve başlık ancak bir girişi varsa görünüyor.
26
41
  *
27
- * YALNIZ GENİŞ RAYDA ÇİZİLİYOR. Dar rayda 40 piksellik bir kutuda başlık okunmuyor; orada
28
- * gruplama boşlukla anlatılıyor.
42
+ * BAŞLIK YALNIZ GENİŞ RAYDA ÇİZİLİYOR. Dar rayda 40 piksellik bir kutuda bir başlık okunmuyor;
43
+ * orada grup değişimi bir ÇİZGİYLE anlatılıyor, rayın tepesindeki marka ayracının aynısı.
29
44
  */
30
45
  section?: string;
31
46
  };
@@ -56,6 +71,13 @@ export type AppShellProps = {
56
71
  topbar?: ReactNode;
57
72
  /** A control at the foot of the rail: an expand/collapse button, say. TR: Rayın dibine giren kontrol: genişlet/daralt düğmesi gibi. */
58
73
  railFooter?: ReactNode;
74
+ /**
75
+ * A state class on the content surface, for something the shell cannot know: a window-wide drop
76
+ * target marking its edge, say. Layout stays the kit's.
77
+ * TR: İçerik yüzeyine binen durum sınıfı · kabuğun bilemeyeceği bir şey için: pencere genelinde
78
+ * bir bırakma hedefinin kenarını işaretlemesi gibi. Düzen kitte kalıyor.
79
+ */
80
+ mainClassName?: string;
59
81
  linkComponent?: LinkComponent;
60
82
  labels: {
61
83
  home: string;
@@ -63,5 +85,5 @@ export type AppShellProps = {
63
85
  };
64
86
  children: ReactNode;
65
87
  };
66
- export declare function AppShell({ brand, nav, activePath, rail, topbar, railFooter, linkComponent: Link, labels, children, }: AppShellProps): import("react").JSX.Element;
88
+ export declare function AppShell({ brand, nav, activePath, rail, topbar, railFooter, mainClassName, linkComponent: Link, labels, children, }: AppShellProps): import("react").JSX.Element;
67
89
  //# sourceMappingURL=app-shell.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-shell.d.ts","sourceRoot":"","sources":["../../src/patterns/app-shell.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5D;;;;;GAKG;AAEH,MAAM,MAAM,QAAQ,GAAG;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,wKAAwK;IACxK,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,cAAc,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;IAC1C;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,wJAAwJ;IACxJ,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,GAAG,EAAE,SAAS,QAAQ,EAAE,CAAC;IACzB,mGAAmG;IACnG,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IACzB;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,uIAAuI;IACvI,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,GAAG,EACH,UAAU,EACV,IAAe,EACf,MAAM,EACN,UAAU,EACV,aAAa,EAAE,IAAgB,EAC/B,MAAM,EACN,QAAQ,GACT,EAAE,aAAa,+BAmHf"}
1
+ {"version":3,"file":"app-shell.d.ts","sourceRoot":"","sources":["../../src/patterns/app-shell.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAG7C,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5D;;;;;GAKG;AAEH,MAAM,MAAM,QAAQ,GAAG;IACrB;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,wKAAwK;IACxK,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,cAAc,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;IAC1C;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,wJAAwJ;IACxJ,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,GAAG,EAAE,SAAS,QAAQ,EAAE,CAAC;IACzB,mGAAmG;IACnG,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IACzB;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,uIAAuI;IACvI,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,GAAG,EACH,UAAU,EACV,IAAe,EACf,MAAM,EACN,UAAU,EACV,aAAa,EACb,aAAa,EAAE,IAAgB,EAC/B,MAAM,EACN,QAAQ,GACT,EAAE,aAAa,+BA+Hf"}
@@ -3,16 +3,18 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
3
3
  import { Fragment } from "react";
4
4
  import { Icon } from "../components/icon.js";
5
5
  import { RailLink } from "../components/rail-link.js";
6
+ import { cn } from "../lib/cn.js";
6
7
  import { PlainLink } from "./shared.js";
7
- export function AppShell({ brand, nav, activePath, rail = "narrow", topbar, railFooter, linkComponent: Link = PlainLink, labels, children, }) {
8
+ export function AppShell({ brand, nav, activePath, rail = "narrow", topbar, railFooter, mainClassName, linkComponent: Link = PlainLink, labels, children, }) {
8
9
  /* Bir giriş kendi alt ağacına sahip, ve EN UZUN EŞLEŞEN KAZANIR: kökün `/`
9
10
  olmadığı bir panelde kök giriş altındaki her rotayı yutuyordu.
10
11
  Gerekçe: docs/gerekce/08-blok-ve-sablon.md */
11
12
  const kapsiyor = (href) => activePath === href || activePath.startsWith(`${href}/`);
12
- const enOzel = nav.reduce((kazanan, entry) => kapsiyor(entry.href) && (kazanan === null || entry.href.length > kazanan.length)
13
+ const enOzel = nav.reduce((kazanan, entry) => entry.href && kapsiyor(entry.href) && (kazanan === null || entry.href.length > kazanan.length)
13
14
  ? entry.href
14
15
  : kazanan, null);
15
- const isCurrent = (href) => href === enOzel;
16
+ /* ADRESİ OLMAYAN GİRİŞ ANAHTARIYLA EŞLEŞİYOR: masaüstü kabuğunda ekran bir durum, yol değil. */
17
+ const isCurrent = (entry) => entry.href ? entry.href === enOzel : entry.key === activePath;
16
18
  const wide = rail === "wide";
17
- return (_jsxs("div", { className: "flex h-dvh w-full overflow-hidden bg-rail text-ink-soft", children: [_jsxs("aside", { className: `flex shrink-0 flex-col gap-2 bg-rail py-4 ${wide ? "w-60 px-3" : "w-20 items-center px-1"}`, "data-rail": rail, children: [brand ? (_jsxs(_Fragment, { children: [_jsx("span", { "aria-label": labels.home, className: `mb-2 flex h-10 shrink-0 items-center text-ink ${wide ? "px-2" : "w-10 justify-center"}`, children: brand }), _jsx("span", { className: `h-0 w-6 border-t border-line ${wide ? "ml-2" : ""}` })] })) : null, _jsx("nav", { "aria-label": labels.primaryNav, className: `tamga-rail-scroll flex w-full flex-1 flex-col gap-2 py-1 ${wide ? "" : "items-center"}`, children: nav.map((entry, i) => (_jsxs(Fragment, { children: [wide && entry.section && entry.section !== nav[i - 1]?.section ? (_jsx("p", { className: `px-2.5 text-caption font-bold uppercase tracking-label text-ink-faint ${i > 0 ? "mt-5 pb-1.5" : "pb-1.5"}`, children: entry.section })) : null, _jsx(RailLink, { href: entry.href, label: entry.label, active: isCurrent(entry.href), showLabel: wide, linkComponent: Link, "data-nav": entry.key, children: _jsx(Icon, { icon: entry.icon, size: "md", weight: isCurrent(entry.href) ? "fill" : "regular" }) })] }, entry.key))) }), railFooter ? _jsx("div", { className: "shrink-0", children: railFooter }) : null] }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [_jsx("header", { className: "tamga-gutter flex items-center gap-4 bg-band py-4", children: topbar }), _jsx("div", { className: "min-h-0 flex-1 overflow-hidden pr-4 pb-4", children: _jsx("main", { className: "tamga-surface tamga-app-main relative h-full min-h-0 overflow-y-auto", children: children }) })] })] }));
19
+ return (_jsxs("div", { className: "flex h-dvh w-full overflow-hidden bg-rail text-ink-soft", children: [_jsxs("aside", { className: `flex shrink-0 flex-col gap-2 bg-rail py-4 ${wide ? "w-60 px-3" : "w-20 items-center px-1"}`, "data-rail": rail, children: [brand ? (_jsxs(_Fragment, { children: [_jsx("span", { "aria-label": labels.home, className: `mb-2 flex h-10 shrink-0 items-center text-ink ${wide ? "px-2" : "w-10 justify-center"}`, children: brand }), _jsx("span", { className: `h-0 w-6 border-t border-line ${wide ? "ml-2" : ""}` })] })) : null, _jsx("nav", { "aria-label": labels.primaryNav, className: `tamga-rail-scroll flex w-full flex-1 flex-col gap-2 py-1 ${wide ? "" : "items-center"}`, children: nav.map((entry, i) => (_jsxs(Fragment, { children: [entry.section && entry.section !== nav[i - 1]?.section ? (wide ? (_jsx("p", { className: `px-2.5 text-caption font-bold uppercase tracking-label text-ink-faint ${i > 0 ? "mt-5 pb-1.5" : "pb-1.5"}`, children: entry.section })) : i > 0 ? (_jsx("span", { className: "my-1.5 h-0 w-6 shrink-0 border-t border-line", "aria-hidden": true })) : null) : null, _jsx(RailLink, { href: entry.href, onClick: entry.onSelect, label: entry.label, active: isCurrent(entry), showLabel: wide, linkComponent: Link, "data-nav": entry.key, children: _jsx(Icon, { icon: entry.icon, size: "md", weight: isCurrent(entry) ? "fill" : "regular" }) })] }, entry.key))) }), railFooter ? _jsx("div", { className: "shrink-0", children: railFooter }) : null] }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [_jsx("header", { className: "tamga-gutter flex items-center gap-4 bg-band py-4", children: topbar }), _jsx("div", { className: "min-h-0 flex-1 overflow-hidden pr-4 pb-4", children: _jsx("main", { className: cn("tamga-surface tamga-app-main relative h-full min-h-0 overflow-y-auto", mainClassName), children: children }) })] })] }));
18
20
  }
package/dist/styles.css CHANGED
@@ -1,4 +1,4 @@
1
- /*! tamga-ui 0.5.4 · MIT · https://tamga.org.tr */
1
+ /*! tamga-ui 0.5.6 · MIT · https://tamga.org.tr */
2
2
  @import "./fonts.css";
3
3
  @import "./theme.css";
4
4
  @import "./kit.css";
package/dist/theme.css CHANGED
@@ -1,4 +1,4 @@
1
- /*! tamga-ui 0.5.4 · MIT · https://tamga.org.tr */
1
+ /*! tamga-ui 0.5.6 · MIT · https://tamga.org.tr */
2
2
  @custom-variant dark (&:is(.dark *));
3
3
 
4
4
  @theme static {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tamga-ui",
3
- "version": "0.5.4",
3
+ "version": "0.5.6",
4
4
  "description": "Mant\u0131ksal's shared interface library: tokens, physics and components.",
5
5
  "license": "MIT",
6
6
  "type": "module",