@teleporthq/teleport-plugin-html-base-component 0.22.1 → 0.22.3

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.
@@ -19,7 +19,7 @@ import {
19
19
  UIDLRouteDefinitions,
20
20
  } from '@teleporthq/teleport-types'
21
21
  import { HASTBuilders, HASTUtils } from '@teleporthq/teleport-plugin-common'
22
- import { StringUtils } from '@teleporthq/teleport-shared'
22
+ import { StringUtils, UIDLUtils } from '@teleporthq/teleport-shared'
23
23
  import { staticNode } from '@teleporthq/teleport-uidl-builders'
24
24
  import { createCSSPlugin } from '@teleporthq/teleport-plugin-css'
25
25
  import { DEFAULT_COMPONENT_CHUNK_NAME } from './constants'
@@ -54,6 +54,9 @@ export const generateHtmlSynatx: NodeToHTML<UIDLNode, Promise<HastNode | HastTex
54
54
  case 'static':
55
55
  return HASTBuilders.createTextNode(StringUtils.encode(node.content.toString()))
56
56
 
57
+ case 'slot':
58
+ return HASTBuilders.createHTMLNode(node.type)
59
+
57
60
  case 'element':
58
61
  return generatElementNode(
59
62
  node,
@@ -108,105 +111,23 @@ const generatElementNode: NodeToHTML<UIDLElementNode, Promise<HastNode | HastTex
108
111
  const elementNode = HASTBuilders.createHTMLNode(elementType)
109
112
  templatesLookUp[key] = elementNode
110
113
 
111
- const { dependencies, chunks, options } = structure
112
-
113
- if (dependency?.type === 'local') {
114
- const comp = externals[elementType]
115
-
116
- if (!comp) {
117
- throw new HTMLComponentGeneratorError(`${elementType} is not found from the externals. \n
118
- Received ${JSON.stringify(Object.keys(externals), null, 2)}`)
119
- }
120
-
121
- const combinedProps = { ...propDefinitions, ...(comp?.propDefinitions || {}) }
122
- const propsForInstance = Object.keys(combinedProps).reduce(
123
- (acc: Record<string, UIDLPropDefinition>, propKey) => {
124
- if (attrs[propKey]) {
125
- acc[propKey] = {
126
- ...combinedProps[propKey],
127
- defaultValue: attrs[propKey].content,
128
- }
129
- } else {
130
- acc[propKey] = combinedProps[propKey]
131
- }
132
-
133
- return acc
134
- },
135
- {}
136
- )
137
-
138
- const combinedStates = { ...stateDefinitions, ...(comp?.stateDefinitions || {}) }
139
- const statesForInstance = Object.keys(combinedStates).reduce(
140
- (acc: Record<string, UIDLStateDefinition>, propKey) => {
141
- if (attrs[propKey]) {
142
- acc[propKey] = {
143
- ...combinedStates[propKey],
144
- defaultValue: attrs[propKey].content,
145
- }
146
- } else {
147
- acc[propKey] = combinedStates[propKey]
148
- }
149
-
150
- return acc
151
- },
152
- {}
153
- )
114
+ const { dependencies } = structure
115
+ if (dependency && (dependency as UIDLDependency)?.type !== 'local') {
116
+ dependencies[dependency.path] = dependency
117
+ }
154
118
 
155
- const lookupTemplate: Record<string, unknown> = {}
156
- const compTag = await generateHtmlSynatx(
157
- comp.node,
158
- lookupTemplate,
159
- propsForInstance,
160
- statesForInstance,
119
+ if (dependency && (dependency as UIDLDependency)?.type === 'local') {
120
+ const compTag = await generateComponentContent(
121
+ node,
122
+ propDefinitions,
123
+ stateDefinitions,
161
124
  externals,
162
125
  routeDefinitions,
163
126
  structure
164
127
  )
165
-
166
- const cssPlugin = createCSSPlugin({
167
- templateStyle: 'html',
168
- templateChunkName: 'html-template',
169
- declareDependency: 'import',
170
- forceScoping: true,
171
- chunkName: comp.name,
172
- staticPropReferences: true,
173
- })
174
-
175
- const result = await cssPlugin({
176
- uidl: {
177
- ...comp,
178
- propDefinitions: propsForInstance,
179
- stateDefinitions: statesForInstance,
180
- },
181
- chunks: [
182
- {
183
- type: ChunkType.HAST,
184
- fileType: FileType.HTML,
185
- name: DEFAULT_COMPONENT_CHUNK_NAME,
186
- linkAfter: [],
187
- content: compTag,
188
- meta: {
189
- nodesLookup: lookupTemplate,
190
- },
191
- },
192
- ],
193
- dependencies,
194
- options,
195
- })
196
-
197
- const chunk = chunks.find((item) => item.name === comp.name)
198
- if (!chunk) {
199
- const styleChunk = result.chunks.find((item: ChunkDefinition) => item.name === comp.name)
200
- chunks.push(styleChunk)
201
- }
202
-
203
128
  return compTag
204
129
  }
205
130
 
206
- if (dependency && (dependency as UIDLDependency)?.type !== 'local') {
207
- dependencies[dependency.path] = dependency
208
- }
209
-
210
131
  if (children) {
211
132
  for (const child of children) {
212
133
  const childTag = await generateHtmlSynatx(
@@ -252,6 +173,166 @@ const generatElementNode: NodeToHTML<UIDLElementNode, Promise<HastNode | HastTex
252
173
  return elementNode
253
174
  }
254
175
 
176
+ const generateComponentContent = async (
177
+ node: UIDLElementNode,
178
+ propDefinitions: Record<string, UIDLPropDefinition>,
179
+ stateDefinitions: Record<string, UIDLStateDefinition>,
180
+ externals: Record<string, ComponentUIDL>,
181
+ routeDefinitions: UIDLRouteDefinitions,
182
+ structure: {
183
+ chunks: ChunkDefinition[]
184
+ dependencies: Record<string, UIDLDependency>
185
+ options: GeneratorOptions
186
+ }
187
+ ) => {
188
+ const { elementType, attrs = {}, key, children = [] } = node.content
189
+ const { dependencies, chunks, options } = structure
190
+ const comp = UIDLUtils.cloneObject(externals[elementType] || {}) as ComponentUIDL
191
+ const lookUpTemplates: Record<string, unknown> = {}
192
+ let compHasSlots: boolean = false
193
+
194
+ if (!comp || !comp?.node) {
195
+ throw new HTMLComponentGeneratorError(`${elementType} is not found from the externals. \n
196
+ Received ${JSON.stringify(Object.keys(externals), null, 2)}`)
197
+ }
198
+
199
+ if (children.length) {
200
+ compHasSlots = true
201
+ UIDLUtils.traverseNodes(comp.node, (childNode, parentNode) => {
202
+ if (childNode.type === 'slot' && parentNode.type === 'element') {
203
+ const nonSlotNodes = parentNode.content?.children?.filter((n) => n.type !== 'slot')
204
+ parentNode.content.children = [
205
+ ...nonSlotNodes,
206
+ {
207
+ type: 'element',
208
+ content: {
209
+ key: 'custom-slot',
210
+ elementType: 'slot',
211
+ style: {
212
+ display: {
213
+ type: 'static',
214
+ content: 'contents',
215
+ },
216
+ },
217
+ children,
218
+ },
219
+ },
220
+ ]
221
+ }
222
+ })
223
+ /*
224
+ Since we don't generate direct component children in HTML. We need to reset this,
225
+ or else the plugins like css and others try to parse and process them.
226
+ */
227
+ node.content.children = []
228
+ }
229
+
230
+ const combinedProps = { ...propDefinitions, ...(comp?.propDefinitions || {}) }
231
+ const propsForInstance = Object.keys(combinedProps).reduce(
232
+ (acc: Record<string, UIDLPropDefinition>, propKey) => {
233
+ if (attrs[propKey]) {
234
+ acc[propKey] = {
235
+ ...combinedProps[propKey],
236
+ defaultValue: attrs[propKey]?.content || combinedProps[propKey]?.defaultValue,
237
+ }
238
+ } else {
239
+ acc[propKey] = combinedProps[propKey]
240
+ }
241
+
242
+ return acc
243
+ },
244
+ {}
245
+ )
246
+
247
+ const combinedStates = { ...stateDefinitions, ...(comp?.stateDefinitions || {}) }
248
+ const statesForInstance = Object.keys(combinedStates).reduce(
249
+ (acc: Record<string, UIDLStateDefinition>, propKey) => {
250
+ if (attrs[propKey]) {
251
+ acc[propKey] = {
252
+ ...combinedStates[propKey],
253
+ defaultValue: attrs[propKey]?.content || combinedStates[propKey]?.defaultValue,
254
+ }
255
+ } else {
256
+ acc[propKey] = combinedStates[propKey]
257
+ }
258
+
259
+ return acc
260
+ },
261
+ {}
262
+ )
263
+ const elementNode = HASTBuilders.createHTMLNode(StringUtils.camelCaseToDashCase(elementType))
264
+ lookUpTemplates[key] = elementNode
265
+
266
+ const compTag = (await generateHtmlSynatx(
267
+ {
268
+ ...comp.node,
269
+ content: {
270
+ ...comp.node.content,
271
+ style: {
272
+ ...(comp.node.content?.style || {}),
273
+ display: {
274
+ type: 'static',
275
+ content: 'contents',
276
+ },
277
+ },
278
+ },
279
+ },
280
+ lookUpTemplates,
281
+ propsForInstance,
282
+ statesForInstance,
283
+ externals,
284
+ routeDefinitions,
285
+ structure
286
+ )) as unknown as HastNode
287
+
288
+ const cssPlugin = createCSSPlugin({
289
+ templateStyle: 'html',
290
+ templateChunkName: 'html-template',
291
+ declareDependency: 'import',
292
+ forceScoping: true,
293
+ chunkName: comp.name,
294
+ staticPropReferences: true,
295
+ })
296
+
297
+ const result = await cssPlugin({
298
+ uidl: {
299
+ ...comp,
300
+ propDefinitions: propsForInstance,
301
+ stateDefinitions: statesForInstance,
302
+ },
303
+ chunks: [
304
+ {
305
+ type: ChunkType.HAST,
306
+ fileType: FileType.HTML,
307
+ name: DEFAULT_COMPONENT_CHUNK_NAME,
308
+ linkAfter: [],
309
+ content: compTag,
310
+ meta: {
311
+ nodesLookup: lookUpTemplates,
312
+ },
313
+ },
314
+ ],
315
+ dependencies,
316
+ options,
317
+ })
318
+
319
+ if (compHasSlots) {
320
+ result.chunks.forEach((chunk) => {
321
+ if (chunk.fileType === FileType.CSS) {
322
+ chunks.push(chunk)
323
+ }
324
+ })
325
+ } else {
326
+ const chunk = chunks.find((item) => item.name === comp.name)
327
+ if (!chunk) {
328
+ const styleChunk = result.chunks.find((item: ChunkDefinition) => item.name === comp.name)
329
+ chunks.push(styleChunk)
330
+ }
331
+ }
332
+
333
+ return compTag
334
+ }
335
+
255
336
  const generateDynamicNode: NodeToHTML<UIDLDynamicReference, HastNode> = (
256
337
  node,
257
338
  _,
@@ -311,6 +392,8 @@ const handleAttributes = (
311
392
  )}`
312
393
  ? staticNode('index.html')
313
394
  : staticNode(`${attrValue.content.split('/').pop()}.html`)
395
+ HASTUtils.addAttributeToNode(htmlNode, attrKey, String(attrValue.content))
396
+ return
314
397
  }
315
398
 
316
399
  if (attrValue.type === 'dynamic') {
@@ -324,8 +407,10 @@ const handleAttributes = (
324
407
 
325
408
  if (typeof attrValue.content === 'boolean') {
326
409
  HASTUtils.addBooleanAttributeToNode(htmlNode, attrKey)
410
+ return
327
411
  } else if (typeof attrValue.content === 'string' || typeof attrValue.content === 'number') {
328
412
  HASTUtils.addAttributeToNode(htmlNode, attrKey, StringUtils.encode(String(attrValue.content)))
413
+ return
329
414
  }
330
415
  })
331
416
  }