@sitecore-feaas/clientside 0.0.9 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/browser/basic.cjs +67 -0
- package/dist/browser/basic.js +67 -0
- package/dist/browser/index.cjs +68 -79
- package/dist/browser/index.js +68 -79
- package/dist/node/{react.cjs → basic.cjs} +436 -443
- package/dist/node/{react.js → basic.js} +432 -439
- package/dist/node/index.cjs +666 -291
- package/dist/node/index.js +666 -295
- package/examples/index.html +1 -1
- package/package.json +17 -17
- package/src/basic.ts +5 -0
- package/src/cloud.ts +9 -5
- package/src/components/FEAASBase.tsx +265 -0
- package/src/components/FEAASComponent.ts +98 -0
- package/src/components/FEAASContext.tsx +105 -0
- package/src/components/FEAASEditor.tsx +291 -0
- package/src/components/FEAASLoader.ts +113 -0
- package/src/components/FEAASPicker.tsx +98 -0
- package/src/components/FEAASStylesheet.ts +43 -0
- package/src/components/index.tsx +7 -0
- package/src/index.ts +4 -11
- package/test/components.js +11 -0
- package/test/components.ts +12 -0
- package/test/render.js +688 -0
- package/tsconfig.json +11 -6
- package/types/basic.d.ts +5 -0
- package/types/cloud.d.ts +18 -0
- package/types/components/FEAASBase.d.ts +70 -0
- package/types/components/FEAASComponent.d.ts +39 -0
- package/types/components/FEAASContext.d.ts +43 -0
- package/types/components/FEAASEditor.d.ts +70 -0
- package/types/components/FEAASLoader.d.ts +20 -0
- package/types/components/FEAASPicker.d.ts +61 -0
- package/types/components/FEAASStylesheet.d.ts +25 -0
- package/types/components/index.d.ts +7 -0
- package/types/dom.d.ts +29 -0
- package/types/fetch.d.ts +1 -0
- package/types/index.d.ts +4 -0
- package/types/tsbuildinfo +1 -0
- package/dist/browser/index.d.ts +0 -25
- package/dist/browser/react.cjs +0 -83
- package/dist/browser/react.d.ts +0 -36
- package/dist/browser/react.js +0 -83
- package/dist/browser/webcomponent-6b45b819.d.ts +0 -120
- package/dist/node/index.d.ts +0 -25
- package/dist/node/react.d.ts +0 -36
- package/dist/node/webcomponent-6b45b819.d.ts +0 -120
- package/index.cjs +0 -83
- package/index.d.ts +0 -25
- package/index.js +0 -83
- package/react.cjs +0 -83
- package/react.d.ts +0 -36
- package/react.js +0 -83
- package/src/react.ts +0 -66
- package/src/webcomponent.ts +0 -393
- package/webcomponent-6b45b819.d.ts +0 -120
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import type * as FEAASEditorImports from '@sitecore-feaas/frontend/src/components/editor/Editor.jsx'
|
|
2
|
+
import { FEAASBase, OptionalExcept } from './FEAASBase.js'
|
|
3
|
+
|
|
4
|
+
export function getFramePosition(element: HTMLElement) {
|
|
5
|
+
let positions = []
|
|
6
|
+
if (element) {
|
|
7
|
+
let currentWindow = element.ownerDocument.defaultView as Window
|
|
8
|
+
let currentParentWindow
|
|
9
|
+
let rect
|
|
10
|
+
while (currentWindow !== window.top) {
|
|
11
|
+
currentParentWindow = currentWindow.parent
|
|
12
|
+
for (let idx = 0; idx < currentParentWindow.frames.length; idx++)
|
|
13
|
+
if (currentParentWindow.frames[idx] === currentWindow) {
|
|
14
|
+
for (let frameElement of currentParentWindow.document.getElementsByTagName('iframe')) {
|
|
15
|
+
if (frameElement.contentWindow === currentWindow) {
|
|
16
|
+
rect = frameElement.getBoundingClientRect()
|
|
17
|
+
const style = frameElement.contentWindow.getComputedStyle(frameElement)
|
|
18
|
+
|
|
19
|
+
positions.push({
|
|
20
|
+
left: rect.left + parseInt(style.borderLeftWidth),
|
|
21
|
+
top: rect.top + parseInt(style.borderTopWidth)
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
currentWindow = currentParentWindow as Window
|
|
26
|
+
break
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return positions.reduce(
|
|
31
|
+
(accumulator, currentValue) => {
|
|
32
|
+
return {
|
|
33
|
+
left: accumulator.left + currentValue.left,
|
|
34
|
+
top: accumulator.top + currentValue.top
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{ left: 0, top: 0 }
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
export function FEAASEditorProps(element: FEAASBase = this) {
|
|
41
|
+
return {
|
|
42
|
+
context: HTMLElement,
|
|
43
|
+
frontend: element?.getContextAttribute('frontend'),
|
|
44
|
+
src: element?.getAttribute('src') ?? '/assets/editor.js',
|
|
45
|
+
library: element?.getAttribute('library'),
|
|
46
|
+
component: element?.getAttribute('component'),
|
|
47
|
+
version: element?.getAttribute('version'),
|
|
48
|
+
revision: element?.getAttribute('revision') || 'saved',
|
|
49
|
+
hidden: element?.getAttribute('hidden') != null,
|
|
50
|
+
for: element?.getAttribute('for')
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
type FEAASEditorProps = ReturnType<typeof FEAASEditorProps>
|
|
54
|
+
type Rect = {
|
|
55
|
+
top: number
|
|
56
|
+
left: number
|
|
57
|
+
width: number
|
|
58
|
+
height: number
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export class FEAASEditor extends FEAASBase<FEAASEditorProps, typeof FEAASEditorImports> {
|
|
62
|
+
chrome: HTMLElement
|
|
63
|
+
wrapper: HTMLElement
|
|
64
|
+
|
|
65
|
+
framePoint: Pick<Rect, 'top' | 'left'> = { top: 0, left: 0 }
|
|
66
|
+
wrapperRect: Rect = { top: 0, left: 0, width: 0, height: 0 }
|
|
67
|
+
bodyRect: Rect = { top: 0, left: 0, width: 0, height: 0 }
|
|
68
|
+
|
|
69
|
+
getProps() {
|
|
70
|
+
return FEAASEditorProps(this)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
getTarget = () => {
|
|
74
|
+
return document.querySelector('iframe').contentWindow.document.getElementById(this.props.for)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
load() {
|
|
78
|
+
/* @vite-ignore */
|
|
79
|
+
return import(this.formatURL(this.props.src, this.props.frontend))
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
onChromeMeasureElement = (element: HTMLElement, rect?: Rect) => {
|
|
83
|
+
if (rect == null) {
|
|
84
|
+
rect = element.getBoundingClientRect()
|
|
85
|
+
}
|
|
86
|
+
if (element.ownerDocument == document) {
|
|
87
|
+
return {
|
|
88
|
+
left: rect.left - this.bodyRect.left,
|
|
89
|
+
top: rect.top - this.bodyRect.top,
|
|
90
|
+
width: rect.width,
|
|
91
|
+
height: rect.height
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
left: rect.left + this.framePoint.left - this.bodyRect.left,
|
|
96
|
+
top: rect.top + this.framePoint.top - this.bodyRect.top,
|
|
97
|
+
width: rect.width,
|
|
98
|
+
height: rect.height
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
onBeforeMeasure: FEAASEditorImports.EditorContext['onChromeBeforeMeasure'] = (refs) => {
|
|
103
|
+
if (refs.memoized.focusable) this.framePoint = getFramePosition(refs.memoized.focusable)
|
|
104
|
+
this.wrapperRect = this.wrapper.getBoundingClientRect()
|
|
105
|
+
this.bodyRect = this.wrapper.ownerDocument.body.parentElement.getBoundingClientRect()
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
onMeasure: FEAASEditorImports.EditorContext['onChromeMeasure'] = () => {}
|
|
109
|
+
onPosition: FEAASEditorImports.EditorContext['onChromePosition'] = ({ focusable, root }) => {
|
|
110
|
+
const chrome = this.wrapper.querySelector('.editor-chrome') as HTMLElement
|
|
111
|
+
const absolute = this.wrapper.querySelector('.ui.overlays') as HTMLElement
|
|
112
|
+
if (focusable) {
|
|
113
|
+
const topbarHeight = 64
|
|
114
|
+
const padding = 16
|
|
115
|
+
chrome.style.width = focusable.width + padding * 2 + 'px'
|
|
116
|
+
chrome.style.height = focusable.height + padding * 1 + topbarHeight + 'px'
|
|
117
|
+
chrome.style.left = focusable.left - padding + 'px'
|
|
118
|
+
chrome.style.top = focusable.top - topbarHeight + 'px'
|
|
119
|
+
if (absolute) {
|
|
120
|
+
absolute.style.left = root.left + 'px'
|
|
121
|
+
absolute.style.top = root.top + 'px'
|
|
122
|
+
}
|
|
123
|
+
} else {
|
|
124
|
+
chrome.style.left = '-1000px'
|
|
125
|
+
chrome.style.top = '-1000px'
|
|
126
|
+
// wrapper.style.left = '-1000px'
|
|
127
|
+
// wrapper.style.top = '-1000px'
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/*
|
|
131
|
+
getRoot(): HTMLElement | FEAASBase<any, any> | ShadowRoot {
|
|
132
|
+
return this.shadowRoot || this.attachShadow({ mode: 'open' })
|
|
133
|
+
}
|
|
134
|
+
reactRoot: HTMLDivElement
|
|
135
|
+
getReactRoot() {
|
|
136
|
+
if (!this.reactRoot) {
|
|
137
|
+
this.reactRoot = document.createElement('div')
|
|
138
|
+
this.reactRoot.className = 'react-root'
|
|
139
|
+
this.getRoot().appendChild(this.reactRoot)
|
|
140
|
+
}
|
|
141
|
+
return this.reactRoot
|
|
142
|
+
}
|
|
143
|
+
*/
|
|
144
|
+
renderReact(
|
|
145
|
+
{ children, component: componentId, version: versionId }: React.PropsWithChildren<FEAASEditorProps>,
|
|
146
|
+
{
|
|
147
|
+
Editor,
|
|
148
|
+
VersionStatusList,
|
|
149
|
+
Version,
|
|
150
|
+
EditorUIUndo,
|
|
151
|
+
EditorUIMode,
|
|
152
|
+
React: { useEffect, useMemo, useState },
|
|
153
|
+
Chakra: { HStack, Box },
|
|
154
|
+
Chrome,
|
|
155
|
+
ReactDOM,
|
|
156
|
+
useSDK,
|
|
157
|
+
useSlots,
|
|
158
|
+
useModelObserver
|
|
159
|
+
}: typeof FEAASEditorImports
|
|
160
|
+
) {
|
|
161
|
+
if (!this.payload) return
|
|
162
|
+
const { sdk } = useSDK()
|
|
163
|
+
const [component, setComponent] = useState<FEAASEditorImports.SDK.ComponentModel>()
|
|
164
|
+
const library = sdk.library
|
|
165
|
+
useEffect(() => {
|
|
166
|
+
return setComponent(library.components.getItem(componentId))
|
|
167
|
+
}, [componentId, library])
|
|
168
|
+
useEffect(() => {
|
|
169
|
+
component?.versions.fetch()
|
|
170
|
+
}, [component])
|
|
171
|
+
|
|
172
|
+
const target = useMemo(this.getTarget, [this.props.for])
|
|
173
|
+
|
|
174
|
+
const observedVersions = useModelObserver(component?.versions)
|
|
175
|
+
const versions = useMemo(() => {
|
|
176
|
+
return observedVersions?.filter((v) => v.id == versionId || !versionId) || []
|
|
177
|
+
}, [observedVersions])
|
|
178
|
+
|
|
179
|
+
if (!component) return
|
|
180
|
+
return useSlots<any, 'picker' | 'children'>(children, ({ picker, children }) => (
|
|
181
|
+
<Box ref={(el) => (this.wrapper = el)}>
|
|
182
|
+
<Box className='editor-wrapper' position='absolute' left={0} top={0}>
|
|
183
|
+
<Editor
|
|
184
|
+
sdk={sdk}
|
|
185
|
+
library={sdk.library}
|
|
186
|
+
component={component}
|
|
187
|
+
versions={versions}
|
|
188
|
+
context={{
|
|
189
|
+
onChromeMeasure: this.onMeasure,
|
|
190
|
+
onChromeBeforeMeasure: this.onBeforeMeasure,
|
|
191
|
+
onChromeMeasureElement: this.onChromeMeasureElement,
|
|
192
|
+
onChromePosition: this.onPosition
|
|
193
|
+
}}
|
|
194
|
+
>
|
|
195
|
+
{({ editor, status, isArchivedDisplayed }) => ({
|
|
196
|
+
after: children,
|
|
197
|
+
picker: picker,
|
|
198
|
+
chrome: editor && <Chrome />,
|
|
199
|
+
children: component
|
|
200
|
+
.reduceVersionRevisions(versions)
|
|
201
|
+
.filter((snapshot) => {
|
|
202
|
+
return isArchivedDisplayed || !(snapshot.saved || snapshot.draft)?.deletedAt
|
|
203
|
+
})
|
|
204
|
+
.map((snapshot, index) => (
|
|
205
|
+
<Box
|
|
206
|
+
key={snapshot.head.id}
|
|
207
|
+
position='absolute'
|
|
208
|
+
left={0}
|
|
209
|
+
top={0}
|
|
210
|
+
className='editor-chrome'
|
|
211
|
+
p={4}
|
|
212
|
+
boxShadow={'2xl'}
|
|
213
|
+
pointerEvents='none'
|
|
214
|
+
>
|
|
215
|
+
<Box
|
|
216
|
+
className='borders'
|
|
217
|
+
pointerEvents={'none'}
|
|
218
|
+
left={0}
|
|
219
|
+
width='4'
|
|
220
|
+
top={0}
|
|
221
|
+
bottom={0}
|
|
222
|
+
backdropFilter='blur(2px)'
|
|
223
|
+
background='rgb(244 244 244 / 80%)'
|
|
224
|
+
position='absolute'
|
|
225
|
+
></Box>
|
|
226
|
+
<Box
|
|
227
|
+
className='borders'
|
|
228
|
+
pointerEvents={'none'}
|
|
229
|
+
right={0}
|
|
230
|
+
width='4'
|
|
231
|
+
top={0}
|
|
232
|
+
bottom={0}
|
|
233
|
+
backdropFilter='blur(2px)'
|
|
234
|
+
background='rgb(244 244 244 / 80%)'
|
|
235
|
+
position='absolute'
|
|
236
|
+
></Box>
|
|
237
|
+
<Box
|
|
238
|
+
className='borders'
|
|
239
|
+
pointerEvents={'none'}
|
|
240
|
+
top={0}
|
|
241
|
+
height='16'
|
|
242
|
+
left={0}
|
|
243
|
+
right={0}
|
|
244
|
+
backdropFilter='blur(2px)'
|
|
245
|
+
background='rgb(244 244 244 / 80%)'
|
|
246
|
+
position='absolute'
|
|
247
|
+
></Box>
|
|
248
|
+
<Box
|
|
249
|
+
className='borders'
|
|
250
|
+
pointerEvents={'none'}
|
|
251
|
+
bottom={0}
|
|
252
|
+
height='4'
|
|
253
|
+
left={0}
|
|
254
|
+
right={0}
|
|
255
|
+
backdropFilter='blur(2px)'
|
|
256
|
+
background='rgb(244 244 244 / 80%)'
|
|
257
|
+
position='absolute'
|
|
258
|
+
></Box>
|
|
259
|
+
<Version version={snapshot.head} node={target}>
|
|
260
|
+
{{
|
|
261
|
+
left: (
|
|
262
|
+
<HStack justifyContent='space-between'>
|
|
263
|
+
<EditorUIUndo size='sm' editor={status == 'ready' ? editor : null} />
|
|
264
|
+
<EditorUIMode size='sm' />
|
|
265
|
+
</HStack>
|
|
266
|
+
),
|
|
267
|
+
middle: <VersionStatusList />
|
|
268
|
+
}}
|
|
269
|
+
</Version>
|
|
270
|
+
</Box>
|
|
271
|
+
))
|
|
272
|
+
})}
|
|
273
|
+
</Editor>
|
|
274
|
+
</Box>
|
|
275
|
+
</Box>
|
|
276
|
+
))
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
isReadyToLoad(): boolean {
|
|
280
|
+
return this.props.component != null && this.props.version != null
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
declare global {
|
|
285
|
+
namespace JSX {
|
|
286
|
+
interface IntrinsicElements {
|
|
287
|
+
'feaas-editor': OptionalExcept<FEAASEditorProps, 'component' | 'version'>
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
FEAASEditor.register('feaas-editor')
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { FEAASBase } from './FEAASBase.js'
|
|
2
|
+
|
|
3
|
+
export function FEAASLoaderProps(element: HTMLElement = this) {
|
|
4
|
+
return {
|
|
5
|
+
hidden: element?.getAttribute('hidden') != null
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
type FEAASLoaderProps = ReturnType<typeof FEAASLoaderProps>
|
|
9
|
+
|
|
10
|
+
export class FEAASLoader extends FEAASBase<FEAASLoaderProps, string> {
|
|
11
|
+
stylesheet: HTMLStyleElement
|
|
12
|
+
loader: HTMLDivElement
|
|
13
|
+
|
|
14
|
+
static observedAttributes = ['hidden']
|
|
15
|
+
|
|
16
|
+
attributeChangedCallback(name: string, oldValue: string, newValue: string): void {
|
|
17
|
+
if (name == 'hidden') {
|
|
18
|
+
this.style.setProperty('display', 'block', 'important')
|
|
19
|
+
this.style.setProperty('transition', 'opacity 0.3s', 'important')
|
|
20
|
+
if (newValue) {
|
|
21
|
+
this.style.setProperty('opacity', '0', 'important')
|
|
22
|
+
this.style.pointerEvents = 'none'
|
|
23
|
+
} else {
|
|
24
|
+
this.style.setProperty('opacity', '1', 'important')
|
|
25
|
+
this.style.pointerEvents = 'all'
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
connectedCallback() {
|
|
31
|
+
this.attributeChangedCallback('hidden', this.getAttribute('hidden'), this.getAttribute('hidden'))
|
|
32
|
+
this.stylesheet = document.createElement('style')
|
|
33
|
+
this.stylesheet.textContent = `
|
|
34
|
+
#loader {
|
|
35
|
+
position: absolute;
|
|
36
|
+
top: 0;
|
|
37
|
+
left: 0;
|
|
38
|
+
right: 0;
|
|
39
|
+
bottom: 0;
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
justify-content: center;
|
|
43
|
+
background: #f6f6ff;
|
|
44
|
+
z-index: 1000;
|
|
45
|
+
}
|
|
46
|
+
@keyframes loader-circular-track {
|
|
47
|
+
0% {
|
|
48
|
+
stroke-dasharray: 1, 400;
|
|
49
|
+
stroke-dashoffset: 0;
|
|
50
|
+
}
|
|
51
|
+
50% {
|
|
52
|
+
stroke-dasharray: 400, 400;
|
|
53
|
+
stroke-dashoffset: -100;
|
|
54
|
+
}
|
|
55
|
+
100% {
|
|
56
|
+
stroke-dasharray: 400, 400;
|
|
57
|
+
stroke-dashoffset: -260;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@keyframes loader-circular-spinner {
|
|
62
|
+
0% {
|
|
63
|
+
transform: rotate(0deg);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
100% {
|
|
67
|
+
transform: rotate(360deg);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
#loader .spinner {
|
|
71
|
+
width: 48px;
|
|
72
|
+
height: 48px;
|
|
73
|
+
}
|
|
74
|
+
`
|
|
75
|
+
this.loader = document.createElement('div')
|
|
76
|
+
this.loader.id = 'loader'
|
|
77
|
+
this.loader.innerHTML = `
|
|
78
|
+
<div class="spinner">
|
|
79
|
+
<svg
|
|
80
|
+
viewBox="0 0 100 100"
|
|
81
|
+
style="
|
|
82
|
+
animation: 2s linear 0s infinite normal none running loader-circular-spinner;
|
|
83
|
+
display: block;
|
|
84
|
+
width: 48px;
|
|
85
|
+
height: 48px;
|
|
86
|
+
"
|
|
87
|
+
>
|
|
88
|
+
<circle fill="transparent" cx="50" cy="50" r="42" stroke="rgba(0,0,0,0.1)" stroke-width="10px"></circle>
|
|
89
|
+
<circle
|
|
90
|
+
fill="transparent"
|
|
91
|
+
stroke="#5548D9"
|
|
92
|
+
cx="50"
|
|
93
|
+
cy="50"
|
|
94
|
+
r="42"
|
|
95
|
+
stroke-width="10px"
|
|
96
|
+
stroke-linecap="round"
|
|
97
|
+
style="animation: 1.5s linear 0s infinite normal none running loader-circular-track"
|
|
98
|
+
></circle>
|
|
99
|
+
</svg>
|
|
100
|
+
</div>`
|
|
101
|
+
this.getRoot().appendChild(this.stylesheet)
|
|
102
|
+
this.getRoot().appendChild(this.loader)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
declare global {
|
|
107
|
+
namespace JSX {
|
|
108
|
+
interface IntrinsicElements {
|
|
109
|
+
'feaas-loader': any
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
FEAASLoader.register('feaas-loader')
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type * as FEAASPickerImports from '@sitecore-feaas/frontend/src/components/picker/Picker.jsx'
|
|
2
|
+
import { FEAASBase } from './FEAASBase.js'
|
|
3
|
+
|
|
4
|
+
export function FEAASPickerProps(element: FEAASBase<any, any> = this) {
|
|
5
|
+
return {
|
|
6
|
+
part: element?.getAttribute('part') || 'picker',
|
|
7
|
+
slot: element?.getAttribute('part') || 'slot',
|
|
8
|
+
mode: element?.getAttribute('mode') as 'library' | 'stylesheet',
|
|
9
|
+
frontend: element?.getContextAttribute('frontend') ?? 'https://components.sitecorecloud.io',
|
|
10
|
+
src: element?.getAttribute('src') ?? '/assets/picker.js',
|
|
11
|
+
hidden: element?.getAttribute('hidden') != null,
|
|
12
|
+
context: undefined as FEAASPickerImports.PickerProps['context'],
|
|
13
|
+
onClose: undefined as (...args: any[]) => {}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
type FEAASPickerProps = ReturnType<typeof FEAASPickerProps>
|
|
17
|
+
|
|
18
|
+
export class FEAASPicker extends FEAASBase<FEAASPickerProps, typeof FEAASPickerImports> {
|
|
19
|
+
getProps() {
|
|
20
|
+
return FEAASPickerProps(this)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
load() {
|
|
24
|
+
/* @vite-ignore */
|
|
25
|
+
return import(this.formatURL(this.props.src, this.props.frontend))
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
renderReact(
|
|
29
|
+
{ context, mode, children }: React.PropsWithChildren<FEAASPickerProps>,
|
|
30
|
+
{ Picker, React, ReactDOM }: typeof FEAASPickerImports
|
|
31
|
+
) {
|
|
32
|
+
return (
|
|
33
|
+
<Picker mode={mode || undefined} onClose={this.props.onClose} context={context}>
|
|
34
|
+
{children}
|
|
35
|
+
</Picker>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
declare global {
|
|
40
|
+
namespace JSX {
|
|
41
|
+
interface IntrinsicElements {
|
|
42
|
+
'feaas-picker': Partial<typeof FEAASPickerImports>
|
|
43
|
+
'feaas-picker-lazy': Partial<typeof FEAASPickerImports>
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
FEAASPicker.register('feaas-picker')
|
|
49
|
+
|
|
50
|
+
export function FEAASPickerLazyProps(element: FEAASBase<any, any> = this) {
|
|
51
|
+
return {
|
|
52
|
+
library: element?.getAttribute('library') || 'library',
|
|
53
|
+
mode: element?.getAttribute('mode') as 'library' | 'stylesheet',
|
|
54
|
+
frontend: element?.getContextAttribute('frontend') ?? 'https://components.sitecorecloud.io',
|
|
55
|
+
src: element?.getAttribute('src') ?? '/assets/picker.js',
|
|
56
|
+
hidden: element?.getAttribute('hidden') != null,
|
|
57
|
+
context: null as FEAASPickerImports.PickerProps['context'],
|
|
58
|
+
getToken: null as (options: any) => Promise<string>
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
type FEAASPickerLazyProps = ReturnType<typeof FEAASPickerLazyProps>
|
|
62
|
+
|
|
63
|
+
export class FEAASPickerLazy extends FEAASBase<FEAASPickerLazyProps, typeof FEAASPickerImports> {
|
|
64
|
+
payload = null as any
|
|
65
|
+
getProps() {
|
|
66
|
+
return FEAASPickerLazyProps(this)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
onClose = () => {
|
|
70
|
+
this.setAttribute('hidden', 'hidden')
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
render() {
|
|
74
|
+
const { frontend, library, getToken, src, mode, context } = this.props
|
|
75
|
+
|
|
76
|
+
if (this.children.length == 0)
|
|
77
|
+
this.innerHTML = `
|
|
78
|
+
<feaas-context src='/components/providers/ContextProvider.tsx' library='${library}'>
|
|
79
|
+
<feaas-picker mode='${mode}'>
|
|
80
|
+
<feaas-loader />
|
|
81
|
+
</feaas-context>
|
|
82
|
+
`
|
|
83
|
+
|
|
84
|
+
this.refs.context.set({
|
|
85
|
+
frontend: frontend,
|
|
86
|
+
library: library,
|
|
87
|
+
getToken: getToken
|
|
88
|
+
})
|
|
89
|
+
this.refs.picker.set({
|
|
90
|
+
frontend: frontend,
|
|
91
|
+
context: context,
|
|
92
|
+
src: src,
|
|
93
|
+
mode: mode,
|
|
94
|
+
onClose: this.onClose
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
FEAASPickerLazy.register('feaas-picker-lazy')
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { fetchStylesheet } from '../cloud.js'
|
|
2
|
+
import { FEAASBase } from './FEAASBase.js'
|
|
3
|
+
|
|
4
|
+
export function FEAASStylesheetProps(element: FEAASBase = this) {
|
|
5
|
+
return {
|
|
6
|
+
library: element?.getContextAttribute('library'),
|
|
7
|
+
revision: (element?.getAttribute('revision') ?? 'published') as 'published' | 'staging' | 'saved' | number,
|
|
8
|
+
cdn: element?.getContextAttribute('cdn')
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export type FEAASStylesheetProps = ReturnType<typeof FEAASStylesheetProps>
|
|
12
|
+
|
|
13
|
+
export class FEAASStylesheet extends FEAASBase<FEAASStylesheetProps, string> {
|
|
14
|
+
stylesheet: HTMLStyleElement
|
|
15
|
+
getProps() {
|
|
16
|
+
return FEAASStylesheetProps(this)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
isReadyToLoad(): boolean {
|
|
20
|
+
return this.props.library != null && this.props.revision != null && this.props.cdn != null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async load() {
|
|
24
|
+
fetchStylesheet(this.props, this.onLoad)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
render() {
|
|
28
|
+
if (!this.stylesheet) {
|
|
29
|
+
this.stylesheet = document.createElement('style')
|
|
30
|
+
this.appendChild(this.stylesheet)
|
|
31
|
+
}
|
|
32
|
+
this.stylesheet.textContent = this.payload
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
declare global {
|
|
37
|
+
namespace JSX {
|
|
38
|
+
interface IntrinsicElements {
|
|
39
|
+
'feaas-stylesheet': Partial<FEAASStylesheetProps>
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
FEAASStylesheet.register('feaas-stylesheet')
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { FEAASBase } from './FEAASBase.jsx'
|
|
2
|
+
export { FEAASComponent } from './FEAASComponent.js'
|
|
3
|
+
export { FEAASContext } from './FEAASContext.jsx'
|
|
4
|
+
export { FEAASEditor } from './FEAASEditor.jsx'
|
|
5
|
+
export { FEAASLoader } from './FEAASLoader.js'
|
|
6
|
+
export { FEAASPicker } from './FEAASPicker.jsx'
|
|
7
|
+
export { FEAASStylesheet } from './FEAASStylesheet.js'
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
|
|
5
|
-
import * as DOM from './dom.js'
|
|
6
|
-
import * as WEB from './webcomponent.js'
|
|
7
|
-
|
|
8
|
-
export default {
|
|
9
|
-
...DOM,
|
|
10
|
-
...WEB
|
|
11
|
-
}
|
|
1
|
+
export * from './basic.js'
|
|
2
|
+
export * from './components/FEAASEditor.jsx'
|
|
3
|
+
export * from './components/FEAASPicker.jsx'
|
|
4
|
+
export * from './components/FEAASContext.jsx'
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { expect } from 'vitest';
|
|
2
|
+
import { describe, it } from 'vitest';
|
|
3
|
+
describe('Components', () => {
|
|
4
|
+
describe('<feaas-context>', () => {
|
|
5
|
+
it('render without data', () => {
|
|
6
|
+
const div = document.createElement('div');
|
|
7
|
+
div.innerHTML = '<feaas-context></feaas-context>';
|
|
8
|
+
expect('').toEqual('');
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { expect } from 'vitest'
|
|
2
|
+
import { describe, it, assert, beforeAll } from 'vitest'
|
|
3
|
+
|
|
4
|
+
describe('Components', () => {
|
|
5
|
+
describe('<feaas-context>', () => {
|
|
6
|
+
it('render without data', () => {
|
|
7
|
+
const div = document.createElement('div')
|
|
8
|
+
div.innerHTML = '<feaas-context></feaas-context>'
|
|
9
|
+
expect('').toEqual('')
|
|
10
|
+
})
|
|
11
|
+
})
|
|
12
|
+
})
|