@cntrl-site/sdk-nextjs 1.9.77 → 1.9.79
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/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/modules.xml +8 -0
- package/.idea/sdk-nextjs.iml +12 -0
- package/.idea/vcs.xml +6 -0
- package/LICENSE +21 -21
- package/README.md +4 -4
- package/TODO.md +1 -1
- package/eslint.config.mjs +35 -35
- package/jest.config.js +6 -6
- package/lib/common/useItemFXData.js +5 -5
- package/lib/components/Article.js +5 -5
- package/lib/components/LayoutStyle.js +4 -4
- package/lib/components/Section/Section.js +27 -27
- package/lib/components/StructuredBlockItem/StructuredBlockItem.js +13 -13
- package/lib/components/StructuredBlockItem/StructuredComponent/StructuredComponent.js +12 -12
- package/lib/components/StructuredContent/StructuredContent.js +11 -11
- package/lib/components/items/CodeEmbedItem/CodeEmbedItem.js +36 -36
- package/lib/components/items/ComponentItem/ComponentItem.js +13 -13
- package/lib/components/items/CompoundItem/CompoundChild.js +20 -20
- package/lib/components/items/CompoundItem/CompoundItem.js +14 -14
- package/lib/components/items/CustomItem/CustomItem.js +9 -9
- package/lib/components/items/EmbedVideoItem/VimeoEmbed.js +24 -24
- package/lib/components/items/EmbedVideoItem/YoutubeEmbed.js +27 -27
- package/lib/components/items/FileItem/ImageItem.js +40 -40
- package/lib/components/items/FileItem/VideoItem.js +64 -64
- package/lib/components/items/GroupItem/GroupItem.js +14 -14
- package/lib/components/items/Item.js +30 -30
- package/lib/components/items/RectangleItem/RectangleItem.js +27 -27
- package/lib/components/items/RichTextItem/RichTextItem.js +22 -22
- package/lib/utils/RichTextConverter/RichTextConverter.js +21 -21
- package/package.json +62 -62
- package/src/ItemGeometry/CSSPropertyNameMap.ts +37 -37
- package/src/ItemGeometry/GenericGeometryController.ts +59 -59
- package/src/ItemGeometry/ItemGeometryContext.ts +4 -4
- package/src/ItemGeometry/ItemGeometryController.ts +22 -22
- package/src/ItemGeometry/ItemGeometryService.ts +34 -34
- package/src/ItemGeometry/RichTextGeometryController.ts +166 -166
- package/src/ItemGeometry/useItemGeometry.ts +25 -25
- package/src/common/useCurrentLayout.ts +52 -52
- package/src/common/useExemplary.ts +9 -9
- package/src/common/useItemFXData.ts +63 -63
- package/src/common/useKeyframeValue.ts +85 -85
- package/src/common/useRegisterResize.ts +16 -16
- package/src/components/Article.tsx +69 -69
- package/src/components/ArticleWrapper.tsx +21 -21
- package/src/components/Head.tsx +95 -95
- package/src/components/LayoutStyle.tsx +21 -21
- package/src/components/Page.tsx +47 -47
- package/src/components/ScrollPlaybackVideo.tsx +75 -75
- package/src/components/Section/Section.tsx +162 -162
- package/src/components/Section/SectionImage.tsx +48 -48
- package/src/components/Section/SectionVideo.tsx +144 -144
- package/src/components/Section/useSectionColor.ts +19 -19
- package/src/components/Section/useSectionHeightMap.ts +19 -19
- package/src/components/StructuredBlockItem/StructuredBlockItem.tsx +69 -69
- package/src/components/StructuredBlockItem/StructuredComponent/StructuredComponent.tsx +66 -66
- package/src/components/StructuredContent/StructuredContent.tsx +42 -42
- package/src/components/items/CodeEmbedItem/CodeEmbedItem.tsx +148 -148
- package/src/components/items/CodeEmbedItem/useCodeEmbedItem.ts +36 -36
- package/src/components/items/ComponentItem/ComponentItem.tsx +85 -85
- package/src/components/items/ComponentItem/useComponentItem.ts +35 -35
- package/src/components/items/CompoundItem/CompoundChild.tsx +151 -151
- package/src/components/items/CompoundItem/CompoundItem.tsx +88 -88
- package/src/components/items/CompoundItem/useCompoundItem.ts +21 -21
- package/src/components/items/CustomItem/CustomItem.tsx +50 -50
- package/src/components/items/EmbedVideoItem/VimeoEmbed.tsx +217 -217
- package/src/components/items/EmbedVideoItem/YoutubeEmbed.tsx +201 -201
- package/src/components/items/EmbedVideoItem/useEmbedVideoItem.ts +46 -46
- package/src/components/items/FileItem/ImageItem.tsx +166 -166
- package/src/components/items/FileItem/VideoItem.tsx +287 -287
- package/src/components/items/FileItem/useFileItem.ts +81 -81
- package/src/components/items/GroupItem/GroupItem.tsx +99 -99
- package/src/components/items/GroupItem/useGroupItem.ts +34 -34
- package/src/components/items/Item.tsx +268 -268
- package/src/components/items/LinkWrapper.tsx +39 -39
- package/src/components/items/RectangleItem/RectangleItem.tsx +177 -177
- package/src/components/items/RectangleItem/useRectangleItem.ts +89 -89
- package/src/components/items/RichTextItem/RichTextItem.tsx +113 -113
- package/src/components/items/RichTextItem/useRichTextItem.ts +12 -12
- package/src/components/items/RichTextWrapper.tsx +15 -15
- package/src/components/items/itemsMap.ts +28 -28
- package/src/components/items/useDraggable.ts +252 -252
- package/src/components/items/useItemAngle.ts +13 -13
- package/src/components/items/useItemArea.ts +35 -35
- package/src/components/items/useItemPointerEvents.ts +23 -23
- package/src/components/items/useItemScale.ts +17 -17
- package/src/components/items/useItemTriggers.ts +15 -15
- package/src/components/items/useRichTextItemValues.ts +66 -66
- package/src/components/items/useSizing.ts +25 -25
- package/src/components/items/useStickyItemTop.ts +21 -21
- package/src/components/useLayoutContext.ts +7 -7
- package/src/index.ts +25 -25
- package/src/interactions/InteractionsRegistry.ts +513 -513
- package/src/interactions/ItemInteractionCtrl.ts +78 -78
- package/src/interactions/getTransition.ts +27 -27
- package/src/interactions/types.ts +36 -36
- package/src/interactions/useItemInteractionCtrl.ts +18 -18
- package/src/provider/ArticleRectContext.ts +4 -4
- package/src/provider/CntrlContext.ts +5 -5
- package/src/provider/CntrlProvider.tsx +11 -11
- package/src/provider/CntrlSdkContext.ts +113 -113
- package/src/provider/CustomItemRegistry.ts +14 -14
- package/src/provider/CustomItemTypes.ts +3 -3
- package/src/provider/CustomSectionRegistry.ts +25 -25
- package/src/provider/InteractionsContext.tsx +73 -73
- package/src/provider/Keyframes.ts +11 -11
- package/src/provider/KeyframesContext.ts +5 -5
- package/src/provider/LayoutContext.ts +3 -3
- package/src/provider/WebGLContextManagerContext.tsx +4 -4
- package/src/provider/defaultContext.ts +8 -8
- package/src/provider/useCntrlContext.ts +8 -8
- package/src/styled-jsx.d.ts +1 -1
- package/src/types/components-utils.d.ts +7 -7
- package/src/utils/Animator/Animator.ts +570 -570
- package/src/utils/ArticleRectManager/ArticleRectObserver.ts +93 -93
- package/src/utils/ArticleRectManager/useArticleRectObserver.ts +17 -17
- package/src/utils/ArticleRectManager/useSectionRegistry.ts +11 -11
- package/src/utils/CSSNumeric.ts +19 -19
- package/src/utils/EventEmitter.ts +41 -41
- package/src/utils/RichTextConverter/RichTextConverter.tsx +342 -342
- package/src/utils/ScaleAnchorMap.ts +13 -13
- package/src/utils/StickyManager/StickyManager.ts +23 -23
- package/src/utils/Youtube/YouTubeIframeApiLoader.ts +58 -58
- package/src/utils/Youtube/YoutubeIframeApi.ts +101 -101
- package/src/utils/Youtube/useYouTubeIframeApi.ts +12 -12
- package/src/utils/areFillsVisible/areFillsVisible.test.ts +63 -63
- package/src/utils/areFillsVisible/areFillsVisible.ts +37 -37
- package/src/utils/binSearchInsertAt.ts +33 -33
- package/src/utils/castObject.ts +10 -10
- package/src/utils/checkOverflowClipSupport.ts +13 -13
- package/src/utils/domDfs.ts +11 -11
- package/src/utils/effects/useImageFx.ts +154 -154
- package/src/utils/effects/useVideoFx.ts +156 -156
- package/src/utils/evaluateComponentBundle.ts +83 -83
- package/src/utils/getAnchoredItemTop.ts +12 -12
- package/src/utils/getCompoundBoundaryStyles.ts +60 -60
- package/src/utils/getFill.ts +46 -46
- package/src/utils/getFontFamilyValue.ts +3 -3
- package/src/utils/getInvertedRanges.ts +43 -43
- package/src/utils/getItemTopStyle.ts +39 -39
- package/src/utils/getStyleFromItemStateAndParams.ts +8 -8
- package/src/utils/getValidYoutubeUrl.ts +29 -29
- package/src/utils/isItemType.ts +5 -5
- package/src/utils/rangeMap.ts +13 -13
- package/src/utils/useElementRect.ts +23 -23
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
import { InteractionsRegistryPort, ItemInteractionCtrl } from './types';
|
|
2
|
-
import { getTransition } from './getTransition';
|
|
3
|
-
import { getStyleKeysFromCSSProperty } from '../ItemGeometry/CSSPropertyNameMap';
|
|
4
|
-
import { InteractionItemTrigger } from '@cntrl-site/sdk';
|
|
5
|
-
|
|
6
|
-
export class ItemInteractionController implements ItemInteractionCtrl {
|
|
7
|
-
private transitionsInProgress: Set<string> = new Set();
|
|
8
|
-
private actionReceiver: ((type: 'play' | 'pause') => void) | undefined;
|
|
9
|
-
|
|
10
|
-
constructor(
|
|
11
|
-
private itemId: string,
|
|
12
|
-
private registry: InteractionsRegistryPort,
|
|
13
|
-
private onChange: () => void,
|
|
14
|
-
) {
|
|
15
|
-
this.registry.register(itemId, this);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
getState<T>(keys: string[]) {
|
|
19
|
-
const stateProps = this.registry.getStatePropsForItem(this.itemId);
|
|
20
|
-
const styles = keys.reduce<Record<string, T>>((map, styleKey) => {
|
|
21
|
-
const prop = stateProps[styleKey];
|
|
22
|
-
if (prop?.value === undefined) return map;
|
|
23
|
-
map[styleKey] = prop.value as T;
|
|
24
|
-
return map;
|
|
25
|
-
}, {});
|
|
26
|
-
const transition = getTransition(stateProps, keys);
|
|
27
|
-
return {
|
|
28
|
-
styles,
|
|
29
|
-
transition
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
getHasTrigger(itemId: string, triggerType: InteractionItemTrigger['triggerEvent']): boolean {
|
|
34
|
-
const triggers = this.registry.getItemAvailableTriggers(itemId);
|
|
35
|
-
return triggers.has(triggerType);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
sendTrigger(type: 'click' | 'hover-in' | 'hover-out') {
|
|
39
|
-
this.registry.notifyItemTrigger(this.itemId, type);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
receiveAction(type: 'play' | 'pause') {
|
|
43
|
-
this.actionReceiver?.(type);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
setActionReceiver(action: (type: 'play' | 'pause') => void) {
|
|
47
|
-
this.actionReceiver = action;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
handleTransitionStart = (types: string[]) => {
|
|
51
|
-
this.transitionsInProgress.clear();
|
|
52
|
-
for (const type of types) {
|
|
53
|
-
this.transitionsInProgress.add(type);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
handleTransitionEnd = (cssPropKey: string) => {
|
|
58
|
-
if (cssPropKey.startsWith('border-') && cssPropKey.endsWith('-radius')) {
|
|
59
|
-
cssPropKey = 'border-radius';
|
|
60
|
-
}
|
|
61
|
-
if (cssPropKey.startsWith('border-') && cssPropKey.endsWith('-width')) {
|
|
62
|
-
cssPropKey = 'border-width';
|
|
63
|
-
}
|
|
64
|
-
const styleKeys = getStyleKeysFromCSSProperty(cssPropKey);
|
|
65
|
-
for (const key of styleKeys) {
|
|
66
|
-
const found = this.transitionsInProgress.has(key);
|
|
67
|
-
if (!found) continue;
|
|
68
|
-
this.transitionsInProgress.delete(key);
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
71
|
-
if (this.transitionsInProgress.size !== 0) return;
|
|
72
|
-
this.registry.notifyTransitionEnd(this.itemId);
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
receiveChange() {
|
|
76
|
-
this.onChange();
|
|
77
|
-
}
|
|
78
|
-
}
|
|
1
|
+
import { InteractionsRegistryPort, ItemInteractionCtrl } from './types';
|
|
2
|
+
import { getTransition } from './getTransition';
|
|
3
|
+
import { getStyleKeysFromCSSProperty } from '../ItemGeometry/CSSPropertyNameMap';
|
|
4
|
+
import { InteractionItemTrigger } from '@cntrl-site/sdk';
|
|
5
|
+
|
|
6
|
+
export class ItemInteractionController implements ItemInteractionCtrl {
|
|
7
|
+
private transitionsInProgress: Set<string> = new Set();
|
|
8
|
+
private actionReceiver: ((type: 'play' | 'pause') => void) | undefined;
|
|
9
|
+
|
|
10
|
+
constructor(
|
|
11
|
+
private itemId: string,
|
|
12
|
+
private registry: InteractionsRegistryPort,
|
|
13
|
+
private onChange: () => void,
|
|
14
|
+
) {
|
|
15
|
+
this.registry.register(itemId, this);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
getState<T>(keys: string[]) {
|
|
19
|
+
const stateProps = this.registry.getStatePropsForItem(this.itemId);
|
|
20
|
+
const styles = keys.reduce<Record<string, T>>((map, styleKey) => {
|
|
21
|
+
const prop = stateProps[styleKey];
|
|
22
|
+
if (prop?.value === undefined) return map;
|
|
23
|
+
map[styleKey] = prop.value as T;
|
|
24
|
+
return map;
|
|
25
|
+
}, {});
|
|
26
|
+
const transition = getTransition(stateProps, keys);
|
|
27
|
+
return {
|
|
28
|
+
styles,
|
|
29
|
+
transition
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
getHasTrigger(itemId: string, triggerType: InteractionItemTrigger['triggerEvent']): boolean {
|
|
34
|
+
const triggers = this.registry.getItemAvailableTriggers(itemId);
|
|
35
|
+
return triggers.has(triggerType);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
sendTrigger(type: 'click' | 'hover-in' | 'hover-out') {
|
|
39
|
+
this.registry.notifyItemTrigger(this.itemId, type);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
receiveAction(type: 'play' | 'pause') {
|
|
43
|
+
this.actionReceiver?.(type);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
setActionReceiver(action: (type: 'play' | 'pause') => void) {
|
|
47
|
+
this.actionReceiver = action;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
handleTransitionStart = (types: string[]) => {
|
|
51
|
+
this.transitionsInProgress.clear();
|
|
52
|
+
for (const type of types) {
|
|
53
|
+
this.transitionsInProgress.add(type);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
handleTransitionEnd = (cssPropKey: string) => {
|
|
58
|
+
if (cssPropKey.startsWith('border-') && cssPropKey.endsWith('-radius')) {
|
|
59
|
+
cssPropKey = 'border-radius';
|
|
60
|
+
}
|
|
61
|
+
if (cssPropKey.startsWith('border-') && cssPropKey.endsWith('-width')) {
|
|
62
|
+
cssPropKey = 'border-width';
|
|
63
|
+
}
|
|
64
|
+
const styleKeys = getStyleKeysFromCSSProperty(cssPropKey);
|
|
65
|
+
for (const key of styleKeys) {
|
|
66
|
+
const found = this.transitionsInProgress.has(key);
|
|
67
|
+
if (!found) continue;
|
|
68
|
+
this.transitionsInProgress.delete(key);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
if (this.transitionsInProgress.size !== 0) return;
|
|
72
|
+
this.registry.notifyTransitionEnd(this.itemId);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
receiveChange() {
|
|
76
|
+
this.onChange();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { CSSPropertyNameMap } from '../ItemGeometry/CSSPropertyNameMap';
|
|
2
|
-
|
|
3
|
-
export function getTransition(
|
|
4
|
-
state: Record<string, StateInfo>,
|
|
5
|
-
keys: string[]
|
|
6
|
-
): string {
|
|
7
|
-
if (Object.keys(state).length === 0) return 'none';
|
|
8
|
-
const transitions = [];
|
|
9
|
-
for (const [key, params] of Object.entries(state)) {
|
|
10
|
-
if (!keys.includes(key) || !params.transition) continue;
|
|
11
|
-
const { transition: { duration, delay, timing } } = params;
|
|
12
|
-
const cssKey = CSSPropertyNameMap[key]!;
|
|
13
|
-
const nonZeroDuration = Math.max(duration, 0.01);
|
|
14
|
-
transitions.push(`${cssKey} ${nonZeroDuration}ms ${timing} ${delay}ms`);
|
|
15
|
-
}
|
|
16
|
-
return transitions.length > 0
|
|
17
|
-
? transitions.join(', ')
|
|
18
|
-
: 'none';
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
type StateInfo = {
|
|
22
|
-
transition?: {
|
|
23
|
-
duration: number;
|
|
24
|
-
delay: number;
|
|
25
|
-
timing: string;
|
|
26
|
-
};
|
|
27
|
-
};
|
|
1
|
+
import { CSSPropertyNameMap } from '../ItemGeometry/CSSPropertyNameMap';
|
|
2
|
+
|
|
3
|
+
export function getTransition(
|
|
4
|
+
state: Record<string, StateInfo>,
|
|
5
|
+
keys: string[]
|
|
6
|
+
): string {
|
|
7
|
+
if (Object.keys(state).length === 0) return 'none';
|
|
8
|
+
const transitions = [];
|
|
9
|
+
for (const [key, params] of Object.entries(state)) {
|
|
10
|
+
if (!keys.includes(key) || !params.transition) continue;
|
|
11
|
+
const { transition: { duration, delay, timing } } = params;
|
|
12
|
+
const cssKey = CSSPropertyNameMap[key]!;
|
|
13
|
+
const nonZeroDuration = Math.max(duration, 0.01);
|
|
14
|
+
transitions.push(`${cssKey} ${nonZeroDuration}ms ${timing} ${delay}ms`);
|
|
15
|
+
}
|
|
16
|
+
return transitions.length > 0
|
|
17
|
+
? transitions.join(', ')
|
|
18
|
+
: 'none';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type StateInfo = {
|
|
22
|
+
transition?: {
|
|
23
|
+
duration: number;
|
|
24
|
+
delay: number;
|
|
25
|
+
timing: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import { ArticleItemType, FillLayer, InteractionItemTrigger, ItemState } from '@cntrl-site/sdk';
|
|
2
|
-
|
|
3
|
-
export interface ItemInteractionCtrl {
|
|
4
|
-
getState<T>(keys: string[]): StateCSSInfo<T>;
|
|
5
|
-
getHasTrigger(itemId: string, triggerType: InteractionItemTrigger['triggerEvent']): boolean;
|
|
6
|
-
sendTrigger(type: 'click' | 'hover-in' | 'hover-out'): void;
|
|
7
|
-
handleTransitionEnd?: (styleKey: string) => void;
|
|
8
|
-
handleTransitionStart?: (styleKeys: string[]) => void;
|
|
9
|
-
receiveChange: () => void;
|
|
10
|
-
receiveAction: (type: 'play' | 'pause') => void;
|
|
11
|
-
setActionReceiver: (action: (type: 'play' | 'pause') => void) => void;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface InteractionsRegistryPort {
|
|
15
|
-
register(itemId: string, ctrl: ItemInteractionCtrl): void;
|
|
16
|
-
getStatePropsForItem(itemId: string): StateProps<unknown>;
|
|
17
|
-
getItemAvailableTriggers(itemId: string): Set<InteractionItemTrigger['triggerEvent']>;
|
|
18
|
-
notifyItemTrigger(itemId: string, type: TriggerType): void;
|
|
19
|
-
notifyTransitionEnd(itemId: string): void;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
type StateCSSInfo<T> = {
|
|
23
|
-
styles: Partial<Record<string, T>>;
|
|
24
|
-
transition?: string;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
type StateProps<T> = Record<keyof ItemState<ArticleItemType>, {
|
|
28
|
-
value?: T;
|
|
29
|
-
transition?: {
|
|
30
|
-
timing: string;
|
|
31
|
-
duration: number;
|
|
32
|
-
delay: number;
|
|
33
|
-
};
|
|
34
|
-
}>;
|
|
35
|
-
|
|
36
|
-
type TriggerType = 'click' | 'hover-in' | 'hover-out';
|
|
1
|
+
import { ArticleItemType, FillLayer, InteractionItemTrigger, ItemState } from '@cntrl-site/sdk';
|
|
2
|
+
|
|
3
|
+
export interface ItemInteractionCtrl {
|
|
4
|
+
getState<T>(keys: string[]): StateCSSInfo<T>;
|
|
5
|
+
getHasTrigger(itemId: string, triggerType: InteractionItemTrigger['triggerEvent']): boolean;
|
|
6
|
+
sendTrigger(type: 'click' | 'hover-in' | 'hover-out'): void;
|
|
7
|
+
handleTransitionEnd?: (styleKey: string) => void;
|
|
8
|
+
handleTransitionStart?: (styleKeys: string[]) => void;
|
|
9
|
+
receiveChange: () => void;
|
|
10
|
+
receiveAction: (type: 'play' | 'pause') => void;
|
|
11
|
+
setActionReceiver: (action: (type: 'play' | 'pause') => void) => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface InteractionsRegistryPort {
|
|
15
|
+
register(itemId: string, ctrl: ItemInteractionCtrl): void;
|
|
16
|
+
getStatePropsForItem(itemId: string): StateProps<unknown>;
|
|
17
|
+
getItemAvailableTriggers(itemId: string): Set<InteractionItemTrigger['triggerEvent']>;
|
|
18
|
+
notifyItemTrigger(itemId: string, type: TriggerType): void;
|
|
19
|
+
notifyTransitionEnd(itemId: string): void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type StateCSSInfo<T> = {
|
|
23
|
+
styles: Partial<Record<string, T>>;
|
|
24
|
+
transition?: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
type StateProps<T> = Record<keyof ItemState<ArticleItemType>, {
|
|
28
|
+
value?: T;
|
|
29
|
+
transition?: {
|
|
30
|
+
timing: string;
|
|
31
|
+
duration: number;
|
|
32
|
+
delay: number;
|
|
33
|
+
};
|
|
34
|
+
}>;
|
|
35
|
+
|
|
36
|
+
type TriggerType = 'click' | 'hover-in' | 'hover-out';
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { useMemo, useState } from 'react';
|
|
2
|
-
import { ItemInteractionController } from './ItemInteractionCtrl';
|
|
3
|
-
import { ItemInteractionCtrl } from './types';
|
|
4
|
-
import { useInteractionsRegistry } from '../provider/InteractionsContext';
|
|
5
|
-
|
|
6
|
-
export function useItemInteractionCtrl(itemId: string): ItemInteractionCtrl | undefined {
|
|
7
|
-
const [_, triggerRender] = useState(0);
|
|
8
|
-
const registry = useInteractionsRegistry();
|
|
9
|
-
const ctrl = useMemo(() => {
|
|
10
|
-
if (!registry) return;
|
|
11
|
-
return new ItemInteractionController(
|
|
12
|
-
itemId,
|
|
13
|
-
registry,
|
|
14
|
-
() => triggerRender(prev => prev + 1)
|
|
15
|
-
);
|
|
16
|
-
}, [itemId, registry]);
|
|
17
|
-
return ctrl;
|
|
18
|
-
}
|
|
1
|
+
import { useMemo, useState } from 'react';
|
|
2
|
+
import { ItemInteractionController } from './ItemInteractionCtrl';
|
|
3
|
+
import { ItemInteractionCtrl } from './types';
|
|
4
|
+
import { useInteractionsRegistry } from '../provider/InteractionsContext';
|
|
5
|
+
|
|
6
|
+
export function useItemInteractionCtrl(itemId: string): ItemInteractionCtrl | undefined {
|
|
7
|
+
const [_, triggerRender] = useState(0);
|
|
8
|
+
const registry = useInteractionsRegistry();
|
|
9
|
+
const ctrl = useMemo(() => {
|
|
10
|
+
if (!registry) return;
|
|
11
|
+
return new ItemInteractionController(
|
|
12
|
+
itemId,
|
|
13
|
+
registry,
|
|
14
|
+
() => triggerRender(prev => prev + 1)
|
|
15
|
+
);
|
|
16
|
+
}, [itemId, registry]);
|
|
17
|
+
return ctrl;
|
|
18
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createContext } from 'react';
|
|
2
|
-
import { ArticleRectObserver } from '../utils/ArticleRectManager/ArticleRectObserver';
|
|
3
|
-
|
|
4
|
-
export const ArticleRectContext = createContext<ArticleRectObserver | null>(null);
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
import { ArticleRectObserver } from '../utils/ArticleRectManager/ArticleRectObserver';
|
|
3
|
+
|
|
4
|
+
export const ArticleRectContext = createContext<ArticleRectObserver | null>(null);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createContext } from 'react';
|
|
2
|
-
import { CntrlSdkContext } from './CntrlSdkContext';
|
|
3
|
-
import { cntrlSdkContext } from './defaultContext';
|
|
4
|
-
|
|
5
|
-
export const CntrlContext = createContext<CntrlSdkContext>(cntrlSdkContext);
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
import { CntrlSdkContext } from './CntrlSdkContext';
|
|
3
|
+
import { cntrlSdkContext } from './defaultContext';
|
|
4
|
+
|
|
5
|
+
export const CntrlContext = createContext<CntrlSdkContext>(cntrlSdkContext);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { FC, PropsWithChildren } from 'react';
|
|
2
|
-
import { CntrlContext } from './CntrlContext';
|
|
3
|
-
import { cntrlSdkContext } from './defaultContext';
|
|
4
|
-
|
|
5
|
-
export const CntrlProvider: FC<PropsWithChildren<{}>> = ({ children }) => {
|
|
6
|
-
return (
|
|
7
|
-
<CntrlContext.Provider value={cntrlSdkContext}>
|
|
8
|
-
{children}
|
|
9
|
-
</CntrlContext.Provider>
|
|
10
|
-
);
|
|
11
|
-
};
|
|
1
|
+
import { FC, PropsWithChildren } from 'react';
|
|
2
|
+
import { CntrlContext } from './CntrlContext';
|
|
3
|
+
import { cntrlSdkContext } from './defaultContext';
|
|
4
|
+
|
|
5
|
+
export const CntrlProvider: FC<PropsWithChildren<{}>> = ({ children }) => {
|
|
6
|
+
return (
|
|
7
|
+
<CntrlContext.Provider value={cntrlSdkContext}>
|
|
8
|
+
{children}
|
|
9
|
+
</CntrlContext.Provider>
|
|
10
|
+
);
|
|
11
|
+
};
|
|
@@ -1,113 +1,113 @@
|
|
|
1
|
-
import { CustomItemRegistry } from './CustomItemRegistry';
|
|
2
|
-
import { Article, Section, Layout, Project, SectionHeight } from '@cntrl-site/sdk';
|
|
3
|
-
import { components, Component as TComponent } from '@cntrl-site/components';
|
|
4
|
-
import { CustomSectionRegistry } from './CustomSectionRegistry';
|
|
5
|
-
|
|
6
|
-
interface SdkContextInitProps {
|
|
7
|
-
project: Project;
|
|
8
|
-
article: Article;
|
|
9
|
-
publicApiBase?: string;
|
|
10
|
-
customComponents?: Map<string, TComponent>;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export class CntrlSdkContext {
|
|
14
|
-
private _layouts: Layout[] = [];
|
|
15
|
-
private _fonts?: Project['fonts'] = undefined;
|
|
16
|
-
private _projectId?: string = undefined;
|
|
17
|
-
private _publicApiBase?: string = undefined;
|
|
18
|
-
private sectionHeightMap: Map<string, Record<string, SectionHeight>> = new Map();
|
|
19
|
-
private components: Map<string, TComponent> = new Map();
|
|
20
|
-
|
|
21
|
-
constructor(
|
|
22
|
-
public readonly customItems: CustomItemRegistry,
|
|
23
|
-
public readonly customSections: CustomSectionRegistry
|
|
24
|
-
) {}
|
|
25
|
-
|
|
26
|
-
async resolveSectionData(sections: Section[]): Promise<Record<string, any>> {
|
|
27
|
-
const resolvers = sections.map(section => {
|
|
28
|
-
const resolver = section.name ? this.customSections.getResolver(section.name) : undefined;
|
|
29
|
-
if (!resolver) return undefined;
|
|
30
|
-
return {
|
|
31
|
-
name: section.name,
|
|
32
|
-
resolver
|
|
33
|
-
};
|
|
34
|
-
}).filter(isDefined);
|
|
35
|
-
return Object.fromEntries(
|
|
36
|
-
await Promise.all(resolvers.map(async ({ name, resolver }) => [name, await resolver()]))
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
init({ project, article, publicApiBase, customComponents }: SdkContextInitProps) {
|
|
41
|
-
this._projectId = project.id;
|
|
42
|
-
if (publicApiBase) {
|
|
43
|
-
this._publicApiBase = publicApiBase;
|
|
44
|
-
}
|
|
45
|
-
this.setLayouts(project.layouts);
|
|
46
|
-
this.setComponents(components);
|
|
47
|
-
if (customComponents) {
|
|
48
|
-
this.setCustomComponents(customComponents);
|
|
49
|
-
}
|
|
50
|
-
this.setFonts(project.fonts);
|
|
51
|
-
this.setSectionsHeight(article.sections);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
setPublicApiBase(url: string) {
|
|
55
|
-
this._publicApiBase = url;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
get projectId(): string | undefined {
|
|
59
|
-
return this._projectId;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
getSubmitUrl(pluginConfigId: string | undefined): string | undefined {
|
|
63
|
-
if (!this._publicApiBase || !this._projectId || !pluginConfigId) return undefined;
|
|
64
|
-
return `${this._publicApiBase}/projects/${this._projectId}/forms/${pluginConfigId}/submit`;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
setLayouts(layouts: Layout[]) {
|
|
68
|
-
this._layouts = layouts;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
private setComponents(components: TComponent[]) {
|
|
72
|
-
for (const component of components) {
|
|
73
|
-
this.components.set(component.id, component);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
setCustomComponents(customComponents: Map<string, TComponent>) {
|
|
78
|
-
for (const [id, component] of customComponents) {
|
|
79
|
-
this.components.set(id, component);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
private setFonts(fonts: Project['fonts']) {
|
|
84
|
-
this._fonts = fonts;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
setSectionsHeight(sections: Section[]) {
|
|
88
|
-
for (const section of sections) {
|
|
89
|
-
this.sectionHeightMap.set(section.id, section.minHeight);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
getSectionHeightData(sectionId: string) {
|
|
94
|
-
const sectionHeightData = this.sectionHeightMap.get(sectionId);
|
|
95
|
-
return sectionHeightData;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
get layouts(): Layout[] {
|
|
99
|
-
return this._layouts;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
get fonts(): Project['fonts'] | undefined {
|
|
103
|
-
return this._fonts;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
getComponent(id: string): TComponent | undefined {
|
|
107
|
-
return this.components.get(id);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function isDefined<T>(value: T): value is Exclude<T, undefined> {
|
|
112
|
-
return value !== undefined;
|
|
113
|
-
}
|
|
1
|
+
import { CustomItemRegistry } from './CustomItemRegistry';
|
|
2
|
+
import { Article, Section, Layout, Project, SectionHeight } from '@cntrl-site/sdk';
|
|
3
|
+
import { components, Component as TComponent } from '@cntrl-site/components';
|
|
4
|
+
import { CustomSectionRegistry } from './CustomSectionRegistry';
|
|
5
|
+
|
|
6
|
+
interface SdkContextInitProps {
|
|
7
|
+
project: Project;
|
|
8
|
+
article: Article;
|
|
9
|
+
publicApiBase?: string;
|
|
10
|
+
customComponents?: Map<string, TComponent>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class CntrlSdkContext {
|
|
14
|
+
private _layouts: Layout[] = [];
|
|
15
|
+
private _fonts?: Project['fonts'] = undefined;
|
|
16
|
+
private _projectId?: string = undefined;
|
|
17
|
+
private _publicApiBase?: string = undefined;
|
|
18
|
+
private sectionHeightMap: Map<string, Record<string, SectionHeight>> = new Map();
|
|
19
|
+
private components: Map<string, TComponent> = new Map();
|
|
20
|
+
|
|
21
|
+
constructor(
|
|
22
|
+
public readonly customItems: CustomItemRegistry,
|
|
23
|
+
public readonly customSections: CustomSectionRegistry
|
|
24
|
+
) {}
|
|
25
|
+
|
|
26
|
+
async resolveSectionData(sections: Section[]): Promise<Record<string, any>> {
|
|
27
|
+
const resolvers = sections.map(section => {
|
|
28
|
+
const resolver = section.name ? this.customSections.getResolver(section.name) : undefined;
|
|
29
|
+
if (!resolver) return undefined;
|
|
30
|
+
return {
|
|
31
|
+
name: section.name,
|
|
32
|
+
resolver
|
|
33
|
+
};
|
|
34
|
+
}).filter(isDefined);
|
|
35
|
+
return Object.fromEntries(
|
|
36
|
+
await Promise.all(resolvers.map(async ({ name, resolver }) => [name, await resolver()]))
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
init({ project, article, publicApiBase, customComponents }: SdkContextInitProps) {
|
|
41
|
+
this._projectId = project.id;
|
|
42
|
+
if (publicApiBase) {
|
|
43
|
+
this._publicApiBase = publicApiBase;
|
|
44
|
+
}
|
|
45
|
+
this.setLayouts(project.layouts);
|
|
46
|
+
this.setComponents(components);
|
|
47
|
+
if (customComponents) {
|
|
48
|
+
this.setCustomComponents(customComponents);
|
|
49
|
+
}
|
|
50
|
+
this.setFonts(project.fonts);
|
|
51
|
+
this.setSectionsHeight(article.sections);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
setPublicApiBase(url: string) {
|
|
55
|
+
this._publicApiBase = url;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get projectId(): string | undefined {
|
|
59
|
+
return this._projectId;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
getSubmitUrl(pluginConfigId: string | undefined): string | undefined {
|
|
63
|
+
if (!this._publicApiBase || !this._projectId || !pluginConfigId) return undefined;
|
|
64
|
+
return `${this._publicApiBase}/projects/${this._projectId}/forms/${pluginConfigId}/submit`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
setLayouts(layouts: Layout[]) {
|
|
68
|
+
this._layouts = layouts;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private setComponents(components: TComponent[]) {
|
|
72
|
+
for (const component of components) {
|
|
73
|
+
this.components.set(component.id, component);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
setCustomComponents(customComponents: Map<string, TComponent>) {
|
|
78
|
+
for (const [id, component] of customComponents) {
|
|
79
|
+
this.components.set(id, component);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private setFonts(fonts: Project['fonts']) {
|
|
84
|
+
this._fonts = fonts;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
setSectionsHeight(sections: Section[]) {
|
|
88
|
+
for (const section of sections) {
|
|
89
|
+
this.sectionHeightMap.set(section.id, section.minHeight);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
getSectionHeightData(sectionId: string) {
|
|
94
|
+
const sectionHeightData = this.sectionHeightMap.get(sectionId);
|
|
95
|
+
return sectionHeightData;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
get layouts(): Layout[] {
|
|
99
|
+
return this._layouts;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
get fonts(): Project['fonts'] | undefined {
|
|
103
|
+
return this._fonts;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
getComponent(id: string): TComponent | undefined {
|
|
107
|
+
return this.components.get(id);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function isDefined<T>(value: T): value is Exclude<T, undefined> {
|
|
112
|
+
return value !== undefined;
|
|
113
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { CustomItemComponent } from './CustomItemTypes';
|
|
2
|
-
|
|
3
|
-
export class CustomItemRegistry {
|
|
4
|
-
private definitions: Map<string, CustomItemComponent<string>> = new Map();
|
|
5
|
-
|
|
6
|
-
define<T extends string>(type: T, component: CustomItemComponent<T>): this {
|
|
7
|
-
this.definitions.set(type, component);
|
|
8
|
-
return this;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
get(type: string): CustomItemComponent<string> | undefined {
|
|
12
|
-
return this.definitions.get(type);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
1
|
+
import { CustomItemComponent } from './CustomItemTypes';
|
|
2
|
+
|
|
3
|
+
export class CustomItemRegistry {
|
|
4
|
+
private definitions: Map<string, CustomItemComponent<string>> = new Map();
|
|
5
|
+
|
|
6
|
+
define<T extends string>(type: T, component: CustomItemComponent<T>): this {
|
|
7
|
+
this.definitions.set(type, component);
|
|
8
|
+
return this;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
get(type: string): CustomItemComponent<string> | undefined {
|
|
12
|
+
return this.definitions.get(type);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { FC } from 'react';
|
|
2
|
-
|
|
3
|
-
export type CustomItemComponent<T extends string> = FC<{}>;
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
|
|
3
|
+
export type CustomItemComponent<T extends string> = FC<{}>;
|