@cntrl-site/sdk-nextjs 1.0.19-alpha.4 → 1.0.19-alpha.5
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/cntrl-site-sdk-nextjs-1.0.19-alpha.4.tgz +0 -0
- package/cntrl-site-sdk-nextjs-1.0.19-alpha.5.tgz +0 -0
- package/lib/components/Item.js +0 -2
- package/lib/interactions/InteractionsRegistry.js +115 -53
- package/lib/interactions/ItemInteractionCtrl.js +6 -0
- package/package.json +1 -1
- package/src/components/Item.tsx +0 -2
- package/src/interactions/InteractionsRegistry.ts +104 -53
- package/src/interactions/ItemInteractionCtrl.ts +6 -0
|
Binary file
|
|
Binary file
|
package/lib/components/Item.js
CHANGED
|
@@ -67,8 +67,6 @@ const Item = ({ item, sectionId, articleHeight, isInGroup = false }) => {
|
|
|
67
67
|
const [itemHeight, setItemHeight] = (0, react_1.useState)(undefined);
|
|
68
68
|
const itemScale = (0, useItemScale_1.useItemScale)(item, sectionId);
|
|
69
69
|
const interactionCtrl = (0, useItemInteractionCtrl_1.useItemInteractionCtrl)(item.id);
|
|
70
|
-
// @ts-ignore
|
|
71
|
-
console.log(interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.transitionsInProgress);
|
|
72
70
|
const wrapperStateProps = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getState(['top', 'left']);
|
|
73
71
|
const innerStateProps = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getState(['width', 'height', 'scale']);
|
|
74
72
|
const position = (0, useItemPosition_1.useItemPosition)(item, sectionId, {
|
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
2
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
14
|
exports.InteractionsRegistry = void 0;
|
|
15
|
+
const sdk_1 = require("@cntrl-site/sdk");
|
|
16
|
+
const Item_1 = require("../components/Item");
|
|
4
17
|
class InteractionsRegistry {
|
|
5
18
|
constructor(article, layoutId) {
|
|
6
19
|
this.layoutId = layoutId;
|
|
7
20
|
this.ctrls = new Map();
|
|
8
21
|
const { interactions } = article;
|
|
9
|
-
|
|
22
|
+
this.items = this.unpackItems(article);
|
|
10
23
|
const activeStatesIds = interactions.reduce((map, inter) => {
|
|
11
24
|
var _a;
|
|
12
25
|
const activeStateId = (_a = inter.states.find((state) => state.id !== inter.startStateId)) === null || _a === void 0 ? void 0 : _a.id;
|
|
@@ -17,12 +30,16 @@ class InteractionsRegistry {
|
|
|
17
30
|
map[id] = startStateId;
|
|
18
31
|
return map;
|
|
19
32
|
}, {});
|
|
20
|
-
|
|
21
|
-
|
|
33
|
+
this.activeStateIdInteractionIdMap = interactions.reduce((map, interaction) => {
|
|
34
|
+
const activeState = interaction.states.find((state) => state.id !== interaction.startStateId);
|
|
35
|
+
if (activeState) {
|
|
36
|
+
map[activeState.id] = interaction.id;
|
|
37
|
+
}
|
|
22
38
|
return map;
|
|
23
39
|
}, {});
|
|
40
|
+
const itemStages = this.getDefaultItemStages();
|
|
24
41
|
const stateItemsIdsMap = activeStatesIds.reduce((map, stateId) => {
|
|
25
|
-
map[stateId] = items
|
|
42
|
+
map[stateId] = this.items
|
|
26
43
|
.filter((item) => {
|
|
27
44
|
var _a, _b;
|
|
28
45
|
const layoutStates = (_a = item.state[layoutId]) !== null && _a !== void 0 ? _a : {};
|
|
@@ -33,9 +50,8 @@ class InteractionsRegistry {
|
|
|
33
50
|
.map((item) => item.id);
|
|
34
51
|
return map;
|
|
35
52
|
}, {});
|
|
36
|
-
this.items = items;
|
|
37
53
|
this.interactions = interactions;
|
|
38
|
-
this.
|
|
54
|
+
this.itemsStages = itemStages;
|
|
39
55
|
this.stateItemsIdsMap = stateItemsIdsMap;
|
|
40
56
|
this.interactionStateMap = interactionStateMap;
|
|
41
57
|
}
|
|
@@ -43,45 +59,43 @@ class InteractionsRegistry {
|
|
|
43
59
|
this.ctrls.set(itemId, ctrl);
|
|
44
60
|
}
|
|
45
61
|
getStatePropsForItem(itemId) {
|
|
46
|
-
var _a, _b;
|
|
62
|
+
var _a, _b, _c, _d, _e;
|
|
47
63
|
const { items, layoutId } = this;
|
|
48
64
|
const item = items.find((item) => item.id === itemId);
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
};
|
|
62
|
-
return map;
|
|
63
|
-
}, {});
|
|
64
|
-
return stateProps;
|
|
65
|
-
}
|
|
66
|
-
// handle "transitioning" stage
|
|
67
|
-
const activeStateId = stage.direction === 'in' ? stage.to : stage.from;
|
|
68
|
-
const params = (_b = item.state[layoutId]) === null || _b === void 0 ? void 0 : _b[activeStateId];
|
|
69
|
-
return Object.entries(params).reduce((map, [key, stateDetails]) => {
|
|
70
|
-
const style = key;
|
|
71
|
-
const details = stateDetails;
|
|
72
|
-
map[style] = {
|
|
73
|
-
value: stage.direction === 'in' ? details.value : undefined,
|
|
74
|
-
transition: {
|
|
75
|
-
timing: details[stage.direction].timing,
|
|
76
|
-
duration: details[stage.direction].duration,
|
|
77
|
-
delay: details[stage.direction].delay
|
|
65
|
+
const itemStages = this.itemsStages.filter((stage) => stage.itemId === itemId);
|
|
66
|
+
itemStages.sort((a, b) => a.updated - b.updated);
|
|
67
|
+
const itemStyles = {};
|
|
68
|
+
for (const stage of itemStages) {
|
|
69
|
+
if (stage.type === 'active') {
|
|
70
|
+
if (stage.isStartState)
|
|
71
|
+
continue;
|
|
72
|
+
const params = (_b = (_a = item.state[layoutId]) === null || _a === void 0 ? void 0 : _a[stage.stateId]) !== null && _b !== void 0 ? _b : {};
|
|
73
|
+
for (const [key, stateDetails] of Object.entries(params)) {
|
|
74
|
+
itemStyles[key] = {
|
|
75
|
+
value: stateDetails.value
|
|
76
|
+
};
|
|
78
77
|
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
}
|
|
79
|
+
if (stage.type === 'transitioning') {
|
|
80
|
+
const activeStateId = stage.direction === 'in' ? stage.to : stage.from;
|
|
81
|
+
const params = (_d = (_c = item.state[layoutId]) === null || _c === void 0 ? void 0 : _c[activeStateId]) !== null && _d !== void 0 ? _d : {};
|
|
82
|
+
for (const [key, stateDetails] of Object.entries(params)) {
|
|
83
|
+
itemStyles[key] = {
|
|
84
|
+
value: stage.direction === 'in' ? stateDetails.value : (_e = itemStyles[key]) === null || _e === void 0 ? void 0 : _e.value,
|
|
85
|
+
transition: {
|
|
86
|
+
timing: stateDetails[stage.direction].timing,
|
|
87
|
+
duration: stateDetails[stage.direction].duration,
|
|
88
|
+
delay: stateDetails[stage.direction].delay
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return itemStyles;
|
|
82
95
|
}
|
|
83
96
|
notifyTrigger(itemId, triggerType) {
|
|
84
97
|
var _a;
|
|
98
|
+
const timestamp = Date.now();
|
|
85
99
|
for (const interaction of this.interactions) {
|
|
86
100
|
const currentStateId = this.getCurrentStateByInteractionId(interaction.id);
|
|
87
101
|
const matchingTrigger = interaction.triggers.find((trigger) => trigger.itemId === itemId
|
|
@@ -93,16 +107,19 @@ class InteractionsRegistry {
|
|
|
93
107
|
const isNewStateActive = matchingTrigger.to === activeStateId;
|
|
94
108
|
this.setCurrentStateForInteraction(interaction.id, matchingTrigger.to);
|
|
95
109
|
const transitioningItems = (_a = this.stateItemsIdsMap[activeStateId]) !== null && _a !== void 0 ? _a : [];
|
|
96
|
-
|
|
97
|
-
if (
|
|
98
|
-
|
|
99
|
-
|
|
110
|
+
this.itemsStages = this.itemsStages.map((stage) => {
|
|
111
|
+
if (stage.interactionId !== interaction.id)
|
|
112
|
+
return stage;
|
|
113
|
+
return {
|
|
114
|
+
itemId: stage.itemId,
|
|
115
|
+
interactionId: stage.interactionId,
|
|
100
116
|
type: 'transitioning',
|
|
101
117
|
from: stage.type === 'transitioning' ? stage.to : stage.stateId,
|
|
102
118
|
to: matchingTrigger.to,
|
|
103
|
-
direction: isNewStateActive ? 'in' : 'out'
|
|
119
|
+
direction: isNewStateActive ? 'in' : 'out',
|
|
120
|
+
updated: timestamp
|
|
104
121
|
};
|
|
105
|
-
}
|
|
122
|
+
});
|
|
106
123
|
this.notifyItemCtrlsChange(transitioningItems);
|
|
107
124
|
this.notifyTransitionStartForItems(transitioningItems, activeStateId);
|
|
108
125
|
}
|
|
@@ -118,14 +135,19 @@ class InteractionsRegistry {
|
|
|
118
135
|
}
|
|
119
136
|
notifyTransitionEnd(itemId) {
|
|
120
137
|
var _a;
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
138
|
+
const timestamp = Date.now();
|
|
139
|
+
this.itemsStages = this.itemsStages.map((stage) => {
|
|
140
|
+
if (stage.itemId !== itemId || stage.type !== 'transitioning')
|
|
141
|
+
return stage;
|
|
142
|
+
return {
|
|
143
|
+
itemId: itemId,
|
|
144
|
+
interactionId: stage.interactionId,
|
|
145
|
+
type: 'active',
|
|
146
|
+
stateId: stage.to,
|
|
147
|
+
isStartState: stage.direction === 'out',
|
|
148
|
+
updated: timestamp
|
|
149
|
+
};
|
|
150
|
+
});
|
|
129
151
|
(_a = this.ctrls.get(itemId)) === null || _a === void 0 ? void 0 : _a.receiveChange();
|
|
130
152
|
}
|
|
131
153
|
getCurrentStateByInteractionId(id) {
|
|
@@ -154,5 +176,45 @@ class InteractionsRegistry {
|
|
|
154
176
|
(_a = this.ctrls.get(itemId)) === null || _a === void 0 ? void 0 : _a.receiveChange();
|
|
155
177
|
}
|
|
156
178
|
}
|
|
179
|
+
unpackItems(article) {
|
|
180
|
+
var _a;
|
|
181
|
+
const itemsArr = [];
|
|
182
|
+
for (const section of article.sections) {
|
|
183
|
+
for (const item of section.items) {
|
|
184
|
+
const { items } = item, itemWithoutChildren = __rest(item, ["items"]);
|
|
185
|
+
itemsArr.push(itemWithoutChildren);
|
|
186
|
+
if (!(0, Item_1.isItemType)(item, sdk_1.ArticleItemType.Group))
|
|
187
|
+
continue;
|
|
188
|
+
const groupChildren = (_a = item === null || item === void 0 ? void 0 : item.items) !== null && _a !== void 0 ? _a : [];
|
|
189
|
+
for (const child of groupChildren) {
|
|
190
|
+
itemsArr.push(child);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return itemsArr;
|
|
195
|
+
}
|
|
196
|
+
getDefaultItemStages() {
|
|
197
|
+
const timestamp = Date.now();
|
|
198
|
+
const { items, layoutId } = this;
|
|
199
|
+
const stages = [];
|
|
200
|
+
for (const item of items) {
|
|
201
|
+
const itemStatesMap = item.state[layoutId];
|
|
202
|
+
if (!itemStatesMap)
|
|
203
|
+
continue;
|
|
204
|
+
for (const stateId of Object.keys(itemStatesMap)) {
|
|
205
|
+
const interactionId = this.activeStateIdInteractionIdMap[stateId];
|
|
206
|
+
if (!interactionId)
|
|
207
|
+
continue;
|
|
208
|
+
stages.push({
|
|
209
|
+
itemId: item.id,
|
|
210
|
+
interactionId,
|
|
211
|
+
type: 'active',
|
|
212
|
+
isStartState: true,
|
|
213
|
+
updated: timestamp
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return stages;
|
|
218
|
+
}
|
|
157
219
|
}
|
|
158
220
|
exports.InteractionsRegistry = InteractionsRegistry;
|
|
@@ -16,6 +16,12 @@ class ItemInteractionController {
|
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
18
|
this.handleTransitionEnd = (cssPropKey) => {
|
|
19
|
+
if (cssPropKey.startsWith('border-') && cssPropKey.endsWith('-radius')) {
|
|
20
|
+
cssPropKey = 'border-radius';
|
|
21
|
+
}
|
|
22
|
+
if (cssPropKey.startsWith('border-') && cssPropKey.endsWith('-width')) {
|
|
23
|
+
cssPropKey = 'border-width';
|
|
24
|
+
}
|
|
19
25
|
const styleKeys = (0, CSSPropertyNameMap_1.getStyleKeysFromCSSProperty)(cssPropKey);
|
|
20
26
|
for (const key of styleKeys) {
|
|
21
27
|
const found = this.transitionsInProgress.has(key);
|
package/package.json
CHANGED
package/src/components/Item.tsx
CHANGED
|
@@ -92,8 +92,6 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isI
|
|
|
92
92
|
const [itemHeight, setItemHeight] = useState<undefined | number>(undefined);
|
|
93
93
|
const itemScale = useItemScale(item, sectionId);
|
|
94
94
|
const interactionCtrl = useItemInteractionCtrl(item.id);
|
|
95
|
-
// @ts-ignore
|
|
96
|
-
console.log(interactionCtrl?.transitionsInProgress);
|
|
97
95
|
const wrapperStateProps = interactionCtrl?.getState(['top', 'left']);
|
|
98
96
|
const innerStateProps = interactionCtrl?.getState(['width', 'height', 'scale']);
|
|
99
97
|
const position = useItemPosition(item, sectionId, {
|
|
@@ -5,9 +5,8 @@ import {
|
|
|
5
5
|
Interaction,
|
|
6
6
|
InteractionTrigger,
|
|
7
7
|
ItemAny,
|
|
8
|
-
ItemState,
|
|
9
|
-
StateParams
|
|
10
8
|
} from '@cntrl-site/sdk';
|
|
9
|
+
import { isItemType } from '../components/Item';
|
|
11
10
|
|
|
12
11
|
export class InteractionsRegistry implements InteractionsRegistryPort {
|
|
13
12
|
private ctrls: Map<ItemId, ItemInteractionCtrl> = new Map();
|
|
@@ -15,11 +14,12 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
|
|
|
15
14
|
private interactions: Interaction[];
|
|
16
15
|
private stateItemsIdsMap: StateItemsIdsMap;
|
|
17
16
|
private interactionStateMap: InteractionStateMap;
|
|
18
|
-
private
|
|
17
|
+
private itemsStages: ItemStages;
|
|
18
|
+
private activeStateIdInteractionIdMap: Record<StateId, InteractionId>;
|
|
19
19
|
|
|
20
20
|
constructor(article: Article, private layoutId: string) {
|
|
21
21
|
const { interactions } = article;
|
|
22
|
-
|
|
22
|
+
this.items = this.unpackItems(article);
|
|
23
23
|
const activeStatesIds = interactions.reduce<StateId[]>((map, inter) => {
|
|
24
24
|
const activeStateId = inter.states.find((state) => state.id !== inter.startStateId)?.id!;
|
|
25
25
|
map.push(activeStateId);
|
|
@@ -29,12 +29,16 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
|
|
|
29
29
|
map[id] = startStateId;
|
|
30
30
|
return map;
|
|
31
31
|
}, {});
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
this.activeStateIdInteractionIdMap = interactions.reduce<Record<StateId, InteractionId>>((map, interaction) => {
|
|
33
|
+
const activeState = interaction.states.find((state) => state.id !== interaction.startStateId);
|
|
34
|
+
if (activeState) {
|
|
35
|
+
map[activeState.id] = interaction.id;
|
|
36
|
+
}
|
|
34
37
|
return map;
|
|
35
38
|
}, {});
|
|
39
|
+
const itemStages = this.getDefaultItemStages();
|
|
36
40
|
const stateItemsIdsMap = activeStatesIds.reduce<StateItemsIdsMap>((map, stateId) => {
|
|
37
|
-
map[stateId] = items
|
|
41
|
+
map[stateId] = this.items
|
|
38
42
|
.filter((item) => {
|
|
39
43
|
const layoutStates = item.state[layoutId] ?? {};
|
|
40
44
|
const state = layoutStates?.[stateId] ?? {};
|
|
@@ -44,9 +48,8 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
|
|
|
44
48
|
.map((item) => item.id);
|
|
45
49
|
return map;
|
|
46
50
|
}, {});
|
|
47
|
-
this.items = items;
|
|
48
51
|
this.interactions = interactions;
|
|
49
|
-
this.
|
|
52
|
+
this.itemsStages = itemStages;
|
|
50
53
|
this.stateItemsIdsMap = stateItemsIdsMap;
|
|
51
54
|
this.interactionStateMap = interactionStateMap;
|
|
52
55
|
}
|
|
@@ -58,40 +61,39 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
|
|
|
58
61
|
getStatePropsForItem(itemId: string) {
|
|
59
62
|
const { items, layoutId } = this;
|
|
60
63
|
const item = items.find((item) => item.id === itemId)!;
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (stage.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return map;
|
|
73
|
-
}, {});
|
|
74
|
-
return stateProps;
|
|
75
|
-
}
|
|
76
|
-
// handle "transitioning" stage
|
|
77
|
-
const activeStateId = stage.direction === 'in' ? stage.to : stage.from;
|
|
78
|
-
const params = item.state[layoutId]?.[activeStateId];
|
|
79
|
-
return Object.entries(params).reduce<StateProps>((map, [key, stateDetails]) => {
|
|
80
|
-
const style = key as keyof ItemState<ArticleItemType>;
|
|
81
|
-
const details = stateDetails as StateParams<string | number>;
|
|
82
|
-
map[style] = {
|
|
83
|
-
value: stage.direction === 'in' ? details.value : undefined,
|
|
84
|
-
transition: {
|
|
85
|
-
timing: details[stage.direction].timing,
|
|
86
|
-
duration: details[stage.direction].duration,
|
|
87
|
-
delay: details[stage.direction].delay
|
|
64
|
+
const itemStages = this.itemsStages.filter((stage) => stage.itemId === itemId);
|
|
65
|
+
itemStages.sort((a, b) => a.updated - b.updated);
|
|
66
|
+
const itemStyles: StateProps = {};
|
|
67
|
+
for (const stage of itemStages) {
|
|
68
|
+
if (stage.type === 'active') {
|
|
69
|
+
if (stage.isStartState) continue;
|
|
70
|
+
const params = item.state[layoutId]?.[stage.stateId!] ?? {};
|
|
71
|
+
for (const [key, stateDetails] of Object.entries(params)) {
|
|
72
|
+
itemStyles[key] = {
|
|
73
|
+
value: stateDetails.value
|
|
74
|
+
};
|
|
88
75
|
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
76
|
+
}
|
|
77
|
+
if (stage.type === 'transitioning') {
|
|
78
|
+
const activeStateId = stage.direction === 'in' ? stage.to : stage.from;
|
|
79
|
+
const params = item.state[layoutId]?.[activeStateId] ?? {};
|
|
80
|
+
for (const [key, stateDetails] of Object.entries(params)) {
|
|
81
|
+
itemStyles[key] = {
|
|
82
|
+
value: stage.direction === 'in' ? stateDetails.value : itemStyles[key]?.value,
|
|
83
|
+
transition: {
|
|
84
|
+
timing: stateDetails[stage.direction].timing,
|
|
85
|
+
duration: stateDetails[stage.direction].duration,
|
|
86
|
+
delay: stateDetails[stage.direction].delay
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return itemStyles;
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
notifyTrigger(itemId: string, triggerType: TriggerType): void {
|
|
96
|
+
const timestamp = Date.now();
|
|
95
97
|
for (const interaction of this.interactions) {
|
|
96
98
|
const currentStateId = this.getCurrentStateByInteractionId(interaction.id);
|
|
97
99
|
const matchingTrigger = interaction.triggers.find((trigger) =>
|
|
@@ -104,15 +106,18 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
|
|
|
104
106
|
const isNewStateActive = matchingTrigger.to === activeStateId;
|
|
105
107
|
this.setCurrentStateForInteraction(interaction.id, matchingTrigger.to);
|
|
106
108
|
const transitioningItems = this.stateItemsIdsMap[activeStateId] ?? [];
|
|
107
|
-
|
|
108
|
-
if (
|
|
109
|
-
|
|
109
|
+
this.itemsStages = this.itemsStages.map((stage) => {
|
|
110
|
+
if (stage.interactionId !== interaction.id) return stage;
|
|
111
|
+
return {
|
|
112
|
+
itemId: stage.itemId,
|
|
113
|
+
interactionId: stage.interactionId,
|
|
110
114
|
type: 'transitioning',
|
|
111
115
|
from: stage.type === 'transitioning' ? stage.to : stage.stateId!,
|
|
112
116
|
to: matchingTrigger.to,
|
|
113
|
-
direction: isNewStateActive ? 'in' : 'out'
|
|
117
|
+
direction: isNewStateActive ? 'in' : 'out',
|
|
118
|
+
updated: timestamp
|
|
114
119
|
};
|
|
115
|
-
}
|
|
120
|
+
});
|
|
116
121
|
this.notifyItemCtrlsChange(transitioningItems);
|
|
117
122
|
this.notifyTransitionStartForItems(transitioningItems, activeStateId);
|
|
118
123
|
}
|
|
@@ -128,13 +133,18 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
|
|
|
128
133
|
}
|
|
129
134
|
|
|
130
135
|
notifyTransitionEnd(itemId: string): void {
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
136
|
+
const timestamp = Date.now();
|
|
137
|
+
this.itemsStages = this.itemsStages.map((stage) => {
|
|
138
|
+
if (stage.itemId !== itemId || stage.type !== 'transitioning') return stage;
|
|
139
|
+
return {
|
|
140
|
+
itemId: itemId,
|
|
141
|
+
interactionId: stage.interactionId,
|
|
142
|
+
type: 'active',
|
|
143
|
+
stateId: stage.to,
|
|
144
|
+
isStartState: stage.direction === 'out',
|
|
145
|
+
updated: timestamp
|
|
146
|
+
};
|
|
147
|
+
});
|
|
138
148
|
this.ctrls.get(itemId)?.receiveChange();
|
|
139
149
|
}
|
|
140
150
|
|
|
@@ -167,16 +177,57 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
|
|
|
167
177
|
this.ctrls.get(itemId)?.receiveChange();
|
|
168
178
|
}
|
|
169
179
|
}
|
|
180
|
+
|
|
181
|
+
private unpackItems(article: Article): ItemAny[] {
|
|
182
|
+
const itemsArr = [];
|
|
183
|
+
for (const section of article.sections) {
|
|
184
|
+
for (const item of section.items) {
|
|
185
|
+
const { items, ...itemWithoutChildren } = item;
|
|
186
|
+
itemsArr.push(itemWithoutChildren);
|
|
187
|
+
if (!isItemType(item, ArticleItemType.Group)) continue;
|
|
188
|
+
const groupChildren = item?.items ?? [];
|
|
189
|
+
for (const child of groupChildren) {
|
|
190
|
+
itemsArr.push(child);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return itemsArr;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private getDefaultItemStages(): ItemStages {
|
|
198
|
+
const timestamp = Date.now();
|
|
199
|
+
const { items, layoutId } = this;
|
|
200
|
+
const stages: ItemStages = [];
|
|
201
|
+
for (const item of items) {
|
|
202
|
+
const itemStatesMap = item.state[layoutId];
|
|
203
|
+
if (!itemStatesMap) continue;
|
|
204
|
+
for (const stateId of Object.keys(itemStatesMap)) {
|
|
205
|
+
const interactionId = this.activeStateIdInteractionIdMap[stateId];
|
|
206
|
+
if (!interactionId) continue;
|
|
207
|
+
stages.push({
|
|
208
|
+
itemId: item.id,
|
|
209
|
+
interactionId,
|
|
210
|
+
type: 'active',
|
|
211
|
+
isStartState: true,
|
|
212
|
+
updated: timestamp
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return stages;
|
|
217
|
+
}
|
|
170
218
|
}
|
|
171
219
|
|
|
172
|
-
type
|
|
220
|
+
type ItemStages = (TransitioningStage | ActiveStage)[];
|
|
173
221
|
type TransitioningStage = {
|
|
222
|
+
itemId: string;
|
|
223
|
+
interactionId: string;
|
|
174
224
|
type: 'transitioning';
|
|
175
225
|
from: StateId;
|
|
176
226
|
to: StateId;
|
|
177
227
|
direction: 'in' | 'out';
|
|
228
|
+
updated: number;
|
|
178
229
|
};
|
|
179
|
-
type ActiveStage = { type: 'active'; stateId?: string; isStartState: boolean; };
|
|
230
|
+
type ActiveStage = { type: 'active'; itemId: string; interactionId: string; stateId?: string; isStartState: boolean; updated: number; };
|
|
180
231
|
type InteractionStateMap = Record<InteractionId, StateId>;
|
|
181
232
|
type StateItemsIdsMap = Record<StateId, ItemId[]>;
|
|
182
233
|
type TriggerType = InteractionTrigger['type'];
|
|
@@ -39,6 +39,12 @@ export class ItemInteractionController implements ItemInteractionCtrl {
|
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
handleTransitionEnd = (cssPropKey: string) => {
|
|
42
|
+
if (cssPropKey.startsWith('border-') && cssPropKey.endsWith('-radius')) {
|
|
43
|
+
cssPropKey = 'border-radius';
|
|
44
|
+
}
|
|
45
|
+
if (cssPropKey.startsWith('border-') && cssPropKey.endsWith('-width')) {
|
|
46
|
+
cssPropKey = 'border-width';
|
|
47
|
+
}
|
|
42
48
|
const styleKeys = getStyleKeysFromCSSProperty(cssPropKey);
|
|
43
49
|
for (const key of styleKeys) {
|
|
44
50
|
const found = this.transitionsInProgress.has(key);
|