tamga-ui 0.4.3 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/CHANGELOG.md +908 -0
  2. package/README.md +3 -1
  3. package/dist/blocks/count-row.d.ts +3 -8
  4. package/dist/blocks/count-row.d.ts.map +1 -1
  5. package/dist/blocks/count-row.js +3 -8
  6. package/dist/blocks/filter-bar.d.ts +42 -28
  7. package/dist/blocks/filter-bar.d.ts.map +1 -1
  8. package/dist/blocks/filter-bar.js +13 -5
  9. package/dist/blocks/index.d.ts +4 -17
  10. package/dist/blocks/index.d.ts.map +1 -1
  11. package/dist/blocks/index.js +4 -17
  12. package/dist/blocks/save-bar.d.ts +4 -12
  13. package/dist/blocks/save-bar.d.ts.map +1 -1
  14. package/dist/blocks/save-bar.js +4 -12
  15. package/dist/components/a11y.d.ts.map +1 -1
  16. package/dist/components/a11y.js +4 -15
  17. package/dist/components/advanced-input.d.ts +54 -48
  18. package/dist/components/advanced-input.d.ts.map +1 -1
  19. package/dist/components/advanced-input.js +64 -59
  20. package/dist/components/announcement.d.ts +34 -0
  21. package/dist/components/announcement.d.ts.map +1 -0
  22. package/dist/components/announcement.js +12 -0
  23. package/dist/components/appearance.d.ts +33 -1
  24. package/dist/components/appearance.d.ts.map +1 -1
  25. package/dist/components/appearance.js +78 -7
  26. package/dist/components/avatar.d.ts +28 -21
  27. package/dist/components/avatar.d.ts.map +1 -1
  28. package/dist/components/avatar.js +46 -22
  29. package/dist/components/badge.d.ts +54 -4
  30. package/dist/components/badge.d.ts.map +1 -1
  31. package/dist/components/badge.js +42 -9
  32. package/dist/components/bar.d.ts.map +1 -1
  33. package/dist/components/bar.js +4 -20
  34. package/dist/components/button.d.ts +15 -7
  35. package/dist/components/button.d.ts.map +1 -1
  36. package/dist/components/button.js +54 -8
  37. package/dist/components/chart.d.ts +5 -0
  38. package/dist/components/chart.d.ts.map +1 -1
  39. package/dist/components/chart.js +18 -11
  40. package/dist/components/checkbox.d.ts +23 -1
  41. package/dist/components/checkbox.d.ts.map +1 -1
  42. package/dist/components/checkbox.js +3 -4
  43. package/dist/components/chrome.d.ts +38 -54
  44. package/dist/components/chrome.d.ts.map +1 -1
  45. package/dist/components/chrome.js +55 -63
  46. package/dist/components/combobox.d.ts.map +1 -1
  47. package/dist/components/combobox.js +19 -3
  48. package/dist/components/data-table.d.ts +4 -4
  49. package/dist/components/data-table.d.ts.map +1 -1
  50. package/dist/components/data-table.js +15 -16
  51. package/dist/components/date-picker.d.ts.map +1 -1
  52. package/dist/components/date-picker.js +11 -4
  53. package/dist/components/disclosure.d.ts +17 -2
  54. package/dist/components/disclosure.d.ts.map +1 -1
  55. package/dist/components/disclosure.js +4 -8
  56. package/dist/components/display.d.ts +119 -94
  57. package/dist/components/display.d.ts.map +1 -1
  58. package/dist/components/display.js +103 -106
  59. package/dist/components/empty-state.d.ts +70 -52
  60. package/dist/components/empty-state.d.ts.map +1 -1
  61. package/dist/components/empty-state.js +40 -52
  62. package/dist/components/error-state.d.ts +21 -4
  63. package/dist/components/error-state.d.ts.map +1 -1
  64. package/dist/components/error-state.js +16 -6
  65. package/dist/components/file-upload.d.ts +45 -2
  66. package/dist/components/file-upload.d.ts.map +1 -1
  67. package/dist/components/file-upload.js +32 -7
  68. package/dist/components/gauge.d.ts +72 -9
  69. package/dist/components/gauge.d.ts.map +1 -1
  70. package/dist/components/gauge.js +52 -49
  71. package/dist/components/icons.d.ts +1 -1
  72. package/dist/components/icons.d.ts.map +1 -1
  73. package/dist/components/icons.js +4 -0
  74. package/dist/components/input.d.ts +21 -0
  75. package/dist/components/input.d.ts.map +1 -1
  76. package/dist/components/input.js +15 -1
  77. package/dist/components/layout.d.ts +47 -70
  78. package/dist/components/layout.d.ts.map +1 -1
  79. package/dist/components/layout.js +31 -73
  80. package/dist/components/link.d.ts +5 -10
  81. package/dist/components/link.d.ts.map +1 -1
  82. package/dist/components/live-scope.d.ts.map +1 -1
  83. package/dist/components/live-scope.js +5 -8
  84. package/dist/components/log-view.d.ts +32 -1
  85. package/dist/components/log-view.d.ts.map +1 -1
  86. package/dist/components/log-view.js +42 -15
  87. package/dist/components/number-input.d.ts +20 -2
  88. package/dist/components/number-input.d.ts.map +1 -1
  89. package/dist/components/number-input.js +32 -9
  90. package/dist/components/overlay.d.ts +69 -61
  91. package/dist/components/overlay.d.ts.map +1 -1
  92. package/dist/components/overlay.js +134 -77
  93. package/dist/components/pagination.d.ts.map +1 -1
  94. package/dist/components/pagination.js +12 -7
  95. package/dist/components/pie.d.ts.map +1 -1
  96. package/dist/components/pie.js +8 -7
  97. package/dist/components/primitives.d.ts +136 -6
  98. package/dist/components/primitives.d.ts.map +1 -1
  99. package/dist/components/primitives.js +73 -20
  100. package/dist/components/progress.d.ts +44 -9
  101. package/dist/components/progress.d.ts.map +1 -1
  102. package/dist/components/progress.js +21 -9
  103. package/dist/components/radio-group.d.ts.map +1 -1
  104. package/dist/components/radio-group.js +11 -12
  105. package/dist/components/rail-link.d.ts +17 -1
  106. package/dist/components/rail-link.d.ts.map +1 -1
  107. package/dist/components/rail-link.js +3 -3
  108. package/dist/components/rich-text.d.ts +8 -1
  109. package/dist/components/rich-text.d.ts.map +1 -1
  110. package/dist/components/rich-text.js +13 -19
  111. package/dist/components/says-bubble.d.ts +38 -0
  112. package/dist/components/says-bubble.d.ts.map +1 -0
  113. package/dist/components/says-bubble.js +6 -0
  114. package/dist/components/scroll-x.d.ts +23 -0
  115. package/dist/components/scroll-x.d.ts.map +1 -0
  116. package/dist/components/scroll-x.js +27 -0
  117. package/dist/components/section.d.ts +18 -1
  118. package/dist/components/section.d.ts.map +1 -1
  119. package/dist/components/section.js +12 -1
  120. package/dist/components/segmented.d.ts +17 -1
  121. package/dist/components/segmented.d.ts.map +1 -1
  122. package/dist/components/segmented.js +26 -6
  123. package/dist/components/skeleton.d.ts.map +1 -1
  124. package/dist/components/skeleton.js +1 -1
  125. package/dist/components/slider.d.ts +16 -2
  126. package/dist/components/slider.d.ts.map +1 -1
  127. package/dist/components/slider.js +12 -5
  128. package/dist/components/sparkline.d.ts +9 -2
  129. package/dist/components/sparkline.d.ts.map +1 -1
  130. package/dist/components/sparkline.js +9 -5
  131. package/dist/components/spinner.d.ts +16 -1
  132. package/dist/components/spinner.d.ts.map +1 -1
  133. package/dist/components/spinner.js +24 -1
  134. package/dist/components/square-picker.d.ts +4 -20
  135. package/dist/components/square-picker.d.ts.map +1 -1
  136. package/dist/components/square-picker.js +4 -20
  137. package/dist/components/stacked-bar.d.ts.map +1 -1
  138. package/dist/components/stacked-bar.js +5 -4
  139. package/dist/components/surface.d.ts +32 -3
  140. package/dist/components/surface.d.ts.map +1 -1
  141. package/dist/components/surface.js +11 -4
  142. package/dist/components/switch.d.ts +14 -1
  143. package/dist/components/switch.d.ts.map +1 -1
  144. package/dist/components/switch.js +2 -3
  145. package/dist/components/tabs.d.ts +35 -11
  146. package/dist/components/tabs.d.ts.map +1 -1
  147. package/dist/components/tabs.js +48 -5
  148. package/dist/components/timeline-strip.d.ts +28 -3
  149. package/dist/components/timeline-strip.d.ts.map +1 -1
  150. package/dist/components/timeline-strip.js +19 -8
  151. package/dist/components/tone.d.ts +51 -14
  152. package/dist/components/tone.d.ts.map +1 -1
  153. package/dist/components/tone.js +76 -14
  154. package/dist/components/tree-select.d.ts.map +1 -1
  155. package/dist/components/tree-select.js +10 -3
  156. package/dist/fonts/LICENSE-jetbrains-mono.txt +93 -0
  157. package/dist/fonts/LICENSE-onest.txt +93 -0
  158. package/dist/fonts/LICENSE-red-hat-display.txt +93 -0
  159. package/dist/fonts/jetbrains-mono-latin-ext-wght-normal.woff2 +0 -0
  160. package/dist/fonts/jetbrains-mono-latin-wght-normal.woff2 +0 -0
  161. package/dist/fonts/onest-latin-ext-wght-normal.woff2 +0 -0
  162. package/dist/fonts/onest-latin-wght-normal.woff2 +0 -0
  163. package/dist/fonts/red-hat-display-latin-ext-wght-normal.woff2 +0 -0
  164. package/dist/fonts/red-hat-display-latin-wght-normal.woff2 +0 -0
  165. package/dist/fonts.css +54 -0
  166. package/dist/index.d.ts +10 -7
  167. package/dist/index.d.ts.map +1 -1
  168. package/dist/index.js +9 -6
  169. package/dist/kit.css +3175 -645
  170. package/dist/lib/color.d.ts +8 -19
  171. package/dist/lib/color.d.ts.map +1 -1
  172. package/dist/lib/color.js +8 -19
  173. package/dist/lib/data-props.d.ts +4 -15
  174. package/dist/lib/data-props.d.ts.map +1 -1
  175. package/dist/lib/data-props.js +4 -15
  176. package/dist/lib/image.d.ts +4 -20
  177. package/dist/lib/image.d.ts.map +1 -1
  178. package/dist/lib/image.js +4 -20
  179. package/dist/lib/palette.d.ts +16 -20
  180. package/dist/lib/palette.d.ts.map +1 -1
  181. package/dist/lib/palette.js +136 -71
  182. package/dist/lib/scroll-lock.d.ts +4 -14
  183. package/dist/lib/scroll-lock.d.ts.map +1 -1
  184. package/dist/lib/scroll-lock.js +4 -14
  185. package/dist/patterns/app-shell.d.ts.map +1 -1
  186. package/dist/patterns/app-shell.js +4 -13
  187. package/dist/patterns/appearance-template.d.ts +20 -15
  188. package/dist/patterns/appearance-template.d.ts.map +1 -1
  189. package/dist/patterns/appearance-template.js +29 -8
  190. package/dist/patterns/list-template.d.ts.map +1 -1
  191. package/dist/patterns/list-template.js +1 -1
  192. package/dist/patterns/overview-template.d.ts.map +1 -1
  193. package/dist/patterns/overview-template.js +1 -1
  194. package/dist/patterns/settings-template.d.ts +1 -12
  195. package/dist/patterns/settings-template.d.ts.map +1 -1
  196. package/dist/patterns/settings-template.js +2 -2
  197. package/dist/patterns/shared.d.ts.map +1 -1
  198. package/dist/patterns/shared.js +8 -1
  199. package/dist/styles.css +2 -1
  200. package/dist/theme.css +96 -259
  201. package/package.json +4 -2
  202. package/dist/components/control-base.d.ts +0 -7
  203. package/dist/components/control-base.d.ts.map +0 -1
  204. package/dist/components/control-base.js +0 -6
@@ -1,4 +1,6 @@
1
1
  import type { ReactNode } from "react";
2
+ import type { IconGlyph } from "./icons.js";
3
+ import type { Tone } from "./tone.js";
2
4
  /**
3
5
  * BOŞ DURUM SİSTEMİ — dört slot, ve hiçbiri neyin eksik olduğunu bilmez.
4
6
  *
@@ -13,17 +15,14 @@ export type Art = (opts: {
13
15
  float: boolean;
14
16
  }) => ReactNode;
15
17
  /**
16
- * The speech bubble — the answer to "and the figure says …".
18
+ * ÇİZİMİN balonu · "ve figür şunu diyor" sorusunun cevabı. Adı bir ara
19
+ * `SaysBubble`dı ve tasarımda o ad KONUŞMA balonunun (04.14): müşteri
20
+ * mesajları, sipariş notları. İkisi aynı adı taşıyınca boş durum arayan da
21
+ * sohbet arayan da yanlış bileşeni buluyordu.
17
22
  *
18
- * It is the one part of the mascot that IS in the system: 1px edge plus a 2px
19
- * hard offset, exactly like every other raised object. That pairing is the
20
- * whole trick — it lets pixel art sit inside a strict interface without either
21
- * one looking lost.
22
- *
23
- * The line is real text, not decoration, so it is readable. Keep it to one
24
- * short sentence: the bubble is a voice, not a paragraph.
23
+ * Gerekçe: docs/gerekce/04-bos-ve-hata.md
25
24
  */
26
- export declare function SaysBubble({ children, art, size, float, className, ...rest }: {
25
+ export declare function ArtSays({ children, art, size, float, className, ...rest }: {
27
26
  children: React.ReactNode;
28
27
  art: Art;
29
28
  size?: number;
@@ -42,43 +41,58 @@ export declare function SaysBubble({ children, art, size, float, className, ...r
42
41
  * No border of its own: it drops into a table body or a list that already has
43
42
  * one, and it inherits that list's row rhythm.
44
43
  */
45
- export declare function EmptyNote({ art, title, children, action, className, ...rest }: {
46
- art: Art;
47
- title: string;
44
+ export declare function EmptyNote({ art, icon, title, children, action, className, ...rest }: {
45
+ /** The drawing. With `icon` instead, the note collapses to a single line. TR: Çizim. Yerine `icon` verilirse not tek satıra iniyor. */
46
+ art?: Art;
47
+ /**
48
+ * A glyph instead of the drawing · and with it the note becomes ONE LINE: a card that is empty
49
+ * inside an otherwise full screen does not deserve a picture, it deserves a sentence. TR:
50
+ * Çizim yerine bir glif · ve onunla birlikte not TEK SATIR oluyor: dolu bir ekranın içindeki
51
+ * boş bir kart resim değil bir cümle hak ediyor.
52
+ */
53
+ icon?: IconGlyph;
54
+ /** Omitted, the sentence stands alone · which is the one-line note's whole shape. TR: Verilmezse cümle tek başına duruyor · tek satırlık notun bütün biçimi bu. */
55
+ title?: string;
48
56
  children?: React.ReactNode;
49
57
  action?: React.ReactNode;
50
58
  className?: string;
51
59
  /** `data-*` hooks pass through. TR: `data-*` kancaları geçiyor. */
52
60
  [k: `data-${string}`]: unknown;
53
61
  }): import("react").JSX.Element;
54
- export type EmptyLayout = "banner" | "ticket" | "routes";
62
+ export type EmptyLayout = "plain" | "banner" | "ticket" | "routes";
55
63
  export type EmptyRoute = {
56
64
  label: string;
57
65
  note?: string;
58
66
  onClick?: () => void;
59
67
  };
60
68
  /**
61
- * A surface that has nothing in it.
62
- *
63
- * Three layouts, one set of content. They are NOT three styles of the same
64
- * picture — each answers a different question about the screen underneath:
69
+ * A surface that has nothing in it · three layouts (banner · ticket · routes),
70
+ * one set of content. Not three styles of the same picture: each answers a
71
+ * different question about the screen underneath, and each wants its own
72
+ * drawing.
65
73
  *
66
- * banner wide and horizontal: art left, words centre, action at the far
67
- * right edge, numbered base plate underneath. Reads as a strip
68
- * across the top of a working screen.
69
- * ticket a narrow tag pinned to a big surface, with a perforation and one
70
- * full-width action. For a single unambiguous next step.
71
- * routes the words and the figure on the left, a list of ways in on the right.
72
- * Two buttons ask a yes/no question; a list answers "what can I even
73
- * do here", which is what somebody arriving actually wants to know.
74
- *
75
- * Each one also wants a different drawing. The layout decides the shape; the
76
- * drawing decides what the emptiness FEELS like, and those are two choices,
77
- * not one.
74
+ * Gerekçe: docs/gerekce/04-bos-ve-hata.md
78
75
  */
79
- export declare function EmptyState({ layout, art, kicker, title, children, action, note, says, steps, routes, size, className, ...rest }: {
76
+ export declare function EmptyState({ layout, art, icon, tone, kicker, title, children, action, note, says, steps, routes, routesLabel, size, className, ...rest }: {
77
+ /**
78
+ * `plain` the dashed card: an icon tile, a line and the first step · the shape most screens
79
+ * need. The other three carry the drawing. TR: `plain` kesik kenarlı kart: bir ikon karosu,
80
+ * bir satır ve ilk adım · çoğu ekranın ihtiyacı olan biçim. Ötekiler çizimi taşıyor.
81
+ */
80
82
  layout?: EmptyLayout;
81
- art: Art;
83
+ /**
84
+ * The drawing, for the three layouts built around one. TR: Çizim, etrafında kurulan üç
85
+ * yerleşim için.
86
+ */
87
+ art?: Art;
88
+ /** `plain` only: the glyph in the tile. TR: yalnız `plain`: karodaki glif. */
89
+ icon?: IconGlyph;
90
+ /**
91
+ * `plain` only: the tile's wash. Left out it stays the accent's light tone, which is what an
92
+ * empty state is: an invitation, not a fault. TR: yalnız `plain`: karonun yıkaması.
93
+ * Verilmezse vurgunun açık tonunda kalıyor · bir boş durum bir davet, bir arıza değil.
94
+ */
95
+ tone?: Tone;
82
96
  /** what KIND of nothing this is: "no records", "no results" TR: bunun NE TÜR bir hiçlik olduğu: "kayıt yok", "sonuç yok" */
83
97
  kicker?: string;
84
98
  title: string;
@@ -99,24 +113,23 @@ export declare function EmptyState({ layout, art, kicker, title, children, actio
99
113
  steps?: string[];
100
114
  /** routes only: the ways in TR: yalnız rotalar: içeri giden yollar */
101
115
  routes?: EmptyRoute[];
116
+ /**
117
+ * routes only: the micro-label over the list. Omitted, the list stands on its
118
+ * own. TR: yalnız rotalar: listenin üstündeki mikro etiket. Verilmezse liste
119
+ * kendi başına duruyor.
120
+ */
121
+ routesLabel?: string;
102
122
  size?: number;
103
123
  className?: string;
104
124
  /** `data-*` hooks pass through. TR: `data-*` kancaları geçiyor. */
105
125
  [k: `data-${string}`]: unknown;
106
126
  }): import("react").JSX.Element;
107
127
  /**
108
- * A whole body with nothing in it — and no box drawn around the nothing.
109
- *
110
- * This is the one that goes straight onto the page, not inside a card. A
111
- * bordered panel needs content to bound; when the entire screen is empty there
112
- * is nothing to bound, and the border becomes a frame around a void. So there
113
- * is no border, no ground, no offset. The only structure is a hard floor rule
114
- * as wide as the figure — enough to say he is standing somewhere, not enough to be a
115
- * box.
128
+ * A whole body with nothing in it, and no box drawn around the nothing: no
129
+ * border, no ground, no offset, just a hard floor rule as wide as the figure.
130
+ * For an empty area INSIDE a working screen use EmptyState instead.
116
131
  *
117
- * Reach for it when somebody lands on a section they have never used. For an
118
- * empty area INSIDE a working screen, use EmptyState instead: that one has a
119
- * card around it because the rest of the screen does too.
132
+ * Gerekçe: docs/gerekce/04-bos-ve-hata.md
120
133
  */
121
134
  export declare function EmptyBlank({ art, kicker, title, children, action, says, size, className, ...rest }: {
122
135
  art: Art;
@@ -131,18 +144,23 @@ export declare function EmptyBlank({ art, kicker, title, children, action, says,
131
144
  [k: `data-${string}`]: unknown;
132
145
  }): import("react").JSX.Element;
133
146
  /**
134
- * A choice you are offering — a template, a starting point, a preset.
135
- *
136
- * It is a real button, so it obeys raised physics: 1px edge, 2px offset, lifts
137
- * under the cursor, presses flat when clicked. A template you cannot pick has
138
- * no business looking like a card.
147
+ * A choice you are offering · a template, a preset. A real button, so it obeys
148
+ * raised physics. The category colour is a 3px SPINE under the art, never a
149
+ * coloured banner behind it (Yasa 3).
139
150
  *
140
- * The category colour is a 3px SPINE under the art rather than a coloured
141
- * banner behind it. A wall of coloured banners would out-shout a real event
142
- * (Yasa 3); a rule carries the same grouping and outranks nothing.
151
+ * Gerekçe: docs/gerekce/04-bos-ve-hata.md
143
152
  */
144
- export declare function EmptyTile({ art, kicker, title, children, tone, onClick, className, ...rest }: {
145
- art: Art;
153
+ export declare function EmptyTile({ art, icon, kicker, title, children, tone, onClick, className, ...rest }: {
154
+ /** The drawing. With `icon` instead, the tile becomes the dashed ADD cell. TR: Çizim. Yerine `icon` verilirse karo kesik kenarlı EKLE hücresi oluyor. */
155
+ art?: Art;
156
+ /**
157
+ * A glyph instead of the drawing · and the tile turns into the grid's empty cell: dashed while
158
+ * it waits, solid and raised under the pointer. The dashed edge says "not content yet", the
159
+ * lift says "this is a control". TR: Çizim yerine bir glif · ve karo ızgaranın boş hücresine
160
+ * dönüşüyor: beklerken kesik, imleç altında kesiksiz ve yükselmiş. Kesik kenar "henüz içerik
161
+ * değil" diyor, yükselme "bu bir kontrol".
162
+ */
163
+ icon?: IconGlyph;
146
164
  /** the identifier-shaped line above the title TR: başlığın üstündeki tanımlayıcı biçimli satır */
147
165
  kicker?: string;
148
166
  title: string;
@@ -1 +1 @@
1
- {"version":3,"file":"empty-state.d.ts","sourceRoot":"","sources":["../../src/components/empty-state.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"empty-state.d.ts","sourceRoot":"","sources":["../../src/components/empty-state.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGtC;;;;GAIG;AAEH;;;GAGG;AACH,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,KAAK,SAAS,CAAC;AA4BxE;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,EACtB,QAAQ,EACR,GAAG,EACH,IAAU,EACV,KAAY,EACZ,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,GAAG,EAAE,GAAG,CAAC;IACT,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BA8BA;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,EACxB,GAAG,EACH,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,MAAM,EACN,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD,uIAAuI;IACvI,GAAG,CAAC,EAAE,GAAG,CAAC;IACV;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,mKAAmK;IACnK,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAiCA;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEnE,MAAM,MAAM,UAAU,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC;AAEhF;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAiB,EACjB,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,KAAK,EACL,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,MAAM,EACN,WAAW,EACX,IAAU,EACV,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;OAGG;IACH,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,8EAA8E;IAC9E,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,4HAA4H;IAC5H,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,gGAAgG;IAChG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,sEAAsE;IACtE,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BA4HA;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,EACzB,GAAG,EACH,MAAM,EACN,KAAK,EACL,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,IAAU,EACV,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD,GAAG,EAAE,GAAG,CAAC;IACT,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BA+BA;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,EACxB,GAAG,EACH,IAAI,EACJ,MAAM,EACN,KAAK,EACL,QAAQ,EACR,IAAQ,EACR,OAAO,EACP,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD,yJAAyJ;IACzJ,GAAG,CAAC,EAAE,GAAG,CAAC;IACV;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,kGAAkG;IAClG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B;;;OAGG;IACH,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAkCA"}
@@ -3,6 +3,7 @@ import { Icon } from "./icon.js";
3
3
  import { cn } from "../lib/cn.js";
4
4
  import { dataProps } from "../lib/data-props.js";
5
5
  import { CaretRight } from "./icons.js";
6
+ import { toneOf } from "./tone.js";
6
7
  /**
7
8
  * The drawing standing on the ground.
8
9
  *
@@ -15,17 +16,14 @@ function ArtFigure({ art, size, float, ground = true, }) {
15
16
  return (_jsx("span", { className: "tamga-art-fig", "data-ground": ground, children: art({ size, float: Boolean(float) }) }));
16
17
  }
17
18
  /**
18
- * The speech bubble — the answer to "and the figure says …".
19
+ * ÇİZİMİN balonu · "ve figür şunu diyor" sorusunun cevabı. Adı bir ara
20
+ * `SaysBubble`dı ve tasarımda o ad KONUŞMA balonunun (04.14): müşteri
21
+ * mesajları, sipariş notları. İkisi aynı adı taşıyınca boş durum arayan da
22
+ * sohbet arayan da yanlış bileşeni buluyordu.
19
23
  *
20
- * It is the one part of the mascot that IS in the system: 1px edge plus a 2px
21
- * hard offset, exactly like every other raised object. That pairing is the
22
- * whole trick — it lets pixel art sit inside a strict interface without either
23
- * one looking lost.
24
- *
25
- * The line is real text, not decoration, so it is readable. Keep it to one
26
- * short sentence: the bubble is a voice, not a paragraph.
24
+ * Gerekçe: docs/gerekce/04-bos-ve-hata.md
27
25
  */
28
- export function SaysBubble({ children, art, size = 168, float = true, className, ...rest }) {
26
+ export function ArtSays({ children, art, size = 168, float = true, className, ...rest }) {
29
27
  return (_jsxs("div", { ...dataProps(rest), className: cn("relative shrink-0 pt-11", float && "tamga-float", className), children: [_jsxs("div", { className: "absolute top-0 left-1/2 z-10 -translate-x-1/2 whitespace-nowrap", children: [_jsx("div", { className: "px-3 py-1.5 text-small font-medium text-ink", style: {
30
28
  background: "var(--color-shell)",
31
29
  border: "1px solid var(--color-edge)",
@@ -47,31 +45,29 @@ export function SaysBubble({ children, art, size = 168, float = true, className,
47
45
  * No border of its own: it drops into a table body or a list that already has
48
46
  * one, and it inherits that list's row rhythm.
49
47
  */
50
- export function EmptyNote({ art, title, children, action, className, ...rest }) {
51
- return (_jsxs("div", { ...dataProps(rest), className: cn("tamga-gutter flex items-center gap-4 py-6", className), children: [_jsx("span", { className: "tamga-art-port tamga-art-well", children: _jsx(ArtFigure, { art: art, size: 56, ground: false }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: "text-body font-medium text-ink", children: title }), children ? (_jsx("p", { className: "mt-1 max-w-[var(--measure)] text-small leading-relaxed text-ink-faint", children: children })) : null] }), action ? _jsx("div", { className: "shrink-0", children: action }) : null] }));
48
+ export function EmptyNote({ art, icon, title, children, action, className, ...rest }) {
49
+ if (icon || !art) {
50
+ return (_jsxs("div", { ...dataProps(rest), className: cn("tamga-gutter flex items-center gap-2.5 py-4", className), children: [icon ? _jsx(Icon, { icon: icon, size: "sm", className: "shrink-0 text-ink-faint" }) : null, _jsxs("span", { className: "min-w-0 flex-1 text-body text-ink-faint", children: [title ? _jsxs("span", { className: "font-semibold text-ink", children: [title, " "] }) : null, children] }), action ? _jsx("div", { className: "shrink-0", children: action }) : null] }));
51
+ }
52
+ return (_jsxs("div", { ...dataProps(rest), className: cn("tamga-gutter flex items-center gap-4 py-6", className), children: [_jsx("span", { className: "tamga-art-port tamga-art-well", children: _jsx(ArtFigure, { art: art, size: 56, ground: false }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [title ? _jsx("p", { className: "font-display text-subhead font-extrabold text-ink", children: title }) : null, children ? (_jsx("p", { className: "mt-1 max-w-[var(--measure)] text-small leading-relaxed text-ink-faint", children: children })) : null] }), action ? _jsx("div", { className: "shrink-0", children: action }) : null] }));
52
53
  }
53
54
  /**
54
- * A surface that has nothing in it.
55
- *
56
- * Three layouts, one set of content. They are NOT three styles of the same
57
- * picture — each answers a different question about the screen underneath:
58
- *
59
- * banner wide and horizontal: art left, words centre, action at the far
60
- * right edge, numbered base plate underneath. Reads as a strip
61
- * across the top of a working screen.
62
- * ticket a narrow tag pinned to a big surface, with a perforation and one
63
- * full-width action. For a single unambiguous next step.
64
- * routes the words and the figure on the left, a list of ways in on the right.
65
- * Two buttons ask a yes/no question; a list answers "what can I even
66
- * do here", which is what somebody arriving actually wants to know.
55
+ * A surface that has nothing in it · three layouts (banner · ticket · routes),
56
+ * one set of content. Not three styles of the same picture: each answers a
57
+ * different question about the screen underneath, and each wants its own
58
+ * drawing.
67
59
  *
68
- * Each one also wants a different drawing. The layout decides the shape; the
69
- * drawing decides what the emptiness FEELS like, and those are two choices,
70
- * not one.
60
+ * Gerekçe: docs/gerekce/04-bos-ve-hata.md
71
61
  */
72
- export function EmptyState({ layout = "banner", art, kicker, title, children, action, note, says, steps, routes, size = 150, className, ...rest }) {
73
- const figure = says !== undefined ? (_jsx(SaysBubble, { art: art, size: size, children: says })) : (_jsx(ArtFigure, { art: art, size: size, float: true }));
74
- const words = (_jsxs(_Fragment, { children: [kicker ? _jsx("p", { className: "tamga-kicker mb-2", children: kicker }) : null, _jsx("h3", { ...dataProps(rest), className: "text-display-sm font-semibold tracking-tight text-ink", children: title }), children ? (_jsx("p", { className: "mt-3 max-w-[var(--measure)] text-control leading-relaxed text-ink-soft", children: children })) : null, note ? (_jsx("p", { className: "mt-2 max-w-[var(--measure)] text-small leading-relaxed text-ink-faint", children: note })) : null] }));
62
+ export function EmptyState({ layout = "banner", art, icon, tone, kicker, title, children, action, note, says, steps, routes, routesLabel, size = 150, className, ...rest }) {
63
+ const figure = !art ? null : says !== undefined ? (_jsx(ArtSays, { art: art, size: size, children: says })) : (_jsx(ArtFigure, { art: art, size: size, float: true }));
64
+ const words = (_jsxs(_Fragment, { children: [kicker ? _jsx("p", { className: "tamga-kicker mb-2", children: kicker }) : null, _jsx("h3", { ...dataProps(rest), className: "font-display text-display-sm font-extrabold tracking-tight text-ink", children: title }), children ? (_jsx("p", { className: "mt-3 max-w-[var(--measure)] text-body leading-relaxed text-ink-soft", children: children })) : null, note ? (_jsx("p", { className: "mt-2 max-w-[var(--measure)] text-small leading-relaxed text-ink-faint", children: note })) : null] }));
65
+ if (layout === "plain") {
66
+ /* KESİK KENARLI KART: kitin her yerinde kesik çizgi "henüz gerçek içerik
67
+ değil" demek, ve boş bir bölüm tam olarak o. Dolu hâlinde aynı yerde
68
+ kesiksiz bir kart duruyor · ikisi aynı kutu, biri henüz dolmamış. */
69
+ return (_jsxs("div", { ...dataProps(rest), className: cn("tamga-empty-plain", className), children: [icon ? (_jsx("span", { "aria-hidden": true, className: "tamga-empty-tile", style: tone ? { background: toneOf(tone).bg, color: toneOf(tone).fg } : undefined, children: _jsx(Icon, { icon: icon, size: "xl", weight: "bold" }) })) : null, words, action ? _jsx("div", { className: "mt-2 flex flex-wrap justify-center gap-3", children: action }) : null] }));
70
+ }
75
71
  if (layout === "banner") {
76
72
  return (_jsxs("div", { className: cn("flex flex-col overflow-hidden", className), children: [_jsxs("div", { className: "flex flex-1 flex-col sm:flex-row sm:items-stretch", children: [_jsx("div", { className: "tamga-art-well tamga-art-stage tamga-art-floor sm:border-b-0", children: figure }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-7 px-6 py-7 sm:flex-row sm:items-center sm:justify-between sm:gap-10 sm:px-9 sm:py-9", children: [_jsx("div", { className: "min-w-0", children: words }), action ? (_jsx("div", { className: "flex shrink-0 flex-wrap items-center gap-3", children: action })) : null] })] }), steps?.length ? (_jsx("ol", { className: "tamga-art-steps tamga-art-well", children: steps.map((step, i) => (_jsxs("li", { className: "tamga-art-step", children: [_jsx("span", { className: "tamga-art-step-n", children: String(i + 1).padStart(2, "0") }), _jsx("span", { className: "text-small leading-relaxed text-ink-soft", children: step })] }, step))) })) : null] }));
77
73
  }
@@ -79,36 +75,28 @@ export function EmptyState({ layout = "banner", art, kicker, title, children, ac
79
75
  return (_jsx("div", { className: cn("flex justify-center px-6 py-10", className), children: _jsxs("div", { className: "tamga-card w-full max-w-90 overflow-hidden", children: [_jsx("div", { className: "tamga-art-well tamga-art-band", children: figure }), _jsx("div", { className: "px-6 pt-6 pb-7 text-center [&_p]:mx-auto", children: words }), _jsx("div", { className: "tamga-art-divider" }), action ? (_jsx("div", { className: "flex flex-col gap-2 p-4 [&>*]:w-full [&>*]:justify-center", children: action })) : null] }) }));
80
76
  }
81
77
  /* routes — three columns on one line: the figure, the words, the ways in */
82
- return (_jsxs("div", { className: cn("flex flex-col gap-8 px-6 py-9 sm:flex-row sm:items-center sm:gap-10 sm:px-10 sm:py-10", className), children: [_jsx("div", { className: "flex shrink-0 items-end", children: says !== undefined ? (_jsx(SaysBubble, { art: art, size: size, children: says })) : (_jsx(ArtFigure, { art: art, size: size, float: true })) }), _jsxs("div", { className: "min-w-0 flex-1", children: [words, action ? _jsx("div", { className: "mt-6 flex flex-wrap gap-3", children: action }) : null] }), _jsxs("div", { className: "flex w-full shrink-0 flex-col gap-2.5 sm:max-w-76", children: [_jsx("p", { className: "tamga-kicker mb-0.5", children: "ways in" }), routes?.map((r) => (_jsxs("button", { type: "button", onClick: r.onClick, className: "tamga-art-route", children: [_jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block text-body font-medium text-ink", children: r.label }), r.note ? _jsx("span", { className: "block text-small text-ink-faint", children: r.note }) : null] }), _jsx(Icon, { icon: CaretRight, size: "sm" })] }, r.label)))] })] }));
78
+ return (_jsxs("div", { className: cn("flex flex-col gap-8 px-6 py-9 sm:flex-row sm:items-center sm:gap-10 sm:px-10 sm:py-10", className), children: [_jsx("div", { className: "flex shrink-0 items-end", children: figure }), _jsxs("div", { className: "min-w-0 flex-1", children: [words, action ? _jsx("div", { className: "mt-6 flex flex-wrap gap-3", children: action }) : null] }), _jsxs("div", { className: "flex w-full shrink-0 flex-col gap-2.5 sm:max-w-76", children: [routesLabel ? _jsx("p", { className: "tamga-kicker mb-0.5", children: routesLabel }) : null, routes?.map((r) => (_jsxs("button", { type: "button", onClick: r.onClick, className: "tamga-art-route", children: [_jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block text-body font-medium text-ink", children: r.label }), r.note ? _jsx("span", { className: "block text-small text-ink-faint", children: r.note }) : null] }), _jsx(Icon, { icon: CaretRight, size: "sm" })] }, r.label)))] })] }));
83
79
  }
84
80
  /**
85
- * A whole body with nothing in it — and no box drawn around the nothing.
86
- *
87
- * This is the one that goes straight onto the page, not inside a card. A
88
- * bordered panel needs content to bound; when the entire screen is empty there
89
- * is nothing to bound, and the border becomes a frame around a void. So there
90
- * is no border, no ground, no offset. The only structure is a hard floor rule
91
- * as wide as the figure — enough to say he is standing somewhere, not enough to be a
92
- * box.
81
+ * A whole body with nothing in it, and no box drawn around the nothing: no
82
+ * border, no ground, no offset, just a hard floor rule as wide as the figure.
83
+ * For an empty area INSIDE a working screen use EmptyState instead.
93
84
  *
94
- * Reach for it when somebody lands on a section they have never used. For an
95
- * empty area INSIDE a working screen, use EmptyState instead: that one has a
96
- * card around it because the rest of the screen does too.
85
+ * Gerekçe: docs/gerekce/04-bos-ve-hata.md
97
86
  */
98
87
  export function EmptyBlank({ art, kicker, title, children, action, says, size = 230, className, ...rest }) {
99
- return (_jsxs("div", { ...dataProps(rest), className: cn("flex w-full flex-col items-center justify-center px-6 py-16 text-center", className), children: [says !== undefined ? (_jsx(SaysBubble, { art: art, size: size, children: says })) : (_jsx(ArtFigure, { art: art, size: size, float: true, ground: false })), _jsx("span", { className: "tamga-art-blank-floor mt-1 mb-8", style: { width: size * 0.72 } }), kicker ? _jsx("p", { className: "tamga-kicker mb-2", children: kicker }) : null, _jsx("h3", { className: "text-display-sm font-semibold tracking-tight text-ink", children: title }), children ? (_jsx("p", { className: "mt-3 max-w-[var(--measure)] text-control leading-relaxed text-ink-soft", children: children })) : null, action ? (_jsx("div", { className: "mt-8 flex flex-wrap items-center justify-center gap-3", children: action })) : null] }));
88
+ return (_jsxs("div", { ...dataProps(rest), className: cn("flex w-full flex-col items-center justify-center px-6 py-16 text-center", className), children: [says !== undefined ? (_jsx(ArtSays, { art: art, size: size, children: says })) : (_jsx(ArtFigure, { art: art, size: size, float: true, ground: false })), _jsx("span", { className: "tamga-art-blank-floor mt-1 mb-8", style: { width: size * 0.72 } }), kicker ? _jsx("p", { className: "tamga-kicker mb-2", children: kicker }) : null, _jsx("h3", { className: "font-display text-display-sm font-extrabold tracking-tight text-ink", children: title }), children ? (_jsx("p", { className: "mt-3 max-w-[var(--measure)] text-body leading-relaxed text-ink-soft", children: children })) : null, action ? (_jsx("div", { className: "mt-8 flex flex-wrap items-center justify-center gap-3", children: action })) : null] }));
100
89
  }
101
90
  /**
102
- * A choice you are offering — a template, a starting point, a preset.
91
+ * A choice you are offering · a template, a preset. A real button, so it obeys
92
+ * raised physics. The category colour is a 3px SPINE under the art, never a
93
+ * coloured banner behind it (Yasa 3).
103
94
  *
104
- * It is a real button, so it obeys raised physics: 1px edge, 2px offset, lifts
105
- * under the cursor, presses flat when clicked. A template you cannot pick has
106
- * no business looking like a card.
107
- *
108
- * The category colour is a 3px SPINE under the art rather than a coloured
109
- * banner behind it. A wall of coloured banners would out-shout a real event
110
- * (Yasa 3); a rule carries the same grouping and outranks nothing.
95
+ * Gerekçe: docs/gerekce/04-bos-ve-hata.md
111
96
  */
112
- export function EmptyTile({ art, kicker, title, children, tone = 1, onClick, className, ...rest }) {
97
+ export function EmptyTile({ art, icon, kicker, title, children, tone = 1, onClick, className, ...rest }) {
98
+ if (icon || !art) {
99
+ return (_jsxs("button", { ...dataProps(rest), type: "button", onClick: onClick, className: cn("tamga-empty-add", className), children: [icon ? (_jsx("span", { "aria-hidden": true, className: "tamga-empty-add-kare", children: _jsx(Icon, { icon: icon, size: "sm", weight: "bold" }) })) : null, _jsx("span", { className: "text-body font-bold", children: title })] }));
100
+ }
113
101
  return (_jsxs("button", { ...dataProps(rest), type: "button", onClick: onClick, className: cn("tamga-art-tile", className), children: [_jsx("span", { className: "tamga-art-well flex h-28 items-end justify-center pt-4", children: _jsx(ArtFigure, { art: art, size: 86 }) }), _jsx("span", { className: "tamga-art-spine", "data-tone": tone }), _jsxs("span", { className: "tamga-gutter flex min-w-0 flex-1 flex-col py-4", children: [kicker ? _jsx("span", { className: "tamga-kicker mb-1.5", children: kicker }) : null, _jsx("span", { className: "text-body font-semibold text-ink", children: title }), children ? (_jsx("span", { className: "mt-1 text-small leading-relaxed text-ink-faint", children: children })) : null] })] }));
114
102
  }
@@ -4,7 +4,16 @@
4
4
  * Gerekçe: docs/gerekce/04-bos-ve-hata.md
5
5
  */
6
6
  export declare function ErrorState({ title, description, detail, onRetry, retryLabel, compact, ...rest }: {
7
- title?: string;
7
+ /**
8
+ * What failed, in the reader's language. Required, with no default: a
9
+ * default here would be an English sentence rendered inside every other
10
+ * language, and nobody notices a wrong default until a user reports it.
11
+ * TR: Neyin başarısız olduğu, okuyanın dilinde. Zorunlu ve varsayılansız:
12
+ * buradaki bir varsayılan, her dilin içinde çizilen bir İngilizce cümle
13
+ * olurdu, ve yanlış bir varsayılanı kimse bir kullanıcı bildirene kadar
14
+ * fark etmiyor.
15
+ */
16
+ title: string;
8
17
  /**
9
18
  * plain words: what the person cannot do right now TR: düz sözcüklerle: kişinin şu an ne
10
19
  * yapamadığı
@@ -20,8 +29,6 @@ export declare function ErrorState({ title, description, detail, onRetry, retryL
20
29
  * ürünün API sözleşmesinin kararı, bu bileşenin değil.
21
30
  */
22
31
  detail?: string;
23
- onRetry?: () => void;
24
- retryLabel?: string;
25
32
  /**
26
33
  * inside a card or a panel rather than a whole page TR: bütün bir sayfa yerine bir kartın ya
27
34
  * da panelin içinde
@@ -29,5 +36,15 @@ export declare function ErrorState({ title, description, detail, onRetry, retryL
29
36
  compact?: boolean;
30
37
  /** `data-*` hooks pass through. TR: `data-*` kancaları geçiyor. */
31
38
  [k: `data-${string}`]: unknown;
32
- }): import("react").JSX.Element;
39
+ } & ({
40
+ onRetry?: undefined;
41
+ retryLabel?: undefined;
42
+ } | {
43
+ onRetry: () => void;
44
+ /**
45
+ * The retry button's words, in the reader's language. TR: Yeniden dene
46
+ * düğmesinin sözcükleri, okuyanın dilinde.
47
+ */
48
+ retryLabel: string;
49
+ })): import("react").JSX.Element;
33
50
  //# sourceMappingURL=error-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"error-state.d.ts","sourceRoot":"","sources":["../../src/components/error-state.tsx"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAA6B,EAC7B,WAAW,EACX,MAAM,EACN,OAAO,EACP,UAAwB,EACxB,OAAe,EACf,GAAG,IAAI,EACR,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAwCA"}
1
+ {"version":3,"file":"error-state.d.ts","sourceRoot":"","sources":["../../src/components/error-state.tsx"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,WAAW,EACX,MAAM,EACN,OAAO,EACP,UAAU,EACV,OAAe,EACf,GAAG,IAAI,EACR,EAAE;IACD;;;;;;;;OAQG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,GAAG,CACA;IAAE,OAAO,CAAC,EAAE,SAAS,CAAC;IAAC,UAAU,CAAC,EAAE,SAAS,CAAA;CAAE,GAI/C;IACE,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB,CACJ,+BAgEA"}
@@ -8,10 +8,20 @@ import { Button } from "./button.js";
8
8
  *
9
9
  * Gerekçe: docs/gerekce/04-bos-ve-hata.md
10
10
  */
11
- export function ErrorState({ title = "Could not load this", description, detail, onRetry, retryLabel = "Try again", compact = false, ...rest }) {
12
- return (_jsxs("div", { ...dataProps(rest), role: "alert", "aria-live": "polite", className: `tamga-gutter flex flex-col items-start gap-4 ${compact ? "py-6" : "py-12"}`, children: [_jsx("span", { className: "flex size-10 items-center justify-center border", style: {
13
- borderRadius: "var(--radius-ctl)",
14
- borderColor: "var(--color-critical)",
15
- color: "var(--color-critical)",
16
- }, children: _jsx(Icon, { icon: Warning, size: "base" }) }), _jsxs("div", { children: [_jsx("p", { className: "text-body font-medium text-ink", children: title }), description ? (_jsx("p", { className: "mt-1 max-w-[var(--measure)] text-small leading-relaxed text-ink-faint", children: description })) : null, detail ? (_jsx("p", { className: "mt-2 max-w-[var(--measure)] break-words font-mono text-caption text-ink-faint", children: detail })) : null] }), onRetry ? (_jsxs(Button, { onClick: onRetry, children: [_jsx(Icon, { icon: Refresh, size: "sm" }), " ", retryLabel] })) : null] }));
11
+ export function ErrorState({ title, description, detail, onRetry, retryLabel, compact = false, ...rest }) {
12
+ return (_jsxs("div", { ...dataProps(rest), role: "alert", "aria-live": "polite",
13
+ /* ORTALANMIŞ: hata bölümün YERİNİ alıyor, kenarına iliştirilmiyor ·
14
+ sola yaslı bir blok, boş kalan alanı hâlâ doldurulacak gibi
15
+ gösteriyordu. */
16
+ className: `tamga-gutter flex flex-col items-center gap-4 text-center ${compact ? "py-6" : "py-12"}`, children: [_jsx("span", { className: "flex size-13 items-center justify-center", style: {
17
+ borderRadius: "var(--radius-card)",
18
+ border: "1.5px solid var(--color-edge)",
19
+ background: "var(--color-critical)",
20
+ color: "var(--color-critical-ink)",
21
+ boxShadow: "4px 4px 0 var(--color-edge)",
22
+ }, children: _jsx(Icon, { icon: Warning, size: "lg" }) }), _jsxs("div", { children: [_jsx("p", { className: "font-display text-title font-extrabold tracking-tight text-ink", children: title }), description ? (_jsx("p", { className: "mx-auto mt-1.5 max-w-[var(--measure)] text-body leading-relaxed text-ink-faint", children: description })) : null, detail ? (_jsx("p", { className: "mt-3 inline-block max-w-[var(--measure)] break-words px-2 py-0.5 font-mono text-caption text-ink-faint", style: {
23
+ background: "var(--color-sunk)",
24
+ border: "1px solid var(--color-line)",
25
+ borderRadius: "var(--radius-chip)",
26
+ }, children: detail })) : null] }), onRetry ? (_jsxs(Button, { variant: "primary", onClick: onRetry, children: [_jsx(Icon, { icon: Refresh, size: "sm" }), " ", retryLabel] })) : null] }));
17
27
  }
@@ -3,6 +3,34 @@
3
3
  *
4
4
  * Gerekçe: docs/gerekce/01-form-ve-girdi.md
5
5
  */
6
+ /**
7
+ * Yüklenmekte olan ya da yüklenmiş bir DOSYA · ızgaradaki görselden ayrı.
8
+ *
9
+ * Gerekçe: docs/gerekce/01-form-ve-girdi.md
10
+ */
11
+ export type UploadFile = {
12
+ id: string;
13
+ name: string;
14
+ /**
15
+ * 0-100 while the file is still going up. Given, the row carries a bar and the percentage.
16
+ * TR: Dosya hâlâ giderken 0-100. Verilirse satır bir çubuk ve yüzde taşıyor.
17
+ */
18
+ progress?: number;
19
+ /**
20
+ * The finished file's size, written by the caller ("1,8 MB"): the kit formats no bytes, because
21
+ * the unit and the separator are a locale. TR: Biten dosyanın boyutu, çağıranın yazdığı gibi
22
+ * ("1,8 MB"): kit bayt biçimlemiyor, çünkü birim de ayraç da bir yerel.
23
+ */
24
+ size?: string;
25
+ /**
26
+ * What went wrong, in the caller's words. Given, the row turns critical · and the reason sits
27
+ * NEXT TO the file name rather than under it: a list of failures reads as a list, not as three
28
+ * paragraphs. TR: Neyin ters gittiği, çağıranın sözcükleriyle. Verilirse satır kritik oluyor ·
29
+ * ve sebep dosya adının ALTINDA değil YANINDA: arka arkaya gelen hatalar bir liste olarak
30
+ * okunmalı, üç paragraf olarak değil.
31
+ */
32
+ error?: string;
33
+ } & Record<string, unknown>;
6
34
  export type UploadItem = {
7
35
  id: string;
8
36
  /**
@@ -12,17 +40,32 @@ export type UploadItem = {
12
40
  url: string;
13
41
  name: string;
14
42
  } & Record<string, unknown>;
15
- export declare function FileUpload({ items, onAdd, onRemove, onReorder, accept, multiple, disabled, labels, className, ...rest }: {
43
+ export declare function FileUpload({ items, files, onAdd, onRemove, onReorder, accept, multiple, disabled, labels, className, ...rest }: {
16
44
  items: readonly UploadItem[];
45
+ /**
46
+ * The file ROWS under the well: what is going up right now, what arrived, what was refused.
47
+ * They are not the image grid · a row is a transfer, a tile is a product image, and the two
48
+ * answer different questions. TR: Kuyunun altındaki dosya SATIRLARI: şu anda ne gidiyor, ne
49
+ * geldi, ne reddedildi. Izgaradan ayrı · satır bir aktarım, karo bir ürün görseli.
50
+ */
51
+ files?: readonly UploadFile[];
17
52
  onAdd?: (files: File[]) => void;
18
53
  onRemove?: (id: string) => void;
19
- onReorder?: (id: string, direction: -1 | 1) => void;
54
+ /**
55
+ * Places the dragged or stepped item at `target` in the list. TR: Sürüklenen ya da okla
56
+ * taşınan ögeyi listenin `hedef` sırasına koyar.
57
+ */
58
+ onReorder?: (id: string, hedef: number) => void;
20
59
  accept?: string;
21
60
  multiple?: boolean;
22
61
  disabled?: boolean;
23
62
  labels: {
24
63
  drop: string;
25
64
  browse: string;
65
+ /** The quiet line under the sentence: "PNG, JPG · max 10 MB". TR: Cümlenin altındaki sessiz satır. */
66
+ hint?: string;
67
+ /** The button that stops a transfer in flight. TR: Süren bir aktarımı durduran düğme. */
68
+ cancel?: string;
26
69
  remove: string;
27
70
  moveLeft: string;
28
71
  moveRight: string;
@@ -1 +1 @@
1
- {"version":3,"file":"file-upload.d.ts","sourceRoot":"","sources":["../../src/components/file-upload.tsx"],"names":[],"mappings":"AAQA;;;;GAIG;AAEH,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5B,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,QAAQ,EACR,SAAS,EACT,MAAkB,EAClB,QAAe,EACf,QAAgB,EAChB,MAAM,EACN,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IAChC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,4GAA4G;QAC5G,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BA0GA"}
1
+ {"version":3,"file":"file-upload.d.ts","sourceRoot":"","sources":["../../src/components/file-upload.tsx"],"names":[],"mappings":"AASA;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5B,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE5B,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,KAAK,EACL,QAAQ,EACR,SAAS,EACT,MAAkB,EAClB,QAAe,EACf,QAAgB,EAChB,MAAM,EACN,SAAS,EACT,GAAG,IAAI,EACR,EAAE;IACD,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IAChC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,sGAAsG;QACtG,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,yFAAyF;QACzF,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,4GAA4G;QAC5G,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,CAAC,CAAC,EAAE,QAAQ,MAAM,EAAE,GAAG,OAAO,CAAC;CAChC,+BAqMA"}
@@ -4,11 +4,17 @@ import { useId, useRef, useState } from "react";
4
4
  import { cn } from "../lib/cn.js";
5
5
  import { dataProps } from "../lib/data-props.js";
6
6
  import { Icon } from "./icon.js";
7
- import { Upload, Close, CaretLeft, CaretRight } from "./icons.js";
8
- export function FileUpload({ items, onAdd, onRemove, onReorder, accept = "image/*", multiple = true, disabled = false, labels, className, ...rest }) {
7
+ import { Upload, Close, CaretLeft, CaretRight, Image as ImageGlyph, Success, Failure, Delete } from "./icons.js";
8
+ import { toneOf } from "./tone.js";
9
+ export function FileUpload({ items, files, onAdd, onRemove, onReorder, accept = "image/*", multiple = true, disabled = false, labels, className, ...rest }) {
9
10
  const id = useId();
10
11
  const input = useRef(null);
11
12
  const [over, setOver] = useState(false);
13
+ /* Sürüklenen ögenin kimliği state'te, `dataTransfer`de değil: Safari
14
+ `dragover` sırasında `getData`yı boş döndürüyor, dolayısıyla bırakma
15
+ hedefini oradan okuyup işaretlemek mümkün değil. */
16
+ const [tasinan, setTasinan] = useState(null);
17
+ const [hedef, setHedef] = useState(null);
12
18
  function take(list) {
13
19
  if (!list || disabled)
14
20
  return;
@@ -23,13 +29,32 @@ export function FileUpload({ items, onAdd, onRemove, onReorder, accept = "image/
23
29
  e.preventDefault();
24
30
  if (!disabled)
25
31
  setOver(true);
26
- }, onDragLeave: () => setOver(false), onDrop: onDrop, "data-over": over, className: "tamga-art-well flex flex-col items-center gap-3 px-6 py-10 text-center", style: {
27
- borderStyle: "dashed",
28
- borderColor: over ? "var(--color-accent-line)" : undefined,
29
- }, children: [_jsx(Icon, { icon: Upload, size: "md", className: "text-ink-faint" }), _jsx("p", { className: "text-body text-ink-faint", children: labels.drop }), _jsx("button", { type: "button", className: "tamga-btn tamga-btn-sm", disabled: disabled, onClick: () => input.current?.click(), children: labels.browse }), _jsx("input", { ref: input, id: id, type: "file", accept: accept, multiple: multiple, disabled: disabled, className: "sr-only", onChange: (e) => {
32
+ }, onDragLeave: () => setOver(false), onDrop: onDrop, "data-over": over, className: "tamga-drop-well flex flex-col items-center gap-3 px-6 py-10 text-center", children: [_jsx("span", { "aria-hidden": true, className: "tamga-drop-tile", children: _jsx(Icon, { icon: Upload, size: "md", weight: "bold" }) }), _jsxs("p", { className: "text-body font-bold text-ink", children: [labels.drop, " ", _jsx("button", { type: "button", className: "tamga-link", disabled: disabled, onClick: () => input.current?.click(), children: labels.browse })] }), labels.hint ? _jsx("p", { className: "text-small text-ink-faint", children: labels.hint }) : null, _jsx("input", { ref: input, id: id, type: "file", accept: accept, multiple: multiple, disabled: disabled, className: "sr-only", onChange: (e) => {
30
33
  take(e.target.files);
31
34
  /* Aynı dosyayı ikinci kez seçebilmek için: aksi hâlde `change`
32
35
  tetiklenmez ve kullanıcı "çalışmıyor" der. */
33
36
  e.target.value = "";
34
- } })] }), items.length > 0 ? (_jsx("ul", { className: "grid grid-cols-2 gap-3 sm:grid-cols-4", children: items.map(({ id: oge, url, name, ...rest }, i) => (_jsxs("li", { ...rest, className: "tamga-card relative overflow-hidden", children: [_jsx("img", { src: url, alt: name, className: "aspect-square w-full object-cover" }), i === 0 ? (_jsx("span", { className: "tamga-chip absolute top-1.5 left-1.5", children: labels.primary })) : null, _jsxs("span", { className: "tamga-gutter flex items-center gap-1 py-1.5", children: [_jsx("button", { type: "button", className: "tamga-mini-btn", "aria-label": labels.moveLeft, disabled: i === 0, onClick: () => onReorder?.(oge, -1), children: _jsx(Icon, { icon: CaretLeft, size: "xs" }) }), _jsx("button", { type: "button", className: "tamga-mini-btn", "aria-label": labels.moveRight, disabled: i === items.length - 1, onClick: () => onReorder?.(oge, 1), children: _jsx(Icon, { icon: CaretRight, size: "xs" }) }), _jsx("button", { type: "button", className: "tamga-mini-btn ml-auto", "aria-label": labels.remove, onClick: () => onRemove?.(oge), children: _jsx(Icon, { icon: Close, size: "xs" }) })] })] }, oge))) })) : null] }));
37
+ } })] }), files?.length ? (_jsx("ul", { className: "flex flex-col gap-2", children: files.map(({ id: dosya, name, progress, size, error, ...rest }) => (_jsxs("li", { ...rest, className: "tamga-file-row", "data-error": error ? true : undefined, children: [_jsx(Icon, { icon: error ? Failure : progress === undefined ? Success : ImageGlyph, size: "sm", weight: progress === undefined ? "fill" : "bold", className: "shrink-0", style: { color: error ? toneOf("danger").fg : "var(--color-accent)" } }), _jsxs("span", { className: "flex min-w-0 flex-1 flex-col gap-1.5", children: [_jsxs("span", { className: "flex items-center justify-between gap-3 text-small font-semibold", children: [_jsxs("span", { className: "min-w-0 truncate", children: [name, error ? (_jsxs("span", { className: "font-medium text-ink-faint", children: [" \u00B7 ", error] })) : null] }), progress !== undefined ? (_jsxs("span", { className: "shrink-0 font-mono text-caption tabular-nums text-ink-faint", children: [progress, "%"] })) : size ? (_jsx("span", { className: "shrink-0 font-mono text-caption text-ink-faint", children: size })) : null] }), progress !== undefined ? (_jsx("span", { className: "tamga-file-bar", children: _jsx("span", { style: { width: `${Math.max(0, Math.min(100, progress))}%` } }) })) : null] }), _jsx("button", { type: "button", className: "tamga-icon-btn tamga-icon-btn-sm tamga-icon-btn-ghost shrink-0", "aria-label": progress !== undefined ? (labels.cancel ?? labels.remove) : labels.remove, onClick: () => onRemove?.(dosya), children: _jsx(Icon, { icon: progress !== undefined ? Close : Delete, size: "xs" }) })] }, dosya))) })) : null, items.length > 0 ? (_jsx("ul", { className: "grid grid-cols-2 gap-3 sm:grid-cols-4", children: items.map(({ id: oge, url, name, ...rest }, i) => (_jsxs("li", { ...rest, draggable: !disabled && items.length > 1, onDragStart: (e) => {
38
+ setTasinan(oge);
39
+ /* Firefox bir yük olmadan sürüklemeyi hiç başlatmıyor. */
40
+ e.dataTransfer.setData("text/plain", oge);
41
+ e.dataTransfer.effectAllowed = "move";
42
+ }, onDragEnd: () => {
43
+ setTasinan(null);
44
+ setHedef(null);
45
+ }, onDragOver: (e) => {
46
+ if (!tasinan || tasinan === oge)
47
+ return;
48
+ /* `preventDefault` olmadan `drop` hiç tetiklenmiyor: tarayıcının
49
+ varsayılanı "buraya bırakılamaz". */
50
+ e.preventDefault();
51
+ e.dataTransfer.dropEffect = "move";
52
+ setHedef(oge);
53
+ }, onDrop: (e) => {
54
+ e.preventDefault();
55
+ if (tasinan && tasinan !== oge)
56
+ onReorder?.(tasinan, i);
57
+ setTasinan(null);
58
+ setHedef(null);
59
+ }, "data-tasinan": tasinan === oge || undefined, "data-hedef": hedef === oge || undefined, className: "tamga-card tamga-tasi relative overflow-hidden", children: [_jsx("img", { src: url, alt: name, className: "aspect-square w-full object-cover" }), i === 0 ? (_jsx("span", { className: "tamga-chip absolute top-1.5 left-1.5", children: labels.primary })) : null, _jsxs("span", { className: "tamga-gutter flex items-center gap-1 py-1.5", children: [_jsx("button", { type: "button", className: "tamga-mini-btn", "aria-label": labels.moveLeft, disabled: i === 0, onClick: () => onReorder?.(oge, i - 1), children: _jsx(Icon, { icon: CaretLeft, size: "xs" }) }), _jsx("button", { type: "button", className: "tamga-mini-btn", "aria-label": labels.moveRight, disabled: i === items.length - 1, onClick: () => onReorder?.(oge, i + 1), children: _jsx(Icon, { icon: CaretRight, size: "xs" }) }), _jsx("button", { type: "button", className: "tamga-mini-btn ml-auto", "aria-label": labels.remove, onClick: () => onRemove?.(oge), children: _jsx(Icon, { icon: Close, size: "xs" }) })] })] }, oge))) })) : null] }));
35
60
  }