@media-quest/builder 0.0.14 → 0.0.15

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@media-quest/builder",
3
- "version": "0.0.14",
3
+ "version": "0.0.15",
4
4
  "description": "Builder library for Media-quest schemas",
5
5
  "main": "src/public-api.ts",
6
6
  "license": "MIT",
@@ -10,6 +10,6 @@
10
10
  "buildXXX": "npm run clean && tsup src/public-api.ts --sourcemap inline --format cjs,esm --dts"
11
11
  },
12
12
  "dependencies": {
13
- "@media-quest/engine": "0.0.14"
13
+ "@media-quest/engine": "0.0.15"
14
14
  }
15
15
  }
@@ -268,11 +268,11 @@ describe("Builder schema", () => {
268
268
  const schemaP2 = schema.pages[1];
269
269
  expect(schemaP1.id).toBe(p1.id);
270
270
  expect(schemaP2.id).toBe(p2.id);
271
- expect(schemaP1.elements.length).toBe(2);
271
+ // expect(schemaP1.elements.length).toBe(2);
272
272
 
273
273
  // Has Buttons
274
274
  const options = p2.defaultQuestion.options;
275
- expect(schemaP2.elements.length).toBe(options.length + 1);
275
+ // expect(schemaP2.elements.length).toBe(options.length + 1);
276
276
  });
277
277
  test("Can get ruleInput!", () => {
278
278
  const p0 = builderSchema.addPage("info-page");
@@ -2,32 +2,31 @@ import { AbstractThemeCompiler } from "./AbstractThemeCompiler";
2
2
  import type { BuilderSchemaDto } from "../Builder-schema";
3
3
  import { BuilderSchema } from "../Builder-schema";
4
4
  import type { BuilderPageDto } from "../Builder-page";
5
- import { DStateProps } from "./standard-props";
6
5
  import { ThemeUtils } from "./theme-utils";
7
6
  import { DefaultTheme, type IDefaultTheme } from "./IDefaultTheme";
8
7
  import type { BuilderMainImageDto } from "../BuilderMainImageDto";
9
8
  import type { BuilderMainVideoDto } from "../BuilderMainVideoDto";
10
9
  import {
11
- DAudioDto,
12
- DAutoPlaySequence,
13
- DCommand,
10
+ ButtonClickAction,
14
11
  DDivDto,
15
12
  DElementDto,
16
13
  DImgDto,
17
14
  DTextDto,
18
15
  DUtil,
19
- DVideoDto,
20
- Fact,
21
16
  PageDto,
17
+ PageComponentDto,
22
18
  PageQueCommand,
19
+ PlayAudioTask,
20
+ PlayVideoTask,
23
21
  Rule,
24
22
  SchemaDto,
25
23
  } from "@media-quest/engine";
24
+
26
25
  import { AudioFile } from "../media-files";
27
26
  import { BuilderRule } from "../rulebuilder";
28
27
 
29
28
  const U = DUtil;
30
- const generateElementId = () => U.randomString(32);
29
+
31
30
  export class DefaultThemeCompiler extends AbstractThemeCompiler<IDefaultTheme> {
32
31
  readonly name = "Ispe default theme.";
33
32
  private readonly TAG = "[ DEFAULT_THEME_COMPILER ]: ";
@@ -56,7 +55,6 @@ export class DefaultThemeCompiler extends AbstractThemeCompiler<IDefaultTheme> {
56
55
  compile(source: BuilderSchemaDto): SchemaDto {
57
56
  const pages = source.pages.map((p) => this.compilePage(p, source.prefix));
58
57
  const rules = this.compileRules(source);
59
- // console.log(pages.map((p) => p.tags));
60
58
 
61
59
  const dto: SchemaDto = {
62
60
  backgroundColor: source.backgroundColor,
@@ -67,270 +65,191 @@ export class DefaultThemeCompiler extends AbstractThemeCompiler<IDefaultTheme> {
67
65
  pages,
68
66
  predefinedFacts: [],
69
67
  rules,
70
- stateFromEvent: [
71
- {
72
- onEvent: "VIDEO_ENDED_EVENT",
73
- thenExecute: [
74
- DStateProps.userPausedVideo.getSetFalseCommand(),
75
- DStateProps.mediaBlockedByVideo.getSetFalseCommand(),
76
- DStateProps.videoIsPlaying.getSetFalseCommand(),
77
- ],
78
- },
79
- {
80
- onEvent: "VIDEO_PAUSED_EVENT",
81
- thenExecute: [
82
- DStateProps.videoIsPlaying.getSetFalseCommand(),
83
- DStateProps.mediaBlockedByVideo.getSetFalseCommand(),
84
- ],
85
- },
86
- {
87
- onEvent: "VIDEO_PLAY_EVENT",
88
- thenExecute: [
89
- DStateProps.videoIsPlaying.getSetTrueCommand(),
90
- DStateProps.userPausedVideo.getSetFalseCommand(),
91
- ],
92
- },
93
- {
94
- onEvent: "AUDIO_PLAY_EVENT",
95
- thenExecute: [
96
- DStateProps.audioIsPlaying.getSetTrueCommand(),
97
- DStateProps.mediaBlockedByAudio.getSetTrueCommand(),
98
- ],
99
- },
100
- {
101
- onEvent: "AUDIO_ENDED_EVENT",
102
- thenExecute: [
103
- DStateProps.audioIsPlaying.getSetFalseCommand(),
104
- DStateProps.mediaBlockedByAudio.getSetFalseCommand(),
105
- ],
106
- },
107
- {
108
- onEvent: "AUDIO_PAUSED_EVENT",
109
- thenExecute: [
110
- DStateProps.audioIsPlaying.getSetFalseCommand(),
111
- DStateProps.mediaBlockedByAudio.getSetFalseCommand(),
112
- ],
113
- },
114
- ],
115
- stateProps: DStateProps.allDefaultProperties.map((def) => def.propDefinition),
116
- stateQueries: DStateProps.allDefaultQueries,
117
68
  };
118
69
  return dto;
119
70
  }
120
71
  private compilePage(page: BuilderPageDto, modulePrefix: string): PageDto {
121
- // console.log(_moduleId);
122
- // const textElement
123
72
  const tags = page.tags ?? [];
124
73
  const { nextButton, mainText, id, mainMedia, _type } = page;
125
- const elements: DElementDto[] = [];
126
- const audioResourcesDto: DAudioDto[] = [];
127
- const videoResources: DVideoDto[] = [];
128
- let mainVideo: DVideoDto | false = false;
129
- let mainTextAudio: DAudioDto | false = false;
74
+ const staticElements: DElementDto[] = [];
75
+ let autoPlayAudioTasks: PlayAudioTask | false = false;
76
+ let autoPlayVideoTasks: PlayVideoTask | false = false;
77
+ const newPage: PageDto = {
78
+ background: "white",
79
+ components: [],
80
+ staticElements,
81
+ id,
82
+ initialTasks: [],
83
+ tags: [...tags],
84
+ };
130
85
 
131
86
  if (page.mainText.audioFile) {
132
- const res = this.compileMainTextAudio(page.mainText.audioFile);
133
- elements.push(...res.elements);
134
- audioResourcesDto.push(res.audioDto);
135
- mainTextAudio = res.audioDto;
87
+ const autoPlay = page.mainText.autoplay;
88
+ const res = this.compileMainTextAudio(page.mainText.audioFile, autoPlay);
89
+ autoPlayAudioTasks = res.autoPlayTask;
90
+ newPage.components.push(...res.components);
136
91
  }
137
92
 
138
93
  if (_type === "question") {
139
94
  const variableId = modulePrefix + "_" + page.prefix;
140
- const { buttons, question } = this.compileQuestion(id, page, variableId);
95
+ const { components, question } = this.compileQuestion(id, page, variableId);
96
+ newPage.components.push(...components);
97
+ newPage.staticElements.push(question);
141
98
  // console.log(question);
142
- elements.push(...buttons, question);
99
+ // elements.push(...buttons, question);
143
100
  }
144
101
 
145
102
  if (_type === "info-page") {
146
103
  const infoText = mainText.text;
147
- const nextBtnElement: DElementDto = this.compileButton(id, nextButton, {
104
+ const nextButtonComponent = this.compileButton(nextButton, {
148
105
  kind: "next-button",
149
106
  });
150
- const textStyle = mainMedia ? DefaultTheme.mainText.withMedia.text.css : DefaultTheme.mainText.noMedia.text.css;
151
- const element: DElementDto = {
152
- text: infoText,
107
+
108
+ const textStyle = mainMedia
109
+ ? DefaultTheme.mainText.withMedia.text.css
110
+ : DefaultTheme.mainText.noMedia.text.css;
111
+ const infoTextElement: DElementDto = {
112
+ innerText: infoText,
153
113
  _tag: "p",
154
- id: generateElementId(),
155
114
  style: textStyle,
156
115
  };
157
- elements.push(element);
158
- elements.push(nextBtnElement);
116
+ newPage.staticElements.push(infoTextElement);
117
+ newPage.components.push(nextButtonComponent);
159
118
  }
160
119
  if (mainMedia && mainMedia.kind === "main-image") {
161
120
  const mainImageElement = this.compileImage(mainMedia);
162
- elements.push(mainImageElement);
121
+ newPage.staticElements.push(mainImageElement);
163
122
  }
164
123
 
165
124
  if (mainMedia && mainMedia.kind === "main-video") {
166
125
  const videoOutput = this.compileVideo(mainMedia);
167
- mainVideo = videoOutput.videoDto;
168
- elements.push(...videoOutput.elements);
169
- videoResources.push(videoOutput.videoDto);
126
+ newPage.videoPlayer = videoOutput.videoPlayer;
127
+ newPage.components.push(...videoOutput.components);
128
+ autoPlayVideoTasks = videoOutput.autoPlayTask;
170
129
  }
171
- const mainVideoId = mainVideo ? mainVideo.id : undefined;
172
- const autoPlaySequence: DAutoPlaySequence = {
173
- blockUserInput: true,
174
- id: "1",
175
- items: [],
176
- startCommands: [
177
- DStateProps.mediaBlockedBySequence.getSetTrueCommand(),
178
- DStateProps.inputBlockingBySequence.getSetTrueCommand(),
179
- ],
180
- endCommands: [
181
- DStateProps.mediaBlockedBySequence.getSetFalseCommand(),
182
- DStateProps.inputBlockingBySequence.getSetFalseCommand(),
183
- ],
184
- };
185
130
 
186
- if (mainVideo && page.mainMedia && page.mainMedia.kind === "main-video" && page.mainMedia.mode === "autoplay") {
187
- autoPlaySequence.items.push({
188
- kind: "autoplay-video",
189
- videoId: mainVideo.id,
190
- });
131
+ if (autoPlayVideoTasks) {
132
+ newPage.initialTasks.push(autoPlayVideoTasks);
191
133
  }
192
-
193
- if (mainTextAudio && page.mainText.autoplay) {
194
- autoPlaySequence.items.push({
195
- kind: "autoplay-audio",
196
- audioId: mainTextAudio.id,
197
- });
134
+ if (autoPlayAudioTasks) {
135
+ newPage.initialTasks.push(autoPlayAudioTasks);
198
136
  }
199
-
200
- const pageDto: PageDto = {
201
- audio: audioResourcesDto,
202
- autoPlaySequence: autoPlaySequence,
203
- backgroundColor: "red",
204
- elements,
205
- id,
206
- mainVideoId,
207
- tags: [...tags],
208
- video: videoResources,
209
- };
210
- return pageDto;
137
+ return newPage;
211
138
  }
212
139
 
213
140
  private compileImage(image: BuilderMainImageDto) {
214
141
  const img: DImgDto = {
215
142
  _tag: "img",
216
- id: image.file.id,
217
143
  style: this.theme.image.style,
218
144
  url: image.file.downloadUrl,
219
145
  };
220
146
  return img;
221
147
  }
222
148
 
223
- private compileMainTextAudio(audioFile: AudioFile): {
224
- audioDto: DAudioDto;
225
- elements: DElementDto[];
149
+ private compileMainTextAudio(
150
+ audioFile: AudioFile,
151
+ autoPlay: boolean,
152
+ ): {
153
+ components: PageComponentDto[];
154
+ autoPlayTask: PlayAudioTask | false;
226
155
  } {
227
156
  const t = this.theme.mainText;
228
157
  const audioId = audioFile.id;
229
158
  const iconUrl =
230
159
  "https://firebasestorage.googleapis.com/v0/b/ispe-backend-dev.appspot.com/o/public-assets%2Fvolume_up-24px.svg?alt=media&token=551bd0a6-a515-4f87-a245-da433f4833f9";
231
160
 
232
- const buttonId = U.randomString(30);
233
161
  const playMainTextAudio: DImgDto = {
234
162
  _tag: "img",
235
- id: buttonId,
236
163
  url: iconUrl,
237
164
  style: { ...t.withMedia.audio.css },
238
- onClick: [
239
- {
240
- kind: "AUDIO_PLAY_COMMAND",
241
- target: "AUDIO",
242
- targetId: audioId,
243
- payload: { volume: 1 },
244
- },
245
- ],
246
- onStateChange: [
247
- {
248
- queryName: DStateProps._Queries.disableAudioIconQuery.name,
249
- whenTrue: [...ThemeUtils.disableClickCommands(buttonId, t.withMedia.audio.cssDisabled)],
250
- whenFalse: [...ThemeUtils.enableClickCommands(buttonId, t.withMedia.audio.cssEnabled)],
251
- },
252
- ],
253
165
  };
254
- const audioDto: DAudioDto = {
255
- _tag: "audio",
256
- // eventHandlers: [],
257
- id: audioFile.id,
166
+
167
+ const task: PlayAudioTask = {
168
+ audioId,
169
+ blockAudio: false,
170
+ blockFormInput: false,
171
+ blockResponseButton: false,
172
+ blockVideo: false,
173
+ kind: "play-audio-task",
174
+ priority: "replace-all",
258
175
  url: audioFile.downloadUrl,
259
176
  };
260
- return { audioDto, elements: [playMainTextAudio] };
177
+
178
+ let autoPlayTask: PlayAudioTask | false = false;
179
+ if (autoPlay) {
180
+ autoPlayTask = { ...task, priority: "follow-queue" };
181
+ }
182
+ // const autoplayTask =
183
+ const playBtn: PageComponentDto = {
184
+ el: playMainTextAudio,
185
+ onClick: { kind: "play-audio", task },
186
+ };
187
+
188
+ return { components: [playBtn], autoPlayTask };
261
189
  }
262
190
 
263
- private compileVideo(video: BuilderMainVideoDto) {
191
+ private compileVideo(video: BuilderMainVideoDto): {
192
+ videoPlayer: PageDto["videoPlayer"];
193
+ components: PageComponentDto[];
194
+ autoPlayTask: PlayVideoTask | false;
195
+ } {
264
196
  const t = this.theme.videoPlayer;
265
- const videoId = video.file.id;
266
- const playButtonId = "play-btn-for" + videoId;
267
- const pauseButtonId = "pause-btn-for" + videoId;
268
- const elements: DElementDto[] = [];
269
- const videoDto: DVideoDto = {
270
- _tag: "video",
271
- id: video.file.id,
272
- style: t.videoElement.css,
197
+ const mode = video.mode;
198
+ const components: PageComponentDto[] = [];
199
+
200
+ let autoPlayTask: PlayVideoTask | false = false;
201
+ const playButtonTask: PlayVideoTask = {
202
+ kind: "play-video-task",
273
203
  url: video.file.downloadUrl,
204
+ videoId: video.file.id,
205
+ blockAudio: false,
206
+ blockFormInput: false,
207
+ blockResponseButton: false,
208
+ loop: mode === "gif-mode",
209
+ blockVideo: false,
210
+ priority: "replace-all",
274
211
  };
275
- const playBtn: DImgDto = {
276
- id: playButtonId,
277
- _tag: "img",
278
- url: t.playButton.iconUrl,
279
- style: { ...t.playButton.css, ...t.playButton.cssEnabled },
280
- onClick: [
281
- {
282
- kind: "VIDEO_PLAY_COMMAND",
283
- target: "VIDEO",
284
- targetId: videoId,
285
- payload: {},
286
- },
287
- // TODO Check if this video shall block other media first?
288
- DStateProps.mediaBlockedByVideo.getSetTrueCommand(),
289
- DStateProps.userPausedVideo.getSetFalseCommand(),
290
- ],
291
- onStateChange: [
292
- {
293
- queryName: DStateProps._Queries.disableVideoPlayQuery.name,
294
- whenTrue: [...ThemeUtils.disableClickCommands(playButtonId, t.playButton.cssDisabled)],
295
- whenFalse: [...ThemeUtils.enableClickCommands(playButtonId, t.playButton.cssEnabled)],
296
- },
297
- {
298
- queryName: DStateProps._Queries.hideVideoPlayQuery.name,
299
- whenTrue: [ThemeUtils.hideCommand(playButtonId)],
300
- whenFalse: [ThemeUtils.showCommand(playButtonId)],
301
- },
302
- ],
212
+ if (video.mode === "autoplay") {
213
+ autoPlayTask = { ...playButtonTask, priority: "follow-queue" };
214
+ }
215
+ if (video.mode === "gif-mode") {
216
+ autoPlayTask = { ...playButtonTask, priority: "follow-queue", loop: true };
217
+ }
218
+
219
+ const videoPlayer: PageDto["videoPlayer"] = {
220
+ playUrl: video.file.downloadUrl,
221
+ style: { h: 45, w: 100, x: 0, y: 55 },
303
222
  };
304
- const pauseBtn: DImgDto = {
305
- id: pauseButtonId,
306
- _tag: "img",
307
- style: {
308
- ...t.pauseButton.css,
309
- visibility: "hidden",
310
- ...t.pauseButton.cssEnabled,
223
+ const playButton: PageComponentDto = {
224
+ el: {
225
+ _tag: "img",
226
+ url: t.playButton.iconUrl,
227
+ style: { ...t.playButton.css, ...t.playButton.cssEnabled },
311
228
  },
312
- url: t.pauseButton.iconUrl,
313
- onClick: [
314
- {
315
- kind: "VIDEO_PAUSE_COMMAND",
316
- target: "VIDEO",
317
- targetId: videoId,
318
- payload: {},
319
- },
320
- DStateProps.mediaBlockedByVideo.getSetFalseCommand(),
321
- DStateProps.userPausedVideo.getSetTrueCommand(),
322
- ],
323
- onStateChange: [
324
- {
325
- queryName: DStateProps._Queries.hideVideoPauseQuery.name,
326
- whenTrue: [ThemeUtils.hideCommand(pauseButtonId)],
327
- whenFalse: [ThemeUtils.showCommand(pauseButtonId)],
229
+ onClick: { kind: "play-video", task: playButtonTask },
230
+ whenVideoPlay: { visibility: "hidden" },
231
+ whenVideoPaused: { visibility: "visible" },
232
+ };
233
+ const pauseBtn: PageComponentDto = {
234
+ el: {
235
+ _tag: "img",
236
+ style: {
237
+ ...t.pauseButton.css,
238
+ visibility: "hidden",
239
+ ...t.pauseButton.cssEnabled,
328
240
  },
329
- ],
241
+ url: t.pauseButton.iconUrl,
242
+ },
243
+ onClick: { kind: "pause-video" },
244
+ whenVideoPlay: { visibility: "visible" },
245
+ whenVideoPaused: { visibility: "hidden" },
330
246
  };
331
- elements.push(playBtn);
332
- elements.push(pauseBtn);
333
- return { videoDto, elements };
247
+
248
+ if (mode !== "gif-mode") {
249
+ components.push(playButton);
250
+ components.push(pauseBtn);
251
+ }
252
+ return { videoPlayer, components, autoPlayTask };
334
253
  }
335
254
  private compileQuestion(
336
255
  pageId: string,
@@ -338,7 +257,7 @@ export class DefaultThemeCompiler extends AbstractThemeCompiler<IDefaultTheme> {
338
257
  variableId: string,
339
258
  ): {
340
259
  question: DTextDto;
341
- buttons: DDivDto[];
260
+ components: PageComponentDto[];
342
261
  } {
343
262
  // TODO REFACTORE DEFAULT QUESTION TO - (REMOVE USE TEXT1)
344
263
  // console.log(page);
@@ -349,80 +268,63 @@ export class DefaultThemeCompiler extends AbstractThemeCompiler<IDefaultTheme> {
349
268
  : DefaultTheme.mainText.noMedia.text.css;
350
269
  const question: DTextDto = {
351
270
  _tag: "p",
352
- text,
353
- eventHandlers: [],
354
- id: U.randomString(30),
355
- onClick: [],
356
- onStateChange: [],
271
+ innerText: text,
357
272
  style: questionStyle,
358
273
  };
359
- const buttons = q.options.map((o) => {
360
- const btns = this.compileButton(pageId, o, {
274
+ const buttons: PageComponentDto[] = q.options.map((o) => {
275
+ const btns = this.compileButton(o, {
361
276
  kind: "response-button",
362
277
  questionId: variableId,
363
278
  });
364
279
  return btns;
365
280
  });
366
- ThemeUtils.spaceEvenlyX(buttons);
367
- return { question, buttons };
281
+ const rootElements = buttons.map((b) => b.el);
282
+ ThemeUtils.spaceEvenlyX(rootElements);
283
+ return { question, components: buttons };
368
284
  }
369
285
 
370
286
  private compileButton(
371
- pageId: string,
372
287
  buttonDto: BuilderPageDto["nextButton"],
373
288
  options: { kind: "response-button"; questionId: string } | { kind: "next-button" },
374
- ) {
375
- const factsCollected: Fact[] = [];
289
+ ): PageComponentDto {
376
290
  const { id, value, label } = buttonDto;
291
+ const onclickAction: ButtonClickAction =
292
+ options.kind === "response-button"
293
+ ? {
294
+ kind: "submit-fact",
295
+ fact: {
296
+ kind: "numeric-fact",
297
+ label: label,
298
+ value: value,
299
+ referenceId: options.questionId,
300
+ referenceLabel: "QuestionId: " + options.questionId,
301
+ },
302
+ }
303
+ : { kind: "next-page" };
377
304
 
378
- // const { div, text1, dontKnow } = DefaultTheme.responseButtons;
379
- if (options.kind === "response-button") {
380
- const fact: Fact = {
381
- kind: "numeric-fact",
382
- label: label,
383
- value: value,
384
- referenceId: options.questionId,
385
- referenceLabel: "QuestionId: " + options.questionId,
386
- };
387
- factsCollected.push(fact);
388
- }
389
-
390
- const onClickHandler: DCommand = {
391
- kind: "ENGINE_LEAVE_PAGE_COMMAND",
392
- target: "ENGINE",
393
- targetId: "ENGINE",
394
- payload: {
395
- pageId,
396
- factsCollected,
397
- },
398
- };
399
- const btnStyles = value === 9 ? DefaultTheme.responseButtons.dontKnow : DefaultTheme.responseButtons.normal;
305
+ const btnStyles =
306
+ value === 9 ? DefaultTheme.responseButtons.dontKnow : DefaultTheme.responseButtons.normal;
400
307
  const btn: DDivDto = {
401
- id,
402
308
  _tag: "div",
403
309
  children: [
404
310
  {
405
311
  _tag: "p",
406
- id: U.randomString(30),
407
- text: label,
312
+ innerText: label,
408
313
  style: btnStyles.text1,
409
314
  },
410
315
  ],
411
- onStateChange: [
412
- {
413
- queryName: DStateProps._Queries.disableUserInputQuery.name,
414
- whenFalse: [...ThemeUtils.enableClickCommands(id, btnStyles.btn.cssEnabled)],
415
- whenTrue: [...ThemeUtils.disableClickCommands(id, btnStyles.btn.cssDisabled)],
416
- },
417
- ],
418
316
  style: { ...btnStyles.btn.css, ...btnStyles.btn.cssEnabled },
419
- onClick: [onClickHandler],
420
317
  };
318
+
421
319
  if (options.kind === "next-button") {
422
320
  btn.style.x = 50;
423
321
  btn.style.y = 8;
424
322
  btn.style.transform = "translate(-50%, 0%)";
425
323
  }
426
- return btn;
324
+ const component: PageComponentDto = {
325
+ el: btn,
326
+ onClick: onclickAction,
327
+ };
328
+ return component;
427
329
  }
428
330
  }
@@ -1,60 +1,7 @@
1
- import { DCommand, ElementCommand } from "@media-quest/engine";
2
1
  import { DStyle } from "@media-quest/engine";
3
2
  import { DElementDto } from "@media-quest/engine";
4
3
 
5
4
  export namespace ThemeUtils {
6
- export const disableClickCommands = (elementId: string, styleChanges: Partial<DStyle>): ElementCommand[] => {
7
- return [
8
- {
9
- kind: "ELEMENT_DISABLE_CLICK_COMMAND",
10
- target: "ELEMENT",
11
- targetId: elementId,
12
- payload: {},
13
- },
14
- {
15
- kind: "ELEMENT_STYLE_COMMAND",
16
- target: "ELEMENT",
17
- targetId: elementId,
18
- payload: { changes: styleChanges },
19
- },
20
- ];
21
- };
22
-
23
- export const enableClickCommands = (elementId: string, styleChanges: Partial<DStyle>): ElementCommand[] => {
24
- return [
25
- {
26
- kind: "ELEMENT_ENABLE_CLICK_COMMAND",
27
- target: "ELEMENT",
28
- targetId: elementId,
29
- payload: {},
30
- },
31
- {
32
- kind: "ELEMENT_STYLE_COMMAND",
33
- target: "ELEMENT",
34
- targetId: elementId,
35
- payload: { changes: styleChanges },
36
- },
37
- ];
38
- };
39
- export const hideCommand = (elementId: string): ElementCommand => {
40
- const hideCommand: DCommand = {
41
- kind: "ELEMENT_STYLE_COMMAND",
42
- target: "ELEMENT",
43
- targetId: elementId,
44
- payload: { changes: { visibility: "hidden" } },
45
- };
46
- return hideCommand;
47
- };
48
- export const showCommand = (elementId: string): ElementCommand => {
49
- const showCommand: DCommand = {
50
- kind: "ELEMENT_STYLE_COMMAND",
51
- target: "ELEMENT",
52
- targetId: elementId,
53
- payload: { changes: { visibility: "visible" } },
54
- };
55
- return showCommand;
56
- };
57
-
58
5
  export const spaceEvenlyX = <T extends Pick<DElementDto, "style">>(
59
6
  items: ReadonlyArray<T>,
60
7
  options: { startAt: number; endAt: number; defaultItemWidth: number } = {