ripple 0.3.72 → 0.3.76

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 (172) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/package.json +3 -3
  3. package/src/jsx-runtime.d.ts +4 -10
  4. package/src/runtime/dynamic-client.js +33 -0
  5. package/src/runtime/dynamic-server.js +80 -0
  6. package/src/runtime/index-client.js +5 -13
  7. package/src/runtime/index-server.js +2 -0
  8. package/src/runtime/internal/client/blocks.js +6 -27
  9. package/src/runtime/internal/client/composite.js +11 -6
  10. package/src/runtime/internal/client/for.js +80 -5
  11. package/src/runtime/internal/client/index.js +0 -2
  12. package/src/runtime/internal/client/render.js +5 -2
  13. package/src/runtime/internal/client/types.d.ts +0 -10
  14. package/src/runtime/internal/server/index.js +8 -1
  15. package/tests/client/__snapshots__/computed-properties.test.tsrx.snap +8 -0
  16. package/tests/client/__snapshots__/for.test.tsrx.snap +22 -0
  17. package/tests/client/__snapshots__/html.test.tsrx.snap +4 -0
  18. package/tests/client/array/array.copy-within.test.tsrx +19 -19
  19. package/tests/client/array/array.derived.test.tsrx +97 -109
  20. package/tests/client/array/array.iteration.test.tsrx +28 -28
  21. package/tests/client/array/array.mutations.test.tsrx +68 -68
  22. package/tests/client/array/array.static.test.tsrx +82 -92
  23. package/tests/client/array/array.to-methods.test.tsrx +15 -15
  24. package/tests/client/async-suspend.test.tsrx +180 -179
  25. package/tests/client/basic/__snapshots__/basic.attributes.test.tsrx.snap +2 -0
  26. package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +4 -0
  27. package/tests/client/basic/basic.attributes.test.tsrx +273 -317
  28. package/tests/client/basic/basic.collections.test.tsrx +55 -61
  29. package/tests/client/basic/basic.components.test.tsrx +198 -220
  30. package/tests/client/basic/basic.errors.test.tsrx +70 -76
  31. package/tests/client/basic/basic.events.test.tsrx +80 -85
  32. package/tests/client/basic/basic.get-set.test.tsrx +54 -64
  33. package/tests/client/basic/basic.hmr.test.tsrx +15 -19
  34. package/tests/client/basic/basic.reactivity.test.tsrx +121 -135
  35. package/tests/client/basic/basic.rendering.test.tsrx +273 -178
  36. package/tests/client/basic/basic.styling.test.tsrx +16 -14
  37. package/tests/client/basic/basic.utilities.test.tsrx +8 -10
  38. package/tests/client/boundaries.test.tsrx +18 -18
  39. package/tests/client/compiler/compiler.assignments.test.tsrx +77 -76
  40. package/tests/client/compiler/compiler.attributes.test.tsrx +18 -14
  41. package/tests/client/compiler/compiler.basic.test.tsrx +357 -288
  42. package/tests/client/compiler/compiler.regex.test.tsrx +40 -44
  43. package/tests/client/compiler/compiler.tracked-access.test.tsrx +57 -38
  44. package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
  45. package/tests/client/compiler/compiler.typescript.test.tsrx +4 -3
  46. package/tests/client/composite/composite.dynamic-components.test.tsrx +62 -47
  47. package/tests/client/composite/composite.generics.test.tsrx +165 -167
  48. package/tests/client/composite/composite.props.test.tsrx +66 -74
  49. package/tests/client/composite/composite.reactivity.test.tsrx +132 -166
  50. package/tests/client/composite/composite.render.test.tsrx +92 -101
  51. package/tests/client/computed-properties.test.tsrx +14 -18
  52. package/tests/client/context.test.tsrx +14 -18
  53. package/tests/client/css/global-additional-cases.test.tsrx +493 -439
  54. package/tests/client/css/global-advanced-selectors.test.tsrx +169 -153
  55. package/tests/client/css/global-at-rules.test.tsrx +71 -66
  56. package/tests/client/css/global-basic.test.tsrx +105 -98
  57. package/tests/client/css/global-classes-ids.test.tsrx +128 -114
  58. package/tests/client/css/global-combinators.test.tsrx +83 -78
  59. package/tests/client/css/global-complex-nesting.test.tsrx +134 -120
  60. package/tests/client/css/global-edge-cases.test.tsrx +138 -120
  61. package/tests/client/css/global-keyframes.test.tsrx +108 -96
  62. package/tests/client/css/global-nested.test.tsrx +88 -78
  63. package/tests/client/css/global-pseudo.test.tsrx +104 -98
  64. package/tests/client/css/global-scoping.test.tsrx +145 -125
  65. package/tests/client/css/style-identifier.test.tsrx +65 -72
  66. package/tests/client/date.test.tsrx +83 -83
  67. package/tests/client/dynamic-elements.test.tsrx +318 -299
  68. package/tests/client/events.test.tsrx +252 -266
  69. package/tests/client/for.test.tsrx +120 -127
  70. package/tests/client/head.test.tsrx +74 -48
  71. package/tests/client/html.test.tsrx +37 -49
  72. package/tests/client/input-value.test.tsrx +1125 -1354
  73. package/tests/client/lazy-array.test.tsrx +10 -16
  74. package/tests/client/lazy-destructuring.test.tsrx +169 -221
  75. package/tests/client/map.test.tsrx +39 -41
  76. package/tests/client/media-query.test.tsrx +15 -19
  77. package/tests/client/object.test.tsrx +46 -56
  78. package/tests/client/portal.test.tsrx +31 -37
  79. package/tests/client/ref.test.tsrx +173 -193
  80. package/tests/client/return.test.tsrx +62 -37
  81. package/tests/client/set.test.tsrx +33 -33
  82. package/tests/client/svg.test.tsrx +197 -216
  83. package/tests/client/switch.test.tsrx +201 -191
  84. package/tests/client/track-async-hydration.test.tsrx +14 -18
  85. package/tests/client/tracked-index-access.test.tsrx +18 -28
  86. package/tests/client/try.test.tsrx +494 -619
  87. package/tests/client/tsx.test.tsrx +286 -292
  88. package/tests/client/typescript-generics.test.tsrx +121 -129
  89. package/tests/client/url/url.derived.test.tsrx +21 -25
  90. package/tests/client/url/url.parsing.test.tsrx +35 -35
  91. package/tests/client/url/url.partial-removal.test.tsrx +32 -32
  92. package/tests/client/url/url.reactivity.test.tsrx +68 -72
  93. package/tests/client/url/url.serialization.test.tsrx +8 -8
  94. package/tests/client/url-search-params/url-search-params.derived.test.tsrx +21 -27
  95. package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +16 -16
  96. package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +37 -37
  97. package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +56 -60
  98. package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +32 -34
  99. package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +9 -9
  100. package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +10 -10
  101. package/tests/hydration/compiled/client/basic.js +390 -319
  102. package/tests/hydration/compiled/client/composite.js +52 -44
  103. package/tests/hydration/compiled/client/for.js +734 -604
  104. package/tests/hydration/compiled/client/head.js +183 -103
  105. package/tests/hydration/compiled/client/html.js +93 -86
  106. package/tests/hydration/compiled/client/if-children.js +95 -71
  107. package/tests/hydration/compiled/client/if.js +113 -89
  108. package/tests/hydration/compiled/client/mixed-control-flow.js +225 -209
  109. package/tests/hydration/compiled/client/nested-control-flow.js +94 -98
  110. package/tests/hydration/compiled/client/reactivity.js +26 -24
  111. package/tests/hydration/compiled/client/return.js +8 -42
  112. package/tests/hydration/compiled/client/switch.js +208 -173
  113. package/tests/hydration/compiled/client/track-async-serialization.js +176 -128
  114. package/tests/hydration/compiled/client/try.js +29 -21
  115. package/tests/hydration/compiled/server/basic.js +210 -221
  116. package/tests/hydration/compiled/server/composite.js +13 -14
  117. package/tests/hydration/compiled/server/for.js +427 -444
  118. package/tests/hydration/compiled/server/head.js +199 -189
  119. package/tests/hydration/compiled/server/html.js +33 -41
  120. package/tests/hydration/compiled/server/if-children.js +114 -117
  121. package/tests/hydration/compiled/server/if.js +77 -83
  122. package/tests/hydration/compiled/server/mixed-control-flow.js +145 -150
  123. package/tests/hydration/compiled/server/nested-control-flow.js +10 -0
  124. package/tests/hydration/compiled/server/reactivity.js +24 -22
  125. package/tests/hydration/compiled/server/return.js +6 -18
  126. package/tests/hydration/compiled/server/switch.js +179 -176
  127. package/tests/hydration/compiled/server/track-async-serialization.js +88 -70
  128. package/tests/hydration/compiled/server/try.js +31 -35
  129. package/tests/hydration/components/basic.tsrx +216 -258
  130. package/tests/hydration/components/composite.tsrx +32 -42
  131. package/tests/hydration/components/events.tsrx +81 -101
  132. package/tests/hydration/components/for.tsrx +270 -336
  133. package/tests/hydration/components/head.tsrx +43 -39
  134. package/tests/hydration/components/hmr.tsrx +16 -22
  135. package/tests/hydration/components/html-in-template.tsrx +15 -21
  136. package/tests/hydration/components/html.tsrx +442 -526
  137. package/tests/hydration/components/if-children.tsrx +107 -125
  138. package/tests/hydration/components/if.tsrx +68 -90
  139. package/tests/hydration/components/mixed-control-flow.tsrx +65 -72
  140. package/tests/hydration/components/nested-control-flow.tsrx +202 -216
  141. package/tests/hydration/components/portal.tsrx +33 -41
  142. package/tests/hydration/components/reactivity.tsrx +26 -34
  143. package/tests/hydration/components/return.tsrx +4 -6
  144. package/tests/hydration/components/switch.tsrx +73 -78
  145. package/tests/hydration/components/track-async-serialization.tsrx +83 -93
  146. package/tests/hydration/components/try.tsrx +37 -51
  147. package/tests/hydration/switch.test.js +8 -8
  148. package/tests/server/await.test.tsrx +3 -3
  149. package/tests/server/basic.attributes.test.tsrx +117 -162
  150. package/tests/server/basic.components.test.tsrx +164 -194
  151. package/tests/server/basic.test.tsrx +299 -199
  152. package/tests/server/compiler.test.tsrx +142 -72
  153. package/tests/server/composite.props.test.tsrx +54 -58
  154. package/tests/server/composite.test.tsrx +165 -167
  155. package/tests/server/context.test.tsrx +13 -17
  156. package/tests/server/dynamic-elements.test.tsrx +147 -148
  157. package/tests/server/for.test.tsrx +115 -84
  158. package/tests/server/head.test.tsrx +54 -31
  159. package/tests/server/html-nesting-validation.test.tsrx +16 -8
  160. package/tests/server/if.test.tsrx +49 -59
  161. package/tests/server/lazy-destructuring.test.tsrx +288 -366
  162. package/tests/server/return.test.tsrx +58 -36
  163. package/tests/server/streaming-ssr.test.tsrx +4 -4
  164. package/tests/server/style-identifier.test.tsrx +61 -69
  165. package/tests/server/switch.test.tsrx +89 -97
  166. package/tests/server/track-async-serialization.test.tsrx +85 -103
  167. package/tests/server/try.test.tsrx +275 -360
  168. package/tests/utils/ref-types.test.js +72 -0
  169. package/tests/utils/vite-plugin-config.test.js +41 -74
  170. package/types/index.d.ts +29 -4
  171. package/src/runtime/internal/client/compat.js +0 -40
  172. package/tests/utils/compiler-compat-config.test.js +0 -38
@@ -1,121 +1,95 @@
1
1
  import { Fragment, track } from 'ripple';
2
2
 
3
- export function StaticHtml() {
4
- return <>
5
- const html = '<p><strong>Bold</strong> text</p>';
6
- <div innerHTML={html} />
7
- </>;
3
+ export function StaticHtml() @{
4
+ const html = '<p><strong>Bold</strong> text</p>';
5
+ <div innerHTML={html} />
8
6
  }
9
7
 
10
- export function DynamicHtml() {
11
- return <>
12
- const content = '<p>Dynamic <span>HTML</span> content</p>';
13
- <div innerHTML={content} />
14
- </>;
8
+ export function DynamicHtml() @{
9
+ const content = '<p>Dynamic <span>HTML</span> content</p>';
10
+ <div innerHTML={content} />
15
11
  }
16
12
 
17
- export function EmptyHtml() {
18
- return <>
19
- const html = '';
20
- <div innerHTML={html} />
21
- </>;
13
+ export function EmptyHtml() @{
14
+ const html = '';
15
+ <div innerHTML={html} />
22
16
  }
23
17
 
24
- export function ComplexHtml() {
25
- return <>
26
- const html = '<div class="nested"><span>Nested <em>content</em></span></div>';
27
- <section innerHTML={html} />
28
- </>;
18
+ export function ComplexHtml() @{
19
+ const html = '<div class="nested"><span>Nested <em>content</em></span></div>';
20
+ <section innerHTML={html} />
29
21
  }
30
22
 
31
- export function MultipleHtml() {
32
- return <>
33
- const html1 = '<p>First paragraph</p>';
34
- const html2 = '<p>Second paragraph</p>';
35
- <div>
36
- <Fragment innerHTML={html1} />
37
- <Fragment innerHTML={html2} />
38
- </div>
39
- </>;
23
+ export function MultipleHtml() @{
24
+ const html1 = '<p>First paragraph</p>';
25
+ const html2 = '<p>Second paragraph</p>';
26
+ <div>
27
+ <Fragment innerHTML={html1} />
28
+ <Fragment innerHTML={html2} />
29
+ </div>
40
30
  }
41
31
 
42
- export function HtmlWithReactivity() {
43
- return <>
44
- <div>
45
- <Fragment innerHTML="<p>Count: 0</p>" />
46
- <button>{'Increment'}</button>
47
- </div>
48
- </>;
32
+ export function HtmlWithReactivity() @{
33
+ <div>
34
+ <Fragment innerHTML="<p>Count: 0</p>" />
35
+ <button>{'Increment'}</button>
36
+ </div>
49
37
  }
50
38
 
51
- export function HtmlWrapper({ children }: { children: any }) {
52
- return <>
53
- <div class="wrapper">
54
- <div class="inner">{children}</div>
55
- </div>
56
- </>;
39
+ export function HtmlWrapper({ children }: { children: any }) @{
40
+ <div class="wrapper">
41
+ <div class="inner">{children}</div>
42
+ </div>
57
43
  }
58
44
 
59
- export function HtmlInChildren() {
60
- return <>
61
- const content = '<p><strong>Bold</strong> text</p>';
62
- <HtmlWrapper>
63
- <div class="vp-doc" innerHTML={content} />
64
- </HtmlWrapper>
65
- </>;
45
+ export function HtmlInChildren() @{
46
+ const content = '<p><strong>Bold</strong> text</p>';
47
+ <HtmlWrapper>
48
+ <div class="vp-doc" innerHTML={content} />
49
+ </HtmlWrapper>
66
50
  }
67
51
 
68
- export function HtmlInChildrenWithSiblings() {
69
- return <>
70
- const content = '<p>Dynamic content</p>';
71
- <HtmlWrapper>
72
- <h1>{'Title'}</h1>
73
- <div class="content" innerHTML={content} />
74
- </HtmlWrapper>
75
- </>;
76
- }
77
-
78
- export function MultipleHtmlInChildren() {
79
- return <>
80
- const html1 = '<p>First</p>';
81
- const html2 = '<p>Second</p>';
82
- <HtmlWrapper>
83
- <div class="doc">
84
- <Fragment innerHTML={html1} />
85
- <Fragment innerHTML={html2} />
86
- </div>
87
- </HtmlWrapper>
88
- </>;
52
+ export function HtmlInChildrenWithSiblings() @{
53
+ const content = '<p>Dynamic content</p>';
54
+ <HtmlWrapper>
55
+ <h1>{'Title'}</h1>
56
+ <div class="content" innerHTML={content} />
57
+ </HtmlWrapper>
58
+ }
59
+
60
+ export function MultipleHtmlInChildren() @{
61
+ const html1 = '<p>First</p>';
62
+ const html2 = '<p>Second</p>';
63
+ <HtmlWrapper>
64
+ <div class="doc">
65
+ <Fragment innerHTML={html1} />
66
+ <Fragment innerHTML={html2} />
67
+ </div>
68
+ </HtmlWrapper>
89
69
  }
90
70
 
91
- export function HtmlWithComments() {
92
- return <>
93
- const content = '<p>Before comment</p><!-- TODO: Elaborate --><p>After comment</p>';
94
- <div innerHTML={content} />
95
- </>;
71
+ export function HtmlWithComments() @{
72
+ const content = '<p>Before comment</p><!-- TODO: Elaborate --><p>After comment</p>';
73
+ <div innerHTML={content} />
96
74
  }
97
75
 
98
- export function HtmlWithEmptyComment() {
99
- return <>
100
- const content = '<p>Before</p><!----><p>After</p>';
101
- <div innerHTML={content} />
102
- </>;
76
+ export function HtmlWithEmptyComment() @{
77
+ const content = '<p>Before</p><!----><p>After</p>';
78
+ <div innerHTML={content} />
103
79
  }
104
80
 
105
- export function HtmlWithCommentsInChildren() {
106
- return <>
107
- const content = '<h2 id="intro">Introduction</h2><p>Some text</p><!-- TODO --><p>More text</p>';
108
- <HtmlWrapper>
109
- <div class="vp-doc" innerHTML={content} />
110
- </HtmlWrapper>
111
- </>;
81
+ export function HtmlWithCommentsInChildren() @{
82
+ const content = '<h2 id="intro">Introduction</h2><p>Some text</p><!-- TODO --><p>More text</p>';
83
+ <HtmlWrapper>
84
+ <div class="vp-doc" innerHTML={content} />
85
+ </HtmlWrapper>
112
86
  }
113
87
 
114
- function DocFooter() {
115
- return <><footer class="doc-footer">{'Footer content'}</footer></>;
88
+ function DocFooter() @{
89
+ <footer class="doc-footer">{'Footer content'}</footer>
116
90
  }
117
91
 
118
- export function DocLayout({
92
+ export function DocLayout(&{
119
93
  children,
120
94
  editPath = '',
121
95
  nextLink = null,
@@ -125,123 +99,107 @@ export function DocLayout({
125
99
  editPath?: string;
126
100
  nextLink?: { href: string; text: string } | null;
127
101
  toc?: { href: string; text: string }[];
128
- }) {
129
- return <>
130
- <div class="layout">
131
- <div class="content-container">
132
- <article>
133
- <div>{children}</div>
134
- </article>
135
- if (editPath) {
136
- <div class="edit-link">
137
- <a href={`https://github.com/edit/${editPath}`}>{'Edit'}</a>
138
- </div>
139
- }
140
- if (nextLink) {
141
- <nav class="prev-next">
142
- <a href={nextLink.href}>{nextLink.text}</a>
143
- </nav>
144
- }
145
- <DocFooter />
146
- </div>
147
- <aside>
148
- if (toc.length > 0) {
149
- <div class="toc">
150
- <ul>
151
- for (const item of toc) {
152
- <li>
153
- <a href={item.href}>{item.text}</a>
154
- </li>
155
- }
156
- </ul>
157
- </div>
158
- }
159
- </aside>
102
+ }) @{
103
+ <div class="layout">
104
+ <div class="content-container">
105
+ <article>
106
+ <div>{children}</div>
107
+ </article>
108
+ @if (editPath) {
109
+ <div class="edit-link">
110
+ <a href={`https://github.com/edit/${editPath}`}>{'Edit'}</a>
111
+ </div>
112
+ }
113
+ @if (nextLink) {
114
+ <nav class="prev-next">
115
+ <a href={nextLink.href}>{nextLink.text}</a>
116
+ </nav>
117
+ }
118
+ <DocFooter />
160
119
  </div>
161
- </>;
162
- }
163
-
164
- export function HtmlWithServerData() {
165
- return <>
166
- const content = '<h1 id="intro" class="doc-h1">Introduction</h1><p>Ripple is a framework.</p>';
167
- <DocLayout
168
- editPath="docs/introduction.md"
169
- nextLink={{ href: '/docs/quick-start', text: 'Quick Start' }}
170
- toc={[
171
- { href: '#intro', text: 'Introduction' },
172
- { href: '#features', text: 'Features' },
173
- ]}
174
- >
175
- <div class="vp-doc" innerHTML={content} />
176
- </DocLayout>
177
- </>;
178
- }
179
-
180
- export function HtmlWithClientDefaults() {
181
- return <>
182
- const content = '<h1 id="intro" class="doc-h1">Introduction</h1><p>Ripple is a framework.</p>';
183
- <DocLayout>
184
- <div class="vp-doc" innerHTML={content} />
185
- </DocLayout>
186
- </>;
187
- }
188
-
189
- export function HtmlWithUndefinedContent() {
190
- return <>
191
- const content: string | undefined = undefined;
192
- <DocLayout>
193
- <div class="vp-doc" innerHTML={content} />
194
- </DocLayout>
195
- </>;
196
- }
197
-
198
- function DynamicHeading({ level, children }: { level: number; children: any }) {
199
- return <>
200
- switch (level) {
201
- case 1:
202
- <h1 class="heading">{children}</h1>
203
- break;
204
- case 2:
205
- <h2 class="heading">{children}</h2>
206
- break;
120
+ <aside>
121
+ @if (toc.length > 0) {
122
+ <div class="toc">
123
+ <ul>
124
+ @for (const item of toc) {
125
+ <li>
126
+ <a href={item.href}>{item.text}</a>
127
+ </li>
128
+ }
129
+ </ul>
130
+ </div>
131
+ }
132
+ </aside>
133
+ </div>
134
+ }
135
+
136
+ export function HtmlWithServerData() @{
137
+ const content = '<h1 id="intro" class="doc-h1">Introduction</h1><p>Ripple is a framework.</p>';
138
+ <DocLayout
139
+ editPath="docs/introduction.md"
140
+ nextLink={{ href: '/docs/quick-start', text: 'Quick Start' }}
141
+ toc={[
142
+ { href: '#intro', text: 'Introduction' },
143
+ { href: '#features', text: 'Features' },
144
+ ]}
145
+ >
146
+ <div class="vp-doc" innerHTML={content} />
147
+ </DocLayout>
148
+ }
149
+
150
+ export function HtmlWithClientDefaults() @{
151
+ const content = '<h1 id="intro" class="doc-h1">Introduction</h1><p>Ripple is a framework.</p>';
152
+ <DocLayout>
153
+ <div class="vp-doc" innerHTML={content} />
154
+ </DocLayout>
155
+ }
156
+
157
+ export function HtmlWithUndefinedContent() @{
158
+ const content: string | undefined = undefined;
159
+ <DocLayout>
160
+ <div class="vp-doc" innerHTML={content} />
161
+ </DocLayout>
162
+ }
163
+
164
+ function DynamicHeading({ level, children }: { level: number; children: any }) @{
165
+ @switch (level) {
166
+ @case 1: {
167
+ <h1 class="heading">{children}</h1>
168
+ }
169
+ @case 2: {
170
+ <h2 class="heading">{children}</h2>
207
171
  }
208
- </>;
172
+ }
209
173
  }
210
174
 
211
- function CodeBlock({ code }: { code: string }) {
212
- return <>
213
- const highlighted = `<pre class="shiki"><code>${code}</code></pre>`;
214
- <div class="code-block">
215
- <div class="header">
216
- <button>{'Copy'}</button>
217
- <span class="lang">{'js'}</span>
218
- </div>
219
- <div class="content" innerHTML={highlighted} />
175
+ function CodeBlock({ code }: { code: string }) @{
176
+ const highlighted = `<pre class="shiki"><code>${code}</code></pre>`;
177
+ <div class="code-block">
178
+ <div class="header">
179
+ <button>{'Copy'}</button>
180
+ <span class="lang">{'js'}</span>
220
181
  </div>
221
- </>;
182
+ <div class="content" innerHTML={highlighted} />
183
+ </div>
222
184
  }
223
185
 
224
- function ContentWrapper({ children }: { children: any }) {
225
- return <>
226
- <div class="wrapper">
227
- <div class="inner">{children}</div>
228
- </div>
229
- </>;
186
+ function ContentWrapper({ children }: { children: any }) @{
187
+ <div class="wrapper">
188
+ <div class="inner">{children}</div>
189
+ </div>
230
190
  }
231
191
 
232
- export function HtmlAfterSwitchInChildren() {
233
- return <>
234
- <ContentWrapper>
235
- <DynamicHeading level={1}>{'Title'}</DynamicHeading>
236
- <p>{'First paragraph'}</p>
237
- <p>{'Second paragraph'}</p>
238
- <CodeBlock code="const x = 1;" />
239
- <p>{'After code'}</p>
240
- </ContentWrapper>
241
- </>;
192
+ export function HtmlAfterSwitchInChildren() @{
193
+ <ContentWrapper>
194
+ <DynamicHeading level={1}>{'Title'}</DynamicHeading>
195
+ <p>{'First paragraph'}</p>
196
+ <p>{'Second paragraph'}</p>
197
+ <CodeBlock code="const x = 1;" />
198
+ <p>{'After code'}</p>
199
+ </ContentWrapper>
242
200
  }
243
201
 
244
- function NavItem({
202
+ function NavItem(&{
245
203
  href,
246
204
  text: label,
247
205
  active = false,
@@ -249,177 +207,157 @@ function NavItem({
249
207
  href: string;
250
208
  text: string;
251
209
  active?: boolean;
252
- }) {
253
- return <>
254
- <div class={`nav-item${active ? ' active' : ''}`}>
255
- if (active) {
256
- <div class="indicator" />
257
- }
258
- <a {href}>
259
- <span>{label}</span>
260
- </a>
210
+ }) @{
211
+ <div class={`nav-item${active ? ' active' : ''}`}>
212
+ @if (active) {
213
+ <div class="indicator" />
214
+ }
215
+ <a {href}>
216
+ <span>{label}</span>
217
+ </a>
218
+ </div>
219
+ }
220
+
221
+ function SidebarSection({ title, children }: { title: string; children: any }) @{
222
+ let &[expanded] = track(true);
223
+ <section class="sidebar-section">
224
+ <div class="section-header">
225
+ <h2>{title}</h2>
226
+ <button onClick={() => (expanded = !expanded)}>{'Toggle'}</button>
261
227
  </div>
262
- </>;
228
+ @if (expanded) {
229
+ <div class="section-items">{children}</div>
230
+ }
231
+ </section>
263
232
  }
264
233
 
265
- function SidebarSection({ title, children }: { title: string; children: any }) {
266
- return <>
267
- let &[expanded] = track(true);
268
- <section class="sidebar-section">
269
- <div class="section-header">
270
- <h2>{title}</h2>
271
- <button onClick={() => (expanded = !expanded)}>{'Toggle'}</button>
234
+ function SideNav({ currentPath }: { currentPath: string }) @{
235
+ <aside class="sidebar">
236
+ <nav>
237
+ <div class="group">
238
+ <SidebarSection title="Getting Started">
239
+ <NavItem href="/intro" text="Introduction" active={currentPath === '/intro'} />
240
+ <NavItem href="/start" text="Quick Start" active={currentPath === '/start'} />
241
+ </SidebarSection>
272
242
  </div>
273
- if (expanded) {
274
- <div class="section-items">{children}</div>
275
- }
276
- </section>
277
- </>;
278
- }
279
-
280
- function SideNav({ currentPath }: { currentPath: string }) {
281
- return <>
282
- <aside class="sidebar">
283
- <nav>
284
- <div class="group">
285
- <SidebarSection title="Getting Started">
286
- <NavItem href="/intro" text="Introduction" active={currentPath === '/intro'} />
287
- <NavItem href="/start" text="Quick Start" active={currentPath === '/start'} />
288
- </SidebarSection>
289
- </div>
290
- <div class="group">
291
- <SidebarSection title="Guide">
292
- <NavItem href="/guide/app" text="Application" active={currentPath === '/guide/app'} />
293
- <NavItem href="/guide/syntax" text="Syntax" active={currentPath === '/guide/syntax'} />
294
- </SidebarSection>
243
+ <div class="group">
244
+ <SidebarSection title="Guide">
245
+ <NavItem href="/guide/app" text="Application" active={currentPath === '/guide/app'} />
246
+ <NavItem href="/guide/syntax" text="Syntax" active={currentPath === '/guide/syntax'} />
247
+ </SidebarSection>
248
+ </div>
249
+ </nav>
250
+ </aside>
251
+ }
252
+
253
+ function PageHeader() @{
254
+ <header class="page-header">
255
+ <div class="logo">{'MyApp'}</div>
256
+ </header>
257
+ }
258
+
259
+ export function LayoutWithSidebarAndMain() @{
260
+ <div class="layout">
261
+ <PageHeader />
262
+ <div class="content-wrapper">
263
+ <SideNav currentPath="/intro" />
264
+ <main class="main-content">
265
+ <div class="article">
266
+ <div>
267
+ <h1>{'Introduction'}</h1>
268
+ <p>{'Welcome to the docs.'}</p>
269
+ </div>
295
270
  </div>
296
- </nav>
297
- </aside>
298
- </>;
299
- }
300
-
301
- function PageHeader() {
302
- return <>
303
- <header class="page-header">
304
- <div class="logo">{'MyApp'}</div>
305
- </header>
306
- </>;
307
- }
308
-
309
- export function LayoutWithSidebarAndMain() {
310
- return <>
311
- <div class="layout">
312
- <PageHeader />
313
- <div class="content-wrapper">
314
- <SideNav currentPath="/intro" />
315
- <main class="main-content">
316
- <div class="article">
317
- <div>
318
- <h1>{'Introduction'}</h1>
319
- <p>{'Welcome to the docs.'}</p>
320
- </div>
271
+ @if (true) {
272
+ <div class="edit-link">
273
+ <a href="/edit">{'Edit'}</a>
321
274
  </div>
322
- if (true) {
323
- <div class="edit-link">
324
- <a href="/edit">{'Edit'}</a>
325
- </div>
326
- }
327
- <PageHeader />
328
- </main>
329
- </div>
275
+ }
276
+ <PageHeader />
277
+ </main>
330
278
  </div>
331
- </>;
279
+ </div>
332
280
  }
333
281
 
334
- function ArticleWrapper({ children }: { children: any }) {
335
- return <>
336
- <article class="doc-content">
337
- <div>{children}</div>
338
- </article>
339
- </>;
282
+ function ArticleWrapper({ children }: { children: any }) @{
283
+ <article class="doc-content">
284
+ <div>{children}</div>
285
+ </article>
340
286
  }
341
287
 
342
- function SimpleFooter() {
343
- return <><footer class="doc-footer">{'Footer'}</footer></>;
288
+ function SimpleFooter() @{
289
+ <footer class="doc-footer">{'Footer'}</footer>
344
290
  }
345
291
 
346
- export function ArticleWithChildrenThenSibling() {
347
- return <>
348
- <div class="content-container">
349
- <ArticleWrapper>
350
- <h1>{'Title'}</h1>
351
- <p>{'Content goes here.'}</p>
352
- </ArticleWrapper>
353
- if (true) {
354
- <div class="edit-link">
355
- <a href="/edit">{'Edit'}</a>
356
- </div>
357
- }
358
- if (true) {
359
- <nav class="prev-next">
360
- <a href="/prev">{'Previous'}</a>
361
- </nav>
362
- }
363
- <SimpleFooter />
364
- </div>
365
- </>;
292
+ export function ArticleWithChildrenThenSibling() @{
293
+ <div class="content-container">
294
+ <ArticleWrapper>
295
+ <h1>{'Title'}</h1>
296
+ <p>{'Content goes here.'}</p>
297
+ </ArticleWrapper>
298
+ @if (true) {
299
+ <div class="edit-link">
300
+ <a href="/edit">{'Edit'}</a>
301
+ </div>
302
+ }
303
+ @if (true) {
304
+ <nav class="prev-next">
305
+ <a href="/prev">{'Previous'}</a>
306
+ </nav>
307
+ }
308
+ <SimpleFooter />
309
+ </div>
366
310
  }
367
311
 
368
- export function ArticleWithHtmlChildThenSibling() {
369
- return <>
370
- const htmlContent = '<pre><code>const x = 1;</code></pre>';
371
- <div class="content-container">
372
- <ArticleWrapper>
373
- <div class="doc-content" innerHTML={htmlContent} />
374
- </ArticleWrapper>
375
- if (true) {
376
- <div class="edit-link">
377
- <a href="/edit">{'Edit'}</a>
378
- </div>
379
- }
380
- <SimpleFooter />
381
- </div>
382
- </>;
312
+ export function ArticleWithHtmlChildThenSibling() @{
313
+ const htmlContent = '<pre><code>const x = 1;</code></pre>';
314
+ <div class="content-container">
315
+ <ArticleWrapper>
316
+ <div class="doc-content" innerHTML={htmlContent} />
317
+ </ArticleWrapper>
318
+ @if (true) {
319
+ <div class="edit-link">
320
+ <a href="/edit">{'Edit'}</a>
321
+ </div>
322
+ }
323
+ <SimpleFooter />
324
+ </div>
383
325
  }
384
326
 
385
- function InlineArticleLayout({ children }: { children: any }) {
386
- return <>
387
- <div class="content-container">
388
- <article class="doc-content">
389
- <div>{children}</div>
390
- </article>
391
- if (true) {
392
- <div class="edit-link">
393
- <a href="/edit">{'Edit'}</a>
394
- </div>
395
- }
396
- <SimpleFooter />
397
- </div>
398
- </>;
327
+ function InlineArticleLayout({ children }: { children: any }) @{
328
+ <div class="content-container">
329
+ <article class="doc-content">
330
+ <div>{children}</div>
331
+ </article>
332
+ @if (true) {
333
+ <div class="edit-link">
334
+ <a href="/edit">{'Edit'}</a>
335
+ </div>
336
+ }
337
+ <SimpleFooter />
338
+ </div>
399
339
  }
400
340
 
401
- export function InlineArticleWithHtmlChild() {
402
- return <>
403
- const htmlContent = '<pre><code>const x = 1;</code></pre>';
404
- <InlineArticleLayout>
405
- <div class="doc-content" innerHTML={htmlContent} />
406
- </InlineArticleLayout>
407
- </>;
341
+ export function InlineArticleWithHtmlChild() @{
342
+ const htmlContent = '<pre><code>const x = 1;</code></pre>';
343
+ <InlineArticleLayout>
344
+ <div class="doc-content" innerHTML={htmlContent} />
345
+ </InlineArticleLayout>
408
346
  }
409
347
 
410
- function HeaderStub() {
411
- return <><header class="header">{'Header'}</header></>;
348
+ function HeaderStub() @{
349
+ <header class="header">{'Header'}</header>
412
350
  }
413
351
 
414
- function SidebarStub() {
415
- return <><aside class="sidebar">{'Sidebar'}</aside></>;
352
+ function SidebarStub() @{
353
+ <aside class="sidebar">{'Sidebar'}</aside>
416
354
  }
417
355
 
418
- function FooterStub() {
419
- return <><footer class="footer">{'Footer'}</footer></>;
356
+ function FooterStub() @{
357
+ <footer class="footer">{'Footer'}</footer>
420
358
  }
421
359
 
422
- function DocsLayoutInner({
360
+ function DocsLayoutInner(&{
423
361
  children,
424
362
  editPath = '',
425
363
  nextLink = null,
@@ -427,58 +365,52 @@ function DocsLayoutInner({
427
365
  children: any;
428
366
  editPath?: string;
429
367
  nextLink?: { href: string; text: string } | null;
430
- }) {
431
- return <>
432
- <div class="layout">
433
- <HeaderStub />
434
- <div class="docs-wrapper">
435
- <SidebarStub />
436
- <main class="docs-main">
437
- <div class="docs-container">
438
- <div class="content">
439
- <div class="content-container">
440
- <article class="doc-content">
441
- <div>{children}</div>
442
- </article>
443
- if (editPath) {
444
- <div class="edit-link">
445
- <a href="/edit">{'Edit on GitHub'}</a>
446
- </div>
447
- }
448
- if (nextLink) {
449
- <nav class="prev-next">
450
- <a href={nextLink.href}>{nextLink.text}</a>
451
- </nav>
452
- }
453
- <FooterStub />
454
- </div>
368
+ }) @{
369
+ <div class="layout">
370
+ <HeaderStub />
371
+ <div class="docs-wrapper">
372
+ <SidebarStub />
373
+ <main class="docs-main">
374
+ <div class="docs-container">
375
+ <div class="content">
376
+ <div class="content-container">
377
+ <article class="doc-content">
378
+ <div>{children}</div>
379
+ </article>
380
+ @if (editPath) {
381
+ <div class="edit-link">
382
+ <a href="/edit">{'Edit on GitHub'}</a>
383
+ </div>
384
+ }
385
+ @if (nextLink) {
386
+ <nav class="prev-next">
387
+ <a href={nextLink.href}>{nextLink.text}</a>
388
+ </nav>
389
+ }
390
+ <FooterStub />
455
391
  </div>
456
392
  </div>
457
- </main>
458
- </div>
393
+ </div>
394
+ </main>
459
395
  </div>
460
- </>;
396
+ </div>
461
397
  }
462
398
 
463
- export function DocsLayoutWithData() {
464
- return <>
465
- const htmlContent = '<h1>Title</h1><p>Content</p>';
466
- <DocsLayoutInner editPath="docs/styling.md" nextLink={{ href: '/next', text: 'Next' }}>
467
- <div class="doc-content" innerHTML={htmlContent} />
468
- </DocsLayoutInner>
469
- </>;
399
+ export function DocsLayoutWithData() @{
400
+ const htmlContent = '<h1>Title</h1><p>Content</p>';
401
+ <DocsLayoutInner editPath="docs/styling.md" nextLink={{ href: '/next', text: 'Next' }}>
402
+ <div class="doc-content" innerHTML={htmlContent} />
403
+ </DocsLayoutInner>
470
404
  }
471
405
 
472
- export function DocsLayoutWithoutData() {
473
- return <>
474
- const htmlContent: string | undefined = undefined;
475
- <DocsLayoutInner>
476
- <div class="doc-content" innerHTML={htmlContent} />
477
- </DocsLayoutInner>
478
- </>;
406
+ export function DocsLayoutWithoutData() @{
407
+ const htmlContent: string | undefined = undefined;
408
+ <DocsLayoutInner>
409
+ <div class="doc-content" innerHTML={htmlContent} />
410
+ </DocsLayoutInner>
479
411
  }
480
412
 
481
- function DocsLayoutExact({
413
+ function DocsLayoutExact(&{
482
414
  children,
483
415
  editPath = '',
484
416
  prevLink = null,
@@ -490,151 +422,135 @@ function DocsLayoutExact({
490
422
  prevLink?: { href: string; text: string } | null;
491
423
  nextLink?: { href: string; text: string } | null;
492
424
  toc?: { href: string; text: string }[];
493
- }) {
494
- return <>
495
- <div class="layout">
496
- <HeaderStub />
497
- <div class="docs-wrapper">
498
- <SidebarStub />
499
- <main class="docs-main">
500
- <div class="docs-container">
501
- <div class="content">
502
- <div class="content-container">
503
- <article class="doc-content">
504
- <div>{children}</div>
505
- </article>
506
- if (editPath) {
507
- <div class="edit-link">
508
- <a href={`/edit/${editPath}`}>{'Edit on GitHub'}</a>
509
- </div>
510
- }
511
- if (prevLink || nextLink) {
512
- <nav class="prev-next">
513
- if (prevLink) {
514
- <a href={prevLink.href} class="pager prev">
515
- <span class="title">{prevLink.text}</span>
516
- </a>
517
- } else {
518
- <span />
519
- }
520
- if (nextLink) {
521
- <a href={nextLink.href} class="pager next">
522
- <span class="title">{nextLink.text}</span>
523
- </a>
524
- }
525
- </nav>
526
- }
527
- <FooterStub />
528
- </div>
529
- </div>
530
- <aside class="aside">
531
- if (toc.length > 0) {
532
- <div class="aside-content">
533
- <nav class="outline">
534
- for (const item of toc) {
535
- <a href={item.href}>{item.text}</a>
536
- }
537
- </nav>
425
+ }) @{
426
+ <div class="layout">
427
+ <HeaderStub />
428
+ <div class="docs-wrapper">
429
+ <SidebarStub />
430
+ <main class="docs-main">
431
+ <div class="docs-container">
432
+ <div class="content">
433
+ <div class="content-container">
434
+ <article class="doc-content">
435
+ <div>{children}</div>
436
+ </article>
437
+ @if (editPath) {
438
+ <div class="edit-link">
439
+ <a href={`/edit/${editPath}`}>{'Edit on GitHub'}</a>
538
440
  </div>
539
441
  }
540
- </aside>
442
+ @if (prevLink || nextLink) {
443
+ <nav class="prev-next">
444
+ @if (prevLink) {
445
+ <a href={prevLink.href} class="pager prev">
446
+ <span class="title">{prevLink.text}</span>
447
+ </a>
448
+ } @else {
449
+ <span />
450
+ }
451
+ @if (nextLink) {
452
+ <a href={nextLink.href} class="pager next">
453
+ <span class="title">{nextLink.text}</span>
454
+ </a>
455
+ }
456
+ </nav>
457
+ }
458
+ <FooterStub />
459
+ </div>
541
460
  </div>
542
- </main>
543
- </div>
544
- </div>
545
- </>;
546
- }
547
-
548
- export function DocsLayoutExactWithData() {
549
- return <>
550
- const htmlContent = '<h1>Styling Guide</h1><p>Content</p>';
551
- <DocsLayoutExact
552
- editPath="docs/guide/styling.md"
553
- prevLink={{ href: '/prev', text: 'Previous' }}
554
- nextLink={{ href: '/next', text: 'Next' }}
555
- toc={[
556
- { href: '#intro', text: 'Introduction' },
557
- { href: '#usage', text: 'Usage' },
558
- ]}
559
- >
560
- <div class="doc-content" innerHTML={htmlContent} />
561
- </DocsLayoutExact>
562
- </>;
563
- }
564
-
565
- export function DocsLayoutExactWithoutData() {
566
- return <>
567
- const htmlContent: string | undefined = undefined;
568
- const editPath: string | undefined = undefined;
569
- const prevLink: { href: string; text: string } | null | undefined = undefined;
570
- const nextLink: { href: string; text: string } | null | undefined = undefined;
571
- const toc: { href: string; text: string }[] | undefined = undefined;
572
- <DocsLayoutExact {editPath} {prevLink} {nextLink} {toc}>
573
- <div class="doc-content" innerHTML={htmlContent} />
574
- </DocsLayoutExact>
575
- </>;
576
- }
577
-
578
- export function TemplateWithHtmlContent() {
579
- return <>
580
- const data = { title: 'Test', value: 42 };
581
- <div>
582
- <template id="t1" innerHTML={JSON.stringify(data)} />
583
- <p class="content">{'Main content'}</p>
584
- </div>
585
- </>;
586
- }
587
-
588
- export function TemplateWithHtmlAndSiblings() {
589
- return <>
590
- const data = { name: 'Ripple', version: '1.0' };
591
- <div class="wrapper">
592
- <h1>{'Title'}</h1>
593
- <template id="data-template" innerHTML={JSON.stringify(data)} />
594
- <p class="after-template">{'Content after template'}</p>
595
- </div>
596
- </>;
597
- }
598
-
599
- function LayoutWithTemplate({ children, data }: { children: any; data: object }) {
600
- return <>
601
- <div class="layout">
602
- <template id="page-data" innerHTML={JSON.stringify(data)} />
603
- <main>{children}</main>
461
+ <aside class="aside">
462
+ @if (toc.length > 0) {
463
+ <div class="aside-content">
464
+ <nav class="outline">
465
+ @for (const item of toc) {
466
+ <a href={item.href}>{item.text}</a>
467
+ }
468
+ </nav>
469
+ </div>
470
+ }
471
+ </aside>
472
+ </div>
473
+ </main>
604
474
  </div>
605
- </>;
606
- }
607
-
608
- export function NestedTemplateInLayout() {
609
- return <>
610
- const doc = { title: 'Comparison', html: '<p>Content</p>' };
611
- <LayoutWithTemplate data={doc}>
612
- <div class="doc-content" innerHTML={doc.html} />
613
- </LayoutWithTemplate>
614
- </>;
615
- }
616
-
617
- export function HtmlCodeBlocksWithSiblingChain() {
618
- return <>
619
- const html1 = '<span class="kw">const</span> <span class="id">a</span> = 1;';
620
- const html2 = '<span class="kw">const</span> <span class="id">b</span> = 2;';
621
- const html3 = '<span class="kw">const</span> <span class="id">c</span> = 3;';
622
- <section class="readable-section">
623
- <p>{'Ergonomics'}</p>
624
- <h2>{'Sibling traversal pattern'}</h2>
625
- <p>{'Before first block'}</p>
626
- <p>{'Before second block'}</p>
627
- <pre class="code-block">
628
- <code innerHTML={html1} />
629
- </pre>
630
- <p>{'Between one and two'}</p>
631
- <pre class="code-block">
632
- <code innerHTML={html2} />
633
- </pre>
634
- <p>{'Between two and three'}</p>
635
- <pre class="code-block">
636
- <code innerHTML={html3} />
637
- </pre>
638
- </section>
639
- </>;
475
+ </div>
476
+ }
477
+
478
+ export function DocsLayoutExactWithData() @{
479
+ const htmlContent = '<h1>Styling Guide</h1><p>Content</p>';
480
+ <DocsLayoutExact
481
+ editPath="docs/guide/styling.md"
482
+ prevLink={{ href: '/prev', text: 'Previous' }}
483
+ nextLink={{ href: '/next', text: 'Next' }}
484
+ toc={[
485
+ { href: '#intro', text: 'Introduction' },
486
+ { href: '#usage', text: 'Usage' },
487
+ ]}
488
+ >
489
+ <div class="doc-content" innerHTML={htmlContent} />
490
+ </DocsLayoutExact>
491
+ }
492
+
493
+ export function DocsLayoutExactWithoutData() @{
494
+ const htmlContent: string | undefined = undefined;
495
+ const editPath: string | undefined = undefined;
496
+ const prevLink: { href: string; text: string } | null | undefined = undefined;
497
+ const nextLink: { href: string; text: string } | null | undefined = undefined;
498
+ const toc: { href: string; text: string }[] | undefined = undefined;
499
+ <DocsLayoutExact {editPath} {prevLink} {nextLink} {toc}>
500
+ <div class="doc-content" innerHTML={htmlContent} />
501
+ </DocsLayoutExact>
502
+ }
503
+
504
+ export function TemplateWithHtmlContent() @{
505
+ const data = { title: 'Test', value: 42 };
506
+ <div>
507
+ <template id="t1" innerHTML={JSON.stringify(data)} />
508
+ <p class="content">{'Main content'}</p>
509
+ </div>
510
+ }
511
+
512
+ export function TemplateWithHtmlAndSiblings() @{
513
+ const data = { name: 'Ripple', version: '1.0' };
514
+ <div class="wrapper">
515
+ <h1>{'Title'}</h1>
516
+ <template id="data-template" innerHTML={JSON.stringify(data)} />
517
+ <p class="after-template">{'Content after template'}</p>
518
+ </div>
519
+ }
520
+
521
+ function LayoutWithTemplate({ children, data }: { children: any; data: object }) @{
522
+ <div class="layout">
523
+ <template id="page-data" innerHTML={JSON.stringify(data)} />
524
+ <main>{children}</main>
525
+ </div>
526
+ }
527
+
528
+ export function NestedTemplateInLayout() @{
529
+ const doc = { title: 'Comparison', html: '<p>Content</p>' };
530
+ <LayoutWithTemplate data={doc}>
531
+ <div class="doc-content" innerHTML={doc.html} />
532
+ </LayoutWithTemplate>
533
+ }
534
+
535
+ export function HtmlCodeBlocksWithSiblingChain() @{
536
+ const html1 = '<span class="kw">const</span> <span class="id">a</span> = 1;';
537
+ const html2 = '<span class="kw">const</span> <span class="id">b</span> = 2;';
538
+ const html3 = '<span class="kw">const</span> <span class="id">c</span> = 3;';
539
+ <section class="readable-section">
540
+ <p>{'Ergonomics'}</p>
541
+ <h2>{'Sibling traversal pattern'}</h2>
542
+ <p>{'Before first block'}</p>
543
+ <p>{'Before second block'}</p>
544
+ <pre class="code-block">
545
+ <code innerHTML={html1} />
546
+ </pre>
547
+ <p>{'Between one and two'}</p>
548
+ <pre class="code-block">
549
+ <code innerHTML={html2} />
550
+ </pre>
551
+ <p>{'Between two and three'}</p>
552
+ <pre class="code-block">
553
+ <code innerHTML={html3} />
554
+ </pre>
555
+ </section>
640
556
  }