@sitecore-feaas/clientside 0.1.56 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +559 -56
- package/build/components/FEAASComponent.js +2 -2
- package/build/components/FEAASComponent.js.map +1 -1
- package/build/components/FEAASElement.js +408 -37
- package/build/components/FEAASElement.js.map +1 -1
- package/build/components/FEAASLoader.js +2 -2
- package/build/components/FEAASLoader.js.map +1 -1
- package/build/components/FEAASReactElement.js +47 -0
- package/build/components/FEAASReactElement.js.map +1 -0
- package/build/components/FEAASStylesheet.js +2 -2
- package/build/components/FEAASStylesheet.js.map +1 -1
- package/build/headless.js +4 -3
- package/build/headless.js.map +1 -1
- package/build/ui/FEAASContext.js +14 -5
- package/build/ui/FEAASContext.js.map +1 -1
- package/build/ui/FEAASEditor.js +2 -2
- package/build/ui/FEAASEditor.js.map +1 -1
- package/build/ui/FEAASExternal.js +66 -23
- package/build/ui/FEAASExternal.js.map +1 -1
- package/build/ui/FEAASPicker.js +3 -2
- package/build/ui/FEAASPicker.js.map +1 -1
- 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 +7 -7
- package/dist/browser/index.cjs.map +4 -4
- package/dist/browser/index.esm.js +7 -7
- package/dist/browser/index.esm.js.map +1 -1
- package/dist/browser/react.cjs +6 -6
- package/dist/browser/react.cjs.map +4 -4
- package/dist/browser/react.esm.js +6 -6
- 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 +2 -2
- package/dist/node/headless.esm.js.map +4 -4
- package/dist/node/index.cjs +4 -4
- 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 +4 -4
- package/dist/node/react.cjs.map +4 -4
- package/dist/node/react.esm.js +4 -4
- 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 +10 -2
- package/react.cjs +6 -6
- package/react.cjs.map +4 -4
- package/react.js +6 -6
- package/react.js.map +4 -4
- package/scripts/test-setup.ts +1 -0
- package/src/components/FEAASComponent.tsx +4 -4
- package/src/components/FEAASElement.tsx +467 -42
- package/src/components/FEAASLoader.tsx +2 -2
- package/src/components/FEAASReactElement.tsx +61 -0
- package/src/components/FEAASStylesheet.tsx +3 -3
- package/src/headless.ts +5 -4
- package/src/ui/FEAASContext.tsx +16 -7
- package/src/ui/FEAASEditor.tsx +7 -7
- package/src/ui/FEAASExternal.tsx +77 -23
- package/src/ui/FEAASPicker.tsx +4 -3
- package/src/ui/tsconfig.json +1 -1
- package/test/FEAASBase.test.tsx +2 -2
- package/test/FEAASComponent.test.tsx +3 -1
- package/test/FEAASContext.test.tsx +206 -29
- package/test/FEAASPicker.test.tsx +4 -2
- package/types/components/FEAASComponent.d.ts +3 -3
- package/types/components/FEAASComponent.d.ts.map +1 -1
- package/types/components/FEAASElement.d.ts +292 -23
- package/types/components/FEAASElement.d.ts.map +1 -1
- package/types/components/FEAASLoader.d.ts +2 -2
- package/types/components/FEAASLoader.d.ts.map +1 -1
- package/types/components/FEAASReactElement.d.ts +30 -0
- package/types/components/FEAASReactElement.d.ts.map +1 -0
- package/types/components/FEAASStylesheet.d.ts +3 -3
- package/types/components/FEAASStylesheet.d.ts.map +1 -1
- package/types/headless.d.ts +4 -3
- package/types/headless.d.ts.map +1 -1
- package/types/tsbuildinfo +1 -1
- package/types/ui/FEAASContext.d.ts +8 -7
- package/types/ui/FEAASContext.d.ts.map +1 -1
- package/types/ui/FEAASEditor.d.ts +6 -6
- package/types/ui/FEAASEditor.d.ts.map +1 -1
- package/types/ui/FEAASExternal.d.ts +8 -10
- package/types/ui/FEAASExternal.d.ts.map +1 -1
- package/types/ui/FEAASPicker.d.ts +7 -6
- package/types/ui/FEAASPicker.d.ts.map +1 -1
- package/types/ui/tsbuildinfo +1 -0
- package/build/components/FEAASBase.js +0 -416
- package/build/components/FEAASBase.js.map +0 -1
- package/src/components/FEAASBase.tsx +0 -485
- package/types/components/FEAASBase.d.ts +0 -299
- package/types/components/FEAASBase.d.ts.map +0 -1
- package/types/tsbuildinfo_ui +0 -1
package/src/ui/FEAASContext.tsx
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type * as FEAASContextImports from '@sitecore-feaas/frontend/context'
|
|
2
2
|
import type { AuthModel } from '@sitecore-feaas/sdk'
|
|
3
|
-
import {
|
|
3
|
+
import { FEAASElement, OptionalExcept } from '../components/FEAASElement.js'
|
|
4
4
|
import { ControlledPromise } from '../utils/promise.js'
|
|
5
5
|
|
|
6
6
|
export function FEAASContextProps(element: HTMLElement) {
|
|
7
7
|
return {
|
|
8
8
|
library: element?.getAttribute('library') as string,
|
|
9
9
|
src: element?.getAttribute('src') ?? '/context.js',
|
|
10
|
-
frontend: element?.getAttribute('frontend') ?? 'https://components.
|
|
11
|
-
backend: element?.getAttribute('backend') ?? 'https://components.
|
|
10
|
+
frontend: element?.getAttribute('frontend') ?? 'https://components.sitecorecloud.io',
|
|
11
|
+
backend: element?.getAttribute('backend') ?? 'https://components.sitecorecloud.io/api',
|
|
12
12
|
cdn: element?.getAttribute('cdn') ?? 'https://feaas.blob.core.windows.net',
|
|
13
13
|
auth: null as Partial<AuthModel>,
|
|
14
14
|
isolate: element?.getAttribute('isolate') == null || element?.getAttribute('isolate') == 'true'
|
|
@@ -20,7 +20,7 @@ export type FEAASContextProps = ReturnType<typeof FEAASContextProps>
|
|
|
20
20
|
* Context provides shared parameters and react providers for its nested elements. It loads lazily once any of its
|
|
21
21
|
* nested components load. Just placing it on the page without any consumers does not impose any overhead.
|
|
22
22
|
*/
|
|
23
|
-
export class FEAASContext extends
|
|
23
|
+
export class FEAASContext extends FEAASElement<FEAASContextProps, typeof FEAASContextImports> {
|
|
24
24
|
static observedAttributes = ['library', 'component', 'version', 'revision', 'hostname', 'template']
|
|
25
25
|
getProps() {
|
|
26
26
|
return FEAASContextProps(this)
|
|
@@ -35,7 +35,6 @@ export class FEAASContext extends FEAASBase<FEAASContextProps, typeof FEAASConte
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
isReadyToLoad() {
|
|
38
|
-
console.log('Is ready?', this.props, super.isReadyToLoad() && this.props.library != null)
|
|
39
38
|
return super.isReadyToLoad() && this.props.library != null
|
|
40
39
|
}
|
|
41
40
|
|
|
@@ -44,7 +43,7 @@ export class FEAASContext extends FEAASBase<FEAASContextProps, typeof FEAASConte
|
|
|
44
43
|
return theme
|
|
45
44
|
}
|
|
46
45
|
|
|
47
|
-
getRoot(): HTMLElement |
|
|
46
|
+
getRoot(): HTMLElement | FEAASElement<any, any> | ShadowRoot {
|
|
48
47
|
if (this.getAttribute('isolate') === 'false') return this
|
|
49
48
|
return this.shadowRoot || this.attachShadow({ mode: 'open' })
|
|
50
49
|
}
|
|
@@ -60,12 +59,20 @@ export class FEAASContext extends FEAASBase<FEAASContextProps, typeof FEAASConte
|
|
|
60
59
|
}
|
|
61
60
|
|
|
62
61
|
/** Pull in children FEAAS react elements into the shadow DOM so they receieve the styles */
|
|
63
|
-
connectedCallback()
|
|
62
|
+
connectedCallback() {
|
|
63
|
+
//if (this.props.isolate)
|
|
64
64
|
Array.from(this.children).forEach((child) => {
|
|
65
65
|
this.getRoot().appendChild(child)
|
|
66
66
|
})
|
|
67
|
+
document.addEventListener('feaasMount', this)
|
|
68
|
+
document.addEventListener('feaasUnmount', this)
|
|
67
69
|
super.connectedCallback()
|
|
68
70
|
}
|
|
71
|
+
disconnectedCallback() {
|
|
72
|
+
document.removeEventListener('feaasMount', this)
|
|
73
|
+
document.removeEventListener('feaasUnmount', this)
|
|
74
|
+
super.disconnectedCallback()
|
|
75
|
+
}
|
|
69
76
|
|
|
70
77
|
sdk: FEAASContextImports.SDK
|
|
71
78
|
onStatusChange: FEAASContextImports.SDKStatusCallback = (status, sdk) => {
|
|
@@ -102,6 +109,7 @@ export class FEAASContext extends FEAASBase<FEAASContextProps, typeof FEAASConte
|
|
|
102
109
|
portalProps
|
|
103
110
|
}}
|
|
104
111
|
chakraProps={{
|
|
112
|
+
resetScope: '.feaas-reset',
|
|
105
113
|
cssVarsRoot: ':host',
|
|
106
114
|
resetCSS: true,
|
|
107
115
|
toastOptions: {
|
|
@@ -123,4 +131,5 @@ declare global {
|
|
|
123
131
|
}
|
|
124
132
|
}
|
|
125
133
|
|
|
134
|
+
export { FEAASContext as Context }
|
|
126
135
|
FEAASContext.register('feaas-context')
|
package/src/ui/FEAASEditor.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type * as FEAASEditorImports from '@sitecore-feaas/frontend/editor'
|
|
2
|
-
import {
|
|
2
|
+
import { FEAASElement, OptionalExcept } from '../components/FEAASElement.js'
|
|
3
3
|
import { FEAASLoader } from '../components/FEAASLoader.js'
|
|
4
4
|
|
|
5
5
|
export function getFramePosition(element: HTMLElement) {
|
|
@@ -38,7 +38,7 @@ export function getFramePosition(element: HTMLElement) {
|
|
|
38
38
|
{ left: 0, top: 0 }
|
|
39
39
|
)
|
|
40
40
|
}
|
|
41
|
-
export function FEAASEditorProps(element:
|
|
41
|
+
export function FEAASEditorProps(element: FEAASElement) {
|
|
42
42
|
return {
|
|
43
43
|
context: HTMLElement,
|
|
44
44
|
frontend: element?.getContextAttribute('frontend'),
|
|
@@ -63,7 +63,7 @@ type Rect = {
|
|
|
63
63
|
height: number
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
export class FEAASEditor extends
|
|
66
|
+
export class FEAASEditor extends FEAASElement<FEAASEditorProps, typeof FEAASEditorImports> {
|
|
67
67
|
framePoint: Pick<Rect, 'top' | 'left'> = { top: 0, left: 0 }
|
|
68
68
|
wrapperRect: Rect = { top: 0, left: 0, width: 0, height: 0 }
|
|
69
69
|
bodyRect: Rect = { top: 0, left: 0, width: 0, height: 0 }
|
|
@@ -329,7 +329,7 @@ export class FEAASEditor extends FEAASBase<FEAASEditorProps, typeof FEAASEditorI
|
|
|
329
329
|
this.setLoadingState()
|
|
330
330
|
}
|
|
331
331
|
|
|
332
|
-
shouldFork(version: FEAASEditorImports.
|
|
332
|
+
shouldFork(version: FEAASEditorImports.Model.VersionModel) {
|
|
333
333
|
return version.forkOriginId == null && this.props.instance != null
|
|
334
334
|
}
|
|
335
335
|
|
|
@@ -423,8 +423,8 @@ export class FEAASEditor extends FEAASBase<FEAASEditorProps, typeof FEAASEditorI
|
|
|
423
423
|
this.setAttribute('state', 'ready')
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
-
component: FEAASEditorImports.
|
|
427
|
-
version: FEAASEditorImports.
|
|
426
|
+
component: FEAASEditorImports.Model.ComponentModel
|
|
427
|
+
version: FEAASEditorImports.Model.VersionModel
|
|
428
428
|
closing: ReturnType<typeof setTimeout>
|
|
429
429
|
|
|
430
430
|
render(
|
|
@@ -458,7 +458,7 @@ export class FEAASEditor extends FEAASBase<FEAASEditorProps, typeof FEAASEditorI
|
|
|
458
458
|
const { React } = this.payload
|
|
459
459
|
const sdk = useSDK()
|
|
460
460
|
const library = useLibrary()
|
|
461
|
-
const [component, setComponent] = useState<FEAASEditorImports.
|
|
461
|
+
const [component, setComponent] = useState<FEAASEditorImports.Model.ComponentModel>()
|
|
462
462
|
const { setConfirm } = useContext(ConfirmationContext)
|
|
463
463
|
const usedId = instanceId || versionId
|
|
464
464
|
|
package/src/ui/FEAASExternal.tsx
CHANGED
|
@@ -1,26 +1,72 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import ReactDOM from 'react-dom'
|
|
3
|
-
import {
|
|
4
|
-
import { ReactJSX, ReactModules } from '../components/
|
|
3
|
+
import { FEAASElement } from '../components/FEAASElement.js'
|
|
4
|
+
import { ReactJSX, ReactModules } from '../components/FEAASReactElement.js'
|
|
5
5
|
import { kebabCase, reverseKebabCase } from '../utils/string.js'
|
|
6
6
|
import { Component, FEAASComponentProps } from './react.js'
|
|
7
|
+
import type { ExternalComponent, ExternalComponentOptions } from '@sitecore-feaas/sdk'
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
/** Checks if title exists in a property and if not, it generates it from (kebab-cased) property key */
|
|
10
|
+
const addTitles = (properties: { [key: string]: any }) =>
|
|
11
|
+
Object.keys(properties).reduce((acc: { [key: string]: any }, key) => {
|
|
12
|
+
if (properties[key].title) {
|
|
13
|
+
acc[key] = properties[key]
|
|
14
|
+
} else {
|
|
15
|
+
const title = key
|
|
16
|
+
.split('-')
|
|
17
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
18
|
+
.join(' ')
|
|
19
|
+
acc[key] = { ...properties[key], title }
|
|
20
|
+
}
|
|
21
|
+
return acc
|
|
22
|
+
}, {})
|
|
23
|
+
|
|
24
|
+
const objectKeysToKebabCase = (object: { [key: string]: any } = {}) =>
|
|
25
|
+
Object.keys(object).reduce((acc: { [key: string]: any }, key) => {
|
|
26
|
+
acc[kebabCase(key)] = object[key]
|
|
27
|
+
return acc
|
|
28
|
+
}, {})
|
|
29
|
+
|
|
30
|
+
const transformSchema = (schema: ExternalComponent['schema']) => {
|
|
9
31
|
if (!schema) return
|
|
32
|
+
if (!schema.properties) return schema
|
|
33
|
+
let properties, required
|
|
10
34
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
acc[kebabCase(key)] = schema.properties[key]
|
|
15
|
-
return acc
|
|
16
|
-
}, {})
|
|
35
|
+
/* kebab-case properties */
|
|
36
|
+
properties = objectKeysToKebabCase(schema.properties)
|
|
37
|
+
required = (schema.required || []).map((item: string) => kebabCase(item))
|
|
17
38
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
39
|
+
/* generate titles if not exist */
|
|
40
|
+
properties = addTitles(properties)
|
|
41
|
+
|
|
42
|
+
/* remove title from schema - it will be passed separately to use custom styling in the form */
|
|
43
|
+
const title: string = undefined
|
|
44
|
+
return { ...schema, properties, required, title }
|
|
21
45
|
}
|
|
22
46
|
|
|
23
|
-
|
|
47
|
+
const transformUiSchema = (uiSchema: ExternalComponent['uiSchema'], properties: { [key: string]: any }) => {
|
|
48
|
+
if (!uiSchema || !properties) return
|
|
49
|
+
let transformed: ExternalComponent['uiSchema']
|
|
50
|
+
|
|
51
|
+
/* kebab-case keys */
|
|
52
|
+
transformed = objectKeysToKebabCase(uiSchema)
|
|
53
|
+
|
|
54
|
+
/* use updown input widget as default for numbers */
|
|
55
|
+
const numberProperties = Object.keys(properties).filter((key) => /(integer|number)/.test(properties[key].type))
|
|
56
|
+
numberProperties.forEach((propertyName) => {
|
|
57
|
+
if (!transformed[propertyName]) transformed[propertyName] = { 'ui:widget': 'updown' }
|
|
58
|
+
else if (!transformed[propertyName]['ui:widget']) transformed[propertyName]['ui:widget'] = 'updown'
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
return transformed
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export const parseProps = (
|
|
65
|
+
propName: string,
|
|
66
|
+
propValue: string,
|
|
67
|
+
properties: ExternalComponent['schema']['properties']
|
|
68
|
+
) => {
|
|
69
|
+
//@ts-ignore
|
|
24
70
|
switch (properties?.[propName]?.type) {
|
|
25
71
|
case 'string':
|
|
26
72
|
return propValue
|
|
@@ -39,10 +85,10 @@ export const parseProps = (propName: string, propValue: string, properties: any)
|
|
|
39
85
|
}
|
|
40
86
|
}
|
|
41
87
|
|
|
42
|
-
export function FEAASExternalProps(element:
|
|
88
|
+
export function FEAASExternalProps(element: FEAASElement) {
|
|
43
89
|
const attributes = element.getAttributeNames()
|
|
44
90
|
const id = element.getAttribute('data-external-id')
|
|
45
|
-
const schema:
|
|
91
|
+
const schema: ExternalComponent['schema'] = FEAASExternal.registered[id]?.schema
|
|
46
92
|
const props = attributes.reduce((prev, curr) => {
|
|
47
93
|
if (!curr.startsWith('data-attribute') && !['class', 'id', 'contenteditable'].includes(curr)) {
|
|
48
94
|
const value = element.getAttribute(curr)
|
|
@@ -54,10 +100,12 @@ export function FEAASExternalProps(element: FEAASBase) {
|
|
|
54
100
|
return props
|
|
55
101
|
}
|
|
56
102
|
|
|
57
|
-
export type RegisteredComponents = {
|
|
103
|
+
export type RegisteredComponents = {
|
|
104
|
+
[id: string]: ExternalComponent
|
|
105
|
+
}
|
|
58
106
|
export type FEAASExternalProps = ReturnType<typeof FEAASExternalProps> & { dataExternalId: string }
|
|
59
107
|
|
|
60
|
-
export default class FEAASExternal extends
|
|
108
|
+
export default class FEAASExternal extends FEAASElement<FEAASExternalProps, ReactModules> {
|
|
61
109
|
static registered: RegisteredComponents = {}
|
|
62
110
|
static registrationCallback: NodeJS.Timeout
|
|
63
111
|
load() {
|
|
@@ -75,10 +123,12 @@ export default class FEAASExternal extends FEAASBase<FEAASExternalProps, ReactMo
|
|
|
75
123
|
return FEAASExternalProps(this)
|
|
76
124
|
}
|
|
77
125
|
|
|
78
|
-
static registerComponent(component: React.FC,
|
|
79
|
-
const id =
|
|
80
|
-
const
|
|
81
|
-
|
|
126
|
+
static registerComponent(component: React.FC, options: ExternalComponentOptions = {}) {
|
|
127
|
+
const id = options.name || component.name
|
|
128
|
+
const { thumbnail, group, ui: uiSchema, ...schemaOptions } = options
|
|
129
|
+
const schema = { ...schemaOptions, type: 'object' } as ExternalComponent['schema']
|
|
130
|
+
FEAASExternal.registered[id] = { component, schema, uiSchema, thumbnail, group, title: schema?.title || id }
|
|
131
|
+
FEAASExternal.setRegistrationCallback()
|
|
82
132
|
}
|
|
83
133
|
|
|
84
134
|
static setRegistrationCallback() {
|
|
@@ -89,12 +139,16 @@ export default class FEAASExternal extends FEAASBase<FEAASExternalProps, ReactMo
|
|
|
89
139
|
const components = Object.keys(FEAASExternal.registered).map((id) => ({
|
|
90
140
|
...FEAASExternal.registered[id],
|
|
91
141
|
name: id,
|
|
92
|
-
schema:
|
|
142
|
+
schema: transformSchema(FEAASExternal.registered[id].schema),
|
|
143
|
+
uiSchema: transformUiSchema(
|
|
144
|
+
FEAASExternal.registered[id].uiSchema,
|
|
145
|
+
FEAASExternal.registered[id].schema?.properties
|
|
146
|
+
)
|
|
93
147
|
//component: FEAASExternal.registered[name].component.toString()
|
|
94
148
|
}))
|
|
95
149
|
|
|
96
150
|
// send components from iframe to parent window
|
|
97
|
-
window
|
|
151
|
+
window.parent?.postMessage(
|
|
98
152
|
JSON.stringify({
|
|
99
153
|
action: 'register-components',
|
|
100
154
|
data: components
|
package/src/ui/FEAASPicker.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type * as FEAASPickerImports from '@sitecore-feaas/frontend/picker'
|
|
2
|
-
import {
|
|
2
|
+
import { FEAASElement } from '../components/FEAASElement.js'
|
|
3
3
|
|
|
4
|
-
export function FEAASPickerProps(element:
|
|
4
|
+
export function FEAASPickerProps(element: FEAASElement<any, any>) {
|
|
5
5
|
return {
|
|
6
6
|
part: element?.getAttribute('part') || 'picker',
|
|
7
7
|
slot: element?.getAttribute('part') || 'picker',
|
|
@@ -18,7 +18,7 @@ export function FEAASPickerProps(element: FEAASBase<any, any>) {
|
|
|
18
18
|
}
|
|
19
19
|
export type FEAASPickerProps = ReturnType<typeof FEAASPickerProps>
|
|
20
20
|
|
|
21
|
-
export class FEAASPicker extends
|
|
21
|
+
export class FEAASPicker extends FEAASElement<FEAASPickerProps, typeof FEAASPickerImports> {
|
|
22
22
|
static observedAttributes = ['library', 'mode', 'frontend', 'src', 'hidden', 'variant']
|
|
23
23
|
|
|
24
24
|
defaultProps = {
|
|
@@ -66,4 +66,5 @@ declare global {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
export { FEAASPicker as Picker }
|
|
69
70
|
FEAASPicker.register('feaas-picker')
|
package/src/ui/tsconfig.json
CHANGED
package/test/FEAASBase.test.tsx
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { describe, it, assert, beforeAll, expect } from 'vitest'
|
|
2
|
-
import {
|
|
2
|
+
import { FEAASElement, ReactPayload } from '../src/headless.js'
|
|
3
3
|
import { JSDOM } from 'jsdom'
|
|
4
4
|
|
|
5
5
|
describe('React', function () {
|
|
6
6
|
describe('Error boundary', () => {
|
|
7
|
-
class FEAASErrorTest extends
|
|
7
|
+
class FEAASErrorTest extends FEAASElement<{ throwAt: string }> {
|
|
8
8
|
static observedAttributes = ['test']
|
|
9
9
|
|
|
10
10
|
log() {}
|
|
@@ -15,7 +15,9 @@ describe('Components', () => {
|
|
|
15
15
|
// vi.useRealTimers()
|
|
16
16
|
})
|
|
17
17
|
beforeEach(() => {
|
|
18
|
-
document.
|
|
18
|
+
document.open()
|
|
19
|
+
document.write('<html><head></head><body></body></html>')
|
|
20
|
+
document.close()
|
|
19
21
|
clearFetchCache()
|
|
20
22
|
})
|
|
21
23
|
it('should load component using', async () => {
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { beforeEach, describe, it, assert, beforeAll, expect } from 'vitest'
|
|
2
|
-
import {
|
|
2
|
+
import { FEAASElement, ReactPayload } from '../src/headless.js'
|
|
3
3
|
import { FEAASContextProps, FEAASContext } from '../src/ui/FEAASContext.js'
|
|
4
4
|
import { JSDOM } from 'jsdom'
|
|
5
5
|
import { vi } from 'vitest'
|
|
6
|
+
import { ReactNode, ReactElement, JSXElementConstructor } from 'react'
|
|
6
7
|
|
|
7
8
|
describe('React', function () {
|
|
8
9
|
describe('FEAASContext', () => {
|
|
9
10
|
beforeEach(() => {
|
|
10
|
-
document.
|
|
11
|
+
document.open()
|
|
12
|
+
document.write('<html><head></head><body></body></html>')
|
|
13
|
+
document.close()
|
|
11
14
|
})
|
|
12
15
|
it('should initiate loading with isolation', async () => {
|
|
13
16
|
// @ts-ignore
|
|
@@ -37,40 +40,214 @@ describe('React', function () {
|
|
|
37
40
|
expect(spyLoad).toHaveBeenCalledTimes(1)
|
|
38
41
|
|
|
39
42
|
expect(component.outerHTML).toBe(
|
|
40
|
-
'<feaas-context src="test.js" library="abc" isolate="false" frontend="https://components.
|
|
43
|
+
'<feaas-context src="test.js" library="abc" isolate="false" frontend="https://components.sitecorecloud.io" backend="https://components.sitecorecloud.io/api" cdn="https://feaas.blob.core.windows.net"><div><p>Context abc</p></div></feaas-context>'
|
|
41
44
|
)
|
|
42
45
|
})
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
46
|
+
it('should initiate loading without isolation', async () => {
|
|
47
|
+
// @ts-ignore
|
|
48
|
+
const spyLoad = vi.spyOn(FEAASContext.prototype, 'import')
|
|
49
|
+
// @ts-ignore
|
|
50
|
+
spyLoad.mockImplementation(async (url: string) => {
|
|
51
|
+
if (url.match('test.js')) {
|
|
52
|
+
return Promise.all([import('react'), import('react-dom'), import('react-dom/client')]).then(
|
|
53
|
+
([React, ReactDOM, ReactDOMClient]) => {
|
|
54
|
+
return {
|
|
55
|
+
React,
|
|
56
|
+
ReactDOM,
|
|
57
|
+
ReactDOMClient,
|
|
58
|
+
Chakra: { Tooltip: {} },
|
|
59
|
+
AppContext: ({ libraryId }: any) => <p>Context {libraryId}</p>
|
|
60
|
+
}
|
|
58
61
|
}
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
// Fixme change to production component
|
|
66
|
+
document.body.innerHTML = '<feaas-context src="test.js" library="abc" isolate="false"></feaas-context>'
|
|
67
|
+
|
|
68
|
+
const component = document.body.firstElementChild as FEAASContext
|
|
69
|
+
|
|
70
|
+
await expect(component.whenRendered).resolves.toEqual(component)
|
|
71
|
+
expect(spyLoad).toHaveBeenCalledTimes(1)
|
|
72
|
+
|
|
73
|
+
expect(component.outerHTML).toBe(
|
|
74
|
+
'<feaas-context src="test.js" library="abc" isolate="false" frontend="https://components.sitecorecloud.io" backend="https://components.sitecorecloud.io/api" cdn="https://feaas.blob.core.windows.net"><div><p>Context abc</p></div></feaas-context>'
|
|
75
|
+
)
|
|
76
|
+
})
|
|
77
|
+
it('should initiate loading with isolation', async () => {
|
|
78
|
+
// @ts-ignore
|
|
79
|
+
const spyLoad = vi.spyOn(FEAASContext.prototype, 'import')
|
|
80
|
+
// @ts-ignore
|
|
81
|
+
spyLoad.mockImplementation(async (url: string) => {
|
|
82
|
+
if (url.match('test.js')) {
|
|
83
|
+
return Promise.all([import('react'), import('react-dom'), import('react-dom/client')]).then(
|
|
84
|
+
([React, ReactDOM, ReactDOMClient]) => {
|
|
85
|
+
return {
|
|
86
|
+
React,
|
|
87
|
+
ReactDOM,
|
|
88
|
+
ReactDOMClient,
|
|
89
|
+
Chakra: { Tooltip: {} },
|
|
90
|
+
AppContext: ({ libraryId }: any) => <p>Context {libraryId}</p>
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
// Fixme change to production component
|
|
97
|
+
document.body.innerHTML = '<feaas-context src="test.js" library="abc"></feaas-context>'
|
|
98
|
+
|
|
99
|
+
const component = document.body.firstElementChild as FEAASContext
|
|
100
|
+
|
|
101
|
+
await expect(component.whenRendered).resolves.toEqual(component)
|
|
102
|
+
expect(spyLoad).toHaveBeenCalledTimes(1)
|
|
103
|
+
|
|
104
|
+
expect(component.outerHTML).toBe(
|
|
105
|
+
'<feaas-context src="test.js" library="abc" frontend="https://components.sitecorecloud.io" backend="https://components.sitecorecloud.io/api" cdn="https://feaas.blob.core.windows.net"></feaas-context>'
|
|
106
|
+
)
|
|
107
|
+
expect(component.shadowRoot.innerHTML).toBe('<div><p>Context abc</p></div>')
|
|
108
|
+
})
|
|
109
|
+
it('should nest components and render them in order', async () => {
|
|
110
|
+
const renders = [] as FEAASElement[]
|
|
111
|
+
class FEAASElementTestRenderOrder extends FEAASElement {
|
|
112
|
+
update() {
|
|
113
|
+
renders.push(this)
|
|
114
|
+
}
|
|
61
115
|
}
|
|
116
|
+
FEAASElementTestRenderOrder.register('feaas-element-test-order')
|
|
117
|
+
|
|
118
|
+
const top = document.createElement('feaas-element-test-order') as FEAASElement
|
|
119
|
+
top.innerHTML = `
|
|
120
|
+
<feaas-element-test-order>
|
|
121
|
+
<feaas-element-test-order></feaas-element-test-order>
|
|
122
|
+
<feaas-element-test-order></feaas-element-test-order>
|
|
123
|
+
</feaas-element-test-order>
|
|
124
|
+
<feaas-element-test-order></feaas-element-test-order>
|
|
125
|
+
<feaas-element-test-order>
|
|
126
|
+
<feaas-element-test-order></feaas-element-test-order>
|
|
127
|
+
</feaas-element-test-order>
|
|
128
|
+
`
|
|
129
|
+
document.body.appendChild(top)
|
|
130
|
+
await expect(top.whenRendered).resolves.toEqual(top)
|
|
131
|
+
expect(top.descendants).toEqual([
|
|
132
|
+
top.children[0],
|
|
133
|
+
top.children[0].children[0],
|
|
134
|
+
|
|
135
|
+
top.children[0].children[1],
|
|
136
|
+
|
|
137
|
+
top.children[1],
|
|
138
|
+
|
|
139
|
+
top.children[2],
|
|
140
|
+
|
|
141
|
+
top.children[2].children[0]
|
|
142
|
+
])
|
|
143
|
+
expect(renders).toEqual([
|
|
144
|
+
top.children[0].children[0],
|
|
145
|
+
top.children[0].children[1],
|
|
146
|
+
top.children[0],
|
|
147
|
+
top.children[1],
|
|
148
|
+
top.children[2].children[0],
|
|
149
|
+
top.children[2],
|
|
150
|
+
top
|
|
151
|
+
])
|
|
62
152
|
})
|
|
63
|
-
// Fixme change to production component
|
|
64
|
-
document.body.innerHTML = '<feaas-context src="test.js" library="abc"></feaas-context>'
|
|
65
153
|
|
|
66
|
-
|
|
154
|
+
it('should nest components into context', async () => {
|
|
155
|
+
const renders = [] as FEAASElement[]
|
|
156
|
+
class FEAASElementTestRenderOrder extends FEAASElement {
|
|
157
|
+
render(props: any, payload: any): ReactNode | ReactElement<any, string | JSXElementConstructor<any>> {
|
|
158
|
+
return null
|
|
159
|
+
}
|
|
160
|
+
load() {
|
|
161
|
+
return this.import('context.js')
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
;[FEAASElementTestRenderOrder, FEAASContext].forEach((klass) => {
|
|
165
|
+
// @ts-ignore
|
|
166
|
+
const spyLoad = vi.spyOn(klass.prototype, 'import')
|
|
167
|
+
// @ts-ignore
|
|
168
|
+
spyLoad.mockImplementation(async (url: string) => {
|
|
169
|
+
if (url.match('context.js')) {
|
|
170
|
+
return Promise.all([import('react'), import('react-dom'), import('react-dom/client')]).then(
|
|
171
|
+
([React, ReactDOM, ReactDOMClient]) => {
|
|
172
|
+
return {
|
|
173
|
+
React,
|
|
174
|
+
ReactDOM,
|
|
175
|
+
ReactDOMClient,
|
|
176
|
+
Chakra: { Tooltip: {} },
|
|
177
|
+
AppContext: ({ libraryId }: any) => <p>Context {libraryId}</p>
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
const spyRender = vi.spyOn(klass.prototype, 'render')
|
|
184
|
+
spyRender.mockImplementation(function (this: FEAASContext, { children }, { React }) {
|
|
185
|
+
renders.push(this)
|
|
186
|
+
return <>{children}</>
|
|
187
|
+
})
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
FEAASElementTestRenderOrder.register('feaas-element-test-nesting')
|
|
191
|
+
|
|
192
|
+
const context = document.createElement('feaas-context') as FEAASElement
|
|
193
|
+
context.setAttribute('library', 'library1')
|
|
194
|
+
const top = document.createElement('feaas-element-test-nesting') as FEAASElement
|
|
195
|
+
top.innerHTML = `
|
|
196
|
+
<feaas-element-test-nesting>
|
|
197
|
+
<feaas-element-test-nesting></feaas-element-test-nesting>
|
|
198
|
+
<feaas-element-test-nesting></feaas-element-test-nesting>
|
|
199
|
+
</feaas-element-test-nesting>
|
|
200
|
+
<feaas-element-test-nesting></feaas-element-test-nesting>
|
|
201
|
+
<feaas-element-test-nesting>
|
|
202
|
+
<feaas-element-test-nesting></feaas-element-test-nesting>
|
|
203
|
+
</feaas-element-test-nesting>
|
|
204
|
+
`
|
|
205
|
+
document.body.appendChild(context)
|
|
206
|
+
context.render = function () {
|
|
207
|
+
renders.push(this)
|
|
208
|
+
return FEAASContext.prototype.render.apply(this, arguments)
|
|
209
|
+
}
|
|
210
|
+
document.body.appendChild(top)
|
|
211
|
+
await expect(top.whenRendered).resolves.toEqual(top)
|
|
212
|
+
await expect(context.whenRendered).resolves.toEqual(context)
|
|
213
|
+
expect(top.refs.top).toEqual(context)
|
|
214
|
+
expect(top.refs.topReact).toEqual(context)
|
|
215
|
+
expect(top.refs.parentReact).toEqual(context)
|
|
216
|
+
expect(context.descendants).toEqual([
|
|
217
|
+
top,
|
|
218
|
+
top.children[0],
|
|
219
|
+
top.children[0].children[0],
|
|
67
220
|
|
|
68
|
-
|
|
69
|
-
expect(spyLoad).toHaveBeenCalledTimes(1)
|
|
221
|
+
top.children[0].children[1],
|
|
70
222
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
223
|
+
top.children[1],
|
|
224
|
+
|
|
225
|
+
top.children[2],
|
|
226
|
+
|
|
227
|
+
top.children[2].children[0]
|
|
228
|
+
])
|
|
229
|
+
// FIXME: Currently re-renders happen on each element addition
|
|
230
|
+
//expect(renders).toEqual([
|
|
231
|
+
// context,
|
|
232
|
+
// top.children[0].children[0],
|
|
233
|
+
// top.children[0].children[1],
|
|
234
|
+
// top.children[0],
|
|
235
|
+
// top.children[1],
|
|
236
|
+
// top.children[2].children[0],
|
|
237
|
+
// top.children[2],
|
|
238
|
+
// top
|
|
239
|
+
//])
|
|
240
|
+
|
|
241
|
+
const els = [
|
|
242
|
+
context,
|
|
243
|
+
top.children[0].children[0],
|
|
244
|
+
top.children[0].children[1],
|
|
245
|
+
top.children[0],
|
|
246
|
+
top.children[1],
|
|
247
|
+
top.children[2].children[0],
|
|
248
|
+
top.children[2],
|
|
249
|
+
top
|
|
250
|
+
].forEach((el) => expect(renders).toContain(el))
|
|
251
|
+
})
|
|
75
252
|
})
|
|
76
253
|
})
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { beforeEach, describe, it, assert, beforeAll, expect } from 'vitest'
|
|
2
|
-
import {
|
|
2
|
+
import { FEAASElement, ReactPayload } from '../src/headless.js'
|
|
3
3
|
import { FEAASPickerProps, FEAASPicker } from '../src/ui/FEAASPicker.js'
|
|
4
4
|
import { JSDOM } from 'jsdom'
|
|
5
5
|
import { vi } from 'vitest'
|
|
@@ -7,7 +7,9 @@ import { vi } from 'vitest'
|
|
|
7
7
|
describe('React', function () {
|
|
8
8
|
describe('FEAASPicker', () => {
|
|
9
9
|
beforeEach(() => {
|
|
10
|
-
document.
|
|
10
|
+
document.open()
|
|
11
|
+
document.write('<html><head></head><body></body></html>')
|
|
12
|
+
document.close()
|
|
11
13
|
})
|
|
12
14
|
it('should initiate loading', async () => {
|
|
13
15
|
// @ts-ignore
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function FEAASComponentsProps(element:
|
|
1
|
+
import { FEAASElement } from './FEAASElement.js';
|
|
2
|
+
export declare function FEAASComponentsProps(element: FEAASElement): {
|
|
3
3
|
data: any;
|
|
4
4
|
cdn: string;
|
|
5
5
|
library: string;
|
|
@@ -15,7 +15,7 @@ export declare function FEAASComponentsProps(element: FEAASBase): {
|
|
|
15
15
|
withStylesheet: boolean;
|
|
16
16
|
};
|
|
17
17
|
export type FEAASComponentsProps = ReturnType<typeof FEAASComponentsProps>;
|
|
18
|
-
export declare class FEAASComponent extends
|
|
18
|
+
export declare class FEAASComponent extends FEAASElement<FEAASComponentsProps, string> {
|
|
19
19
|
static observedAttributes: string[];
|
|
20
20
|
defaultProps: Partial<{
|
|
21
21
|
data: any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FEAASComponent.d.ts","sourceRoot":"","sources":["../../src/components/FEAASComponent.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"FEAASComponent.d.ts","sourceRoot":"","sources":["../../src/components/FEAASComponent.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY;;;;;;;;;;;;;;EA6BzD;AACD,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAC1E,qBAAa,cAAe,SAAQ,YAAY,CAAC,oBAAoB,EAAE,MAAM,CAAC;IAC5E,MAAM,CAAC,kBAAkB,WAYxB;IAED,YAAY;;;;;;;;;;;;;;OAOsB;IAElC,YAAY,EAAE,OAAO,CAAA;IACrB,OAAO,CAAC,IAAI,EAAE,GAAG;IAIjB,QAAQ;;;;;;;;;;;;;;;IAIR,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAUhF,SAAS,IAAI,GAAG;;IAahB,IAAI;IASJ,WAAW;IAaX,aAAa;IAMb,MAAM,SAAU,MAAM,UAGrB;IAEK,IAAI;IAsBV,MAAM;CAYP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,GAAG,CAAC;QACZ,UAAU,iBAAiB;YACzB,iBAAiB,EAAE;gBACjB,IAAI,CAAC,EAAE,GAAG,CAAA;gBACV,QAAQ,CAAC,EAAE,MAAM,CAAA;gBACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;gBACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;gBAClB,QAAQ,CAAC,EAAE,GAAG,CAAA;gBACd,uBAAuB,CAAC,EAAE;oBAAE,MAAM,EAAE,MAAM,CAAA;iBAAE,CAAA;gBAC5C,eAAe,CAAC,EAAE,MAAM,CAAA;gBACxB,iBAAiB,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,EAAE,CAAA;aAC1C,GAAG,CACA;gBACE,kCAAkC;gBAClC,QAAQ,CAAC,EAAE,MAAM,CAAA;gBACjB,GAAG,CAAC,EAAE,MAAM,CAAA;gBACZ,OAAO,EAAE,MAAM,CAAA;gBACf,SAAS,EAAE,MAAM,CAAA;gBACjB,OAAO,CAAC,EAAE,MAAM,CAAA;gBAChB,QAAQ,CAAC,EAAE,oBAAoB,CAAC,UAAU,CAAC,CAAA;aAC5C,GACD;gBAAE,GAAG,EAAE,MAAM,CAAA;aAAE,GACf;gBAAE,QAAQ,EAAE,MAAM,CAAA;aAAE,CACvB,CAAA;SACF;KACF;CACF;AAGD,OAAO,EAAE,cAAc,IAAI,SAAS,EAAE,oBAAoB,IAAI,cAAc,EAAE,CAAA"}
|