@fiscozen/thumbnail 0.2.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.
@@ -0,0 +1,131 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for src</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../prettify.css" />
9
+ <link rel="stylesheet" href="../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../index.html">All files</a> src</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">100% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>18/18</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">100% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>21/21</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">100% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>6/6</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">100% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>15/15</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line high'></div>
65
+ <div class="pad1">
66
+ <table class="coverage-summary">
67
+ <thead>
68
+ <tr>
69
+ <th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
70
+ <th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
71
+ <th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
72
+ <th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
73
+ <th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
74
+ <th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
75
+ <th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
76
+ <th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
77
+ <th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
78
+ <th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
79
+ </tr>
80
+ </thead>
81
+ <tbody><tr>
82
+ <td class="file high" data-value="FzThumbnail.vue"><a href="FzThumbnail.vue.html">FzThumbnail.vue</a></td>
83
+ <td data-value="100" class="pic high">
84
+ <div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
85
+ </td>
86
+ <td data-value="100" class="pct high">100%</td>
87
+ <td data-value="18" class="abs high">18/18</td>
88
+ <td data-value="100" class="pct high">100%</td>
89
+ <td data-value="21" class="abs high">21/21</td>
90
+ <td data-value="100" class="pct high">100%</td>
91
+ <td data-value="6" class="abs high">6/6</td>
92
+ <td data-value="100" class="pct high">100%</td>
93
+ <td data-value="15" class="abs high">15/15</td>
94
+ </tr>
95
+
96
+ <tr>
97
+ <td class="file empty" data-value="types.ts"><a href="types.ts.html">types.ts</a></td>
98
+ <td data-value="0" class="pic empty">
99
+ <div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
100
+ </td>
101
+ <td data-value="0" class="pct empty">0%</td>
102
+ <td data-value="0" class="abs empty">0/0</td>
103
+ <td data-value="0" class="pct empty">0%</td>
104
+ <td data-value="0" class="abs empty">0/0</td>
105
+ <td data-value="0" class="pct empty">0%</td>
106
+ <td data-value="0" class="abs empty">0/0</td>
107
+ <td data-value="0" class="pct empty">0%</td>
108
+ <td data-value="0" class="abs empty">0/0</td>
109
+ </tr>
110
+
111
+ </tbody>
112
+ </table>
113
+ </div>
114
+ <div class='push'></div><!-- for sticky footer -->
115
+ </div><!-- /wrapper -->
116
+ <div class='footer quiet pad2 space-top1 center small'>
117
+ Code coverage generated by
118
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
119
+ at 2026-09-08T09:30:48.131Z
120
+ </div>
121
+ <script src="../prettify.js"></script>
122
+ <script>
123
+ window.onload = function () {
124
+ prettyPrint();
125
+ };
126
+ </script>
127
+ <script src="../sorter.js"></script>
128
+ <script src="../block-navigation.js"></script>
129
+ </body>
130
+ </html>
131
+
@@ -0,0 +1,379 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for src/types.ts</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../prettify.css" />
9
+ <link rel="stylesheet" href="../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> types.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">0% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>0/0</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">0% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>0/0</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">0% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>0/0</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">0% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>0/0</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line low'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
165
+ <span class="cline-any cline-neutral">&nbsp;</span>
166
+ <span class="cline-any cline-neutral">&nbsp;</span>
167
+ <span class="cline-any cline-neutral">&nbsp;</span>
168
+ <span class="cline-any cline-neutral">&nbsp;</span>
169
+ <span class="cline-any cline-neutral">&nbsp;</span>
170
+ <span class="cline-any cline-neutral">&nbsp;</span>
171
+ <span class="cline-any cline-neutral">&nbsp;</span>
172
+ <span class="cline-any cline-neutral">&nbsp;</span>
173
+ <span class="cline-any cline-neutral">&nbsp;</span>
174
+ <span class="cline-any cline-neutral">&nbsp;</span>
175
+ <span class="cline-any cline-neutral">&nbsp;</span>
176
+ <span class="cline-any cline-neutral">&nbsp;</span>
177
+ <span class="cline-any cline-neutral">&nbsp;</span>
178
+ <span class="cline-any cline-neutral">&nbsp;</span>
179
+ <span class="cline-any cline-neutral">&nbsp;</span>
180
+ <span class="cline-any cline-neutral">&nbsp;</span>
181
+ <span class="cline-any cline-neutral">&nbsp;</span>
182
+ <span class="cline-any cline-neutral">&nbsp;</span>
183
+ <span class="cline-any cline-neutral">&nbsp;</span>
184
+ <span class="cline-any cline-neutral">&nbsp;</span>
185
+ <span class="cline-any cline-neutral">&nbsp;</span>
186
+ <span class="cline-any cline-neutral">&nbsp;</span>
187
+ <span class="cline-any cline-neutral">&nbsp;</span>
188
+ <span class="cline-any cline-neutral">&nbsp;</span>
189
+ <span class="cline-any cline-neutral">&nbsp;</span>
190
+ <span class="cline-any cline-neutral">&nbsp;</span>
191
+ <span class="cline-any cline-neutral">&nbsp;</span>
192
+ <span class="cline-any cline-neutral">&nbsp;</span>
193
+ <span class="cline-any cline-neutral">&nbsp;</span>
194
+ <span class="cline-any cline-neutral">&nbsp;</span>
195
+ <span class="cline-any cline-neutral">&nbsp;</span>
196
+ <span class="cline-any cline-neutral">&nbsp;</span>
197
+ <span class="cline-any cline-neutral">&nbsp;</span>
198
+ <span class="cline-any cline-neutral">&nbsp;</span>
199
+ <span class="cline-any cline-neutral">&nbsp;</span>
200
+ <span class="cline-any cline-neutral">&nbsp;</span>
201
+ <span class="cline-any cline-neutral">&nbsp;</span>
202
+ <span class="cline-any cline-neutral">&nbsp;</span>
203
+ <span class="cline-any cline-neutral">&nbsp;</span>
204
+ <span class="cline-any cline-neutral">&nbsp;</span>
205
+ <span class="cline-any cline-neutral">&nbsp;</span>
206
+ <span class="cline-any cline-neutral">&nbsp;</span>
207
+ <span class="cline-any cline-neutral">&nbsp;</span>
208
+ <span class="cline-any cline-neutral">&nbsp;</span>
209
+ <span class="cline-any cline-neutral">&nbsp;</span>
210
+ <span class="cline-any cline-neutral">&nbsp;</span>
211
+ <span class="cline-any cline-neutral">&nbsp;</span>
212
+ <span class="cline-any cline-neutral">&nbsp;</span>
213
+ <span class="cline-any cline-neutral">&nbsp;</span>
214
+ <span class="cline-any cline-neutral">&nbsp;</span>
215
+ <span class="cline-any cline-neutral">&nbsp;</span>
216
+ <span class="cline-any cline-neutral">&nbsp;</span>
217
+ <span class="cline-any cline-neutral">&nbsp;</span>
218
+ <span class="cline-any cline-neutral">&nbsp;</span>
219
+ <span class="cline-any cline-neutral">&nbsp;</span>
220
+ <span class="cline-any cline-neutral">&nbsp;</span>
221
+ <span class="cline-any cline-neutral">&nbsp;</span>
222
+ <span class="cline-any cline-neutral">&nbsp;</span>
223
+ <span class="cline-any cline-neutral">&nbsp;</span>
224
+ <span class="cline-any cline-neutral">&nbsp;</span>
225
+ <span class="cline-any cline-neutral">&nbsp;</span>
226
+ <span class="cline-any cline-neutral">&nbsp;</span>
227
+ <span class="cline-any cline-neutral">&nbsp;</span>
228
+ <span class="cline-any cline-neutral">&nbsp;</span>
229
+ <span class="cline-any cline-neutral">&nbsp;</span>
230
+ <span class="cline-any cline-neutral">&nbsp;</span>
231
+ <span class="cline-any cline-neutral">&nbsp;</span>
232
+ <span class="cline-any cline-neutral">&nbsp;</span>
233
+ <span class="cline-any cline-neutral">&nbsp;</span>
234
+ <span class="cline-any cline-neutral">&nbsp;</span>
235
+ <span class="cline-any cline-neutral">&nbsp;</span>
236
+ <span class="cline-any cline-neutral">&nbsp;</span>
237
+ <span class="cline-any cline-neutral">&nbsp;</span>
238
+ <span class="cline-any cline-neutral">&nbsp;</span>
239
+ <span class="cline-any cline-neutral">&nbsp;</span>
240
+ <span class="cline-any cline-neutral">&nbsp;</span>
241
+ <span class="cline-any cline-neutral">&nbsp;</span>
242
+ <span class="cline-any cline-neutral">&nbsp;</span>
243
+ <span class="cline-any cline-neutral">&nbsp;</span>
244
+ <span class="cline-any cline-neutral">&nbsp;</span>
245
+ <span class="cline-any cline-neutral">&nbsp;</span>
246
+ <span class="cline-any cline-neutral">&nbsp;</span>
247
+ <span class="cline-any cline-neutral">&nbsp;</span>
248
+ <span class="cline-any cline-neutral">&nbsp;</span>
249
+ <span class="cline-any cline-neutral">&nbsp;</span>
250
+ <span class="cline-any cline-neutral">&nbsp;</span>
251
+ <span class="cline-any cline-neutral">&nbsp;</span>
252
+ <span class="cline-any cline-neutral">&nbsp;</span>
253
+ <span class="cline-any cline-neutral">&nbsp;</span>
254
+ <span class="cline-any cline-neutral">&nbsp;</span>
255
+ <span class="cline-any cline-neutral">&nbsp;</span>
256
+ <span class="cline-any cline-neutral">&nbsp;</span>
257
+ <span class="cline-any cline-neutral">&nbsp;</span>
258
+ <span class="cline-any cline-neutral">&nbsp;</span>
259
+ <span class="cline-any cline-neutral">&nbsp;</span>
260
+ <span class="cline-any cline-neutral">&nbsp;</span>
261
+ <span class="cline-any cline-neutral">&nbsp;</span>
262
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import type { ImgHTMLAttributes } from 'vue'
263
+ &nbsp;
264
+ /**
265
+ * Corner radius, named after the design system's radius tokens.
266
+ * `base` is 4px — the value the designs use for an image in a feed.
267
+ */
268
+ type FzThumbnailRadius = 'none' | 'sm' | 'base' | 'lg' | 'xl'
269
+ &nbsp;
270
+ /**
271
+ * Corner the `overlay` slot's content is pinned to.
272
+ */
273
+ type FzThumbnailOverlayPosition = 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'center'
274
+ &nbsp;
275
+ /**
276
+ * Props for FzThumbnail.
277
+ */
278
+ export interface FzThumbnailProps {
279
+ /** URL of the image to show. */
280
+ src: string
281
+ /**
282
+ * The image's accessible name. Required on purpose: pass an explicit empty
283
+ * string for a decorative image, so that the decision is visible at the call
284
+ * site rather than forgotten.
285
+ */
286
+ alt: string
287
+ /**
288
+ * Box width, as any CSS length (`'158px'`, `'100%'`, `'12rem'`).
289
+ *
290
+ * A prop rather than a class on purpose. This component hardwires no size, so
291
+ * the caller has to supply one — but the consuming apps forbid `class` outright
292
+ * at the organism, template and page layers, and `style` at every layer above
293
+ * an atom. Deciding it inside the component is the only way those layers can
294
+ * size a thumbnail at all. Same reasoning as `FzNavbar`'s `elevation`.
295
+ *
296
+ * A Tailwind class on the call site still works where the layer permits one,
297
+ * and wins over this prop only if it beats an inline style — so pick one.
298
+ */
299
+ width?: string
300
+ /** Box height, as any CSS length. See `width`. */
301
+ height?: string
302
+ /**
303
+ * Box aspect ratio (`'16 / 9'`, `'1'`), for when only one dimension is known —
304
+ * a thumbnail filling a column of unknown width, say. Ignored if both `width`
305
+ * and `height` are set.
306
+ */
307
+ aspectRatio?: string
308
+ /** Corner radius. Defaults to `base` (4px). */
309
+ radius?: FzThumbnailRadius
310
+ /** Draws a 1px `grey-100` border around the box. */
311
+ bordered?: boolean
312
+ /**
313
+ * Lays a translucent scrim over the image, so an action rendered in the
314
+ * `overlay` slot stays legible on a light photo. Not drawn over the
315
+ * placeholder, which is already a flat light surface.
316
+ */
317
+ scrim?: boolean
318
+ /**
319
+ * Where the `overlay` slot's content sits inside the box, 8px in from the
320
+ * chosen corner. `bottom-end` by default — the download button's place in the
321
+ * chat feed; `top-end` is the composer's remove control.
322
+ *
323
+ * A prop for the same reason the dimensions are: the layers that may not write
324
+ * a `class` would otherwise have no way to place an overlaid action. Content
325
+ * that needs finer placement can still position itself, from a layer that
326
+ * permits it.
327
+ */
328
+ overlayPosition?: FzThumbnailOverlayPosition
329
+ /**
330
+ * Icon shown in place of the image when it fails to load. Any name in the
331
+ * Font Awesome kit; `file` by default, since the kit has no image glyph.
332
+ */
333
+ placeholderIcon?: string
334
+ /** Native loading hint. `lazy` by default — a feed of images is the use case. */
335
+ loading?: 'lazy' | 'eager'
336
+ /**
337
+ * Extra attributes for the `&lt;img&gt;` itself — `referrerpolicy`, `crossorigin`,
338
+ * `decoding`, `fetchpriority`, `srcset`, `sizes`.
339
+ *
340
+ * Needed because a fallthrough attribute lands on the root box, not the image:
341
+ * the component has one root element, so `&lt;FzThumbnail referrerpolicy="..."&gt;`
342
+ * would set it on the wrapping `&lt;div&gt;`, where it means nothing. That keeps
343
+ * `class` and listeners on the box, which is what a caller sizing or clicking
344
+ * the thumbnail wants — but it leaves the image itself out of reach without
345
+ * this.
346
+ *
347
+ * `src`, `alt`, `loading` and `onError` are the component's own contract, so
348
+ * the type excludes them: naming one is a compile error rather than a silent
349
+ * no-op. `onError` has to be *excluded* rather than merely documented —
350
+ * Vue's `mergeProps` chains listeners, so a handler named here would fire
351
+ * alongside the component's own rather than losing to it.
352
+ *
353
+ * @example Do not send a Referer to a third-party image host.
354
+ * :imgProps="{ referrerpolicy: 'no-referrer' }"
355
+ */
356
+ imgProps?: Omit&lt;ImgHTMLAttributes, 'src' | 'alt' | 'loading' | 'onError'&gt;
357
+ }
358
+ &nbsp;
359
+ export type { FzThumbnailRadius, FzThumbnailOverlayPosition }
360
+ &nbsp;</pre></td></tr></table></pre>
361
+
362
+ <div class='push'></div><!-- for sticky footer -->
363
+ </div><!-- /wrapper -->
364
+ <div class='footer quiet pad2 space-top1 center small'>
365
+ Code coverage generated by
366
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
367
+ at 2026-09-08T09:30:48.131Z
368
+ </div>
369
+ <script src="../prettify.js"></script>
370
+ <script>
371
+ window.onload = function () {
372
+ prettyPrint();
373
+ };
374
+ </script>
375
+ <script src="../sorter.js"></script>
376
+ <script src="../block-navigation.js"></script>
377
+ </body>
378
+ </html>
379
+
@@ -0,0 +1,2 @@
1
+ export * from './src/index'
2
+ export {}
@@ -0,0 +1,29 @@
1
+ import { FzThumbnailOverlayPosition, FzThumbnailProps, FzThumbnailRadius } from './types';
2
+ declare function __VLS_template(): {
3
+ attrs: Partial<{}>;
4
+ slots: {
5
+ overlay?(_: {}): any;
6
+ };
7
+ refs: {};
8
+ rootEl: HTMLDivElement;
9
+ };
10
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
11
+ declare const __VLS_component: import('vue').DefineComponent<FzThumbnailProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
12
+ error: (src: string) => any;
13
+ }, string, import('vue').PublicProps, Readonly<FzThumbnailProps> & Readonly<{
14
+ onError?: ((src: string) => any) | undefined;
15
+ }>, {
16
+ loading: "lazy" | "eager";
17
+ radius: FzThumbnailRadius;
18
+ bordered: boolean;
19
+ scrim: boolean;
20
+ overlayPosition: FzThumbnailOverlayPosition;
21
+ placeholderIcon: string;
22
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
23
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
24
+ export default _default;
25
+ type __VLS_WithTemplateSlots<T, S> = T & {
26
+ new (): {
27
+ $slots: S;
28
+ };
29
+ };
@@ -0,0 +1,2 @@
1
+ export { default as FzThumbnail } from './FzThumbnail.vue';
2
+ export type * from './types';
@@ -0,0 +1,94 @@
1
+ import { ImgHTMLAttributes } from 'vue';
2
+ /**
3
+ * Corner radius, named after the design system's radius tokens.
4
+ * `base` is 4px — the value the designs use for an image in a feed.
5
+ */
6
+ type FzThumbnailRadius = 'none' | 'sm' | 'base' | 'lg' | 'xl';
7
+ /**
8
+ * Corner the `overlay` slot's content is pinned to.
9
+ */
10
+ type FzThumbnailOverlayPosition = 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'center';
11
+ /**
12
+ * Props for FzThumbnail.
13
+ */
14
+ export interface FzThumbnailProps {
15
+ /** URL of the image to show. */
16
+ src: string;
17
+ /**
18
+ * The image's accessible name. Required on purpose: pass an explicit empty
19
+ * string for a decorative image, so that the decision is visible at the call
20
+ * site rather than forgotten.
21
+ */
22
+ alt: string;
23
+ /**
24
+ * Box width, as any CSS length (`'158px'`, `'100%'`, `'12rem'`).
25
+ *
26
+ * A prop rather than a class on purpose. This component hardwires no size, so
27
+ * the caller has to supply one — but the consuming apps forbid `class` outright
28
+ * at the organism, template and page layers, and `style` at every layer above
29
+ * an atom. Deciding it inside the component is the only way those layers can
30
+ * size a thumbnail at all. Same reasoning as `FzNavbar`'s `elevation`.
31
+ *
32
+ * A Tailwind class on the call site still works where the layer permits one,
33
+ * and wins over this prop only if it beats an inline style — so pick one.
34
+ */
35
+ width?: string;
36
+ /** Box height, as any CSS length. See `width`. */
37
+ height?: string;
38
+ /**
39
+ * Box aspect ratio (`'16 / 9'`, `'1'`), for when only one dimension is known —
40
+ * a thumbnail filling a column of unknown width, say. Ignored if both `width`
41
+ * and `height` are set.
42
+ */
43
+ aspectRatio?: string;
44
+ /** Corner radius. Defaults to `base` (4px). */
45
+ radius?: FzThumbnailRadius;
46
+ /** Draws a 1px `grey-100` border around the box. */
47
+ bordered?: boolean;
48
+ /**
49
+ * Lays a translucent scrim over the image, so an action rendered in the
50
+ * `overlay` slot stays legible on a light photo. Not drawn over the
51
+ * placeholder, which is already a flat light surface.
52
+ */
53
+ scrim?: boolean;
54
+ /**
55
+ * Where the `overlay` slot's content sits inside the box, 8px in from the
56
+ * chosen corner. `bottom-end` by default — the download button's place in the
57
+ * chat feed; `top-end` is the composer's remove control.
58
+ *
59
+ * A prop for the same reason the dimensions are: the layers that may not write
60
+ * a `class` would otherwise have no way to place an overlaid action. Content
61
+ * that needs finer placement can still position itself, from a layer that
62
+ * permits it.
63
+ */
64
+ overlayPosition?: FzThumbnailOverlayPosition;
65
+ /**
66
+ * Icon shown in place of the image when it fails to load. Any name in the
67
+ * Font Awesome kit; `file` by default, since the kit has no image glyph.
68
+ */
69
+ placeholderIcon?: string;
70
+ /** Native loading hint. `lazy` by default — a feed of images is the use case. */
71
+ loading?: 'lazy' | 'eager';
72
+ /**
73
+ * Extra attributes for the `<img>` itself — `referrerpolicy`, `crossorigin`,
74
+ * `decoding`, `fetchpriority`, `srcset`, `sizes`.
75
+ *
76
+ * Needed because a fallthrough attribute lands on the root box, not the image:
77
+ * the component has one root element, so `<FzThumbnail referrerpolicy="...">`
78
+ * would set it on the wrapping `<div>`, where it means nothing. That keeps
79
+ * `class` and listeners on the box, which is what a caller sizing or clicking
80
+ * the thumbnail wants — but it leaves the image itself out of reach without
81
+ * this.
82
+ *
83
+ * `src`, `alt`, `loading` and `onError` are the component's own contract, so
84
+ * the type excludes them: naming one is a compile error rather than a silent
85
+ * no-op. `onError` has to be *excluded* rather than merely documented —
86
+ * Vue's `mergeProps` chains listeners, so a handler named here would fire
87
+ * alongside the component's own rather than losing to it.
88
+ *
89
+ * @example Do not send a Referer to a third-party image host.
90
+ * :imgProps="{ referrerpolicy: 'no-referrer' }"
91
+ */
92
+ imgProps?: Omit<ImgHTMLAttributes, 'src' | 'alt' | 'loading' | 'onError'>;
93
+ }
94
+ export type { FzThumbnailRadius, FzThumbnailOverlayPosition };
@@ -0,0 +1,2 @@
1
+ .fz-thumbnail__scrim[data-v-a2d500cf]{background-color:var(--fz-thumbnail-scrim,var(--grey-500,#596167));opacity:var(--fz-thumbnail-scrim-opacity,.2)}
2
+ /*$vite$:1*/