@fuzdev/fuz_ui 0.206.9 → 0.208.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.
package/README.md CHANGED
@@ -60,7 +60,7 @@ See [the library](https://ui.fuz.dev/docs) for more.
60
60
 
61
61
  ## Contributing
62
62
 
63
- See [contributing.md](contributing.md).
63
+ [fuz.dev/contributing](https://www.fuz.dev/contributing)
64
64
 
65
65
  ## Develop
66
66
 
@@ -6,7 +6,7 @@
6
6
  import DocsSearch from './DocsSearch.svelte';
7
7
  import ApiModulesList from './ApiModulesList.svelte';
8
8
  import ApiDeclarationList from './ApiDeclarationList.svelte';
9
- import { create_api_search } from './api_search.svelte.js';
9
+ import { ApiSearchState } from './api_search.svelte.js';
10
10
 
11
11
  const {
12
12
  library: library_prop,
@@ -33,7 +33,7 @@
33
33
  const get_library = set_library_context_with_fallback(() => library_prop, 'ApiIndex');
34
34
  const library = $derived(get_library());
35
35
 
36
- const search = $derived(create_api_search(library));
36
+ const search = $derived(new ApiSearchState(library));
37
37
  </script>
38
38
 
39
39
  <svelte:head>
@@ -49,21 +49,21 @@
49
49
  <section>
50
50
  <p>{library.pkg_json.description}</p>
51
51
 
52
- {#if search.modules.all.length + search.declarations.all.length > 1}
52
+ {#if search.modules.length + search.declarations.length > 1}
53
53
  <DocsSearch
54
- module_count={search.modules.all.length}
55
- declaration_count={search.declarations.all.length}
56
- filtered_module_count={search.query.trim() ? search.modules.filtered.length : undefined}
54
+ module_count={search.modules.length}
55
+ declaration_count={search.declarations.length}
56
+ filtered_module_count={search.query.trim() ? search.modules_filtered.length : undefined}
57
57
  filtered_declaration_count={search.query.trim()
58
- ? search.declarations.filtered.length
58
+ ? search.declarations_filtered.length
59
59
  : undefined}
60
60
  bind:search_query={search.query}
61
61
  />
62
62
  {/if}
63
63
  </section>
64
64
 
65
- <ApiModulesList modules={search.modules.filtered} search_query={search.query} />
65
+ <ApiModulesList modules={search.modules_filtered} search_query={search.query} />
66
66
 
67
- <ApiDeclarationList declarations={search.declarations.filtered} search_query={search.query} />
67
+ <ApiDeclarationList declarations={search.declarations_filtered} search_query={search.query} />
68
68
  {/if}
69
69
  </TomeContent>
@@ -17,7 +17,7 @@
17
17
  import DocsLink from './DocsLink.svelte';
18
18
  import DeclarationLink from './DeclarationLink.svelte';
19
19
  import ApiDeclarationList from './ApiDeclarationList.svelte';
20
- import { create_module_declaration_search } from './api_search.svelte.js';
20
+ import { DeclarationSearchState } from './api_search.svelte.js';
21
21
 
22
22
  const {
23
23
  module_path: module_path_param,
@@ -64,7 +64,7 @@
64
64
  module?.path || (directory_modules ? module_path : '[missing module]')
65
65
  );
66
66
 
67
- const search = $derived(create_module_declaration_search(module?.declarations ?? []));
67
+ const search = $derived(new DeclarationSearchState(module?.declarations ?? []));
68
68
 
69
69
  // GitHub source URL for the module
70
70
  const source_url = $derived(module?.url_github);
@@ -117,11 +117,11 @@
117
117
  <TomeSection>
118
118
  <TomeSectionHeader text="Declarations" />
119
119
 
120
- {#if search.all.length > 1}
120
+ {#if search.declarations.length > 1}
121
121
  <section>
122
122
  <DocsSearch
123
123
  placeholder="search declarations in this module..."
124
- declaration_count={search.all.length}
124
+ declaration_count={search.declarations.length}
125
125
  filtered_declaration_count={search.query.trim() ? search.filtered.length : undefined}
126
126
  bind:search_query={search.query}
127
127
  />
@@ -4,10 +4,10 @@
4
4
  Renders the full detail view for an exported declaration.
5
5
  Handles all svelte-docinfo declaration kinds (function, class, interface,
6
6
  type, variable, enum, component, snippet) and their kind-specific fields
7
- including parameters, props, members, overloads, intersects, and more.
7
+ including parameters, props, members, overloads, external types, and more.
8
8
 
9
9
  @see `declaration.svelte.ts` for the `Declaration` wrapper class
10
- @see {@link https://github.com/ryanatkn/svelte-docinfo svelte-docinfo} for the analysis library
10
+ @see {@link https://github.com/fuzdev/svelte-docinfo svelte-docinfo} for the analysis library
11
11
  -->
12
12
  <script lang="ts">
13
13
  import Code from '@fuzdev/fuz_code/Code.svelte';
@@ -22,11 +22,24 @@ including parameters, props, members, overloads, intersects, and more.
22
22
 
23
23
  import type { Declaration } from './declaration.svelte.js';
24
24
  import TypeLink from './TypeLink.svelte';
25
+ import TypeJsonView from './TypeJsonView.svelte';
25
26
  import ModuleLink from './ModuleLink.svelte';
26
27
  import DocsLink from './DocsLink.svelte';
27
28
 
28
29
  const { declaration }: { declaration: Declaration } = $props();
29
30
 
31
+ // external types not already shown in the inheritance section — on direct
32
+ // heritage (`interface Props extends HTMLButtonAttributes`) the producer
33
+ // deliberately records the same name in both fields, so the external-types
34
+ // section keeps only what heritage doesn't already display
35
+ const external_types_not_inherited = $derived.by(() => {
36
+ const external_types = declaration.external_types;
37
+ if (!external_types?.length) return undefined;
38
+ const heritage = (declaration.extends_types ?? []).concat(declaration.implements_types ?? []);
39
+ const filtered = external_types.filter((t) => !heritage.includes(t));
40
+ return filtered.length ? filtered : undefined;
41
+ });
42
+
30
43
  // render mdz inline `code` as API-linking `DocsLink` and fenced blocks as syntax-highlighted
31
44
  // `Code`, matching the rest of the docs — the injection mdz core leaves open
32
45
  mdz_set_context_with_fallback(mdz_code_context, () => DocsLink);
@@ -37,6 +50,7 @@ including parameters, props, members, overloads, intersects, and more.
37
50
  // sections for the same fields instead).
38
51
  interface DocExtras {
39
52
  deprecatedMessage?: string;
53
+ internalMessage?: string;
40
54
  since?: string;
41
55
  examples?: Array<string>;
42
56
  seeAlso?: Array<string>;
@@ -57,7 +71,7 @@ including parameters, props, members, overloads, intersects, and more.
57
71
  {/if}
58
72
  <div class="row gap_md mb_sm">
59
73
  <strong>type</strong>
60
- <TypeLink type={param.type} />
74
+ <TypeLink type={param.type} type_info={param.typeInfo} />
61
75
  </div>
62
76
  {#if param.optional || param.defaultValue}
63
77
  <div class="row gap_md">
@@ -79,11 +93,11 @@ including parameters, props, members, overloads, intersects, and more.
79
93
  <code>
80
94
  {param.name}{#if param.optional}?{/if}
81
95
  </code>
82
- <TypeLink type={param.type} />
96
+ <TypeLink type={param.type} type_info={param.typeInfo} />
83
97
  </div>
84
98
  {/snippet}
85
99
 
86
- <!-- Compact prose metadata for props and members (deprecated, since, examples, see also, throws). -->
100
+ <!-- Compact prose metadata for props and members (deprecated, internal, since, examples, see also, throws). -->
87
101
  {#snippet doc_extras(item: DocExtras)}
88
102
  <!-- eslint-disable-next-line @typescript-eslint/no-deprecated -->
89
103
  {#if item.deprecatedMessage !== undefined}
@@ -93,6 +107,12 @@ including parameters, props, members, overloads, intersects, and more.
93
107
  {#if item.deprecatedMessage}{item.deprecatedMessage}{/if}
94
108
  </p>
95
109
  {/if}
110
+ {#if item.internalMessage !== undefined}
111
+ <p class="row gap_md">
112
+ <span class="chip">internal</span>
113
+ {#if item.internalMessage}{item.internalMessage}{/if}
114
+ </p>
115
+ {/if}
96
116
  {#if item.since}
97
117
  <p><strong>since</strong> {item.since}</p>
98
118
  {/if}
@@ -125,7 +145,7 @@ including parameters, props, members, overloads, intersects, and more.
125
145
  {/if}
126
146
  {/snippet}
127
147
 
128
- <!-- A comma-separated inline list of type links (extends, implements, intersects are rarely more than one). -->
148
+ <!-- A comma-separated inline list of type links (extends, implements, external types are rarely more than one). -->
129
149
  {#snippet type_list(types: Array<string>)}
130
150
  {#each types as type, i (type)}
131
151
  {#if i > 0}
@@ -146,8 +166,10 @@ including parameters, props, members, overloads, intersects, and more.
146
166
  <!-- chips -->
147
167
  <!-- eslint-disable-next-line @typescript-eslint/no-deprecated -->
148
168
  {#if declaration.is_deprecated ||
169
+ declaration.is_internal ||
149
170
  declaration.reactivity ||
150
171
  declaration.accepts_children ||
172
+ declaration.merged_value ||
151
173
  declaration.alias_of
152
174
  }
153
175
  <p class="row gap_md flex-wrap:wrap">
@@ -155,12 +177,18 @@ including parameters, props, members, overloads, intersects, and more.
155
177
  {#if declaration.is_deprecated}
156
178
  <span class="chip">⚠️ deprecated</span>
157
179
  {/if}
180
+ {#if declaration.is_internal}
181
+ <span class="chip">internal</span>
182
+ {/if}
158
183
  {#if declaration.reactivity}
159
184
  <span class="chip">{declaration.reactivity}</span>
160
185
  {/if}
161
186
  {#if declaration.accepts_children}
162
187
  <span class="chip">accepts children</span>
163
188
  {/if}
189
+ {#if declaration.merged_value}
190
+ <span class="chip">value + type</span>
191
+ {/if}
164
192
  {#if declaration.alias_of}
165
193
  <span class="chip">
166
194
  alias of {declaration.alias_of.name}{#if declaration.alias_of.module}
@@ -189,11 +217,34 @@ including parameters, props, members, overloads, intersects, and more.
189
217
  </p>
190
218
  {/if}
191
219
 
220
+ {#if declaration.internal_message}
221
+ <p>{declaration.internal_message}</p>
222
+ {/if}
223
+
192
224
  <!-- type signature -->
193
225
  {#if declaration.type_signature}
194
226
  <Code lang="ts" content={declaration.type_signature} />
195
227
  {/if}
196
228
 
229
+ <!-- structured type (variables and type aliases; carries what the flat
230
+ signature lost — union members, recovered alias names — with links);
231
+ `type_info_expanded` strips a self-aliased root so a union alias expands
232
+ into its members here instead of linking circularly to itself -->
233
+ {#if declaration.type_info_expanded}
234
+ <p class="row gap_md">
235
+ <strong>type</strong>
236
+ <TypeJsonView type_info={declaration.type_info_expanded} title={declaration.type_signature} />
237
+ </p>
238
+ {/if}
239
+
240
+ <!-- default (top-level variables; params, props, and members render theirs inline) -->
241
+ {#if declaration.default_value}
242
+ <p class="row gap_md">
243
+ <strong>default</strong>
244
+ <Code lang="ts" content={declaration.default_value} />
245
+ </p>
246
+ {/if}
247
+
197
248
  <!-- import statement -->
198
249
  <Code lang="ts" content={declaration.import_statement} />
199
250
 
@@ -226,7 +277,7 @@ including parameters, props, members, overloads, intersects, and more.
226
277
  {/if}
227
278
  <div class="row gap_md mb_sm">
228
279
  <strong>type</strong>
229
- <TypeLink type={prop.type} />
280
+ <TypeLink type={prop.type} type_info={prop.typeInfo} />
230
281
  </div>
231
282
  {#if prop.optional || prop.bindable || prop.defaultValue}
232
283
  <div class="row gap_md">
@@ -274,7 +325,7 @@ including parameters, props, members, overloads, intersects, and more.
274
325
  {#if overload.returnType}
275
326
  <div class="row gap_md">
276
327
  <strong>returns</strong>
277
- <TypeLink type={overload.returnType} />
328
+ <TypeLink type={overload.returnType} type_info={overload.returnTypeInfo} />
278
329
  </div>
279
330
  {#if overload.returnDescription}
280
331
  <Mdz content={overload.returnDescription} />
@@ -285,12 +336,13 @@ including parameters, props, members, overloads, intersects, and more.
285
336
  </section>
286
337
  {/if}
287
338
 
288
- <!-- intersects (component/type intersection types) -->
289
- {#if declaration.intersects?.length}
339
+ <!-- external types whose contributions are filtered out of (or, on
340
+ interfaces/classes, never enumerated in) props/members -->
341
+ {#if external_types_not_inherited}
290
342
  <section>
291
- <h4>intersects</h4>
343
+ <h4>external types</h4>
292
344
  <div class="row gap_md flex-wrap:wrap">
293
- {@render type_list(declaration.intersects)}
345
+ {@render type_list(external_types_not_inherited)}
294
346
  </div>
295
347
  </section>
296
348
  {/if}
@@ -299,7 +351,14 @@ including parameters, props, members, overloads, intersects, and more.
299
351
  {#if declaration.return_type}
300
352
  <section>
301
353
  <h4>returns</h4>
302
- <Code lang="ts" content={declaration.return_type} />
354
+ {#if declaration.return_type_info}
355
+ <!-- the flat expansion stays visible in the type signature above -->
356
+ <p>
357
+ <TypeJsonView type_info={declaration.return_type_info} title={declaration.return_type} />
358
+ </p>
359
+ {:else}
360
+ <Code lang="ts" content={declaration.return_type} />
361
+ {/if}
303
362
  {#if declaration.return_description}
304
363
  <Mdz content={declaration.return_description} />
305
364
  {/if}
@@ -334,17 +393,13 @@ including parameters, props, members, overloads, intersects, and more.
334
393
  {/if}
335
394
 
336
395
  <!-- Extends/Implements -->
337
- {#if declaration.extends_type || declaration.implements_types?.length}
396
+ {#if declaration.extends_types?.length || declaration.implements_types?.length}
338
397
  <section>
339
398
  <h4>inheritance</h4>
340
- {#if declaration.extends_type}
399
+ {#if declaration.extends_types?.length}
341
400
  <div class="row gap_md flex-wrap:wrap">
342
401
  <strong>extends:</strong>
343
- {@render type_list(
344
- Array.isArray(declaration.extends_type)
345
- ? declaration.extends_type
346
- : [declaration.extends_type]
347
- )}
402
+ {@render type_list(declaration.extends_types)}
348
403
  </div>
349
404
  {/if}
350
405
  {#if declaration.implements_types?.length}
@@ -440,6 +495,7 @@ including parameters, props, members, overloads, intersects, and more.
440
495
  type={member.kind === 'constructor'
441
496
  ? `new ${member.typeSignature}`
442
497
  : member.typeSignature}
498
+ type_info={member.kind === 'variable' ? member.typeInfo : undefined}
443
499
  />
444
500
  </p>
445
501
  {/if}
@@ -455,7 +511,7 @@ including parameters, props, members, overloads, intersects, and more.
455
511
  {/if}
456
512
  </div>
457
513
  {/if}
458
- {#if member.kind === 'variable' && member.defaultValue}
514
+ {#if (member.kind === 'variable' || member.kind === 'function') && member.defaultValue}
459
515
  <div class="row gap_md">
460
516
  <strong>default</strong>
461
517
  <Code lang="ts" content={member.defaultValue} />
@@ -475,7 +531,7 @@ including parameters, props, members, overloads, intersects, and more.
475
531
  {#if member.kind === 'function' && member.returnType}
476
532
  <div class="row gap_md">
477
533
  <strong>returns</strong>
478
- <TypeLink type={member.returnType} />
534
+ <TypeLink type={member.returnType} type_info={member.returnTypeInfo} />
479
535
  </div>
480
536
  {#if member.returnDescription}
481
537
  <Mdz content={member.returnDescription} />
@@ -6,10 +6,10 @@ type $$ComponentProps = {
6
6
  * Renders the full detail view for an exported declaration.
7
7
  * Handles all svelte-docinfo declaration kinds (function, class, interface,
8
8
  * type, variable, enum, component, snippet) and their kind-specific fields
9
- * including parameters, props, members, overloads, intersects, and more.
9
+ * including parameters, props, members, overloads, external types, and more.
10
10
  *
11
11
  * @see `declaration.svelte.ts` for the `Declaration` wrapper class
12
- * @see {@link https://github.com/ryanatkn/svelte-docinfo svelte-docinfo} for the analysis library
12
+ * @see {@link https://github.com/fuzdev/svelte-docinfo svelte-docinfo} for the analysis library
13
13
  */
14
14
  declare const DeclarationDetail: import("svelte").Component<$$ComponentProps, {}, "">;
15
15
  type DeclarationDetail = ReturnType<typeof DeclarationDetail>;
@@ -1 +1 @@
1
- {"version":3,"file":"DeclarationDetail.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/DeclarationDetail.svelte"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAgB1D,KAAK,gBAAgB,GAAI;IAAE,WAAW,EAAE,WAAW,CAAA;CAAE,CAAC;AA+cvD;;;;;;;;GAQG;AACH,QAAA,MAAM,iBAAiB,sDAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"DeclarationDetail.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/DeclarationDetail.svelte"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAkB1D,KAAK,gBAAgB,GAAI;IAAE,WAAW,EAAE,WAAW,CAAA;CAAE,CAAC;AAigBvD;;;;;;;;GAQG;AACH,QAAA,MAAM,iBAAiB,sDAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
@@ -19,16 +19,20 @@
19
19
  {/each}
20
20
  </menu>
21
21
  <small class="display:block text-align:right">
22
- the charts show public commit activity<br />since Gro planted on August 7, 2019
22
+ the charts show public commit activity<br />since Gro started in August 2019 -<br />most of the
23
+ repos created in 2023-2024 are<br />history-resetting forks from 2020~2023 attempts
23
24
  </small>
24
25
 
25
26
  {#snippet package_thumbnail(project_item: ProjectItem)}
26
27
  {@const counts = series_by_name.get(project_item.name)}
27
- <!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
28
- <a class="thumbnail row shade_00 px_md py_xs border_radius_sm mb_lg" href={project_item.url}>
28
+ <!-- eslint-disable svelte/no-navigation-without-resolve -->
29
+ <a
30
+ class="thumbnail row align-items:start shade_00 px_md py_xs border_radius_sm mb_lg"
31
+ href={project_item.url}
32
+ >
29
33
  <Svg shrink={false} data={project_item.logo} size="var(--icon_size_lg)" />
30
34
  <div class="pl_lg width_atmost_sm">
31
- <div class="thumbnail-name row align-items:start {project_item.color_class}">
35
+ <div class="thumbnail-name row {project_item.color_class}">
32
36
  {project_item.name}
33
37
  {#if counts}
34
38
  {@const stats_label = label_by_name.get(project_item.name)}
@@ -43,6 +47,7 @@
43
47
  </div>
44
48
  </div>
45
49
  </a>
50
+ <!-- eslint-enable svelte/no-navigation-without-resolve -->
46
51
  {/snippet}
47
52
 
48
53
  <style>
@@ -1 +1 @@
1
- {"version":3,"file":"ProjectLinks.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/ProjectLinks.svelte"],"names":[],"mappings":"AA4DA,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,YAAY;;kBAA+E,CAAC;AAChF,KAAK,YAAY,GAAG,YAAY,CAAC,OAAO,YAAY,CAAC,CAAC;AACxD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"ProjectLinks.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/ProjectLinks.svelte"],"names":[],"mappings":"AA8DA,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,YAAY;;kBAA+E,CAAC;AAChF,KAAK,YAAY,GAAG,YAAY,CAAC,OAAO,YAAY,CAAC,CAAC;AACxD,eAAe,YAAY,CAAC"}
@@ -0,0 +1,90 @@
1
+ <!--
2
+ @component
3
+
4
+ Renders svelte-docinfo's structured `TypeJson` tree as inline code: `reference`
5
+ nodes (and alias-carrying unions/intersections) link to API docs via
6
+ `DeclarationLink` when the name resolves in the library — scoped to the token's
7
+ declaring module when the analysis names one — terminal type text is
8
+ syntax-highlighted via fuz_code's `Code`, and structural punctuation comes
9
+ from svelte-docinfo's `typeJsonToTokens`, which owns spacing and
10
+ parenthesization so rendering is whitespace-exact.
11
+
12
+ The structured sibling of `TypeLink`, which renders flat type strings —
13
+ `TypeLink` delegates here when given `type_info`, and svelte-docinfo omits the
14
+ tree wherever the flat string is the whole story, so the two compose as
15
+ "structured when it says something, flat otherwise". Pass `title` (typically
16
+ the flat sibling string) to keep the expansion reachable on hover where the
17
+ tree replaced it with a recovered name.
18
+ -->
19
+ <script lang="ts">
20
+ import Code from '@fuzdev/fuz_code/Code.svelte';
21
+ import type { TypeJson } from 'svelte-docinfo/types.js';
22
+ import { typeJsonToTokens } from 'svelte-docinfo/declaration-helpers.js';
23
+
24
+ import DeclarationLink from './DeclarationLink.svelte';
25
+ import { library_context } from './library.svelte.js';
26
+
27
+ const {
28
+ type_info,
29
+ title
30
+ }: {
31
+ type_info: TypeJson;
32
+ /** Hover text for the root element — pass the flat type string so the checker's expansion stays reachable. */
33
+ title?: string;
34
+ } = $props();
35
+
36
+ const get_library = library_context.get();
37
+ const library = $derived(get_library());
38
+
39
+ const tokens = $derived(typeJsonToTokens(type_info));
40
+
41
+ // a bare name renders without the code wrapper, matching the plain chip
42
+ // link `TypeLink` produces for whole-string matches
43
+ const bare_name_token = $derived(
44
+ tokens.length === 1 && tokens[0]!.kind === 'name' ? tokens[0]! : undefined
45
+ );
46
+
47
+ // the gate mirrors `DeclarationLink`'s resolution exactly — a moduled token
48
+ // (registry-recovered reference) is scoped to its declaring module with no
49
+ // by-name fallback, so the gate can't admit a name the link then fails on
50
+ const resolves = (name: string, module?: string): boolean =>
51
+ module === undefined
52
+ ? library.declaration_by_name.has(name)
53
+ : library.module_by_path.get(module)?.get_declaration_by_name(name) !== undefined;
54
+ </script>
55
+
56
+ {#snippet name_view(name: string, module: string | undefined, root_title?: string)}
57
+ {#if resolves(name, module)}
58
+ <DeclarationLink {name} module_path={module} title={root_title} />
59
+ {:else}
60
+ <Code lang="ts" content={name} inline title={root_title} />
61
+ {/if}
62
+ {/snippet}
63
+
64
+ {#if bare_name_token}
65
+ {@render name_view(bare_name_token.name, bare_name_token.module, title)}
66
+ {:else}
67
+ <!-- token adjacency survives the multi-line template: Svelte trims
68
+ block-boundary whitespace here, locked by the `TypeJsonView` render tests
69
+ (`textContent` equality would catch stray spaces) -->
70
+ <code class="type-json-view" {title}>
71
+ {#each tokens as token, i (i)}
72
+ {#if token.kind === 'text'}
73
+ {token.text}
74
+ {:else if token.kind === 'name'}
75
+ {@render name_view(token.name, token.module)}
76
+ {:else}
77
+ <Code lang="ts" content={token.text} inline />
78
+ {/if}
79
+ {/each}
80
+ </code>
81
+ {/if}
82
+
83
+ <style>
84
+ /* the outer element is the one code pill; inner `Code` fragments contribute
85
+ syntax coloring only */
86
+ .type-json-view :global(code) {
87
+ background: transparent;
88
+ padding: 0;
89
+ }
90
+ </style>
@@ -0,0 +1,26 @@
1
+ import type { TypeJson } from 'svelte-docinfo/types.js';
2
+ type $$ComponentProps = {
3
+ type_info: TypeJson;
4
+ /** Hover text for the root element — pass the flat type string so the checker's expansion stays reachable. */
5
+ title?: string;
6
+ };
7
+ /**
8
+ * Renders svelte-docinfo's structured `TypeJson` tree as inline code: `reference`
9
+ * nodes (and alias-carrying unions/intersections) link to API docs via
10
+ * `DeclarationLink` when the name resolves in the library — scoped to the token's
11
+ * declaring module when the analysis names one — terminal type text is
12
+ * syntax-highlighted via fuz_code's `Code`, and structural punctuation comes
13
+ * from svelte-docinfo's `typeJsonToTokens`, which owns spacing and
14
+ * parenthesization so rendering is whitespace-exact.
15
+ *
16
+ * The structured sibling of `TypeLink`, which renders flat type strings —
17
+ * `TypeLink` delegates here when given `type_info`, and svelte-docinfo omits the
18
+ * tree wherever the flat string is the whole story, so the two compose as
19
+ * "structured when it says something, flat otherwise". Pass `title` (typically
20
+ * the flat sibling string) to keep the expansion reachable on hover where the
21
+ * tree replaced it with a recovered name.
22
+ */
23
+ declare const TypeJsonView: import("svelte").Component<$$ComponentProps, {}, "">;
24
+ type TypeJsonView = ReturnType<typeof TypeJsonView>;
25
+ export default TypeJsonView;
26
+ //# sourceMappingURL=TypeJsonView.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TypeJsonView.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/TypeJsonView.svelte"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAMvD,KAAK,gBAAgB,GAAI;IACxB,SAAS,EAAE,QAAQ,CAAC;IACpB,8GAA8G;IAC9G,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAgEH;;;;;;;;;;;;;;;GAeG;AACH,QAAA,MAAM,YAAY,sDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -1,12 +1,26 @@
1
+ <!--
2
+ @component
3
+
4
+ Renders a type reference, linking the parts that resolve to library declarations.
5
+
6
+ With `type_info` it delegates to `TypeJsonView`, which renders the structured
7
+ tree — reference names become `DeclarationLink`s and everything else is
8
+ syntax-highlighted in place, so `Map<string, Tome> | null` links `Map` and
9
+ `Tome` independently, with the flat `type` as hover text. Without it the whole
10
+ `type` string links only when it names a declaration outright.
11
+ -->
1
12
  <script lang="ts">
2
13
  import Code from '@fuzdev/fuz_code/Code.svelte';
3
14
  import type { HTMLAttributes, SvelteHTMLElements } from 'svelte/elements';
15
+ import type { TypeJson } from 'svelte-docinfo/types.js';
4
16
 
5
17
  import DeclarationLink from './DeclarationLink.svelte';
18
+ import TypeJsonView from './TypeJsonView.svelte';
6
19
  import { library_context } from './library.svelte.js';
7
20
 
8
21
  const {
9
22
  type,
23
+ type_info,
10
24
  hash,
11
25
  a_attrs,
12
26
  code_attrs,
@@ -14,6 +28,15 @@
14
28
  }: // generic element attrs, the common denominator of the rendered roots - // assignable to the anchor rest of `DeclarationLink` and the code rest of `Code`
15
29
  HTMLAttributes<HTMLElement> & {
16
30
  type: string;
31
+ /**
32
+ * Structured type tree, when svelte-docinfo emitted one beside the flat
33
+ * string — rendered via `TypeJsonView` (per-node linkification, with
34
+ * `type` as hover text) instead of the whole-string match below. An
35
+ * absent tree falls through to `type`, so call sites pass both fields
36
+ * unconditionally. `hash` and the rest/`a_attrs`/`code_attrs`
37
+ * attributes apply only to the flat branches, not the delegated tree.
38
+ */
39
+ type_info?: TypeJson;
17
40
  /** URL fragment to append, with or without the `#`. */
18
41
  hash?: string;
19
42
  /** Anchor attributes, applied only when the type resolves to a declaration link. */
@@ -28,7 +51,11 @@
28
51
  // TODO maybe better name?
29
52
  </script>
30
53
 
31
- {#if library.declaration_by_name.has(type)}
54
+ {#if type_info}
55
+ <!-- the flat string rides along as hover text so the checker's expansion
56
+ stays reachable where the tree replaced it with a recovered name -->
57
+ <TypeJsonView {type_info} title={type} />
58
+ {:else if library.declaration_by_name.has(type)}
32
59
  <DeclarationLink {...rest} {...a_attrs} name={type} {hash} />
33
60
  {:else}
34
61
  <Code {...rest} {...code_attrs} lang="ts" content={type} inline />
@@ -1,7 +1,17 @@
1
1
  import type { HTMLAttributes, SvelteHTMLElements } from 'svelte/elements';
2
+ import type { TypeJson } from 'svelte-docinfo/types.js';
2
3
  type $$ComponentProps = // generic element attrs, the common denominator of the rendered roots - // assignable to the anchor rest of `DeclarationLink` and the code rest of `Code`
3
4
  HTMLAttributes<HTMLElement> & {
4
5
  type: string;
6
+ /**
7
+ * Structured type tree, when svelte-docinfo emitted one beside the flat
8
+ * string — rendered via `TypeJsonView` (per-node linkification, with
9
+ * `type` as hover text) instead of the whole-string match below. An
10
+ * absent tree falls through to `type`, so call sites pass both fields
11
+ * unconditionally. `hash` and the rest/`a_attrs`/`code_attrs`
12
+ * attributes apply only to the flat branches, not the delegated tree.
13
+ */
14
+ type_info?: TypeJson;
5
15
  /** URL fragment to append, with or without the `#`. */
6
16
  hash?: string;
7
17
  /** Anchor attributes, applied only when the type resolves to a declaration link. */
@@ -9,6 +19,15 @@ HTMLAttributes<HTMLElement> & {
9
19
  /** Code attributes, applied only to the fallback `Code` when the type doesn't resolve. */
10
20
  code_attrs?: SvelteHTMLElements['code'];
11
21
  };
22
+ /**
23
+ * Renders a type reference, linking the parts that resolve to library declarations.
24
+ *
25
+ * With `type_info` it delegates to `TypeJsonView`, which renders the structured
26
+ * tree — reference names become `DeclarationLink`s and everything else is
27
+ * syntax-highlighted in place, so `Map<string, Tome> | null` links `Map` and
28
+ * `Tome` independently, with the flat `type` as hover text. Without it the whole
29
+ * `type` string links only when it names a declaration outright.
30
+ */
12
31
  declare const TypeLink: import("svelte").Component<$$ComponentProps, {}, "">;
13
32
  type TypeLink = ReturnType<typeof TypeLink>;
14
33
  export default TypeLink;
@@ -1 +1 @@
1
- {"version":3,"file":"TypeLink.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/TypeLink.svelte"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAKzE,KAAK,gBAAgB,GACpB,AADwB,0JAA0J;AAClL,cAAc,CAAC,WAAW,CAAC,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,OAAO,CAAC,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAClC,0FAA0F;IAC1F,UAAU,CAAC,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;CACxC,CAAC;AA8BJ,QAAA,MAAM,QAAQ,sDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"TypeLink.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/TypeLink.svelte"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAMvD,KAAK,gBAAgB,GACpB,AADwB,0JAA0J;AAClL,cAAc,CAAC,WAAW,CAAC,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,QAAQ,CAAC;IACrB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,OAAO,CAAC,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAClC,0FAA0F;IAC1F,UAAU,CAAC,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;CACxC,CAAC;AAqCJ;;;;;;;;GAQG;AACH,QAAA,MAAM,QAAQ,sDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
@@ -1,28 +1,25 @@
1
1
  import type { Declaration } from './declaration.svelte.js';
2
2
  import type { Library } from './library.svelte.js';
3
3
  import type { Module } from './module.svelte.js';
4
- export interface DeclarationSearchState {
5
- query: string;
6
- all: Array<Declaration>;
7
- filtered: Array<Declaration>;
8
- }
9
- export interface ApiSearchState {
10
- query: string;
11
- modules: {
12
- all: Array<Module>;
13
- filtered: Array<Module>;
14
- };
15
- declarations: {
16
- all: Array<Declaration>;
17
- filtered: Array<Declaration>;
18
- };
19
- }
20
4
  /**
21
- * Creates unified search state for the API index page (modules and declarations).
5
+ * Unified search state for the API index page (modules and declarations).
22
6
  */
23
- export declare const create_api_search: (library: Library) => ApiSearchState;
7
+ export declare class ApiSearchState {
8
+ readonly library: Library;
9
+ query: string;
10
+ readonly modules: Array<Module>;
11
+ readonly modules_filtered: Array<Module>;
12
+ readonly declarations: Array<Declaration>;
13
+ readonly declarations_filtered: Array<Declaration>;
14
+ constructor(library: Library);
15
+ }
24
16
  /**
25
- * Creates search state for module-specific declaration lists.
17
+ * Search state for a module-specific declaration list.
26
18
  */
27
- export declare const create_module_declaration_search: (declarations: Array<Declaration>) => DeclarationSearchState;
19
+ export declare class DeclarationSearchState {
20
+ readonly declarations: Array<Declaration>;
21
+ query: string;
22
+ readonly filtered: Array<Declaration>;
23
+ constructor(declarations: Array<Declaration>);
24
+ }
28
25
  //# sourceMappingURL=api_search.svelte.d.ts.map