starlight-fsharp-oracle 0.1.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 (89) hide show
  1. package/Directory.Build.props +25 -0
  2. package/Directory.Packages.props +18 -0
  3. package/README.md +80 -0
  4. package/dist/Extensions/StringBuilder.js +28 -0
  5. package/dist/Extensions/TextNode.js +115 -0
  6. package/dist/FSharp.Oracle.Schema/Schema.js +674 -0
  7. package/dist/Generate.js +254 -0
  8. package/dist/Helpers.js +69 -0
  9. package/dist/Plugin.js +139 -0
  10. package/dist/Render/Documentation.js +87 -0
  11. package/dist/Render/Entries.js +148 -0
  12. package/dist/Render/Pages.js +292 -0
  13. package/dist/Render/Primitives.js +114 -0
  14. package/dist/Render/Types.js +30 -0
  15. package/dist/Render.js +12 -0
  16. package/dist/Themes.js +78 -0
  17. package/oracle-bin/FSharp.Compiler.Service.dll +0 -0
  18. package/oracle-bin/FSharp.Core.dll +0 -0
  19. package/oracle-bin/FSharp.DependencyManager.Nuget.dll +0 -0
  20. package/oracle-bin/FSharp.Oracle.Schema.dll +0 -0
  21. package/oracle-bin/FSharp.Oracle.Schema.pdb +0 -0
  22. package/oracle-bin/FSharp.Oracle.Schema.xml +219 -0
  23. package/oracle-bin/Fable.Core.dll +0 -0
  24. package/oracle-bin/Oracle +0 -0
  25. package/oracle-bin/Oracle.deps.json +280 -0
  26. package/oracle-bin/Oracle.dll +0 -0
  27. package/oracle-bin/Oracle.pdb +0 -0
  28. package/oracle-bin/Oracle.runtimeconfig.json +13 -0
  29. package/oracle-bin/Oracle.xml +111 -0
  30. package/oracle-bin/Thoth.Json.Core.Auto.dll +0 -0
  31. package/oracle-bin/Thoth.Json.Core.dll +0 -0
  32. package/oracle-bin/Thoth.Json.System.Text.Json.dll +0 -0
  33. package/oracle-bin/cs/FSharp.Compiler.Service.resources.dll +0 -0
  34. package/oracle-bin/cs/FSharp.Core.resources.dll +0 -0
  35. package/oracle-bin/cs/FSharp.DependencyManager.Nuget.resources.dll +0 -0
  36. package/oracle-bin/de/FSharp.Compiler.Service.resources.dll +0 -0
  37. package/oracle-bin/de/FSharp.Core.resources.dll +0 -0
  38. package/oracle-bin/de/FSharp.DependencyManager.Nuget.resources.dll +0 -0
  39. package/oracle-bin/es/FSharp.Compiler.Service.resources.dll +0 -0
  40. package/oracle-bin/es/FSharp.Core.resources.dll +0 -0
  41. package/oracle-bin/es/FSharp.DependencyManager.Nuget.resources.dll +0 -0
  42. package/oracle-bin/fr/FSharp.Compiler.Service.resources.dll +0 -0
  43. package/oracle-bin/fr/FSharp.Core.resources.dll +0 -0
  44. package/oracle-bin/fr/FSharp.DependencyManager.Nuget.resources.dll +0 -0
  45. package/oracle-bin/it/FSharp.Compiler.Service.resources.dll +0 -0
  46. package/oracle-bin/it/FSharp.Core.resources.dll +0 -0
  47. package/oracle-bin/it/FSharp.DependencyManager.Nuget.resources.dll +0 -0
  48. package/oracle-bin/ja/FSharp.Compiler.Service.resources.dll +0 -0
  49. package/oracle-bin/ja/FSharp.Core.resources.dll +0 -0
  50. package/oracle-bin/ja/FSharp.DependencyManager.Nuget.resources.dll +0 -0
  51. package/oracle-bin/ko/FSharp.Compiler.Service.resources.dll +0 -0
  52. package/oracle-bin/ko/FSharp.Core.resources.dll +0 -0
  53. package/oracle-bin/ko/FSharp.DependencyManager.Nuget.resources.dll +0 -0
  54. package/oracle-bin/pl/FSharp.Compiler.Service.resources.dll +0 -0
  55. package/oracle-bin/pl/FSharp.Core.resources.dll +0 -0
  56. package/oracle-bin/pl/FSharp.DependencyManager.Nuget.resources.dll +0 -0
  57. package/oracle-bin/pt-BR/FSharp.Compiler.Service.resources.dll +0 -0
  58. package/oracle-bin/pt-BR/FSharp.Core.resources.dll +0 -0
  59. package/oracle-bin/pt-BR/FSharp.DependencyManager.Nuget.resources.dll +0 -0
  60. package/oracle-bin/ru/FSharp.Compiler.Service.resources.dll +0 -0
  61. package/oracle-bin/ru/FSharp.Core.resources.dll +0 -0
  62. package/oracle-bin/ru/FSharp.DependencyManager.Nuget.resources.dll +0 -0
  63. package/oracle-bin/tr/FSharp.Compiler.Service.resources.dll +0 -0
  64. package/oracle-bin/tr/FSharp.Core.resources.dll +0 -0
  65. package/oracle-bin/tr/FSharp.DependencyManager.Nuget.resources.dll +0 -0
  66. package/oracle-bin/zh-Hans/FSharp.Compiler.Service.resources.dll +0 -0
  67. package/oracle-bin/zh-Hans/FSharp.Core.resources.dll +0 -0
  68. package/oracle-bin/zh-Hans/FSharp.DependencyManager.Nuget.resources.dll +0 -0
  69. package/oracle-bin/zh-Hant/FSharp.Compiler.Service.resources.dll +0 -0
  70. package/oracle-bin/zh-Hant/FSharp.Core.resources.dll +0 -0
  71. package/oracle-bin/zh-Hant/FSharp.DependencyManager.Nuget.resources.dll +0 -0
  72. package/package.json +38 -0
  73. package/packages/FSharp.Oracle/Extractor/Assembly.fs +160 -0
  74. package/packages/FSharp.Oracle/Extractor/EntityExtractor.fs +608 -0
  75. package/packages/FSharp.Oracle/Extractor/Helpers.fs +150 -0
  76. package/packages/FSharp.Oracle/Extractor/MemberExtractor.fs +172 -0
  77. package/packages/FSharp.Oracle/Extractor/ModuleExtractor.fs +45 -0
  78. package/packages/FSharp.Oracle/Extractor/ParameterExtractor.fs +47 -0
  79. package/packages/FSharp.Oracle/Extractor/SignatureRendering.fs +464 -0
  80. package/packages/FSharp.Oracle/Extractor/ValueExtractor.fs +171 -0
  81. package/packages/FSharp.Oracle/FSharp.Oracle.fsproj +36 -0
  82. package/packages/FSharp.Oracle/Program.fs +66 -0
  83. package/packages/FSharp.Oracle/XmlDoc.fs +463 -0
  84. package/packages/FSharp.Oracle.Schema/FSharp.Oracle.Schema.fsproj +16 -0
  85. package/packages/FSharp.Oracle.Schema/Schema.fs +454 -0
  86. package/packages/Starlight.FSharp.Oracle/components/DocEntry.astro +256 -0
  87. package/packages/Starlight.FSharp.Oracle/components/FSharpDocPage.astro +121 -0
  88. package/packages/Starlight.FSharp.Oracle/components/fsharp-doc.css +58 -0
  89. package/packages/Starlight.FSharp.Oracle/layouts/FSharpDocLayout.astro +27 -0
@@ -0,0 +1,454 @@
1
+ module FSharp.Oracle.Schema
2
+
3
+ // ---------------------------------------------------------------------------
4
+ // XML doc comment payloads
5
+ // ---------------------------------------------------------------------------
6
+
7
+ #nowarn 40
8
+
9
+ type XmlDocParam =
10
+ {
11
+ Name: string
12
+ Doc: string
13
+ }
14
+
15
+ type XmlDoc =
16
+ {
17
+ Summary: string option
18
+ Remarks: string option
19
+ Returns: string option
20
+ Params: XmlDocParam list
21
+ Examples: string list
22
+ }
23
+
24
+ /// Whether an API is obsolete and, if so, whether a custom message was supplied.
25
+ [<RequireQualifiedAccess>]
26
+ type ObsoleteInfo =
27
+ | Active
28
+ | Deprecated
29
+ | DeprecatedWithMessage of string
30
+
31
+ // ---------------------------------------------------------------------------
32
+ // Signature AST
33
+ // ---------------------------------------------------------------------------
34
+
35
+ [<RequireQualifiedAccess>]
36
+ type TextNode =
37
+ /// Plain identifier, e.g. "string", "int", "unit".
38
+ | Text of string
39
+ /// Named type with its full name for link generation, e.g. ("Option", "Microsoft.FSharp.Core.FSharpOption`1").
40
+ /// The url field is the pre-computed page URL (slugified, with output base prefix).
41
+ | TypeRef of name: string * fullName: string * url: string
42
+ /// Generic type variable, e.g. "T" (the tick is implied — rendered as 'T).
43
+ | TypeVar of string
44
+ /// F# keyword, e.g. "val", "type".
45
+ | Keyword of string
46
+ | LeftBrace
47
+ | RightBrace
48
+ | Equal
49
+ | Arrow
50
+ | Tick
51
+ | Space
52
+ | Spaces of int
53
+ | Comma
54
+ | Colon
55
+ | Dot
56
+ | LeftParen
57
+ | RightParen
58
+ | LessThan
59
+ | GreaterThan
60
+ /// Tuple separator (*).
61
+ | Star
62
+ /// Grouping node — a flat list of child nodes.
63
+ | Node of nodes: TextNode list
64
+ | NewLine
65
+ | OpenTag of string
66
+ | CloseTag of string
67
+ | OpenTagWithClass of string * string
68
+ /// An inline hyperlink; href is used as-is (supports page-local `#anchor` refs).
69
+ | Anchor of text: string * href: string
70
+ | AnchoredProperty of text: string * href: string
71
+ /// An inline hyperlink styled as a keyword (e.g. `new` in a constructor declaration).
72
+ | AnchoredKeyword of text: string * href: string
73
+
74
+ member this.TrimStart() =
75
+ let isWhitespace =
76
+ function
77
+ | Space
78
+ | Spaces _
79
+ | NewLine -> true
80
+ | _ -> false
81
+
82
+ match this with
83
+ | Space
84
+ | Spaces _
85
+ | NewLine -> Node []
86
+ | Node nodes -> nodes |> List.skipWhile isWhitespace |> Node
87
+ | _ -> this
88
+
89
+ // ---------------------------------------------------------------------------
90
+ // Parameters
91
+ // ---------------------------------------------------------------------------
92
+
93
+ type Parameter =
94
+ {
95
+ Name: string
96
+ Type: TextNode
97
+ /// Signature line without column alignment: `\n name : type`
98
+ Declaration: TextNode
99
+ /// Signature line with colon aligned to the common column: `\n name : type`
100
+ AlignedDeclaration: TextNode
101
+ }
102
+
103
+ // ---------------------------------------------------------------------------
104
+ // Module-level functions and values
105
+ // ---------------------------------------------------------------------------
106
+
107
+ type Function =
108
+ {
109
+ Name: string
110
+ FullName: string
111
+ Signature: TextNode
112
+ /// Curried parameter groups. Each outer list is a curried group;
113
+ /// each inner list holds the parameters within that group (tupled parameters).
114
+ Parameters: Parameter list list
115
+ /// First line without column alignment: `val name :`
116
+ Declaration: TextNode
117
+ /// First line with colon aligned to the common column: `val name :`
118
+ AlignedDeclaration: TextNode
119
+ /// Generic parameters with constraints, e.g. `<\'T when \'T : comparison>`.
120
+ GenericParameters: TextNode option
121
+ /// Pre-formatted return type with contextual prefix.
122
+ /// With parameters: `\n -> returnType`
123
+ /// Without parameters: ` returnType`
124
+ ReturnType: TextNode
125
+ XmlDoc: XmlDoc
126
+ ObsoleteInfo: ObsoleteInfo
127
+ }
128
+
129
+ type Value =
130
+ {
131
+ Name: string
132
+ FullName: string
133
+ Signature: TextNode
134
+ /// Pre-formatted signature line: `val name : type`
135
+ Declaration: TextNode
136
+ /// Generic parameters with constraints, e.g. `<\'T when \'T : comparison>`.
137
+ GenericParameters: TextNode option
138
+ XmlDoc: XmlDoc
139
+ ObsoleteInfo: ObsoleteInfo
140
+ }
141
+
142
+ // ---------------------------------------------------------------------------
143
+ // Entity members (methods, properties, constructors)
144
+ // ---------------------------------------------------------------------------
145
+
146
+ [<RequireQualifiedAccess>]
147
+ type MemberKind =
148
+ | Method
149
+ | Property
150
+ | Constructor
151
+ | Operator
152
+
153
+ type Member =
154
+ {
155
+ Kind: MemberKind
156
+ Name: string
157
+ FullName: string
158
+ /// Curried parameter groups. Each outer list is a curried group;
159
+ /// each inner list holds the parameters within that group (tupled parameters).
160
+ Parameters: Parameter list list
161
+ /// The return type of the member (property type, method return type, or constructed type for constructors).
162
+ ReturnType: TextNode
163
+ /// Pre-formatted signature line for the DocEntry slot,
164
+ /// e.g. `member Add : other : Vector -> Vector` or `property Length : float with get`.
165
+ Declaration: TextNode
166
+ /// Generic parameters with constraints, e.g. `<\'T when \'T : comparison>`.
167
+ GenericParameters: TextNode option
168
+ XmlDoc: XmlDoc
169
+ IsStatic: bool
170
+ /// True for `abstract member` declarations (interface members and abstract class members).
171
+ IsAbstract: bool
172
+ ObsoleteInfo: ObsoleteInfo
173
+ }
174
+
175
+ // ---------------------------------------------------------------------------
176
+ // Record fields
177
+ // ---------------------------------------------------------------------------
178
+
179
+ type Field =
180
+ {
181
+ Name: string
182
+ Type: TextNode
183
+ XmlDoc: XmlDoc
184
+ /// Pre-formatted signature: `field1 : type`
185
+ Declaration: TextNode
186
+ }
187
+
188
+ /// Pre-formatted signature: `val field1 : type`
189
+ member this.Signature =
190
+ TextNode.Node
191
+ [
192
+ TextNode.Keyword "val"
193
+ TextNode.Space
194
+ this.Declaration
195
+ ]
196
+
197
+ // ---------------------------------------------------------------------------
198
+ // Union cases
199
+ // ---------------------------------------------------------------------------
200
+
201
+ type UnionCase =
202
+ {
203
+ Name: string
204
+ FullName: string
205
+ Fields: Field list
206
+ XmlDoc: XmlDoc
207
+ /// Pre-formatted signature: `| Name of field1: type1 * field2: type2`
208
+ Declaration: TextNode
209
+ }
210
+
211
+ // ---------------------------------------------------------------------------
212
+ // Entities (types)
213
+ // ---------------------------------------------------------------------------
214
+
215
+ type RecordEntity =
216
+ {
217
+ Name: string
218
+ FullName: string
219
+ XmlDoc: XmlDoc
220
+ Fields: Field list
221
+ Members: Member list
222
+ /// Pre-formatted full type declaration: `type Name =\n { field1 : t1\n ... }`
223
+ Declaration: TextNode
224
+ ObsoleteInfo: ObsoleteInfo
225
+ IsStruct: bool
226
+ }
227
+
228
+ type UnionEntity =
229
+ {
230
+ Name: string
231
+ FullName: string
232
+ XmlDoc: XmlDoc
233
+ Cases: UnionCase list
234
+ Members: Member list
235
+ /// Pre-formatted full type declaration with anchor links on case names.
236
+ Declaration: TextNode
237
+ ObsoleteInfo: ObsoleteInfo
238
+ IsStruct: bool
239
+ }
240
+
241
+ type AbbrevEntity =
242
+ {
243
+ Name: string
244
+ FullName: string
245
+ XmlDoc: XmlDoc
246
+ /// The abbreviated type (right-hand side only).
247
+ Signature: TextNode
248
+ /// Pre-formatted full declaration: `type Name = abbreviatedType`
249
+ Declaration: TextNode
250
+ ObsoleteInfo: ObsoleteInfo
251
+ IsStruct: bool
252
+ }
253
+
254
+ type ClassEntity =
255
+ {
256
+ Name: string
257
+ FullName: string
258
+ XmlDoc: XmlDoc
259
+ Members: Member list
260
+ /// Pre-formatted full type declaration with member signatures.
261
+ Declaration: TextNode
262
+ ObsoleteInfo: ObsoleteInfo
263
+ IsStruct: bool
264
+ }
265
+
266
+ type InterfaceEntity =
267
+ {
268
+ Name: string
269
+ FullName: string
270
+ XmlDoc: XmlDoc
271
+ Members: Member list
272
+ /// Pre-formatted full type declaration with member signatures.
273
+ Declaration: TextNode
274
+ ObsoleteInfo: ObsoleteInfo
275
+ IsStruct: bool
276
+ }
277
+
278
+ type EnumEntity =
279
+ {
280
+ Name: string
281
+ FullName: string
282
+ XmlDoc: XmlDoc
283
+ Fields: Field list
284
+ /// Pre-formatted full type declaration: `type Name =\n | Case1\n | ...`
285
+ Declaration: TextNode
286
+ ObsoleteInfo: ObsoleteInfo
287
+ IsStruct: bool
288
+ }
289
+
290
+ type MeasureEntity =
291
+ {
292
+ Name: string
293
+ FullName: string
294
+ XmlDoc: XmlDoc
295
+ /// Pre-formatted declaration: `[<Measure>] type Name`
296
+ Declaration: TextNode
297
+ ObsoleteInfo: ObsoleteInfo
298
+ }
299
+
300
+ type ExceptionEntity =
301
+ {
302
+ Name: string
303
+ FullName: string
304
+ XmlDoc: XmlDoc
305
+ Fields: Field list
306
+ /// Pre-formatted declaration: `exception Name of field1: type1 * field2: type2`
307
+ Declaration: TextNode
308
+ ObsoleteInfo: ObsoleteInfo
309
+ }
310
+
311
+ type DelegateEntity =
312
+ {
313
+ Name: string
314
+ FullName: string
315
+ XmlDoc: XmlDoc
316
+ /// Pre-formatted signature of the Invoke method.
317
+ Signature: TextNode
318
+ /// Pre-formatted declaration: `type Name = delegate of ... -> ...`
319
+ Declaration: TextNode
320
+ ObsoleteInfo: ObsoleteInfo
321
+ }
322
+
323
+ [<RequireQualifiedAccess>]
324
+ type Entity =
325
+ | Record of RecordEntity
326
+ | Union of UnionEntity
327
+ | Abbrev of AbbrevEntity
328
+ | Class of ClassEntity
329
+ | Interface of InterfaceEntity
330
+ | Enum of EnumEntity
331
+ | Measure of MeasureEntity
332
+ | Exception of ExceptionEntity
333
+ | Delegate of DelegateEntity
334
+
335
+ member this.Name =
336
+ match this with
337
+ | Record e -> e.Name
338
+ | Union e -> e.Name
339
+ | Abbrev e -> e.Name
340
+ | Class e -> e.Name
341
+ | Interface e -> e.Name
342
+ | Enum e -> e.Name
343
+ | Measure e -> e.Name
344
+ | Exception e -> e.Name
345
+ | Delegate e -> e.Name
346
+
347
+ member this.FullName =
348
+ match this with
349
+ | Record e -> e.FullName
350
+ | Union e -> e.FullName
351
+ | Abbrev e -> e.FullName
352
+ | Class e -> e.FullName
353
+ | Interface e -> e.FullName
354
+ | Enum e -> e.FullName
355
+ | Measure e -> e.FullName
356
+ | Exception e -> e.FullName
357
+ | Delegate e -> e.FullName
358
+
359
+ member this.XmlDoc =
360
+ match this with
361
+ | Record e -> e.XmlDoc
362
+ | Union e -> e.XmlDoc
363
+ | Abbrev e -> e.XmlDoc
364
+ | Class e -> e.XmlDoc
365
+ | Interface e -> e.XmlDoc
366
+ | Enum e -> e.XmlDoc
367
+ | Measure e -> e.XmlDoc
368
+ | Exception e -> e.XmlDoc
369
+ | Delegate e -> e.XmlDoc
370
+
371
+ member this.Declaration =
372
+ match this with
373
+ | Record e -> e.Declaration
374
+ | Union e -> e.Declaration
375
+ | Abbrev e -> e.Declaration
376
+ | Class e -> e.Declaration
377
+ | Interface e -> e.Declaration
378
+ | Enum e -> e.Declaration
379
+ | Measure e -> e.Declaration
380
+ | Exception e -> e.Declaration
381
+ | Delegate e -> e.Declaration
382
+
383
+ member this.ObsoleteInfo =
384
+ match this with
385
+ | Record e -> e.ObsoleteInfo
386
+ | Union e -> e.ObsoleteInfo
387
+ | Abbrev e -> e.ObsoleteInfo
388
+ | Class e -> e.ObsoleteInfo
389
+ | Interface e -> e.ObsoleteInfo
390
+ | Enum e -> e.ObsoleteInfo
391
+ | Measure e -> e.ObsoleteInfo
392
+ | Exception e -> e.ObsoleteInfo
393
+ | Delegate e -> e.ObsoleteInfo
394
+
395
+ member this.IsStruct =
396
+ match this with
397
+ | Record e -> e.IsStruct
398
+ | Union e -> e.IsStruct
399
+ | Abbrev e -> e.IsStruct
400
+ | Class e -> e.IsStruct
401
+ | Interface e -> e.IsStruct
402
+ | Enum e -> e.IsStruct
403
+ | Measure _ -> false
404
+ | Exception _ -> false
405
+ | Delegate _ -> false
406
+
407
+ // ---------------------------------------------------------------------------
408
+ // Modules
409
+ // ---------------------------------------------------------------------------
410
+
411
+ type Module =
412
+ {
413
+ Name: string
414
+ FullName: string
415
+ /// The parent namespace, Encode.g. "Encode.Geometry" for "Encode.Geometry.Points".
416
+ /// Empty string for root-level modules with no Encode.
417
+ Namespace: string
418
+ XmlDoc: string option
419
+ Entities: Entity list
420
+ Functions: Function list
421
+ Values: Value list
422
+ /// True for synthetic modules that carry bare namespace-level types.
423
+ /// The plugin generates individual entity pages from these rather than a module Encode.
424
+ IsSynthetic: bool
425
+ ObsoleteInfo: ObsoleteInfo
426
+ }
427
+
428
+ // ---------------------------------------------------------------------------
429
+ // Namespaces
430
+ // ---------------------------------------------------------------------------
431
+
432
+ type Namespace =
433
+ {
434
+ /// Short display name, e.g. "global", "Reference", "Geometry".
435
+ Name: string
436
+ /// Fully-qualified name, e.g. "", "Reference", "Reference.Geometry".
437
+ FullName: string
438
+ }
439
+
440
+ // ---------------------------------------------------------------------------
441
+ // Assemblies — top-level root
442
+ // ---------------------------------------------------------------------------
443
+
444
+ type Assembly =
445
+ {
446
+ Name: string
447
+ Namespaces: Namespace list
448
+ Modules: Module list
449
+ }
450
+
451
+ type Root =
452
+ {
453
+ Assemblies: Assembly list
454
+ }
@@ -0,0 +1,256 @@
1
+ ---
2
+ import { Aside } from "@astrojs/starlight/components";
3
+
4
+ interface Props {
5
+ open?: boolean;
6
+ name: string;
7
+ obsolete?: boolean;
8
+ obsoleteMessage?: string;
9
+ }
10
+
11
+ const { open = false, name, obsolete = false, obsoleteMessage } = Astro.props;
12
+ ---
13
+
14
+ <div class="collapsible" data-open={open}>
15
+ <div
16
+ class="collapsible__trigger"
17
+ aria-expanded={open ? "true" : "false"}
18
+ role="button"
19
+ >
20
+ <h2 id={name} class="sr-only">{name}</h2>
21
+ <span class="not-content">
22
+ <slot name="signature" />
23
+ </span>
24
+ {obsolete && <span class="deprecated-badge">Deprecated</span>}
25
+ <div class="collapsible__icon">
26
+ <svg
27
+ width="24"
28
+ height="24"
29
+ viewBox="0 0 24 24"
30
+ fill="none"
31
+ xmlns="http://www.w3.org/2000/svg"
32
+ >
33
+ <path
34
+ d="M10.5858 6.34317L12 4.92896L19.0711 12L12 19.0711L10.5858 17.6569L16.2427 12L10.5858 6.34317Z"
35
+ fill="currentColor"></path>
36
+ </svg>
37
+ </div>
38
+ <a
39
+ href={`#${name}`}
40
+ class="collapsible__anchor-link"
41
+ aria-label={`Permalink to ${name}`}
42
+ title={`Permalink to ${name}`}
43
+ tabindex="-1"
44
+ >
45
+ <svg
46
+ width="24"
47
+ height="24"
48
+ viewBox="0 0 24 24"
49
+ fill="none"
50
+ xmlns="http://www.w3.org/2000/svg"
51
+ >
52
+ <path
53
+ d="M14.8284 12L16.2426 13.4142L19.071 10.5858C20.6331 9.02365 20.6331 6.49099 19.071 4.9289C17.509 3.3668 14.9763 3.3668 13.4142 4.9289L10.5858 7.75732L12 9.17154L14.8284 6.34311C15.6095 5.56206 16.8758 5.56206 17.6568 6.34311C18.4379 7.12416 18.4379 8.39049 17.6568 9.17154L14.8284 12Z"
54
+ fill="currentColor"></path>
55
+ <path
56
+ d="M12 14.8285L13.4142 16.2427L10.5858 19.0711C9.02372 20.6332 6.49106 20.6332 4.92896 19.0711C3.36686 17.509 3.36686 14.9764 4.92896 13.4143L7.75739 10.5858L9.1716 12L6.34317 14.8285C5.56212 15.6095 5.56212 16.8758 6.34317 17.6569C7.12422 18.4379 8.39055 18.4379 9.1716 17.6569L12 14.8285Z"
57
+ fill="currentColor"></path>
58
+ <path
59
+ d="M14.8285 10.5857C15.219 10.1952 15.219 9.56199 14.8285 9.17147C14.4379 8.78094 13.8048 8.78094 13.4142 9.17147L9.1716 13.4141C8.78107 13.8046 8.78107 14.4378 9.1716 14.8283C9.56212 15.2188 10.1953 15.2188 10.5858 14.8283L14.8285 10.5857Z"
60
+ fill="currentColor"></path>
61
+ </svg>
62
+ </a>
63
+ </div>
64
+ <div class="collapsible__content" role="region" hidden={!open}>
65
+ {
66
+ obsolete && (
67
+ <Aside type="caution" title="Deprecated">
68
+ {obsoleteMessage}
69
+ </Aside>
70
+ )
71
+ }
72
+ <slot />
73
+ </div>
74
+ </div>
75
+
76
+ <style>
77
+ .collapsible {
78
+ --fo-collapsible-border-raduis: 6px;
79
+ /*
80
+ Trying to use Starlight colors for better integration
81
+ If needed, we can revisit this and add specific colors for the collapsible component
82
+ */
83
+ --fo-collapsible-primary-color: var(--sl-color-gray-6);
84
+ --fo-collapsible-secondary-color: var(--sl-color-gray-7);
85
+ }
86
+
87
+ :global([data-theme="dark"]) .collapsible {
88
+ --fo-collapsible-primary-color: var(--sl-color-gray-5);
89
+ --fo-collapsible-secondary-color: var(--sl-color-gray-6);
90
+ }
91
+
92
+ .collapsible__trigger {
93
+ width: 100%;
94
+ background-color: transparent;
95
+ padding: 1rem;
96
+ cursor: pointer;
97
+ text-align: left;
98
+ transition: background 0.15s;
99
+ position: relative;
100
+ border-radius: var(--fo-collapsible-border-raduis);
101
+ }
102
+
103
+ .collapsible__trigger:hover {
104
+ background: var(--fo-collapsible-secondary-color);
105
+ }
106
+
107
+ .collapsible__icon {
108
+ transition: transform 0.2s ease;
109
+ position: absolute;
110
+ left: -1.5rem;
111
+ top: 1rem;
112
+ display: flex;
113
+ }
114
+
115
+ .collapsible__anchor-link {
116
+ position: absolute;
117
+ left: -3rem;
118
+ top: 1rem;
119
+ text-decoration: none;
120
+ color: var(--sl-color-gray-3);
121
+ opacity: 0;
122
+ /* delayed fade-out: wait 400ms before fading over 200ms */
123
+ transition: opacity 0.2s 0.4s;
124
+ }
125
+
126
+ .collapsible:hover .collapsible__anchor-link {
127
+ opacity: 0.75;
128
+ /* fast fade-in on hover, no delay */
129
+ transition: opacity 0.15s;
130
+ }
131
+
132
+ @keyframes collapsible-flash {
133
+ 50% {
134
+ background-color: var(--sl-color-accent-low);
135
+ }
136
+ }
137
+
138
+ .collapsible__trigger[data-flash] {
139
+ animation: collapsible-flash 0.75s ease;
140
+ animation-iteration-count: 2;
141
+ }
142
+
143
+ .collapsible[data-open="true"] .collapsible__trigger {
144
+ border-radius: var(--fo-collapsible-border-raduis)
145
+ var(--fo-collapsible-border-raduis) 0 0;
146
+ background-color: var(--fo-collapsible-primary-color);
147
+ }
148
+
149
+ .collapsible[data-open="true"] .collapsible__icon {
150
+ transform: rotate(90deg);
151
+ }
152
+
153
+ .collapsible__content {
154
+ margin-top: 0.5rem;
155
+ padding: 1rem;
156
+ background-color: var(--fo-collapsible-secondary-color);
157
+ border-radius: 0 0 var(--fo-collapsible-border-raduis)
158
+ var(--fo-collapsible-border-raduis);
159
+ }
160
+
161
+ .collapsible__content[hidden] {
162
+ display: none;
163
+ }
164
+
165
+ .deprecated-badge {
166
+ position: absolute;
167
+ top: 1rem;
168
+ right: 1rem;
169
+ background-color: var(--sl-color-orange-low);
170
+ color: var(--sl-color-orange-high);
171
+ font-size: 0.75em;
172
+ padding: 0.15em 0.5em;
173
+ border-radius: 4px;
174
+ font-weight: 600;
175
+ }
176
+
177
+ .sr-only {
178
+ position: absolute;
179
+ width: 1px;
180
+ height: 1px;
181
+ overflow: hidden;
182
+ clip: rect(0, 0, 0, 0);
183
+ white-space: nowrap;
184
+ }
185
+ </style>
186
+
187
+ <script>
188
+ const toggleCollapsible = (el: HTMLElement, isOpen: boolean) => {
189
+ const trigger = el.querySelector(".collapsible__trigger")!;
190
+ const content = el.querySelector<HTMLElement>(".collapsible__content")!;
191
+ const newState = String(!isOpen);
192
+ el.classList.toggle("is-open", !isOpen);
193
+ el.dataset["open"] = newState;
194
+ trigger.setAttribute("aria-expanded", newState);
195
+ content.hidden = isOpen;
196
+ };
197
+
198
+ document.querySelectorAll<HTMLElement>(".collapsible").forEach((el) => {
199
+ const trigger = el.querySelector<HTMLElement>(".collapsible__trigger")!;
200
+
201
+ trigger.addEventListener("click", (e) => {
202
+ // Don't toggle when clicking the anchor link
203
+ if ((e.target as HTMLElement).closest(".collapsible__anchor-link"))
204
+ return;
205
+ const isOpen = el.dataset["open"] === "true";
206
+ toggleCollapsible(el, isOpen);
207
+ });
208
+ });
209
+
210
+ function flashTrigger(collapsible: HTMLElement) {
211
+ const trigger = collapsible.querySelector<HTMLElement>(
212
+ ".collapsible__trigger",
213
+ )!;
214
+ trigger.removeAttribute("data-flash");
215
+ void trigger.offsetWidth; // force reflow to restart animation
216
+ trigger.setAttribute("data-flash", "");
217
+ trigger.addEventListener(
218
+ "animationend",
219
+ () => trigger.removeAttribute("data-flash"),
220
+ { once: true },
221
+ );
222
+ }
223
+
224
+ function openCollapsibleForHash(hash: string) {
225
+ if (!hash) return;
226
+ const target = document.getElementById(hash);
227
+ if (!target) return;
228
+ const collapsible = target.closest<HTMLElement>(".collapsible");
229
+ if (!collapsible) return;
230
+ if (collapsible.dataset["open"] !== "true") {
231
+ toggleCollapsible(collapsible, false);
232
+ }
233
+ collapsible.scrollIntoView({ behavior: "instant", block: "start" });
234
+ flashTrigger(collapsible);
235
+ }
236
+
237
+ openCollapsibleForHash(window.location.hash.slice(1));
238
+
239
+ let ignoreNextHashChange = false;
240
+
241
+ document
242
+ .querySelectorAll<HTMLElement>(".collapsible__anchor-link")
243
+ .forEach((link) => {
244
+ link.addEventListener("click", () => {
245
+ ignoreNextHashChange = true;
246
+ });
247
+ });
248
+
249
+ window.addEventListener("hashchange", () => {
250
+ if (ignoreNextHashChange) {
251
+ ignoreNextHashChange = false;
252
+ return;
253
+ }
254
+ openCollapsibleForHash(window.location.hash.slice(1));
255
+ });
256
+ </script>