tamga-ui 0.1.1 → 0.2.1

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 (64) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/README.md +83 -91
  3. package/dist/blocks/count-row.d.ts +3 -3
  4. package/dist/blocks/count-row.d.ts.map +1 -1
  5. package/dist/blocks/filter-bar.d.ts +13 -13
  6. package/dist/blocks/filter-bar.d.ts.map +1 -1
  7. package/dist/blocks/save-bar.d.ts +3 -3
  8. package/dist/blocks/save-bar.d.ts.map +1 -1
  9. package/dist/components/appearance.d.ts +78 -0
  10. package/dist/components/appearance.d.ts.map +1 -0
  11. package/dist/components/appearance.js +73 -0
  12. package/dist/components/chrome.d.ts +54 -3
  13. package/dist/components/chrome.d.ts.map +1 -1
  14. package/dist/components/chrome.js +43 -2
  15. package/dist/components/primitives.d.ts +32 -2
  16. package/dist/components/primitives.d.ts.map +1 -1
  17. package/dist/components/primitives.js +11 -4
  18. package/dist/components/rail-link.d.ts +15 -2
  19. package/dist/components/rail-link.d.ts.map +1 -1
  20. package/dist/components/rail-link.js +11 -9
  21. package/dist/components/square-picker.d.ts +41 -0
  22. package/dist/components/square-picker.d.ts.map +1 -0
  23. package/dist/components/square-picker.js +90 -0
  24. package/dist/index.d.ts +4 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +4 -1
  27. package/dist/kit.css +257 -4
  28. package/dist/lib/color.d.ts +31 -11
  29. package/dist/lib/color.d.ts.map +1 -1
  30. package/dist/lib/color.js +40 -18
  31. package/dist/lib/image.d.ts +46 -0
  32. package/dist/lib/image.d.ts.map +1 -0
  33. package/dist/lib/image.js +95 -0
  34. package/dist/lib/palette.d.ts +38 -19
  35. package/dist/lib/palette.d.ts.map +1 -1
  36. package/dist/lib/palette.js +45 -33
  37. package/dist/patterns/app-shell.d.ts +22 -6
  38. package/dist/patterns/app-shell.d.ts.map +1 -1
  39. package/dist/patterns/app-shell.js +4 -5
  40. package/dist/patterns/appearance-template.d.ts +105 -0
  41. package/dist/patterns/appearance-template.d.ts.map +1 -0
  42. package/dist/patterns/appearance-template.js +23 -0
  43. package/dist/patterns/auth-template.d.ts +9 -6
  44. package/dist/patterns/auth-template.d.ts.map +1 -1
  45. package/dist/patterns/detail-template.d.ts +5 -5
  46. package/dist/patterns/detail-template.d.ts.map +1 -1
  47. package/dist/patterns/index.d.ts +2 -1
  48. package/dist/patterns/index.d.ts.map +1 -1
  49. package/dist/patterns/index.js +6 -1
  50. package/dist/patterns/list-template.d.ts +6 -6
  51. package/dist/patterns/list-template.d.ts.map +1 -1
  52. package/dist/patterns/overview-template.d.ts +3 -3
  53. package/dist/patterns/overview-template.d.ts.map +1 -1
  54. package/dist/patterns/public-template.d.ts +3 -3
  55. package/dist/patterns/public-template.d.ts.map +1 -1
  56. package/dist/patterns/settings-template.d.ts +15 -4
  57. package/dist/patterns/settings-template.d.ts.map +1 -1
  58. package/dist/patterns/settings-template.js +2 -2
  59. package/dist/patterns/shared.d.ts +3 -3
  60. package/dist/patterns/shared.d.ts.map +1 -1
  61. package/dist/patterns/wizard-template.d.ts +1 -1
  62. package/dist/patterns/wizard-template.d.ts.map +1 -1
  63. package/dist/patterns/wizard-template.js +2 -9
  64. package/package.json +3 -2
@@ -1,4 +1,4 @@
1
- import { acikligi, dL, gecerliHex, oran } from "./color.js";
1
+ import { lightness, deltaL, isHex, contrast } from "./color.js";
2
2
  /**
3
3
  * Tek bir marka renginden iki temalık palet.
4
4
  *
@@ -17,7 +17,7 @@ import { acikligi, dL, gecerliHex, oran } from "./color.js";
17
17
  * `check-token-contrast` ile aynı aritmetikten geçiyor (bkz. `lib/color.ts`).
18
18
  */
19
19
  /** Bir temanın üreteceği token'lar. Adlar `theme.css`'teki kit ailesiyle birebir. */
20
- export type Palet = {
20
+ export type Palette = {
21
21
  page: string;
22
22
  shell: string;
23
23
  hover: string;
@@ -42,24 +42,27 @@ export type Palet = {
42
42
  navHover: string;
43
43
  navHoverBg: string;
44
44
  };
45
- export type PaletCifti = {
46
- light: Palet;
47
- dark: Palet;
45
+ export type PalettePair = {
46
+ light: Palette;
47
+ dark: Palette;
48
48
  };
49
49
  /**
50
50
  * Bir marka renginden iki tema.
51
51
  *
52
52
  * Geçersiz bir kodda FIRLATIYOR, sessizce griye düşmüyor: yarım yazılmış bir
53
- * hex'in ne anlama geldiğine çağıran karar veriyor (`gecerliHex`).
53
+ * hex'in ne anlama geldiğine çağıran karar veriyor (`isHex`).
54
54
  */
55
- export declare function paletUret(markaHex: string): PaletCifti;
56
- export { gecerliHex };
57
- export type Olcum = {
58
- ad: string;
59
- tur: "oran" | "dL";
60
- deger: number;
61
- esik: number;
62
- gecti: boolean;
55
+ export declare function makePalette(markaHex: string): PalettePair;
56
+ export { isHex };
57
+ /** Tek bir kontrast ölçümü. */
58
+ export type Measurement = {
59
+ /** Neyin neye karşı ölçüldüğü: "ink · page". */
60
+ name: string;
61
+ /** `contrast` WCAG oranı, `deltaL` açıklık farkı. */
62
+ kind: "contrast" | "deltaL";
63
+ value: number;
64
+ threshold: number;
65
+ passed: boolean;
63
66
  };
64
67
  /**
65
68
  * Üretilen paleti `check-token-contrast` ile AYNI eşiklerden geçirir.
@@ -68,17 +71,33 @@ export type Olcum = {
68
71
  * yarın bir ton için yanlış olur. Marka rengi değiştiğinde bu liste yeniden
69
72
  * koşuyor, ve geçmeyen bir palet build'i kırıyor.
70
73
  */
71
- export declare function paletiOlc(p: Palet): Olcum[];
74
+ export declare function measurePalette(p: Palette): Measurement[];
72
75
  /**
73
76
  * Bir paleti CSS değişkeni sözlüğüne çevirir: `{ "--color-accent": "#..." }`.
74
77
  *
75
- * NEDEN `paletCss` YETMİYOR: o bir STİL SAYFASI dizgisi üretiyor (`:root { … }`),
78
+ * NEDEN `paletteCss` YETMİYOR: o bir STİL SAYFASI dizgisi üretiyor (`:root { … }`),
76
79
  * ve bir stil sayfası ancak belgenin tamamına uygulanabiliyor. Bir paleti tek
77
80
  * bir kutuya uygulamak (bir önizleme, bir tema seçici) ya da köke çalışma
78
81
  * zamanında yazmak için gereken şey bir SÖZLÜK. Simge adları kalıtsal olduğu
79
82
  * için bir kutuya yazılan palet, içindeki her bileşeni birlikte döndürüyor.
80
83
  */
81
- export declare function paletStili(p: Palet): Record<string, string>;
82
- export declare function paletCss(cift: PaletCifti): string;
83
- export { acikligi, dL, oran };
84
+ export declare function paletteVars(p: Palette): Record<string, string>;
85
+ export declare function paletteCss(cift: PalettePair): string;
86
+ export { lightness, deltaL, contrast };
87
+ /** @deprecated `makePalette` kullan. 0.3.0'da kaldırılacak. */
88
+ export declare const paletUret: typeof makePalette;
89
+ /** @deprecated `measurePalette` kullan. 0.3.0'da kaldırılacak. */
90
+ export declare const paletiOlc: typeof measurePalette;
91
+ /** @deprecated `paletteVars` kullan. 0.3.0'da kaldırılacak. */
92
+ export declare const paletStili: typeof paletteVars;
93
+ /** @deprecated `paletteCss` kullan. 0.3.0'da kaldırılacak. */
94
+ export declare const paletCss: typeof paletteCss;
95
+ /** @deprecated `Palette` kullan. 0.3.0'da kaldırılacak. */
96
+ export type Palet = Palette;
97
+ /** @deprecated `PalettePair` kullan. 0.3.0'da kaldırılacak. */
98
+ export type PaletCifti = PalettePair;
99
+ /** @deprecated `Measurement` kullan. 0.3.0'da kaldırılacak. */
100
+ export type Olcum = Measurement;
101
+ /** @deprecated `isHex` kullan (tamga-ui/palette üzerinden). 0.3.0'da kaldırılacak. */
102
+ export { gecerliHex, hexRgb, rgbHex, parlaklik, oran, acikligi, dL, hexOklch, oklchHex, oranaGoreAcikligi } from "./color.js";
84
103
  //# sourceMappingURL=palette.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"palette.d.ts","sourceRoot":"","sources":["../../src/lib/palette.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAsB,IAAI,EAAc,MAAM,YAAY,CAAC;AAE5F;;;;;;;;;;;;;;;;GAgBG;AAEH,qFAAqF;AACrF,MAAM,MAAM,KAAK,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC;AAqHvD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAItD;AAED,OAAO,EAAE,UAAU,EAAE,CAAC;AAItB,MAAM,MAAM,KAAK,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpG;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,EAAE,CAsB3C;AAwBD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAI3D;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAMjD;AAED,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"palette.d.ts","sourceRoot":"","sources":["../../src/lib/palette.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAA0B,QAAQ,EAAc,MAAM,YAAY,CAAC;AAEpG;;;;;;;;;;;;;;;;GAgBG;AAEH,qFAAqF;AACrF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAqH5D;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,CAIzD;AAED,OAAO,EAAE,KAAK,EAAE,CAAC;AAIjB,+BAA+B;AAC/B,MAAM,MAAM,WAAW,GAAG;IACxB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,IAAI,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,CAsBxD;AAwBD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAI9D;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAMpD;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAKvC,+DAA+D;AAC/D,eAAO,MAAM,SAAS,oBAAc,CAAC;AACrC,kEAAkE;AAClE,eAAO,MAAM,SAAS,uBAAiB,CAAC;AACxC,+DAA+D;AAC/D,eAAO,MAAM,UAAU,oBAAc,CAAC;AACtC,8DAA8D;AAC9D,eAAO,MAAM,QAAQ,mBAAa,CAAC;AACnC,2DAA2D;AAC3D,MAAM,MAAM,KAAK,GAAG,OAAO,CAAC;AAC5B,+DAA+D;AAC/D,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC;AACrC,+DAA+D;AAC/D,MAAM,MAAM,KAAK,GAAG,WAAW,CAAC;AAChC,sFAAsF;AACtF,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
@@ -1,4 +1,4 @@
1
- import { acikligi, dL, gecerliHex, hexOklch, oklchHex, oran } from "./color.js";
1
+ import { lightness, deltaL, isHex, hexToOklch, oklchToHex, contrast } from "./color.js";
2
2
  /**
3
3
  * Nötrlerin AÇIKLIK basamakları, iki temada.
4
4
  *
@@ -23,7 +23,7 @@ const BASAMAK = {
23
23
  * sabit, rengi değişken.
24
24
  */
25
25
  const NOTR_DOYUM = { zemin: 0.006, yuzey: 0, cizgi: 0.009, murekkep: 0.014 };
26
- const notr = (h, l, c) => oklchHex({ l, c, h });
26
+ const notr = (h, l, c) => oklchToHex({ l, c, h });
27
27
  /**
28
28
  * Yüzün üstündeki mürekkep: beyaz mı koyu mu.
29
29
  *
@@ -32,7 +32,7 @@ const notr = (h, l, c) => oklchHex({ l, c, h });
32
32
  * markada okunmayan bir düğme üretiyor.
33
33
  */
34
34
  function yuzMurekkebi(yuz, acikNotr, koyuNotr) {
35
- return oran(acikNotr, yuz) >= oran(koyuNotr, yuz) ? acikNotr : koyuNotr;
35
+ return contrast(acikNotr, yuz) >= contrast(koyuNotr, yuz) ? acikNotr : koyuNotr;
36
36
  }
37
37
  function temaUret(marka, koyu) {
38
38
  const h = marka.h;
@@ -57,25 +57,25 @@ function temaUret(marka, koyu) {
57
57
  const yuzL = Math.max(band.alt, Math.min(band.ust, marka.l));
58
58
  /* DOYUM KIRPILMIYOR. Bir süre `min(marka.c, 0.16)` vardı ve doygun bir marka
59
59
  kırmızısını (C 0.215) `#c74a4a`ya soldurup markayı gözle görülür şekilde
60
- değiştiriyordu. Kırpma gereksizdi: `oklchHex` zaten gamut'a sığmayan bir
60
+ değiştiriyordu. Kırpma gereksizdi: `oklchToHex` zaten gamut'a sığmayan bir
61
61
  rengi ikili aramayla sığdırıyor ve TONU koruyor. Kırpmak, çözülmüş bir
62
62
  sorunu ikinci kez ve daha kötü çözmekti. */
63
63
  const kroma = marka.c;
64
- let yuz = oklchHex({ l: yuzL, c: kroma, h });
64
+ let yuz = oklchToHex({ l: yuzL, c: kroma, h });
65
65
  let murekkep = yuzMurekkebi(yuz, shell, ink);
66
- for (let i = 1; i <= 40 && oran(yuz, murekkep) < 4.5; i++) {
66
+ for (let i = 1; i <= 40 && contrast(yuz, murekkep) < 4.5; i++) {
67
67
  /* Mürekkep açıksa yüz koyulaşır, koyuysa açılır: mesafe hep açılıyor. */
68
- const yon = acikligi(murekkep) > 50 ? -1 : 1;
69
- yuz = oklchHex({ l: Math.max(0.2, Math.min(0.92, yuzL + yon * 0.01 * i)), c: kroma, h });
68
+ const yon = lightness(murekkep) > 50 ? -1 : 1;
69
+ yuz = oklchToHex({ l: Math.max(0.2, Math.min(0.92, yuzL + yon * 0.01 * i)), c: kroma, h });
70
70
  murekkep = yuzMurekkebi(yuz, shell, ink);
71
71
  }
72
- const yuzOk = hexOklch(yuz);
73
- const adim = (d) => oklchHex({ ...yuzOk, l: Math.max(0.06, Math.min(0.96, yuzOk.l + d)) });
72
+ const yuzOk = hexToOklch(yuz);
73
+ const adim = (d) => oklchToHex({ ...yuzOk, l: Math.max(0.06, Math.min(0.96, yuzOk.l + d)) });
74
74
  /* ÇİZGİ RENGİ (bağlantı, odak halkası) sayfada AA geçmek zorunda: bir
75
75
  bağlantı metindir. Yüz genelde geçmiyor, o yüzden ayrıca aranıyor. */
76
76
  let cizgi = koyu ? adim(0.08) : adim(-0.18);
77
- for (let i = 0; i < 40 && oran(cizgi, page) < 4.5; i++) {
78
- cizgi = oklchHex({ ...yuzOk, l: Math.max(0.08, Math.min(0.95, yuzOk.l + (koyu ? 1 : -1) * (0.18 + 0.01 * i))) });
77
+ for (let i = 0; i < 40 && contrast(cizgi, page) < 4.5; i++) {
78
+ cizgi = oklchToHex({ ...yuzOk, l: Math.max(0.08, Math.min(0.95, yuzOk.l + (koyu ? 1 : -1) * (0.18 + 0.01 * i))) });
79
79
  }
80
80
  return {
81
81
  page,
@@ -97,9 +97,9 @@ function temaUret(marka, koyu) {
97
97
  accentInk: murekkep,
98
98
  accentLine: cizgi,
99
99
  /* Seçili satır zemini: sayfaya çok yakın, ama ayrı okunuyor. */
100
- accentBg: oklchHex({ l: koyu ? b.page + 0.06 : b.page - 0.035, c: 0.03, h }),
100
+ accentBg: oklchToHex({ l: koyu ? b.page + 0.06 : b.page - 0.035, c: 0.03, h }),
101
101
  /* Taban: yüzün ALTINDA duran koyu, doygun renk (13 Yasa 1). */
102
- accentShadow: oklchHex({ l: koyu ? 0.42 : 0.28, c: Math.min(marka.c, 0.13), h }),
102
+ accentShadow: oklchToHex({ l: koyu ? 0.42 : 0.28, c: Math.min(marka.c, 0.13), h }),
103
103
  navIdle: notr(h, b.navIdle, NOTR_DOYUM.murekkep),
104
104
  navHover: notr(h, b.navHover, NOTR_DOYUM.murekkep),
105
105
  navHoverBg: notr(h, koyu ? b.hover : b.hover - 0.01, NOTR_DOYUM.zemin),
@@ -109,15 +109,15 @@ function temaUret(marka, koyu) {
109
109
  * Bir marka renginden iki tema.
110
110
  *
111
111
  * Geçersiz bir kodda FIRLATIYOR, sessizce griye düşmüyor: yarım yazılmış bir
112
- * hex'in ne anlama geldiğine çağıran karar veriyor (`gecerliHex`).
112
+ * hex'in ne anlama geldiğine çağıran karar veriyor (`isHex`).
113
113
  */
114
- export function paletUret(markaHex) {
115
- if (!gecerliHex(markaHex))
114
+ export function makePalette(markaHex) {
115
+ if (!isHex(markaHex))
116
116
  throw new Error(`Geçersiz marka rengi: ${JSON.stringify(markaHex)}`);
117
- const marka = hexOklch(markaHex);
117
+ const marka = hexToOklch(markaHex);
118
118
  return { light: temaUret(marka, false), dark: temaUret(marka, true) };
119
119
  }
120
- export { gecerliHex };
120
+ export { isHex };
121
121
  /**
122
122
  * Üretilen paleti `check-token-contrast` ile AYNI eşiklerden geçirir.
123
123
  *
@@ -125,14 +125,14 @@ export { gecerliHex };
125
125
  * yarın bir ton için yanlış olur. Marka rengi değiştiğinde bu liste yeniden
126
126
  * koşuyor, ve geçmeyen bir palet build'i kırıyor.
127
127
  */
128
- export function paletiOlc(p) {
129
- const metin = (ad, a, b, esik = 4.5) => {
130
- const deger = Number(oran(a, b).toFixed(2));
131
- return { ad, tur: "oran", deger, esik, gecti: deger >= esik };
128
+ export function measurePalette(p) {
129
+ const metin = (name, a, b, threshold = 4.5) => {
130
+ const value = Number(contrast(a, b).toFixed(2));
131
+ return { name, kind: "contrast", value, threshold, passed: value >= threshold };
132
132
  };
133
- const yuzey = (ad, a, b, esik) => {
134
- const deger = Number(dL(a, b).toFixed(1));
135
- return { ad, tur: "dL", deger, esik, gecti: deger >= esik };
133
+ const yuzey = (name, a, b, threshold) => {
134
+ const value = Number(deltaL(a, b).toFixed(1));
135
+ return { name, kind: "deltaL", value, threshold, passed: value >= threshold };
136
136
  };
137
137
  return [
138
138
  metin("ink · page", p.ink, p.page),
@@ -150,9 +150,9 @@ export function paletiOlc(p) {
150
150
  }
151
151
  /** `:root` bloğuna yapıştırılabilir CSS. */
152
152
  /**
153
- * Palet alanı → CSS simge adı.
153
+ * Palette alanı → CSS simge adı.
154
154
  *
155
- * DIŞARI AÇIK, ÇÜNKÜ ÜÇÜNCÜ KOPYASI DOĞACAKTI. Bu eşleme `paletCss`in içinde
155
+ * DIŞARI AÇIK, ÇÜNKÜ ÜÇÜNCÜ KOPYASI DOĞACAKTI. Bu eşleme `paletteCss`in içinde
156
156
  * özeldi; bir ürün paneli aynısını kendi dosyasına elle yazmıştı (rengi
157
157
  * çalışma zamanında köke yazmak için), ve doküman sitesi de üçüncüsünü
158
158
  * yazacaktı. Aynı yirmi iki satırın üç kopyası, kite bir simge eklendiği gün
@@ -172,22 +172,34 @@ const AD = {
172
172
  /**
173
173
  * Bir paleti CSS değişkeni sözlüğüne çevirir: `{ "--color-accent": "#..." }`.
174
174
  *
175
- * NEDEN `paletCss` YETMİYOR: o bir STİL SAYFASI dizgisi üretiyor (`:root { … }`),
175
+ * NEDEN `paletteCss` YETMİYOR: o bir STİL SAYFASI dizgisi üretiyor (`:root { … }`),
176
176
  * ve bir stil sayfası ancak belgenin tamamına uygulanabiliyor. Bir paleti tek
177
177
  * bir kutuya uygulamak (bir önizleme, bir tema seçici) ya da köke çalışma
178
178
  * zamanında yazmak için gereken şey bir SÖZLÜK. Simge adları kalıtsal olduğu
179
179
  * için bir kutuya yazılan palet, içindeki her bileşeni birlikte döndürüyor.
180
180
  */
181
- export function paletStili(p) {
181
+ export function paletteVars(p) {
182
182
  const stil = {};
183
183
  for (const alan of Object.keys(AD))
184
184
  stil[AD[alan]] = p[alan];
185
185
  return stil;
186
186
  }
187
- export function paletCss(cift) {
188
- const blok = (p) => Object.entries(paletStili(p))
187
+ export function paletteCss(cift) {
188
+ const blok = (p) => Object.entries(paletteVars(p))
189
189
  .map(([ad, deger]) => ` ${ad}: ${deger};`)
190
190
  .join("\n");
191
191
  return `:root {\n${blok(cift.light)}\n}\n\n.dark {\n${blok(cift.dark)}\n}\n`;
192
192
  }
193
- export { acikligi, dL, oran };
193
+ export { lightness, deltaL, contrast };
194
+ /* Eski Türkçe adlar, 0.3.0'a kadar. SİLME: 0.1.1 npm'de yayında ve bu adları
195
+ kullanan bir tüketici var. */
196
+ /** @deprecated `makePalette` kullan. 0.3.0'da kaldırılacak. */
197
+ export const paletUret = makePalette;
198
+ /** @deprecated `measurePalette` kullan. 0.3.0'da kaldırılacak. */
199
+ export const paletiOlc = measurePalette;
200
+ /** @deprecated `paletteVars` kullan. 0.3.0'da kaldırılacak. */
201
+ export const paletStili = paletteVars;
202
+ /** @deprecated `paletteCss` kullan. 0.3.0'da kaldırılacak. */
203
+ export const paletCss = paletteCss;
204
+ /** @deprecated `isHex` kullan (tamga-ui/palette üzerinden). 0.3.0'da kaldırılacak. */
205
+ export { gecerliHex, hexRgb, rgbHex, parlaklik, oran, acikligi, dL, hexOklch, oklchHex, oranaGoreAcikligi } from "./color.js";
@@ -10,21 +10,37 @@ import { type LinkComponent } from "./shared.js";
10
10
  export type NavEntry = {
11
11
  key: string;
12
12
  href: string;
13
- /** Çevrilmiş etiket. Ray dar olduğu için ekranda değil, `title` ve etikette. */
13
+ /** 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
14
  label: string;
15
15
  icon: ComponentProps<typeof Icon>["icon"];
16
16
  };
17
17
  export type AppShellProps = {
18
- /** Rayın tepesindeki marka işareti; kendi bağlantısını çağıran veriyor. */
18
+ /** The brand mark at the top of the rail; the caller supplies its own link. TR: Rayın tepesindeki marka işareti; kendi bağlantısını çağıran veriyor. */
19
19
  brand?: ReactNode;
20
20
  nav: readonly NavEntry[];
21
- /** Açık yol. Rota `usePathname()` geçiyor. */
21
+ /** The open path. The route passes `usePathname()`. TR: Açık yol. Rota `usePathname()` geçiyor. */
22
22
  activePath: string;
23
23
  /**
24
- * Üst şerit KÜRESEL BAĞLAM, iş değil. İçerik çağıranın; şablon yalnız yerini
25
- * garanti ediyor.
24
+ * How wide the rail is. TR: Rayın genişliği.
25
+ *
26
+ * `narrow` yalnız simge, etiket ipucunda; `wide` simge ve etiket yan yana.
27
+ * Dar ray ekranı içeriğe bırakıyor ve simgeleri tanıyan birine yetiyor;
28
+ * geniş ray yeni gelen birine menüyü okutuyor. Hangisinin doğru olduğu
29
+ * ürüne bağlı, o yüzden şablon karar vermiyor, soruyor.
30
+ *
31
+ * "Kullanıcı seçsin" diye bir üçüncü değer YOK ve olmamalı: o bir TERCİH,
32
+ * ve tercihin nerede saklandığını (oturum, hesap, tarayıcı) kit bilemez.
33
+ * Ürün tercihi okur, buraya `narrow` ya da `wide` geçer.
34
+ */
35
+ rail?: "narrow" | "wide";
36
+ /**
37
+ * The top bar is GLOBAL CONTEXT, not work. The content belongs to the caller; the template
38
+ * only guarantees its place. TR: Üst şerit KÜRESEL BAĞLAM, iş değil. İçerik çağıranın; şablon
39
+ * yalnız yerini garanti ediyor.
26
40
  */
27
41
  topbar?: ReactNode;
42
+ /** 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. */
43
+ railFooter?: ReactNode;
28
44
  linkComponent?: LinkComponent;
29
45
  labels: {
30
46
  home: string;
@@ -32,5 +48,5 @@ export type AppShellProps = {
32
48
  };
33
49
  children: ReactNode;
34
50
  };
35
- export declare function AppShell({ brand, nav, activePath, topbar, linkComponent: Link, labels, children, }: AppShellProps): import("react").JSX.Element;
51
+ export declare function AppShell({ brand, nav, activePath, rail, topbar, railFooter, linkComponent: Link, labels, children, }: AppShellProps): import("react").JSX.Element;
36
52
  //# 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":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,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,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,cAAc,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,2EAA2E;IAC3E,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,GAAG,EAAE,SAAS,QAAQ,EAAE,CAAC;IACzB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,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,MAAM,EACN,aAAa,EAAE,IAAgB,EAC/B,MAAM,EACN,QAAQ,GACT,EAAE,aAAa,+BAwDf"}
1
+ {"version":3,"file":"app-shell.d.ts","sourceRoot":"","sources":["../../src/patterns/app-shell.tsx"],"names":[],"mappings":"AAEA,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;CAC3C,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,+BAuEf"}
@@ -1,14 +1,13 @@
1
1
  "use client";
2
2
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { Icon } from "../components/icon.js";
4
+ import { RailLink } from "../components/rail-link.js";
4
5
  import { PlainLink } from "./shared.js";
5
- export function AppShell({ brand, nav, activePath, topbar, linkComponent: Link = PlainLink, labels, children, }) {
6
+ export function AppShell({ brand, nav, activePath, rail = "narrow", topbar, railFooter, linkComponent: Link = PlainLink, labels, children, }) {
6
7
  /* Bir giriş kendi alt ağacına sahip: `/urunler`, `/urunler/42/fotograflar`
7
8
  üzerinde de açık giriştir. Tam eşleşme yalnız kök yol için, yoksa kısa href
8
9
  altındaki her rotayı yutar. */
9
10
  const isCurrent = (href) => href === "/" ? activePath === href : activePath === href || activePath.startsWith(`${href}/`);
10
- return (_jsxs("div", { className: "flex h-dvh w-full overflow-hidden bg-shell text-ink-soft", children: [_jsxs("aside", { className: "flex w-16 shrink-0 flex-col items-center gap-2 bg-shell px-1 py-4", children: [brand ? (_jsxs(_Fragment, { children: [_jsx("span", { "aria-label": labels.home, className: "mb-2 flex size-10 shrink-0 items-center justify-center text-ink", children: brand }), _jsx("span", { className: "h-0 w-6 border-t border-line" })] })) : null, _jsx("nav", { "aria-label": labels.primaryNav, className: "tamga-rail-scroll flex w-full flex-1 flex-col items-center gap-2 py-1", children: nav.map((entry) => {
11
- const current = isCurrent(entry.href);
12
- return (_jsx(Link, { href: entry.href, "aria-label": entry.label, title: entry.label, "aria-current": current ? "page" : undefined, "data-active": current, "data-nav": entry.key, className: "tamga-rail-link", children: _jsx(Icon, { icon: entry.icon, size: "base" }) }, entry.key));
13
- }) })] }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [_jsx("header", { className: "tamga-gutter flex items-center gap-4 py-4", children: topbar }), _jsx("div", { className: "min-h-0 flex-1 overflow-hidden p-4 pt-0", children: _jsx("main", { className: "tamga-surface h-full min-h-0 overflow-y-auto", children: children }) })] })] }));
11
+ const wide = rail === "wide";
12
+ return (_jsxs("div", { className: "flex h-dvh w-full overflow-hidden bg-shell text-ink-soft", children: [_jsxs("aside", { className: `flex shrink-0 flex-col gap-2 bg-shell 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) => (_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: "base" }) }, 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 py-4", children: topbar }), _jsx("div", { className: "min-h-0 flex-1 overflow-hidden pr-4 pb-4", children: _jsx("main", { className: "tamga-surface h-full min-h-0 overflow-y-auto", children: children }) })] })] }));
14
13
  }
@@ -0,0 +1,105 @@
1
+ import { type ReactNode } from "react";
2
+ import { type SwatchOption, type ThemeChoice } from "../components/appearance.js";
3
+ /**
4
+ * The Appearance screen: logo, mark, brand colour, theme, sidebar.
5
+ *
6
+ * WHY A WHOLE SCREEN AND NOT FIVE PARTS. Every panel grows an appearance
7
+ * setting, and the kit not giving one is why two products drew their own hex
8
+ * box. Handing over the parts would not have fixed it: each product arranges
9
+ * them differently and they drift apart again, which is the thing this layer
10
+ * exists to prevent (ADR-0004).
11
+ *
12
+ * IT STORES NOTHING. `value` comes in, `onChange` goes out, `onSave` belongs
13
+ * to the caller. Where the preference lives (session, account, browser) is a
14
+ * product decision and a template that learns it stops being a template.
15
+ *
16
+ * THE PALETTE IS NOT APPLIED HERE EITHER. This screen reports the chosen
17
+ * colour; turning it into tokens is `makePalette` plus `paletteVars`, and the
18
+ * product decides when that happens, because the product owns the root
19
+ * element.
20
+ */
21
+ export type Appearance = {
22
+ brand: string;
23
+ theme: ThemeChoice;
24
+ /** `free` means each user decides. TR: `free`, her kullanıcı kendi seçer demek. */
25
+ rail: "narrow" | "wide" | "free";
26
+ logo: string | null;
27
+ mark: string | null;
28
+ };
29
+ export type AppearanceLabels = {
30
+ title: string;
31
+ description: string;
32
+ logo: {
33
+ title: string;
34
+ description: string;
35
+ field: ImageLabels;
36
+ pickMark: string;
37
+ };
38
+ mark: {
39
+ title: string;
40
+ description: string;
41
+ field: ImageLabels;
42
+ fallbackNote: string;
43
+ };
44
+ brand: {
45
+ title: string;
46
+ description: string;
47
+ swatches: readonly SwatchOption[];
48
+ custom: string;
49
+ };
50
+ theme: {
51
+ title: string;
52
+ description: string;
53
+ light: string;
54
+ dark: string;
55
+ system: string;
56
+ group: string;
57
+ };
58
+ rail: {
59
+ title: string;
60
+ description: string;
61
+ narrow: string;
62
+ wide: string;
63
+ free: string;
64
+ group: string;
65
+ };
66
+ picker: {
67
+ title: string;
68
+ hint: string;
69
+ size: string;
70
+ cancel: string;
71
+ confirm: string;
72
+ close: string;
73
+ };
74
+ save: string;
75
+ saving: string;
76
+ reset: string;
77
+ clean: string;
78
+ dirty: string;
79
+ };
80
+ type ImageLabels = {
81
+ name: string;
82
+ upload: string;
83
+ replace: string;
84
+ remove: string;
85
+ empty: string;
86
+ errorType: string;
87
+ errorSize: string;
88
+ errorUnreadable: string;
89
+ };
90
+ export declare function AppearanceTemplate({ value, onChange, saved, onSave, onReset, saving, fallbackName, labels, extra, }: {
91
+ value: Appearance;
92
+ onChange: (next: Appearance) => void;
93
+ /** The stored version; "is anything unsaved" is answered by comparing with it. TR: Kayıtlı hâli; "kaydedilmemiş bir şey var mı" sorusu bununla cevaplanıyor. */
94
+ saved: Appearance;
95
+ onSave: () => void;
96
+ onReset: () => void;
97
+ saving?: boolean;
98
+ /** The name a tile is drawn from when there is no mark. TR: Amblem yokken karonun çizildiği ad. */
99
+ fallbackName: string;
100
+ labels: AppearanceLabels;
101
+ /** Extra panels the product adds, after the built-in ones. TR: Ürünün eklediği ek bölümler, hazır olanlardan sonra. */
102
+ extra?: ReactNode;
103
+ }): import("react").JSX.Element;
104
+ export {};
105
+ //# sourceMappingURL=appearance-template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appearance-template.d.ts","sourceRoot":"","sources":["../../src/patterns/appearance-template.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { ColorSwatches, ImageField, ThemeCards } from "../components/appearance.js";
5
+ import { LogoTile } from "../components/chrome.js";
6
+ import { Segmented } from "../components/segmented.js";
7
+ import { SquarePicker } from "../components/square-picker.js";
8
+ import { Button } from "../components/button.js";
9
+ import { Label } from "../components/surface.js";
10
+ import { SettingsPanel } from "./settings-template.js";
11
+ export function AppearanceTemplate({ value, onChange, saved, onSave, onReset, saving = false, fallbackName, labels, extra, }) {
12
+ const [picking, setPicking] = useState(false);
13
+ const dirty = JSON.stringify(value) !== JSON.stringify(saved);
14
+ return (_jsxs("form", { className: "flex flex-col gap-5", onSubmit: (e) => {
15
+ e.preventDefault();
16
+ if (dirty && !saving)
17
+ onSave();
18
+ }, children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsx("h1", { className: "text-display-sm font-semibold text-ink", children: labels.title }), _jsx("p", { className: "w-full text-control leading-relaxed text-ink-soft", children: labels.description })] }), _jsx(SettingsPanel, { accent: true, title: labels.logo.title, description: labels.logo.description, children: _jsx(ImageField, { value: value.logo, onChange: (v) => onChange({ ...value, logo: v }), maxEdge: 512, labels: labels.logo.field, preview: (src) => (_jsx("img", { src: src, alt: "", className: "max-h-full w-auto max-w-56 object-contain" })), extra: value.logo ? (_jsx(Button, { type: "button", onClick: () => setPicking(true), children: labels.logo.pickMark })) : undefined }) }), _jsxs(SettingsPanel, { accent: true, title: labels.mark.title, description: labels.mark.description, children: [_jsx(ImageField, { value: value.mark, onChange: (v) => onChange({ ...value, mark: v }), maxEdge: 256, labels: labels.mark.field, preview: (src) => (_jsx("img", { src: src, alt: "", className: "size-12 object-contain" })) }), !value.mark ? (_jsxs("span", { className: "mt-4 flex items-center gap-3", children: [_jsx(LogoTile, { name: fallbackName }), _jsx(Label, { children: labels.mark.fallbackNote })] })) : null] }), _jsx(SettingsPanel, { accent: true, title: labels.brand.title, description: labels.brand.description, children: _jsx(ColorSwatches, { options: labels.brand.swatches, value: value.brand, onChange: (hex) => onChange({ ...value, brand: hex }), customLabel: labels.brand.custom }) }), _jsx(SettingsPanel, { accent: true, title: labels.theme.title, description: labels.theme.description, children: _jsx(ThemeCards, { value: value.theme, onChange: (t) => onChange({ ...value, theme: t }), labels: labels.theme }) }), _jsx(SettingsPanel, { accent: true, title: labels.rail.title, description: labels.rail.description, children: _jsx(Segmented, { label: labels.rail.group, value: value.rail, onChange: (r) => onChange({ ...value, rail: r }), options: [
19
+ { value: "narrow", label: labels.rail.narrow },
20
+ { value: "wide", label: labels.rail.wide },
21
+ { value: "free", label: labels.rail.free },
22
+ ] }) }), extra, value.logo ? (_jsx(SquarePicker, { open: picking, source: value.logo, onClose: () => setPicking(false), onPick: (square) => onChange({ ...value, mark: square }), labels: labels.picker })) : null, _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsxs("span", { className: "flex flex-wrap items-center gap-3", children: [_jsx(Button, { variant: "primary", type: "submit", disabled: !dirty, busy: saving, busyLabel: labels.saving, children: labels.save }), _jsx(Button, { type: "button", disabled: saving, onClick: onReset, children: labels.reset })] }), _jsx(Label, { children: dirty ? labels.dirty : labels.clean })] })] }));
23
+ }
@@ -6,17 +6,20 @@ import type { ReactNode } from "react";
6
6
  * Gerekçe: docs/adr/0004-sablon-katmani.md
7
7
  */
8
8
  export declare function AuthTemplate({ brand, title, subtitle, children, footer, aside, }: {
9
- /** Markanın işareti. Sözcük markası değil işaret: bu ekranın işi tek alan ve tek düğme. */
9
+ /** The brand's mark. The mark, not the wordmark: this screen's job is one field and one button. TR: Markanın işareti. Sözcük markası değil işaret: bu ekranın işi tek alan ve tek düğme. */
10
10
  brand?: ReactNode;
11
11
  title: string;
12
12
  subtitle?: string;
13
13
  children: ReactNode;
14
14
  footer?: ReactNode;
15
15
  /**
16
- * Ekranın öteki yarısındaki panel. Kayıtta var, girişte yok, ve asimetri
17
- * kasıtlı: giriş yapan kişi acelesi olan, dönen bir kullanıcı; kaydolan kişi
18
- * hâlâ karar veriyor. Birinciye bir şey satmak gürültü, ikinciye hiçbir şey
19
- * dememek ekranı ziyan etmek.
16
+ * The panel on the screen's other half. Present on sign-up, absent on sign-in, and the
17
+ * asymmetry is deliberate: the person signing in is a returning user in a hurry; the person
18
+ * signing up is still deciding. Selling something to the first is noise; saying nothing to
19
+ * the second wastes the screen. TR: Ekranın öteki yarısındaki panel. Kayıtta var, girişte
20
+ * yok, ve asimetri kasıtlı: giriş yapan kişi acelesi olan, dönen bir kullanıcı; kaydolan kişi
21
+ * hâlâ karar veriyor. Birinciye bir şey satmak gürültü, ikinciye hiçbir şey dememek ekranı
22
+ * ziyan etmek.
20
23
  */
21
24
  aside?: ReactNode;
22
25
  }): import("react").JSX.Element;
@@ -30,7 +33,7 @@ export declare function AuthTemplate({ brand, title, subtitle, children, footer,
30
33
  */
31
34
  export declare function AuthProviders({ children, dividerLabel, }: {
32
35
  children: ReactNode;
33
- /** Ayıracın üstündeki sözcük. */
36
+ /** The word sitting on the divider. TR: Ayıracın üstündeki sözcük. */
34
37
  dividerLabel: string;
35
38
  }): import("react").JSX.Element;
36
39
  //# sourceMappingURL=auth-template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-template.d.ts","sourceRoot":"","sources":["../../src/patterns/auth-template.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,KAAK,GACN,EAAE;IACD,2FAA2F;IAC3F,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,+BAyDA;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,YAAY,GACb,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,iCAAiC;IACjC,YAAY,EAAE,MAAM,CAAC;CACtB,+BAWA"}
1
+ {"version":3,"file":"auth-template.d.ts","sourceRoot":"","sources":["../../src/patterns/auth-template.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,KAAK,GACN,EAAE;IACD,4LAA4L;IAC5L,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,+BAyDA;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,YAAY,GACb,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAC;CACtB,+BAWA"}
@@ -8,20 +8,20 @@ import { type ErrorLabels, type LinkComponent, type TemplateError } from "./shar
8
8
  */
9
9
  export type DetailState = "ready" | "loading" | "error";
10
10
  export type DetailTab = {
11
- /** Kararlı kimlik; karşılaştırma ve testler bununla. */
11
+ /** A stable identity; comparisons and tests use this. TR: Kararlı kimlik; karşılaştırma ve testler bununla. */
12
12
  key: string;
13
- /** Çevrilmiş etiket: şablon kendisine verilen sözcüğü çiziyor, aramıyor. */
13
+ /** The translated label: the template draws the word it is given, it does not look one up. TR: Çevrilmiş etiket: şablon kendisine verilen sözcüğü çiziyor, aramıyor. */
14
14
  label: string;
15
15
  href: string;
16
16
  };
17
17
  export type DetailTemplateProps = {
18
- /** Başlığın üstündeki iz. Son öğe o anki nesnedir ve href almaz. */
18
+ /** The trail above the title. The last item is the current object and takes no href. TR: Başlığın üstündeki iz. Son öğe o anki nesnedir ve href almaz. */
19
19
  breadcrumb: {
20
20
  label: string;
21
21
  href?: string;
22
22
  }[];
23
23
  title: string;
24
- /** Başlığın altı: nesnenin kimlik satırı. */
24
+ /** Under the title: the object's identity line. TR: Başlığın altı: nesnenin kimlik satırı. */
25
25
  subtitle?: string;
26
26
  actions?: ReactNode;
27
27
  /**
@@ -45,7 +45,7 @@ export type DetailTemplateProps = {
45
45
  breadcrumb: string;
46
46
  tabs: string;
47
47
  } & ErrorLabels;
48
- /** Açık sekmenin gövdesi. Şablon hangi sekme olduğunu bilmiyor, bilmemeli. */
48
+ /** The body of the open tab. The template does not know which tab it is, and must not. TR: Açık sekmenin gövdesi. Şablon hangi sekme olduğunu bilmiyor, bilmemeli. */
49
49
  children?: ReactNode;
50
50
  };
51
51
  export declare function DetailTemplate({ breadcrumb, title, subtitle, actions, tabs, activeTab, state, error, linkComponent: Link, labels, children, }: DetailTemplateProps): import("react").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"detail-template.d.ts","sourceRoot":"","sources":["../../src/patterns/detail-template.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAErB;;;;;GAKG;AAEH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAExD,MAAM,MAAM,SAAS,GAAG;IACtB,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,oEAAoE;IACpE,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IAC5B,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,WAAW,CAAC;IAE5E,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,KAAK,EACL,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,SAAS,EACT,KAAe,EACf,KAAK,EACL,aAAa,EAAE,IAAgB,EAC/B,MAAM,EACN,QAAQ,GACT,EAAE,mBAAmB,+BA+CrB"}
1
+ {"version":3,"file":"detail-template.d.ts","sourceRoot":"","sources":["../../src/patterns/detail-template.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAErB;;;;;GAKG;AAEH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAExD,MAAM,MAAM,SAAS,GAAG;IACtB,+GAA+G;IAC/G,GAAG,EAAE,MAAM,CAAC;IACZ,wKAAwK;IACxK,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,0JAA0J;IAC1J,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IAC5B,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,WAAW,CAAC;IAE5E,sKAAsK;IACtK,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,KAAK,EACL,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,SAAS,EACT,KAAe,EACf,KAAK,EACL,aAAa,EAAE,IAAgB,EAC/B,MAAM,EACN,QAAQ,GACT,EAAE,mBAAmB,+BA+CrB"}
@@ -6,7 +6,7 @@
6
6
  * dayatıyor, çünkü işleri o. Ayrı bir giriş, bir ürünün "yalnız bileşenleri
7
7
  * alayım" diyebilmesi demek.
8
8
  */
9
- export { PlainLink, ErrorSlot, Busy, errorDetail, type ErrorLabels, type LinkComponent, type TemplateError, } from "./shared.js";
9
+ export { PlainLink, errorDetail, type ErrorLabels, type LinkComponent, type TemplateError, } from "./shared.js";
10
10
  export { ListTemplate, type ListState, type ListTemplateProps } from "./list-template.js";
11
11
  export { OverviewTemplate, type OverviewState, type OverviewTemplateProps, } from "./overview-template.js";
12
12
  export { DetailTemplate, type DetailState, type DetailTab, type DetailTemplateProps, } from "./detail-template.js";
@@ -15,4 +15,5 @@ export { AuthTemplate, AuthProviders } from "./auth-template.js";
15
15
  export { WizardTemplate, type WizardStep, type WizardTemplateProps } from "./wizard-template.js";
16
16
  export { PublicTemplate, type PublicState, type PublicTemplateProps } from "./public-template.js";
17
17
  export { AppShell, type NavEntry, type AppShellProps } from "./app-shell.js";
18
+ export { AppearanceTemplate, type Appearance, type AppearanceLabels, } from "./appearance-template.js";
18
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/patterns/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,SAAS,EACT,SAAS,EACT,IAAI,EACJ,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EACL,gBAAgB,EAChB,KAAK,aAAa,EAClB,KAAK,qBAAqB,GAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,mBAAmB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,qBAAqB,GAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAClG,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/patterns/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EACL,SAAS,EACT,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EACL,gBAAgB,EAChB,KAAK,aAAa,EAClB,KAAK,qBAAqB,GAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,mBAAmB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,qBAAqB,GAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,KAAK,UAAU,EAAE,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAClG,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EACL,kBAAkB,EAClB,KAAK,UAAU,EACf,KAAK,gBAAgB,GACtB,MAAM,0BAA0B,CAAC"}
@@ -6,7 +6,11 @@
6
6
  * dayatıyor, çünkü işleri o. Ayrı bir giriş, bir ürünün "yalnız bileşenleri
7
7
  * alayım" diyebilmesi demek.
8
8
  */
9
- export { PlainLink, ErrorSlot, Busy, errorDetail, } from "./shared.js";
9
+ /* `ErrorSlot` ve `Busy` DIŞA VURULMUYOR: şablonların iç makinesi. Hata ve
10
+ yükleme hâllerini şablonlar zaten kendileri çiziyor, ve ikisini ayrıca
11
+ sunmak "aynı hâli iki farklı yoldan çizme" davetiydi. Bir tüketici o
12
+ görünümü istiyorsa şablonu kullanıyor. */
13
+ export { PlainLink, errorDetail, } from "./shared.js";
10
14
  export { ListTemplate } from "./list-template.js";
11
15
  export { OverviewTemplate, } from "./overview-template.js";
12
16
  export { DetailTemplate, } from "./detail-template.js";
@@ -15,3 +19,4 @@ export { AuthTemplate, AuthProviders } from "./auth-template.js";
15
19
  export { WizardTemplate } from "./wizard-template.js";
16
20
  export { PublicTemplate } from "./public-template.js";
17
21
  export { AppShell } from "./app-shell.js";
22
+ export { AppearanceTemplate, } from "./appearance-template.js";