@sitecore-feaas/clientside 0.1.48 → 0.1.49
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/build/components/FEAASExternal.js +79 -0
- package/build/components/FEAASExternal.js.map +1 -0
- package/build/headless.js +1 -0
- package/build/headless.js.map +1 -1
- package/build/ui/react.js +1 -1
- package/build/ui/react.js.map +1 -1
- package/build/utils/string.js +13 -0
- package/build/utils/string.js.map +1 -0
- package/dist/browser/headless.cjs +5 -5
- package/dist/browser/headless.cjs.map +4 -4
- package/dist/browser/headless.esm.js +5 -5
- package/dist/browser/headless.esm.js.map +1 -1
- package/dist/browser/index.cjs +5 -5
- package/dist/browser/index.cjs.map +4 -4
- package/dist/browser/index.esm.js +5 -5
- package/dist/browser/index.esm.js.map +1 -1
- package/dist/browser/react.cjs +5 -5
- package/dist/browser/react.cjs.map +4 -4
- package/dist/browser/react.esm.js +5 -5
- package/dist/browser/react.esm.js.map +1 -1
- package/dist/node/headless.cjs +3 -3
- package/dist/node/headless.cjs.map +4 -4
- package/dist/node/headless.esm.js +3 -3
- package/dist/node/headless.esm.js.map +4 -4
- package/dist/node/index.cjs +3 -3
- package/dist/node/index.cjs.map +4 -4
- package/dist/node/index.esm.js +3 -3
- package/dist/node/index.esm.js.map +4 -4
- package/dist/node/react.cjs +3 -3
- package/dist/node/react.cjs.map +4 -4
- package/dist/node/react.esm.js +3 -3
- package/dist/node/react.esm.js.map +4 -4
- package/headless.cjs +3 -3
- package/headless.cjs.map +4 -4
- package/headless.js +3 -3
- package/headless.js.map +4 -4
- package/package.json +1 -1
- package/react.cjs +5 -5
- package/react.cjs.map +4 -4
- package/react.js +5 -5
- package/react.js.map +4 -4
- package/src/components/FEAASExternal.tsx +107 -0
- package/src/headless.ts +1 -0
- package/src/ui/react.tsx +1 -1
- package/src/utils/string.ts +12 -0
- package/test/FEAASComponent.react.test.tsx +153 -39
- package/test/FEAASExternal.test.tsx +49 -0
- package/types/components/FEAASExternal.d.ts +44 -0
- package/types/components/FEAASExternal.d.ts.map +1 -0
- package/types/headless.d.ts +1 -0
- package/types/headless.d.ts.map +1 -1
- package/types/tsbuildinfo +1 -1
- package/types/tsbuildinfo_ui +1 -1
- package/types/utils/string.d.ts +3 -0
- package/types/utils/string.d.ts.map +1 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import ReactDOM from 'react-dom'
|
|
3
|
+
import { FEAASBase } from './FEAASBase.js'
|
|
4
|
+
import { ReactJSX, ReactModules } from './FEAASElement.js'
|
|
5
|
+
import { kebabCase, reverseKebabCase } from '../utils/string.js'
|
|
6
|
+
|
|
7
|
+
const convertSchemaPropertiesToKebabCase = (schema: any) => {
|
|
8
|
+
if (!schema) return
|
|
9
|
+
|
|
10
|
+
let kebabSchemaProperties, kebabRequiredProperties
|
|
11
|
+
if (schema.properties) {
|
|
12
|
+
kebabSchemaProperties = Object.keys(schema.properties).reduce((acc: { [key: string]: string }, key) => {
|
|
13
|
+
acc[kebabCase(key)] = schema.properties[key]
|
|
14
|
+
return acc
|
|
15
|
+
}, {})
|
|
16
|
+
|
|
17
|
+
kebabRequiredProperties = schema.required.map((item: string) => kebabCase(item))
|
|
18
|
+
}
|
|
19
|
+
return { ...schema, properties: kebabSchemaProperties, required: kebabRequiredProperties }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function FEAASExternalProps(element: FEAASBase = this) {
|
|
23
|
+
const attributes = element.getAttributeNames()
|
|
24
|
+
const props = attributes.reduce((prev, curr) => {
|
|
25
|
+
if (!curr.startsWith('data-attribute') && !['class', 'id', 'contenteditable'].includes(curr))
|
|
26
|
+
return { ...prev, [reverseKebabCase(curr)]: element.getAttribute(curr) }
|
|
27
|
+
else return prev
|
|
28
|
+
}, {})
|
|
29
|
+
return props
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type RegisteredComponents = { [id: string]: { component: React.ElementType; schema: any } }
|
|
33
|
+
export type FEAASExternalProps = ReturnType<typeof FEAASExternalProps> & { dataExternalId: string }
|
|
34
|
+
|
|
35
|
+
export default class FEAASExternal extends FEAASBase<FEAASExternalProps, ReactModules> {
|
|
36
|
+
static registered: RegisteredComponents = {}
|
|
37
|
+
static registrationCallback: NodeJS.Timeout
|
|
38
|
+
load() {
|
|
39
|
+
return Promise.resolve({ React, ReactDOM })
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
render(props: FEAASExternalProps, { React }: ReactModules): ReactJSX {
|
|
43
|
+
const { dataExternalId: id } = props
|
|
44
|
+
const Component = FEAASExternal.registered[id]?.component
|
|
45
|
+
if (!Component) console.warn('FEAASExternal: The component you requested is not registered')
|
|
46
|
+
return <>{Component && <Component {...props} />}</>
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
getProps() {
|
|
50
|
+
return FEAASExternalProps(this)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static registerComponent(component: React.FC, schema: any = {}, id?: string) {
|
|
54
|
+
FEAASExternal.registered[id || component.name] = { component, schema }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static setRegistrationCallback() {
|
|
58
|
+
// if registerCallback has not already been triggered by another component, set it
|
|
59
|
+
if (!FEAASExternal.registrationCallback) {
|
|
60
|
+
FEAASExternal.registrationCallback = setTimeout(() => {
|
|
61
|
+
// create components array from object
|
|
62
|
+
const components = Object.keys(FEAASExternal.registered).map((name) => ({
|
|
63
|
+
...FEAASExternal.registered[name],
|
|
64
|
+
name,
|
|
65
|
+
schema: convertSchemaPropertiesToKebabCase(FEAASExternal.registered[name].schema),
|
|
66
|
+
component: FEAASExternal.registered[name].component.toString()
|
|
67
|
+
}))
|
|
68
|
+
// send components from iframe to parent window
|
|
69
|
+
window.parent.postMessage(
|
|
70
|
+
JSON.stringify({
|
|
71
|
+
action: 'register-components',
|
|
72
|
+
data: components
|
|
73
|
+
}),
|
|
74
|
+
'*'
|
|
75
|
+
)
|
|
76
|
+
}, 500)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static loadComponents() {
|
|
81
|
+
const components = JSON.parse(sessionStorage.getItem('feaas-external-components'))
|
|
82
|
+
components.forEach((c: { name: string; schema: any; component: React.FC }) => {
|
|
83
|
+
const name = c.name
|
|
84
|
+
const schema = c.schema
|
|
85
|
+
const component = eval('(' + c.component + ')')
|
|
86
|
+
FEAASExternal.registerComponent(component, schema, name)
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
declare global {
|
|
92
|
+
namespace JSX {
|
|
93
|
+
interface IntrinsicElements {
|
|
94
|
+
'feaas-external': {
|
|
95
|
+
'data-external-id': string
|
|
96
|
+
children?: any
|
|
97
|
+
dangerouslySetInnerHTML?: { __html: string }
|
|
98
|
+
[key: string]: any
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
FEAASExternal.register('feaas-external')
|
|
105
|
+
FEAASExternal.setRegistrationCallback()
|
|
106
|
+
|
|
107
|
+
export { FEAASExternal as External }
|
package/src/headless.ts
CHANGED
|
@@ -17,6 +17,7 @@ export * from './components/FEAASElement.js'
|
|
|
17
17
|
export * from './components/FEAASComponent.js'
|
|
18
18
|
export * from './components/FEAASLoader.js'
|
|
19
19
|
export * from './components/FEAASStylesheet.js'
|
|
20
|
+
export * from './components/FEAASExternal.js'
|
|
20
21
|
|
|
21
22
|
declare global {
|
|
22
23
|
interface Window {
|
package/src/ui/react.tsx
CHANGED
|
@@ -5,7 +5,7 @@ import { renderHTMLContent } from '../dom/html.js'
|
|
|
5
5
|
export { renderHTMLContent }
|
|
6
6
|
|
|
7
7
|
export function FEAASEmbed({ data, ...props }: FEAASComponentProps<any>) {
|
|
8
|
-
if ('template' in props && props.template) {
|
|
8
|
+
if ('template' in props && typeof props.template == 'string') {
|
|
9
9
|
var html = renderHTMLContent(props.template, data || {})
|
|
10
10
|
}
|
|
11
11
|
if ('src' in props) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function kebabCase(str: string) {
|
|
2
|
+
const KEBAB_REGEX = /[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g
|
|
3
|
+
return str.replace(KEBAB_REGEX, function (match) {
|
|
4
|
+
return '-' + match.toLowerCase()
|
|
5
|
+
})
|
|
6
|
+
}
|
|
7
|
+
export function reverseKebabCase(str: string) {
|
|
8
|
+
const REVERSE_KEBAB_REGEX = /-[a-z\u00E0-\u00F6\u00F8-\u00FE]/g
|
|
9
|
+
return str.replace(REVERSE_KEBAB_REGEX, function (match) {
|
|
10
|
+
return match.slice(1).toUpperCase()
|
|
11
|
+
})
|
|
12
|
+
}
|
|
@@ -6,76 +6,136 @@ import { Component } from '../src/ui/react.js'
|
|
|
6
6
|
import ReactDOM from 'react-dom'
|
|
7
7
|
import React from 'react'
|
|
8
8
|
|
|
9
|
-
async function test(react: any, html: string) {
|
|
10
|
-
const div = document.createElement('div')
|
|
11
|
-
document.body.appendChild(div)
|
|
12
|
-
const root = ReactDOM.render(react, div)
|
|
13
|
-
expect(div.innerHTML).toEqual(html)
|
|
14
|
-
|
|
15
|
-
const div2 = document.createElement('div')
|
|
16
|
-
document.body.appendChild(div2)
|
|
17
|
-
div2.innerHTML = html
|
|
18
|
-
|
|
19
|
-
var onHydrate
|
|
20
|
-
const promise = new Promise((r) => {
|
|
21
|
-
onHydrate = r
|
|
22
|
-
})
|
|
23
|
-
ReactDOM.hydrate(react, div2, onHydrate)
|
|
24
|
-
await promise
|
|
25
|
-
expect(div2.innerHTML).toEqual(html)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
9
|
describe('React', () => {
|
|
29
|
-
it('render react component',
|
|
30
|
-
|
|
10
|
+
it('render react component', () => {
|
|
11
|
+
const div = document.createElement('div')
|
|
12
|
+
document.body.appendChild(div)
|
|
13
|
+
const root = ReactDOM.render(
|
|
31
14
|
<section>
|
|
32
15
|
<Component src='library/test'></Component>
|
|
33
16
|
</section>,
|
|
17
|
+
div
|
|
18
|
+
)
|
|
19
|
+
expect(div.innerHTML).toEqual(
|
|
34
20
|
'<section><feaas-component library="library" component="test" src="library/test"></feaas-component></section>'
|
|
35
21
|
)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
22
|
+
const div2 = document.createElement('div')
|
|
23
|
+
document.body.appendChild(div2)
|
|
24
|
+
div2.innerHTML = div.innerHTML
|
|
25
|
+
ReactDOM.hydrate(
|
|
39
26
|
<section>
|
|
40
|
-
<Component src='library/test'
|
|
27
|
+
<Component src='library/test'></Component>
|
|
41
28
|
</section>,
|
|
29
|
+
div2
|
|
30
|
+
)
|
|
31
|
+
expect(div2.innerHTML).toEqual(
|
|
42
32
|
'<section><feaas-component library="library" component="test" src="library/test"></feaas-component></section>'
|
|
43
33
|
)
|
|
44
34
|
})
|
|
45
|
-
it('render react component with src and overrides',
|
|
46
|
-
|
|
35
|
+
it('render react component with src and overrides', () => {
|
|
36
|
+
const div = document.createElement('div')
|
|
37
|
+
document.body.appendChild(div)
|
|
38
|
+
const root = ReactDOM.render(
|
|
47
39
|
<section>
|
|
48
40
|
<Component src='library/test' component='test2'></Component>
|
|
49
41
|
</section>,
|
|
42
|
+
div
|
|
43
|
+
)
|
|
44
|
+
expect(div.innerHTML).toEqual(
|
|
45
|
+
'<section><feaas-component library="library" component="test2" src="library/test"></feaas-component></section>'
|
|
46
|
+
)
|
|
47
|
+
const div2 = document.createElement('div')
|
|
48
|
+
document.body.appendChild(div2)
|
|
49
|
+
div2.innerHTML = div.innerHTML
|
|
50
|
+
ReactDOM.hydrate(
|
|
51
|
+
<section>
|
|
52
|
+
<Component src='library/test' component='test2'></Component>
|
|
53
|
+
</section>,
|
|
54
|
+
div2
|
|
55
|
+
)
|
|
56
|
+
expect(div2.innerHTML).toEqual(
|
|
50
57
|
'<section><feaas-component library="library" component="test2" src="library/test"></feaas-component></section>'
|
|
51
58
|
)
|
|
52
59
|
})
|
|
53
|
-
it('render react component with extras',
|
|
54
|
-
|
|
60
|
+
it('render react component with extras', () => {
|
|
61
|
+
const div = document.createElement('div')
|
|
62
|
+
document.body.appendChild(div)
|
|
63
|
+
const root = ReactDOM.render(
|
|
55
64
|
<section>
|
|
56
65
|
<Component src='library/test' version='v1'></Component>
|
|
57
66
|
</section>,
|
|
67
|
+
div
|
|
68
|
+
)
|
|
69
|
+
expect(div.innerHTML).toEqual(
|
|
70
|
+
'<section><feaas-component library="library" component="test" version="v1" src="library/test"></feaas-component></section>'
|
|
71
|
+
)
|
|
72
|
+
const div2 = document.createElement('div')
|
|
73
|
+
document.body.appendChild(div2)
|
|
74
|
+
div2.innerHTML = div.innerHTML
|
|
75
|
+
ReactDOM.hydrate(
|
|
76
|
+
<section>
|
|
77
|
+
<Component src='library/test' version='v1'></Component>
|
|
78
|
+
</section>,
|
|
79
|
+
div2
|
|
80
|
+
)
|
|
81
|
+
expect(div2.innerHTML).toEqual(
|
|
58
82
|
'<section><feaas-component library="library" component="test" version="v1" src="library/test"></feaas-component></section>'
|
|
59
83
|
)
|
|
60
84
|
})
|
|
61
|
-
it('render react template',
|
|
62
|
-
|
|
85
|
+
it('render react template', () => {
|
|
86
|
+
const div = document.createElement('div')
|
|
87
|
+
document.body.appendChild(div)
|
|
88
|
+
const root = ReactDOM.render(
|
|
63
89
|
<section>
|
|
64
90
|
<Component src='library/test' template={'<div data-path-src="abc">'}></Component>
|
|
65
91
|
</section>,
|
|
92
|
+
div
|
|
93
|
+
)
|
|
94
|
+
expect(div.innerHTML).toEqual(
|
|
95
|
+
'<section><feaas-component library="library" component="test" src="library/test"><div data-path-src="abc"></div></feaas-component></section>'
|
|
96
|
+
)
|
|
97
|
+
const div2 = document.createElement('div')
|
|
98
|
+
document.body.appendChild(div2)
|
|
99
|
+
div2.innerHTML = div.innerHTML
|
|
100
|
+
ReactDOM.hydrate(
|
|
101
|
+
<section>
|
|
102
|
+
<Component src='library/test' template={'<div data-path-src="abc">'}></Component>
|
|
103
|
+
</section>,
|
|
104
|
+
div2
|
|
105
|
+
)
|
|
106
|
+
expect(div2.innerHTML).toEqual(
|
|
66
107
|
'<section><feaas-component library="library" component="test" src="library/test"><div data-path-src="abc"></div></feaas-component></section>'
|
|
67
108
|
)
|
|
68
109
|
})
|
|
69
|
-
it('render template with data and src',
|
|
70
|
-
|
|
110
|
+
it('render template with data and src', () => {
|
|
111
|
+
const div = document.createElement('div')
|
|
112
|
+
document.body.appendChild(div)
|
|
113
|
+
const root = ReactDOM.render(
|
|
114
|
+
<section>
|
|
115
|
+
<Component src='library/test' template={'<div data-path-src="abc">'} data={{ abc: 321 }}></Component>
|
|
116
|
+
</section>,
|
|
117
|
+
div
|
|
118
|
+
)
|
|
119
|
+
expect(div.innerHTML).toEqual(
|
|
120
|
+
'<section><feaas-component library="library" component="test" src="library/test" data="{"abc":321}"><div data-path-src="abc"></div></feaas-component></section>'
|
|
121
|
+
)
|
|
122
|
+
const div2 = document.createElement('div')
|
|
123
|
+
document.body.appendChild(div2)
|
|
124
|
+
div2.innerHTML = div.innerHTML
|
|
125
|
+
ReactDOM.hydrate(
|
|
71
126
|
<section>
|
|
72
127
|
<Component src='library/test' template={'<div data-path-src="abc">'} data={{ abc: 321 }}></Component>
|
|
73
128
|
</section>,
|
|
129
|
+
div2
|
|
130
|
+
)
|
|
131
|
+
expect(div2.innerHTML).toEqual(
|
|
74
132
|
'<section><feaas-component library="library" component="test" src="library/test" data="{"abc":321}"><div data-path-src="abc"></div></feaas-component></section>'
|
|
75
133
|
)
|
|
76
134
|
})
|
|
77
|
-
it('render template with data but without src',
|
|
78
|
-
|
|
135
|
+
it('render template with data but without src', () => {
|
|
136
|
+
const div = document.createElement('div')
|
|
137
|
+
document.body.appendChild(div)
|
|
138
|
+
const root = ReactDOM.render(
|
|
79
139
|
<section>
|
|
80
140
|
<Component
|
|
81
141
|
library='library'
|
|
@@ -84,22 +144,76 @@ describe('React', () => {
|
|
|
84
144
|
data={{ abc: 321 }}
|
|
85
145
|
></Component>
|
|
86
146
|
</section>,
|
|
147
|
+
div
|
|
148
|
+
)
|
|
149
|
+
expect(div.innerHTML).toEqual(
|
|
150
|
+
'<section><feaas-component library="library" component="test" data="{"abc":321}"><div data-path-src="abc"></div></feaas-component></section>'
|
|
151
|
+
)
|
|
152
|
+
const div2 = document.createElement('div')
|
|
153
|
+
document.body.appendChild(div2)
|
|
154
|
+
div2.innerHTML = div.innerHTML
|
|
155
|
+
ReactDOM.hydrate(
|
|
156
|
+
<section>
|
|
157
|
+
<Component
|
|
158
|
+
library='library'
|
|
159
|
+
component='test'
|
|
160
|
+
template={'<div data-path-src="abc">'}
|
|
161
|
+
data={{ abc: 321 }}
|
|
162
|
+
></Component>
|
|
163
|
+
</section>,
|
|
164
|
+
div2
|
|
165
|
+
)
|
|
166
|
+
expect(div2.innerHTML).toEqual(
|
|
87
167
|
'<section><feaas-component library="library" component="test" data="{"abc":321}"><div data-path-src="abc"></div></feaas-component></section>'
|
|
88
168
|
)
|
|
89
169
|
})
|
|
90
|
-
it('render template with data with src and stringy data',
|
|
91
|
-
|
|
170
|
+
it('render template with data with src and stringy data', () => {
|
|
171
|
+
const div = document.createElement('div')
|
|
172
|
+
document.body.appendChild(div)
|
|
173
|
+
const root = ReactDOM.render(
|
|
174
|
+
<section>
|
|
175
|
+
<Component src='library/test' template={'<div data-path-src="abc">'} data={'{"abc":321}'}></Component>
|
|
176
|
+
</section>,
|
|
177
|
+
div
|
|
178
|
+
)
|
|
179
|
+
expect(div.innerHTML).toEqual(
|
|
180
|
+
'<section><feaas-component library="library" component="test" src="library/test" data="{"abc":321}"><div data-path-src="abc"></div></feaas-component></section>'
|
|
181
|
+
)
|
|
182
|
+
const div2 = document.createElement('div')
|
|
183
|
+
document.body.appendChild(div2)
|
|
184
|
+
div2.innerHTML = div.innerHTML
|
|
185
|
+
ReactDOM.hydrate(
|
|
92
186
|
<section>
|
|
93
187
|
<Component src='library/test' template={'<div data-path-src="abc">'} data={'{"abc":321}'}></Component>
|
|
94
188
|
</section>,
|
|
189
|
+
div2
|
|
190
|
+
)
|
|
191
|
+
expect(div2.innerHTML).toEqual(
|
|
95
192
|
'<section><feaas-component library="library" component="test" src="library/test" data="{"abc":321}"><div data-path-src="abc"></div></feaas-component></section>'
|
|
96
193
|
)
|
|
97
194
|
})
|
|
98
|
-
it('render template with data and template',
|
|
99
|
-
|
|
195
|
+
it('render template with data and template', () => {
|
|
196
|
+
const div = document.createElement('div')
|
|
197
|
+
document.body.appendChild(div)
|
|
198
|
+
const root = ReactDOM.render(
|
|
100
199
|
<section>
|
|
101
200
|
<Component template={'<div data-path-src="abc">'} data={'{"abc":321}'}></Component>
|
|
102
201
|
</section>,
|
|
202
|
+
div
|
|
203
|
+
)
|
|
204
|
+
expect(div.innerHTML).toEqual(
|
|
205
|
+
'<section><feaas-component data="{"abc":321}"><div data-path-src="abc"></div></feaas-component></section>'
|
|
206
|
+
)
|
|
207
|
+
const div2 = document.createElement('div')
|
|
208
|
+
document.body.appendChild(div2)
|
|
209
|
+
div2.innerHTML = div.innerHTML
|
|
210
|
+
ReactDOM.hydrate(
|
|
211
|
+
<section>
|
|
212
|
+
<Component template={'<div data-path-src="abc">'} data={'{"abc":321}'}></Component>
|
|
213
|
+
</section>,
|
|
214
|
+
div2
|
|
215
|
+
)
|
|
216
|
+
expect(div2.innerHTML).toEqual(
|
|
103
217
|
'<section><feaas-component data="{"abc":321}"><div data-path-src="abc"></div></feaas-component></section>'
|
|
104
218
|
)
|
|
105
219
|
})
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it } from 'vitest'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import * as Clientside from '@sitecore-feaas/clientside/react'
|
|
4
|
+
import FEAASExternal from '../types/components/FEAASExternal.js'
|
|
5
|
+
|
|
6
|
+
describe('External', () => {
|
|
7
|
+
function Hello(props: { firstName: string; telephone: string }) {
|
|
8
|
+
return React.createElement('div', {}, `Hello my name is ${props.firstName} and my tel is ${props.telephone}`)
|
|
9
|
+
}
|
|
10
|
+
function Hello2(props: { firstName: string; address: string }) {
|
|
11
|
+
return React.createElement('div', {}, `Hello my name is ${props.firstName} and my address is ${props.address}`)
|
|
12
|
+
}
|
|
13
|
+
it('can register and render component', async () => {
|
|
14
|
+
Clientside.External.registerComponent(Hello, {}, 'MyTestComponent')
|
|
15
|
+
document.body.innerHTML =
|
|
16
|
+
'<feaas-external id="external-component" class="-component" data-attributes-keys="first-name,telephone" first-name="Chuck" telephone="45657890875643" data-attributes="{"first-name":"Chuck","telephone":"45657890875643"}" data-external-id="MyTestComponent" contenteditable="false"></feaas-external>'
|
|
17
|
+
const component = document.getElementById('external-component') as FEAASExternal
|
|
18
|
+
await expect(component.whenRendered).resolves.toEqual(component)
|
|
19
|
+
expect(component.innerHTML).toEqual('<div>Hello my name is Chuck and my tel is 45657890875643</div>')
|
|
20
|
+
})
|
|
21
|
+
it('can take functional component name as id', async () => {
|
|
22
|
+
Clientside.External.registerComponent(Hello)
|
|
23
|
+
document.body.innerHTML =
|
|
24
|
+
'<feaas-external id="external-component" class="-component" data-attributes-keys="first-name,telephone" first-name="Chuck" telephone="45657890875643" data-attributes="{"first-name":"Chuck","telephone":"45657890875643"}" data-external-id="Hello" contenteditable="false"></feaas-external>'
|
|
25
|
+
const component = document.getElementById('external-component') as FEAASExternal
|
|
26
|
+
await expect(component.whenRendered).resolves.toEqual(component)
|
|
27
|
+
expect(component.innerHTML).toEqual('<div>Hello my name is Chuck and my tel is 45657890875643</div>')
|
|
28
|
+
})
|
|
29
|
+
it('should return empty if component is not registered', async () => {
|
|
30
|
+
document.body.innerHTML =
|
|
31
|
+
'<feaas-external id="external-component" class="-component" data-external-id="NotRegisteredComponent" contenteditable="false"></feaas-external>'
|
|
32
|
+
const component = document.getElementById('external-component') as FEAASExternal
|
|
33
|
+
await expect(component.whenRendered).resolves.toEqual(component)
|
|
34
|
+
expect(component.innerHTML).toEqual('')
|
|
35
|
+
})
|
|
36
|
+
it('can register and render multiple components', async () => {
|
|
37
|
+
Clientside.External.registerComponent(Hello, {}, 'MyTestComponent1')
|
|
38
|
+
Clientside.External.registerComponent(Hello2, {}, 'MyTestComponent2')
|
|
39
|
+
document.body.innerHTML =
|
|
40
|
+
'<feaas-external id="external-component1" class="-component" data-attributes-keys="first-name,telephone" first-name="Chuck" telephone="45657890875643" data-attributes="{"first-name":"Chuck","telephone":"45657890875643"}" data-external-id="MyTestComponent1" contenteditable="false"></feaas-external>' +
|
|
41
|
+
'<feaas-external id="external-component2" class="-component" data-attributes-keys="first-name,address" first-name="George" address="Test street 12" data-attributes="{"first-name":"George","address":"Test street 12"}" data-external-id="MyTestComponent2" contenteditable="false"></feaas-external>'
|
|
42
|
+
const component1 = document.getElementById('external-component1') as FEAASExternal
|
|
43
|
+
await expect(component1.whenRendered).resolves.toEqual(component1)
|
|
44
|
+
expect(component1.innerHTML).toEqual('<div>Hello my name is Chuck and my tel is 45657890875643</div>')
|
|
45
|
+
const component2 = document.getElementById('external-component2') as FEAASExternal
|
|
46
|
+
await expect(component2.whenRendered).resolves.toEqual(component2)
|
|
47
|
+
expect(component2.innerHTML).toEqual('<div>Hello my name is George and my address is Test street 12</div>')
|
|
48
|
+
})
|
|
49
|
+
})
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import ReactDOM from 'react-dom';
|
|
4
|
+
import { FEAASBase } from './FEAASBase.js';
|
|
5
|
+
import { ReactJSX, ReactModules } from './FEAASElement.js';
|
|
6
|
+
export declare function FEAASExternalProps(element?: FEAASBase): {};
|
|
7
|
+
export type RegisteredComponents = {
|
|
8
|
+
[id: string]: {
|
|
9
|
+
component: React.ElementType;
|
|
10
|
+
schema: any;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
export type FEAASExternalProps = ReturnType<typeof FEAASExternalProps> & {
|
|
14
|
+
dataExternalId: string;
|
|
15
|
+
};
|
|
16
|
+
export default class FEAASExternal extends FEAASBase<FEAASExternalProps, ReactModules> {
|
|
17
|
+
static registered: RegisteredComponents;
|
|
18
|
+
static registrationCallback: NodeJS.Timeout;
|
|
19
|
+
load(): Promise<{
|
|
20
|
+
React: typeof React;
|
|
21
|
+
ReactDOM: typeof ReactDOM;
|
|
22
|
+
}>;
|
|
23
|
+
render(props: FEAASExternalProps, { React }: ReactModules): ReactJSX;
|
|
24
|
+
getProps(): {};
|
|
25
|
+
static registerComponent(component: React.FC, schema?: any, id?: string): void;
|
|
26
|
+
static setRegistrationCallback(): void;
|
|
27
|
+
static loadComponents(): void;
|
|
28
|
+
}
|
|
29
|
+
declare global {
|
|
30
|
+
namespace JSX {
|
|
31
|
+
interface IntrinsicElements {
|
|
32
|
+
'feaas-external': {
|
|
33
|
+
'data-external-id': string;
|
|
34
|
+
children?: any;
|
|
35
|
+
dangerouslySetInnerHTML?: {
|
|
36
|
+
__html: string;
|
|
37
|
+
};
|
|
38
|
+
[key: string]: any;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export { FEAASExternal as External };
|
|
44
|
+
//# sourceMappingURL=FEAASExternal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FEAASExternal.d.ts","sourceRoot":"","sources":["../../src/components/FEAASExternal.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,QAAQ,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAkB1D,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,SAAgB,MAQ3D;AAED,MAAM,MAAM,oBAAoB,GAAG;IAAE,CAAC,EAAE,EAAE,MAAM,GAAG;QAAE,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC;QAAC,MAAM,EAAE,GAAG,CAAA;KAAE,CAAA;CAAE,CAAA;AAClG,MAAM,MAAM,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,GAAG;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,CAAA;AAEnG,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,SAAS,CAAC,kBAAkB,EAAE,YAAY,CAAC;IACpF,MAAM,CAAC,UAAU,EAAE,oBAAoB,CAAK;IAC5C,MAAM,CAAC,oBAAoB,EAAE,MAAM,CAAC,OAAO,CAAA;IAC3C,IAAI;;;;IAIJ,MAAM,CAAC,KAAK,EAAE,kBAAkB,EAAE,EAAE,KAAK,EAAE,EAAE,YAAY,GAAG,QAAQ;IAOpE,QAAQ;IAIR,MAAM,CAAC,iBAAiB,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,GAAE,GAAQ,EAAE,EAAE,CAAC,EAAE,MAAM;IAI3E,MAAM,CAAC,uBAAuB;IAuB9B,MAAM,CAAC,cAAc;CAStB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,GAAG,CAAC;QACZ,UAAU,iBAAiB;YACzB,gBAAgB,EAAE;gBAChB,kBAAkB,EAAE,MAAM,CAAA;gBAC1B,QAAQ,CAAC,EAAE,GAAG,CAAA;gBACd,uBAAuB,CAAC,EAAE;oBAAE,MAAM,EAAE,MAAM,CAAA;iBAAE,CAAA;gBAC5C,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;aACnB,CAAA;SACF;KACF;CACF;AAKD,OAAO,EAAE,aAAa,IAAI,QAAQ,EAAE,CAAA"}
|
package/types/headless.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export * from './components/FEAASElement.js';
|
|
|
15
15
|
export * from './components/FEAASComponent.js';
|
|
16
16
|
export * from './components/FEAASLoader.js';
|
|
17
17
|
export * from './components/FEAASStylesheet.js';
|
|
18
|
+
export * from './components/FEAASExternal.js';
|
|
18
19
|
declare global {
|
|
19
20
|
interface Window {
|
|
20
21
|
FEAASLoading: Promise<any>;
|
package/types/headless.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headless.d.ts","sourceRoot":"","sources":["../src/headless.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,YAAY,MAAM,8BAA8B,CAAA;AAEvD,cAAc,oBAAoB,CAAA;AAClC,cAAc,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,oBAAoB,CAAA;AAClC,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,2BAA2B,CAAA;AACzC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,iCAAiC,CAAA;
|
|
1
|
+
{"version":3,"file":"headless.d.ts","sourceRoot":"","sources":["../src/headless.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,YAAY,MAAM,8BAA8B,CAAA;AAEvD,cAAc,oBAAoB,CAAA;AAClC,cAAc,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,oBAAoB,CAAA;AAClC,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,2BAA2B,CAAA;AACzC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,+BAA+B,CAAA;AAE7C,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;QAC1B,YAAY,EAAE,OAAO,YAAY,CAAA;KAClC;CACF"}
|