@cntrl-site/sdk-nextjs 1.8.9-alpha.1 → 1.8.9-alpha.10
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/lib/components/items/LinkWrapper.js +9 -1
- package/lib/interactions/InteractionsRegistry.js +2 -53
- package/lib/interactions/ItemInteractionCtrl.js +1 -1
- package/lib/provider/InteractionsContext.js +0 -10
- package/package.json +2 -2
- package/src/components/items/LinkWrapper.tsx +11 -1
- package/src/interactions/InteractionsRegistry.ts +6 -52
- package/src/interactions/ItemInteractionCtrl.ts +3 -4
- package/src/interactions/types.ts +4 -4
- package/src/provider/InteractionsContext.tsx +1 -12
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/.idea/modules.xml +0 -8
- package/.idea/sdk-nextjs.iml +0 -12
- package/.idea/vcs.xml +0 -6
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LinkWrapper = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || '';
|
|
5
6
|
const LinkWrapper = ({ url, children, target }) => {
|
|
6
|
-
const validUrl = url && buildValidUrl(url);
|
|
7
|
+
const validUrl = url && prependBasePath(buildValidUrl(url));
|
|
7
8
|
const targetParams = target === '_blank' ? { target, rel: 'noreferrer' } : {};
|
|
8
9
|
return url ? ((0, jsx_runtime_1.jsx)("a", Object.assign({ href: validUrl }, targetParams, { children: children }))) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children }));
|
|
9
10
|
};
|
|
@@ -25,3 +26,10 @@ function buildValidUrl(url) {
|
|
|
25
26
|
return url;
|
|
26
27
|
return `//${url}`;
|
|
27
28
|
}
|
|
29
|
+
function prependBasePath(url) {
|
|
30
|
+
// Only prepend for internal links (starting with '/')
|
|
31
|
+
if (url && url.startsWith('/') && basePath && !url.startsWith(basePath)) {
|
|
32
|
+
return `${basePath}${url}`;
|
|
33
|
+
}
|
|
34
|
+
return url;
|
|
35
|
+
}
|
|
@@ -93,8 +93,6 @@ class InteractionsRegistry {
|
|
|
93
93
|
for (const interaction of this.interactions) {
|
|
94
94
|
const { triggers } = interaction;
|
|
95
95
|
for (const trigger of triggers) {
|
|
96
|
-
if (!('itemId' in trigger))
|
|
97
|
-
continue;
|
|
98
96
|
if (trigger.itemId !== itemId)
|
|
99
97
|
continue;
|
|
100
98
|
if (activeStates.includes(trigger.from)) {
|
|
@@ -104,59 +102,12 @@ class InteractionsRegistry {
|
|
|
104
102
|
}
|
|
105
103
|
return available;
|
|
106
104
|
}
|
|
107
|
-
|
|
108
|
-
var _a, _b;
|
|
109
|
-
const timestamp = Date.now();
|
|
110
|
-
for (const interaction of this.interactions) {
|
|
111
|
-
const currentStateId = this.getCurrentStateByInteractionId(interaction.id);
|
|
112
|
-
const matchingTrigger = interaction.triggers.find((trigger) => 'position' in trigger && (trigger.position < position ? trigger.from : trigger.to) === currentStateId // refactor
|
|
113
|
-
);
|
|
114
|
-
if (!matchingTrigger || !('position' in matchingTrigger))
|
|
115
|
-
continue;
|
|
116
|
-
const activeStateId = this.getActiveInteractionState(interaction.id);
|
|
117
|
-
const targetStateId = matchingTrigger.position > position ? matchingTrigger.from : matchingTrigger.to;
|
|
118
|
-
const isNewStateActive = targetStateId === activeStateId;
|
|
119
|
-
this.setCurrentStateForInteraction(interaction.id, targetStateId !== null && targetStateId !== void 0 ? targetStateId : activeStateId);
|
|
120
|
-
const transitioningItems = (_a = this.stateItemsIdsMap[activeStateId]) !== null && _a !== void 0 ? _a : [];
|
|
121
|
-
const state = interaction.states.find((state) => state.id === targetStateId);
|
|
122
|
-
const actions = (_b = state === null || state === void 0 ? void 0 : state.actions) !== null && _b !== void 0 ? _b : [];
|
|
123
|
-
for (const action of actions) {
|
|
124
|
-
const ctrl = this.ctrls.get(action.itemId);
|
|
125
|
-
if (!ctrl)
|
|
126
|
-
continue;
|
|
127
|
-
ctrl.receiveAction(action.type);
|
|
128
|
-
}
|
|
129
|
-
const itemsStages = this.itemsStages.map((stage) => {
|
|
130
|
-
if (stage.interactionId !== interaction.id)
|
|
131
|
-
return stage;
|
|
132
|
-
return {
|
|
133
|
-
itemId: stage.itemId,
|
|
134
|
-
interactionId: stage.interactionId,
|
|
135
|
-
type: 'transitioning',
|
|
136
|
-
from: stage.type === 'transitioning' ? stage.to : stage.stateId,
|
|
137
|
-
to: targetStateId,
|
|
138
|
-
direction: isNewStateActive ? 'in' : 'out',
|
|
139
|
-
updated: timestamp
|
|
140
|
-
};
|
|
141
|
-
});
|
|
142
|
-
this.itemsStages = itemsStages;
|
|
143
|
-
const itemsToNotify = new Set(transitioningItems);
|
|
144
|
-
for (const trigger of interaction.triggers) {
|
|
145
|
-
if (!('itemId' in trigger))
|
|
146
|
-
continue;
|
|
147
|
-
itemsToNotify.add(trigger.itemId);
|
|
148
|
-
}
|
|
149
|
-
this.notifyItemCtrlsChange(Array.from(itemsToNotify));
|
|
150
|
-
this.notifyTransitionStartForItems(transitioningItems, activeStateId);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
notifyItemTrigger(itemId, triggerType) {
|
|
105
|
+
notifyTrigger(itemId, triggerType) {
|
|
154
106
|
var _a, _b;
|
|
155
107
|
const timestamp = Date.now();
|
|
156
108
|
for (const interaction of this.interactions) {
|
|
157
109
|
const currentStateId = this.getCurrentStateByInteractionId(interaction.id);
|
|
158
|
-
const matchingTrigger = interaction.triggers.find((trigger) =>
|
|
159
|
-
&& trigger.itemId === itemId
|
|
110
|
+
const matchingTrigger = interaction.triggers.find((trigger) => trigger.itemId === itemId
|
|
160
111
|
&& trigger.from === currentStateId
|
|
161
112
|
&& trigger.type === triggerType);
|
|
162
113
|
if (!matchingTrigger)
|
|
@@ -188,8 +139,6 @@ class InteractionsRegistry {
|
|
|
188
139
|
});
|
|
189
140
|
const itemsToNotify = new Set(transitioningItems);
|
|
190
141
|
for (const trigger of interaction.triggers) {
|
|
191
|
-
if (!('itemId' in trigger))
|
|
192
|
-
continue;
|
|
193
142
|
itemsToNotify.add(trigger.itemId);
|
|
194
143
|
}
|
|
195
144
|
this.notifyItemCtrlsChange(Array.from(itemsToNotify));
|
|
@@ -13,16 +13,6 @@ const InteractionsProvider = ({ article, children }) => {
|
|
|
13
13
|
return;
|
|
14
14
|
return new InteractionsRegistry_1.InteractionsRegistry(article, layoutId);
|
|
15
15
|
}, [layoutId]);
|
|
16
|
-
(0, react_1.useEffect)(() => {
|
|
17
|
-
if (!registry)
|
|
18
|
-
return;
|
|
19
|
-
const handleScroll = () => {
|
|
20
|
-
const scrollY = window.scrollY;
|
|
21
|
-
registry.notifyScrollTrigger(scrollY);
|
|
22
|
-
};
|
|
23
|
-
window.addEventListener('scroll', handleScroll, { passive: true });
|
|
24
|
-
return () => window.removeEventListener('scroll', handleScroll);
|
|
25
|
-
}, [registry]);
|
|
26
16
|
return ((0, jsx_runtime_1.jsx)(exports.InteractionsContext.Provider, { value: registry, children: children }));
|
|
27
17
|
};
|
|
28
18
|
exports.InteractionsProvider = InteractionsProvider;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cntrl-site/sdk-nextjs",
|
|
3
|
-
"version": "1.8.9-alpha.
|
|
3
|
+
"version": "1.8.9-alpha.10",
|
|
4
4
|
"description": "SDK for Next.js",
|
|
5
5
|
"author": "arsen@momdesign.nyc",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@antfu/eslint-config": "^3.8.0",
|
|
32
32
|
"@cntrl-site/color": "^1.0.0",
|
|
33
33
|
"@cntrl-site/effects": "^1.3.2",
|
|
34
|
-
"@cntrl-site/sdk": "^1.22.
|
|
34
|
+
"@cntrl-site/sdk": "^1.22.8",
|
|
35
35
|
"@types/vimeo__player": "^2.18.0",
|
|
36
36
|
"@vimeo/player": "^2.25.0",
|
|
37
37
|
"html-react-parser": "^3.0.1",
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React, { ReactElement, ReactNode } from 'react';
|
|
2
2
|
|
|
3
|
+
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || '';
|
|
4
|
+
|
|
3
5
|
interface Props {
|
|
4
6
|
url?: string;
|
|
5
7
|
children: ReactElement | ReactNode[];
|
|
@@ -7,7 +9,7 @@ interface Props {
|
|
|
7
9
|
}
|
|
8
10
|
|
|
9
11
|
export const LinkWrapper: React.FC<Props> = ({ url, children, target }) => {
|
|
10
|
-
const validUrl = url && buildValidUrl(url);
|
|
12
|
+
const validUrl = url && prependBasePath(buildValidUrl(url));
|
|
11
13
|
const targetParams = target === '_blank' ? { target, rel: 'noreferrer' } : {};
|
|
12
14
|
return url ? (
|
|
13
15
|
<a
|
|
@@ -37,3 +39,11 @@ function buildValidUrl(url: string): string {
|
|
|
37
39
|
if (protocolCheck) return url;
|
|
38
40
|
return `//${url}`;
|
|
39
41
|
}
|
|
42
|
+
|
|
43
|
+
function prependBasePath(url: string): string {
|
|
44
|
+
// Only prepend for internal links (starting with '/')
|
|
45
|
+
if (url && url.startsWith('/') && basePath && !url.startsWith(basePath)) {
|
|
46
|
+
return `${basePath}${url}`;
|
|
47
|
+
}
|
|
48
|
+
return url;
|
|
49
|
+
}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
Article,
|
|
4
4
|
ArticleItemType,
|
|
5
5
|
Interaction,
|
|
6
|
-
|
|
6
|
+
InteractionTrigger,
|
|
7
7
|
ItemAny,
|
|
8
8
|
} from '@cntrl-site/sdk';
|
|
9
9
|
import { isItemType } from '../utils/isItemType';
|
|
@@ -96,13 +96,12 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
|
|
|
96
96
|
return itemStyles;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
getItemAvailableTriggers(itemId: string): Set<
|
|
100
|
-
const available = new Set<
|
|
99
|
+
getItemAvailableTriggers(itemId: string): Set<InteractionTrigger['type']> {
|
|
100
|
+
const available = new Set<InteractionTrigger['type']>();
|
|
101
101
|
const activeStates = Object.values(this.interactionStateMap);
|
|
102
102
|
for (const interaction of this.interactions) {
|
|
103
103
|
const { triggers } = interaction;
|
|
104
104
|
for (const trigger of triggers) {
|
|
105
|
-
if (!('itemId' in trigger)) continue;
|
|
106
105
|
if (trigger.itemId !== itemId) continue;
|
|
107
106
|
if (activeStates.includes(trigger.from)) {
|
|
108
107
|
available.add(trigger.type);
|
|
@@ -112,56 +111,12 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
|
|
|
112
111
|
return available;
|
|
113
112
|
}
|
|
114
113
|
|
|
115
|
-
|
|
114
|
+
notifyTrigger(itemId: string, triggerType: TriggerType): void {
|
|
116
115
|
const timestamp = Date.now();
|
|
117
116
|
for (const interaction of this.interactions) {
|
|
118
117
|
const currentStateId = this.getCurrentStateByInteractionId(interaction.id);
|
|
119
118
|
const matchingTrigger = interaction.triggers.find((trigger) =>
|
|
120
|
-
|
|
121
|
-
);
|
|
122
|
-
if (!matchingTrigger || !('position' in matchingTrigger)) continue;
|
|
123
|
-
const activeStateId = this.getActiveInteractionState(interaction.id);
|
|
124
|
-
const targetStateId = matchingTrigger.position > position ? matchingTrigger.from : matchingTrigger.to;
|
|
125
|
-
const isNewStateActive = targetStateId === activeStateId;
|
|
126
|
-
this.setCurrentStateForInteraction(interaction.id, targetStateId ?? activeStateId);
|
|
127
|
-
const transitioningItems = this.stateItemsIdsMap[activeStateId] ?? [];
|
|
128
|
-
const state = interaction.states.find((state) => state.id === targetStateId);
|
|
129
|
-
const actions = state?.actions ?? [];
|
|
130
|
-
for (const action of actions) {
|
|
131
|
-
const ctrl = this.ctrls.get(action.itemId);
|
|
132
|
-
if (!ctrl) continue;
|
|
133
|
-
ctrl.receiveAction(action.type);
|
|
134
|
-
}
|
|
135
|
-
const itemsStages = this.itemsStages.map((stage) => {
|
|
136
|
-
if (stage.interactionId !== interaction.id) return stage;
|
|
137
|
-
return {
|
|
138
|
-
itemId: stage.itemId,
|
|
139
|
-
interactionId: stage.interactionId,
|
|
140
|
-
type: 'transitioning' as const,
|
|
141
|
-
from: stage.type === 'transitioning' ? stage.to : stage.stateId!,
|
|
142
|
-
to: targetStateId,
|
|
143
|
-
direction: isNewStateActive ? 'in' as const : 'out' as const,
|
|
144
|
-
updated: timestamp
|
|
145
|
-
};
|
|
146
|
-
});
|
|
147
|
-
this.itemsStages = itemsStages;
|
|
148
|
-
const itemsToNotify = new Set<ItemId>(transitioningItems);
|
|
149
|
-
for (const trigger of interaction.triggers) {
|
|
150
|
-
if (!('itemId' in trigger)) continue;
|
|
151
|
-
itemsToNotify.add(trigger.itemId);
|
|
152
|
-
}
|
|
153
|
-
this.notifyItemCtrlsChange(Array.from(itemsToNotify));
|
|
154
|
-
this.notifyTransitionStartForItems(transitioningItems, activeStateId);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
notifyItemTrigger(itemId: string, triggerType: TriggerType): void {
|
|
159
|
-
const timestamp = Date.now();
|
|
160
|
-
for (const interaction of this.interactions) {
|
|
161
|
-
const currentStateId = this.getCurrentStateByInteractionId(interaction.id);
|
|
162
|
-
const matchingTrigger = interaction.triggers.find((trigger) =>
|
|
163
|
-
'itemId' in trigger
|
|
164
|
-
&& trigger.itemId === itemId
|
|
119
|
+
trigger.itemId === itemId
|
|
165
120
|
&& trigger.from === currentStateId
|
|
166
121
|
&& trigger.type === triggerType
|
|
167
122
|
);
|
|
@@ -191,7 +146,6 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
|
|
|
191
146
|
});
|
|
192
147
|
const itemsToNotify = new Set<ItemId>(transitioningItems);
|
|
193
148
|
for (const trigger of interaction.triggers) {
|
|
194
|
-
if (!('itemId' in trigger)) continue;
|
|
195
149
|
itemsToNotify.add(trigger.itemId);
|
|
196
150
|
}
|
|
197
151
|
this.notifyItemCtrlsChange(Array.from(itemsToNotify));
|
|
@@ -315,7 +269,7 @@ type TransitioningStage = {
|
|
|
315
269
|
type ActiveStage = { type: 'active'; itemId: string; interactionId: string; stateId?: string; isStartState: boolean; updated: number; };
|
|
316
270
|
type InteractionStateMap = Record<InteractionId, StateId>;
|
|
317
271
|
type StateItemsIdsMap = Record<StateId, ItemId[]>;
|
|
318
|
-
type TriggerType =
|
|
272
|
+
type TriggerType = InteractionTrigger['type'];
|
|
319
273
|
type InteractionId = string;
|
|
320
274
|
type StateId = string;
|
|
321
275
|
type ItemId = string;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { InteractionsRegistryPort, ItemInteractionCtrl } from './types';
|
|
2
2
|
import { getTransition } from './getTransition';
|
|
3
3
|
import { getStyleKeysFromCSSProperty } from './CSSPropertyNameMap';
|
|
4
|
-
import {
|
|
4
|
+
import { InteractionTrigger } from '@cntrl-site/sdk';
|
|
5
5
|
|
|
6
6
|
export class ItemInteractionController implements ItemInteractionCtrl {
|
|
7
7
|
private transitionsInProgress: Set<string> = new Set();
|
|
8
8
|
private actionReceiver: ((type: 'play' | 'pause') => void) | undefined;
|
|
9
|
-
|
|
10
9
|
constructor(
|
|
11
10
|
private itemId: string,
|
|
12
11
|
private registry: InteractionsRegistryPort,
|
|
@@ -30,13 +29,13 @@ export class ItemInteractionController implements ItemInteractionCtrl {
|
|
|
30
29
|
};
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
getHasTrigger(itemId: string, triggerType:
|
|
32
|
+
getHasTrigger(itemId: string, triggerType: InteractionTrigger['type']): boolean {
|
|
34
33
|
const triggers = this.registry.getItemAvailableTriggers(itemId);
|
|
35
34
|
return triggers.has(triggerType);
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
sendTrigger(type: 'click' | 'hover-in' | 'hover-out') {
|
|
39
|
-
this.registry.
|
|
38
|
+
this.registry.notifyTrigger(this.itemId, type);
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
receiveAction(type: 'play' | 'pause') {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ArticleItemType,
|
|
1
|
+
import { ArticleItemType, InteractionTrigger, ItemState } from '@cntrl-site/sdk';
|
|
2
2
|
|
|
3
3
|
export interface ItemInteractionCtrl {
|
|
4
4
|
getState(keys: string[]): StateCSSInfo;
|
|
5
|
-
getHasTrigger(itemId: string, triggerType:
|
|
5
|
+
getHasTrigger(itemId: string, triggerType: InteractionTrigger['type']): boolean;
|
|
6
6
|
sendTrigger(type: 'click' | 'hover-in' | 'hover-out'): void;
|
|
7
7
|
handleTransitionEnd?: (styleKey: string) => void;
|
|
8
8
|
handleTransitionStart?: (styleKeys: string[]) => void;
|
|
@@ -14,8 +14,8 @@ export interface ItemInteractionCtrl {
|
|
|
14
14
|
export interface InteractionsRegistryPort {
|
|
15
15
|
register(itemId: string, ctrl: ItemInteractionCtrl): void;
|
|
16
16
|
getStatePropsForItem(itemId: string): StateProps;
|
|
17
|
-
getItemAvailableTriggers(itemId: string): Set<
|
|
18
|
-
|
|
17
|
+
getItemAvailableTriggers(itemId: string): Set<InteractionTrigger['type']>;
|
|
18
|
+
notifyTrigger(itemId: string, type: TriggerType): void;
|
|
19
19
|
notifyTransitionEnd(itemId: string): void;
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createContext, FC, PropsWithChildren, useContext,
|
|
1
|
+
import { createContext, FC, PropsWithChildren, useContext, useMemo } from 'react';
|
|
2
2
|
import { InteractionsRegistry } from '../interactions/InteractionsRegistry';
|
|
3
3
|
import { Article } from '@cntrl-site/sdk';
|
|
4
4
|
import { useCurrentLayout } from '../common/useCurrentLayout';
|
|
@@ -15,17 +15,6 @@ export const InteractionsProvider: FC<PropsWithChildren<Props>> = ({ article, ch
|
|
|
15
15
|
if (!layoutId) return;
|
|
16
16
|
return new InteractionsRegistry(article, layoutId);
|
|
17
17
|
}, [layoutId]);
|
|
18
|
-
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
if (!registry) return;
|
|
21
|
-
const handleScroll = () => {
|
|
22
|
-
const scrollY = window.scrollY;
|
|
23
|
-
registry.notifyScrollTrigger(scrollY);
|
|
24
|
-
};
|
|
25
|
-
window.addEventListener('scroll', handleScroll, { passive: true });
|
|
26
|
-
return () => window.removeEventListener('scroll', handleScroll);
|
|
27
|
-
}, [registry]);
|
|
28
|
-
|
|
29
18
|
return (
|
|
30
19
|
<InteractionsContext.Provider value={registry}>
|
|
31
20
|
{children}
|
package/.idea/modules.xml
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="ProjectModuleManager">
|
|
4
|
-
<modules>
|
|
5
|
-
<module fileurl="file://$PROJECT_DIR$/.idea/sdk-nextjs.iml" filepath="$PROJECT_DIR$/.idea/sdk-nextjs.iml" />
|
|
6
|
-
</modules>
|
|
7
|
-
</component>
|
|
8
|
-
</project>
|
package/.idea/sdk-nextjs.iml
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<module type="WEB_MODULE" version="4">
|
|
3
|
-
<component name="NewModuleRootManager">
|
|
4
|
-
<content url="file://$MODULE_DIR$">
|
|
5
|
-
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
|
6
|
-
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
|
7
|
-
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
|
8
|
-
</content>
|
|
9
|
-
<orderEntry type="inheritedJdk" />
|
|
10
|
-
<orderEntry type="sourceFolder" forTests="false" />
|
|
11
|
-
</component>
|
|
12
|
-
</module>
|