generator-folklore 3.0.30 → 3.0.33

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.
Files changed (48) hide show
  1. package/lib/generators/build/index.js +0 -12
  2. package/lib/generators/html-project/index.js +5 -0
  3. package/lib/generators/laravel-project/index.js +4 -0
  4. package/lib/generators/micromag-project/index.js +82 -25
  5. package/lib/generators/micromag-project/templates/App.tsx +50 -0
  6. package/lib/generators/micromag-project/templates/Layout.tsx +38 -0
  7. package/lib/generators/micromag-project/templates/MicromagPage.tsx +73 -0
  8. package/lib/generators/micromag-project/templates/Routes.tsx +32 -0
  9. package/lib/generators/micromag-project/templates/contexts/AnalyticsContext.tsx +44 -0
  10. package/lib/generators/micromag-project/templates/contexts/ModalContext.tsx +69 -0
  11. package/lib/generators/micromag-project/templates/hooks/useKeyboardKeys.ts +29 -0
  12. package/lib/generators/micromag-project/templates/hooks/useMicromagPreview.ts +15 -0
  13. package/lib/generators/micromag-project/templates/hooks/useMicromagStory.ts +48 -0
  14. package/lib/generators/micromag-project/templates/hooks/useMicromagVideo.ts +40 -0
  15. package/lib/generators/micromag-project/templates/hooks/useParseFonts.ts +15 -0
  16. package/lib/generators/micromag-project/templates/hooks/useStoryTrackingVariables.ts +41 -0
  17. package/lib/generators/micromag-project/templates/icons/Cookie.tsx +22 -0
  18. package/lib/generators/micromag-project/templates/index.html.ejs +95 -0
  19. package/lib/generators/micromag-project/templates/kiosk/HomePage.tsx +35 -0
  20. package/lib/generators/micromag-project/templates/kiosk/Routes.tsx +47 -0
  21. package/lib/generators/micromag-project/templates/kiosk/home-page.module.css +83 -0
  22. package/lib/generators/micromag-project/templates/kiosk/micromags.ts +13 -0
  23. package/lib/generators/micromag-project/templates/kiosk/styles.css +86 -0
  24. package/lib/generators/micromag-project/templates/layout.module.css +26 -0
  25. package/lib/generators/micromag-project/templates/lib/addTrackingCodesToStory.ts +26 -0
  26. package/lib/generators/micromag-project/templates/micromags.ts +13 -0
  27. package/lib/generators/micromag-project/templates/modals/Consent.tsx +63 -0
  28. package/lib/generators/micromag-project/templates/partials/Micromag.tsx +156 -0
  29. package/lib/generators/micromag-project/templates/partials/Preview.tsx +28 -0
  30. package/lib/generators/micromag-project/templates/partials/Thumbnail.tsx +24 -0
  31. package/lib/generators/micromag-project/templates/partials/Video.tsx +36 -0
  32. package/lib/generators/micromag-project/templates/styles/modals/consent.module.css +150 -0
  33. package/lib/generators/micromag-project/templates/styles/pages/micromag.module.css +6 -0
  34. package/lib/generators/micromag-project/templates/styles/partials/micromag.module.css +17 -0
  35. package/lib/generators/micromag-project/templates/styles/partials/preview.module.css +3 -0
  36. package/lib/generators/micromag-project/templates/styles/partials/thumbnail.module.css +3 -0
  37. package/lib/generators/micromag-project/templates/styles/partials/video.module.css +3 -0
  38. package/lib/generators/micromag-project/templates/styles.css +85 -2
  39. package/lib/generators/micromag-project/templates/types/micromag.d.ts +58 -0
  40. package/lib/generators/react-app/templates/types/base.d.ts +1 -0
  41. package/lib/generators/typescript/index.js +50 -0
  42. package/lib/generators/typescript/templates/_tsconfig.json +8 -0
  43. package/package.json +3 -3
  44. package/lib/generators/build/templates/.jsconfig.json +0 -9
  45. package/lib/generators/build/templates/.tsconfig.json +0 -7
  46. package/lib/generators/micromag-project/templates/Home.jsx +0 -33
  47. package/lib/generators/micromag-project/templates/Routes.jsx +0 -26
  48. package/lib/generators/micromag-project/templates/home.module.css +0 -19
@@ -83,18 +83,6 @@ module.exports = class AppGenerator extends _generator.default {
83
83
  this.addDevDependencies({
84
84
  '@folklore/cli': '^0.1.28'
85
85
  });
86
- this.addDevDependencies({
87
- '@tsconfig/create-react-app': '^2.0.7'
88
- });
89
- },
90
- templates() {
91
- // const srcPathJs = this.templatePath('.jsconfig.json');
92
- // const destPathJs = this.destinationPath('jsconfig.json');
93
- // this.fs.copy(srcPathJs, destPathJs);
94
-
95
- const srcPathTs = this.templatePath('.tsconfig.json');
96
- const destPathTs = this.destinationPath('tsconfig.json');
97
- this.fs.copy(srcPathTs, destPathTs);
98
86
  }
99
87
  };
100
88
  }
@@ -92,6 +92,11 @@ module.exports = class HTMLProjectGenerator extends _generator.default {
92
92
  'skip-install': true,
93
93
  quiet: true
94
94
  });
95
+ this.composeWith('folklore:typescript', {
96
+ 'src-path': srcPath,
97
+ 'skip-install': true,
98
+ quiet: true
99
+ });
95
100
  this.composeWith('folklore:eslint', {
96
101
  'skip-install': true,
97
102
  quiet: true
@@ -194,6 +194,10 @@ module.exports = class LaravelProjectGenerator extends _generator.default {
194
194
  'skip-install': true,
195
195
  quiet: true
196
196
  });
197
+ this.composeWith('folklore:typescript', {
198
+ 'src-path': jsSrcPath,
199
+ quiet: true
200
+ });
197
201
  this.composeWith('folklore:eslint', {
198
202
  'skip-install': true,
199
203
  quiet: true
@@ -24,6 +24,12 @@ module.exports = class MicromagProjectGenerator extends _generator.default {
24
24
  desc: 'Path for build',
25
25
  defaults: './dist'
26
26
  });
27
+ this.option('kiosk', {
28
+ type: Boolean,
29
+ required: false,
30
+ defaults: false
31
+ });
32
+ this.relativeStylesPath = (from, src) => _path.default.relative(this.destinationPath(_path.default.dirname(_path.default.join(this.options['src-path'], from))), this.destinationPath(_path.default.join(_path.default.join(this.options['src-path'], 'styles'), src)));
27
33
  this.srcPath = filePath => this.destinationPath(_path.default.join(this.options['src-path'], filePath));
28
34
  }
29
35
  get prompting() {
@@ -35,6 +41,7 @@ module.exports = class MicromagProjectGenerator extends _generator.default {
35
41
  console.log(_chalk.default.yellow('\n----------------------'));
36
42
  console.log('Micromag Project Generator');
37
43
  console.log(_chalk.default.yellow('----------------------\n'));
44
+ console.log('Kiosk mode: ' + (this.options.kiosk ? 'Enabled' : 'Disabled'));
38
45
  },
39
46
  prompts() {
40
47
  const prompts = [];
@@ -66,41 +73,91 @@ module.exports = class MicromagProjectGenerator extends _generator.default {
66
73
  'dest-path': destPath
67
74
  });
68
75
  }
69
- get conflicts() {
76
+ conflicts() {
77
+ const {
78
+ kiosk = false
79
+ } = this.options;
80
+ const files = {
81
+ 'index.html.ejs': 'index.html.ejs',
82
+ 'components/App.tsx': 'App.tsx',
83
+ 'components/Routes.tsx': kiosk ? 'kiosk/Routes.tsx' : 'Routes.tsx',
84
+ 'styles/styles.css': kiosk ? 'kiosk/styles.css' : 'styles.css',
85
+ 'components/layouts/Main.tsx': 'Layout.tsx',
86
+ 'styles/layouts/main.module.css': 'layout.module.css',
87
+ 'components/pages/Home.tsx': kiosk ? 'kiosk/HomePage.tsx' : null,
88
+ 'styles/pages/home.module.css': kiosk ? 'kiosk/home-page.module.css' : null
89
+ };
90
+ Object.keys(files).forEach(destFile => {
91
+ if (files[destFile] === null) {
92
+ return;
93
+ }
94
+ this.fs.delete(this.srcPath(destFile));
95
+ this.fs.copyTpl(this.templatePath(files[destFile]), this.srcPath(destFile), {
96
+ getRelativeStylesPath: this.relativeStylesPath
97
+ });
98
+ });
99
+ }
100
+ get writing() {
70
101
  return {
71
- home() {
102
+ data() {
72
103
  const {
73
- 'src-path': srcPath
104
+ kiosk = false
74
105
  } = this.options;
75
- const templateData = {
76
- getRelativeStylesPath: (from, src) => _path.default.relative(this.destinationPath(_path.default.dirname(_path.default.join(srcPath, from))), this.destinationPath(_path.default.join(_path.default.join(srcPath, 'styles'), src)))
77
- };
78
- this.fs.delete(this.srcPath('components/pages/Home.jsx'));
79
- this.fs.delete(this.srcPath('styles/pages/home.module.css'));
80
- this.fs.copyTpl(this.templatePath('Home.jsx'), this.srcPath('components/pages/Home.jsx'), templateData);
81
- this.fs.copyTpl(this.templatePath('home.module.css'), this.srcPath('styles/pages/home.module.css'), templateData);
106
+ this.fs.copyTpl(this.templatePath('data.json'), this.srcPath(kiosk ? 'micromags/test/data.json' : 'micromag/data.json'));
107
+ this.fs.copyTpl(this.templatePath(kiosk ? 'kiosk/micromags.ts' : 'micromags.ts'), this.srcPath('micromags.ts'));
82
108
  },
83
- routes() {
84
- const {
85
- 'src-path': srcPath
86
- } = this.options;
87
- const templateData = {
88
- getRelativeStylesPath: (from, src) => _path.default.relative(this.destinationPath(_path.default.dirname(_path.default.join(srcPath, from))), this.destinationPath(_path.default.join(_path.default.join(srcPath, 'styles'), src)))
89
- };
90
- this.fs.delete(this.srcPath('components/Routes.jsx'));
91
- this.fs.copyTpl(this.templatePath('Routes.jsx'), this.srcPath('components/Routes.jsx'), templateData);
109
+ micromagPage() {
110
+ this.fs.copyTpl(this.templatePath('MicromagPage.tsx'), this.srcPath('components/pages/Micromag.tsx'), {
111
+ getRelativeStylesPath: this.relativeStylesPath
112
+ });
113
+ },
114
+ types() {
115
+ this.fs.copyTpl(this.templatePath('types'), this.srcPath('types'), {
116
+ getRelativeStylesPath: this.relativeStylesPath
117
+ });
92
118
  },
93
119
  styles() {
94
- this.fs.delete(this.srcPath('styles/styles.css'));
95
- this.fs.copyTpl(this.templatePath('styles.css'), this.srcPath('styles/styles.css'));
120
+ this.fs.copyTpl(this.templatePath('styles'), this.srcPath('styles'), {
121
+ getRelativeStylesPath: this.relativeStylesPath
122
+ });
123
+ },
124
+ hooks() {
125
+ this.fs.copyTpl(this.templatePath('hooks'), this.srcPath('hooks'), {
126
+ getRelativeStylesPath: this.relativeStylesPath
127
+ });
128
+ },
129
+ contexts() {
130
+ this.fs.copyTpl(this.templatePath('contexts'), this.srcPath('contexts'), {
131
+ getRelativeStylesPath: this.relativeStylesPath
132
+ });
133
+ },
134
+ lib() {
135
+ this.fs.copyTpl(this.templatePath('lib'), this.srcPath('lib'), {
136
+ getRelativeStylesPath: this.relativeStylesPath
137
+ });
138
+ },
139
+ partials() {
140
+ this.fs.copyTpl(this.templatePath('partials'), this.srcPath('components/partials'), {
141
+ getRelativeStylesPath: this.relativeStylesPath
142
+ });
96
143
  },
97
- micromag() {
98
- this.fs.copyTpl(this.templatePath('data.json'), this.srcPath('micromag/data.json'));
144
+ modals() {
145
+ this.fs.copyTpl(this.templatePath('modals'), this.srcPath('components/modals'), {
146
+ getRelativeStylesPath: this.relativeStylesPath
147
+ });
148
+ },
149
+ icons() {
150
+ this.fs.copyTpl(this.templatePath('icons'), this.srcPath('components/icons'), {
151
+ getRelativeStylesPath: this.relativeStylesPath
152
+ });
99
153
  },
100
154
  dependencies() {
101
155
  this.addDependencies({
102
- '@micromag/viewer': '^0.3.492',
103
- '@micromag/intl': '^0.3.488'
156
+ '@micromag/viewer': '^0.3.767',
157
+ '@micromag/data': '^0.3.767',
158
+ '@micromag/core': '^0.3.767',
159
+ '@micromag/consent': '^0.3.767',
160
+ '@micromag/intl': '^0.3.767'
104
161
  });
105
162
  }
106
163
  };
@@ -0,0 +1,50 @@
1
+ import { RoutesProvider } from '@folklore/routes';
2
+ import { ConsentProvider } from '@micromag/core/contexts';
3
+ import { Router } from 'wouter';
4
+ import { IntlProvider } from '@micromag/intl';
5
+
6
+ import { AnalyticsProvider } from '../contexts/AnalyticsContext';
7
+ import { ModalProvider } from '../contexts/ModalContext';
8
+ import { MicromagItem } from '../types/micromag';
9
+ import Routes from './Routes';
10
+
11
+ import defaultMicromags from '../micromags';
12
+
13
+ import '<%= getRelativeStylesPath('components/App.jsx', 'styles.css') %>';
14
+
15
+
16
+ interface IntlProps {
17
+ locale?: string;
18
+ messages?: Record<string, Record<string, string>> | Record<string, string>;
19
+ }
20
+
21
+ interface AppProps {
22
+ intl?: IntlProps | null;
23
+ routes?: Record<string, string>;
24
+ googleAnalyticsIds?: Array<string>;
25
+ micromags?: MicromagItem[] | null;
26
+ }
27
+
28
+ function App({ intl = null, routes = {}, micromags = defaultMicromags, googleAnalyticsIds }: AppProps) {
29
+ const { locale = 'fr', messages = null } = intl || {};
30
+ const finalMessages = messages !== null && messages[locale] ? messages[locale] : messages;
31
+
32
+ return (
33
+ <IntlProvider locale={locale} messages={finalMessages || {}}>
34
+ <ConsentProvider>
35
+ <ModalProvider>
36
+ <AnalyticsProvider googleAnalyticsIds={googleAnalyticsIds || null}>
37
+ <Router>
38
+ <RoutesProvider routes={routes}>
39
+ <Routes micromags={micromags} />
40
+ </RoutesProvider>
41
+ </Router>
42
+ </AnalyticsProvider>
43
+ </ModalProvider>
44
+ </ConsentProvider>
45
+ </IntlProvider>
46
+ );
47
+ }
48
+
49
+ export default App;
50
+
@@ -0,0 +1,38 @@
1
+ import { useCallback, ReactNode } from 'react';
2
+
3
+ import { useModal } from '../../contexts/ModalContext';
4
+ import Button from '../buttons/Button';
5
+ import Cookie from '../icons/Cookie';
6
+ import Consent from '../modals/Consent';
7
+
8
+ import styles from '<%= getRelativeStylesPath('components/layouts/Main.jsx', 'layouts/main.module.css') %>';
9
+
10
+ interface MainLayoutProps {
11
+ children?: ReactNode;
12
+ }
13
+
14
+ function MainLayout({ children = null }: MainLayoutProps) {
15
+ const { modal = null, setModal = null } = useModal();
16
+ const onClickCookie = useCallback(() => {
17
+ if (setModal !== null) {
18
+ setModal('consent');
19
+ }
20
+ }, [setModal]);
21
+
22
+ return (
23
+ <div className={styles.container}>
24
+ <div className={styles.inner}>
25
+ <div className={styles.content}>{children}</div>
26
+ </div>
27
+ {modal === 'consent' ? (
28
+ <Consent className={styles.consentModal} />
29
+ ) : (
30
+ <Button className={styles.cookies} onClick={onClickCookie}>
31
+ <Cookie className={styles.cookieIcon} />
32
+ </Button>
33
+ )}
34
+ </div>
35
+ );
36
+ }
37
+
38
+ export default MainLayout;
@@ -0,0 +1,73 @@
1
+ import { useCallback } from 'react';
2
+ import { useLocation } from 'wouter';
3
+
4
+ import useMicromagStory from '../../hooks/useMicromagStory';
5
+
6
+ import { MicromagItem } from '../../types/micromag';
7
+ import Micromag from '../partials/Micromag';
8
+ import PageMeta from '../partials/PageMeta';
9
+
10
+ import styles from '<%= getRelativeStylesPath('components/pages/Micromag.jsx', 'pages/micromag.module.css') %>';
11
+
12
+ interface MicromagPageProps {
13
+ micromag: MicromagItem;
14
+ screen?: string | null;
15
+ hasHome?: boolean;
16
+ }
17
+
18
+ function MicromagPage({ micromag, screen = null, hasHome = false }: MicromagPageProps) {
19
+ const [, setLocation] = useLocation();
20
+ const { slug = null } = micromag || {};
21
+ const { story = null } = useMicromagStory(micromag);
22
+ const { title = null } = story || {};
23
+
24
+ const { components: screens = [] } = story || {};
25
+ const baseUrl = slug !== null && hasHome ? `/${slug}` : '/';
26
+
27
+ const pathScreenId = screen || null;
28
+ const pathScreenIndex =
29
+ pathScreenId !== null && pathScreenId.match(/^[0-9]+$/) !== null
30
+ ? parseInt(pathScreenId, 10) - 1
31
+ : null;
32
+ const screenByPathId =
33
+ pathScreenId !== null
34
+ ? screens.find(({ id: screenId = null }) => screenId === pathScreenId) || null
35
+ : null;
36
+ const screenByPathIndex = pathScreenIndex !== null ? screens[pathScreenIndex] || null : null;
37
+ const currentScreen =
38
+ screenByPathId ||
39
+ screenByPathIndex ||
40
+ (pathScreenId === '' ? screens[0] : null) ||
41
+ screens[0] ||
42
+ null;
43
+
44
+ const onScreenChange = useCallback(
45
+ (newScreen = null) => {
46
+ const { id: newScreenId = null } = newScreen || {};
47
+ const newScreenIndex =
48
+ screens.findIndex(({ id: screenId = null }) => screenId === newScreenId) || null;
49
+ setLocation(
50
+ newScreenIndex !== null && newScreenIndex > 0
51
+ ? `${baseUrl.replace(/\/$/, '')}/${newScreenIndex + 1}`
52
+ : `${baseUrl.replace(/\/$/, '')}/`,
53
+ );
54
+ },
55
+ [screens, setLocation],
56
+ );
57
+
58
+ return (
59
+ <div className={styles.container}>
60
+ <PageMeta title={title} />
61
+ <Micromag
62
+ micromag={story}
63
+ basePath={baseUrl}
64
+ hasHome={hasHome}
65
+ currentScreenId={currentScreen !== null ? currentScreen.id : undefined}
66
+ className={styles.micromag}
67
+ onScreenChange={onScreenChange}
68
+ />
69
+ </div>
70
+ );
71
+ }
72
+
73
+ export default MicromagPage;
@@ -0,0 +1,32 @@
1
+ import { Route, Switch } from 'wouter';
2
+
3
+ import { MicromagItem } from '../types/micromag';
4
+ import MainLayout from './layouts/Main';
5
+ import MicromagPage from './pages/Micromag';
6
+
7
+ interface RoutesProps {
8
+ micromags?: MicromagItem[] | null;
9
+ loading?: boolean;
10
+ }
11
+
12
+ function Routes({ micromags = null, loading = false }: RoutesProps) {
13
+ const [micromag] = micromags || [];
14
+ return (
15
+ <Switch>
16
+ <Route path="/:screen">
17
+ {({ screen = null }: { screen?: string; }) => (
18
+ <MainLayout>
19
+ <MicromagPage micromag={micromag} screen={screen} />
20
+ </MainLayout>
21
+ )}
22
+ </Route>
23
+ <Route>
24
+ <MainLayout>
25
+ <MicromagPage micromag={micromag} />
26
+ </MainLayout>
27
+ </Route>
28
+ </Switch>
29
+ );
30
+ }
31
+
32
+ export default Routes;
@@ -0,0 +1,44 @@
1
+ import { useCallback, useContext, useMemo, useState, createContext, ReactNode } from 'react';
2
+
3
+ type AnalyticsContextType = {
4
+ googleAnalyticsIds: Array<string> | null;
5
+ setGoogleAnalyticsIds: ((val: string | null) => void) | null;
6
+ };
7
+
8
+ export const AnalyticsContext = createContext<AnalyticsContextType>({
9
+ googleAnalyticsIds: null,
10
+ setGoogleAnalyticsIds: null,
11
+ });
12
+
13
+ export const useAnalyticsContext = (): AnalyticsContextType => useContext(AnalyticsContext);
14
+
15
+ export const useAnalytics = () => {
16
+ const { googleAnalyticsIds = null, setGoogleAnalyticsIds = null } = useAnalyticsContext() || {};
17
+ return { googleAnalyticsIds, setGoogleAnalyticsIds };
18
+ };
19
+
20
+ interface AnalyticsProviderProps {
21
+ children: ReactNode;
22
+ googleAnalyticsIds: Array<string> | null;
23
+ }
24
+
25
+ export const AnalyticsProvider = ({
26
+ children,
27
+ googleAnalyticsIds: initialIds = null,
28
+ }: AnalyticsProviderProps) => {
29
+ const [googleAnalyticsIds, setGoogleAnalyticsIdsState] = useState(initialIds);
30
+ const setGoogleAnalyticsIds = useCallback(
31
+ (val) => {
32
+ setGoogleAnalyticsIdsState(val);
33
+ },
34
+ [setGoogleAnalyticsIdsState],
35
+ );
36
+ const value = useMemo(
37
+ () => ({
38
+ googleAnalyticsIds,
39
+ setGoogleAnalyticsIds,
40
+ }),
41
+ [googleAnalyticsIds, setGoogleAnalyticsIds],
42
+ );
43
+ return <AnalyticsContext.Provider value={value}>{children}</AnalyticsContext.Provider>;
44
+ };
@@ -0,0 +1,69 @@
1
+ import { useConsent } from '@micromag/core/contexts';
2
+ import {
3
+ useCallback,
4
+ useContext,
5
+ useEffect,
6
+ useMemo,
7
+ useState,
8
+ createContext,
9
+ ReactNode,
10
+ } from 'react';
11
+
12
+ type ModalContextType = {
13
+ modal: any;
14
+ setModal: ((val: any) => void) | null;
15
+ unsetModal: (() => void) | null;
16
+ };
17
+
18
+ export const ModalContext = createContext<ModalContextType>({
19
+ modal: null,
20
+ setModal: null,
21
+ unsetModal: null,
22
+ });
23
+
24
+ export const useModalContext = (): ModalContextType => useContext(ModalContext);
25
+
26
+ export const useModal = () => {
27
+ const { modal = null, setModal = null, unsetModal = null } = useModalContext() || {};
28
+ return { modal, setModal, unsetModal };
29
+ };
30
+
31
+ interface ModalProviderProps {
32
+ children: ReactNode;
33
+ modal?: any;
34
+ }
35
+
36
+ export const ModalProvider = ({
37
+ children = null,
38
+ modal: initialModal = null,
39
+ }: ModalProviderProps) => {
40
+ const [modal, setModalState] = useState(initialModal);
41
+ const { consented = null } = useConsent();
42
+
43
+ useEffect(() => {
44
+ if (!consented) {
45
+ setModalState('consent');
46
+ }
47
+ }, [consented]);
48
+
49
+ const setModal = useCallback(
50
+ (val) => {
51
+ setModalState(val);
52
+ },
53
+ [setModalState],
54
+ );
55
+
56
+ const unsetModal = useCallback(() => {
57
+ setModalState(null);
58
+ }, [setModalState]);
59
+
60
+ const value = useMemo(
61
+ () => ({
62
+ modal,
63
+ setModal,
64
+ unsetModal,
65
+ }),
66
+ [modal, setModalState, setModal, unsetModal],
67
+ );
68
+ return <ModalContext.Provider value={value}>{children}</ModalContext.Provider>;
69
+ };
@@ -0,0 +1,29 @@
1
+ import { useEffect } from 'react';
2
+
3
+ export const KEYS = {
4
+ ARROW_LEFT: 37,
5
+ ARROW_UP: 38,
6
+ ARROW_RIGHT: 39,
7
+ ARROW_DOWN: 40,
8
+ ESCAPE: 27,
9
+ SPACE: 32,
10
+ };
11
+
12
+ const useKeyboardKeys = (keys = {}, { eventName = 'keydown' } = {}) => {
13
+ const keysNames = Object.keys(keys);
14
+ const keysListeners = keysNames.map((key) => keys[key]);
15
+ useEffect(() => {
16
+ const onKeyDown = (e) => {
17
+ const { keyCode } = e;
18
+ if (typeof keys[keyCode] !== 'undefined') {
19
+ keys[keyCode](e);
20
+ }
21
+ };
22
+ document.addEventListener(eventName, onKeyDown);
23
+ return () => {
24
+ document.removeEventListener(eventName, onKeyDown);
25
+ };
26
+ }, [...keysNames, ...keysListeners, eventName]);
27
+ };
28
+
29
+ export default useKeyboardKeys;
@@ -0,0 +1,15 @@
1
+ import { useMemo } from 'react';
2
+ import { MicromagStory } from '../types/micromag';
3
+
4
+ export function useMicromagPreview(story: MicromagStory): MicromagStory {
5
+ return useMemo(() => {
6
+ const { components = null } = story || {};
7
+ const [firstScreen = null] = components || [];
8
+ return {
9
+ ...(story || {}),
10
+ components: [firstScreen],
11
+ };
12
+ }, [story]);
13
+ }
14
+
15
+ export default useMicromagPreview;
@@ -0,0 +1,48 @@
1
+ import { getJSON } from '@folklore/fetch';
2
+ import { useEffect, useState } from 'react';
3
+
4
+ import addTrackingCodesToStory from '../lib/addTrackingCodesToStory';
5
+
6
+ import { useAnalytics } from '../contexts/AnalyticsContext';
7
+ import { MicromagItem } from '../types/micromag';
8
+
9
+ const cache = new Map();
10
+
11
+ export function useMicromagStory(initialMicromag: MicromagItem) {
12
+ const { googleAnalyticsIds = null } = useAnalytics();
13
+
14
+ const [micromag, setMicromag] = useState(initialMicromag);
15
+ const [loading, setLoading] = useState(false);
16
+
17
+ useEffect(() => {
18
+ if (micromag === null) {
19
+ return;
20
+ }
21
+ const { url = null } = micromag || {};
22
+ const previous = cache.get(url) || null;
23
+
24
+ if (previous === null && url !== null) {
25
+ setLoading(true);
26
+ getJSON(url)
27
+ .then((newMicromag) => {
28
+ cache.set(url, newMicromag);
29
+ setMicromag({
30
+ ...micromag,
31
+ story: addTrackingCodesToStory(newMicromag, googleAnalyticsIds),
32
+ });
33
+ setLoading(false);
34
+ })
35
+ .catch(() => {
36
+ // Load failure
37
+ setLoading(false);
38
+ });
39
+ }
40
+ }, [setLoading, setMicromag, micromag, googleAnalyticsIds]);
41
+
42
+ return {
43
+ story: micromag?.story || null,
44
+ loading,
45
+ };
46
+ }
47
+
48
+ export default useMicromagStory;
@@ -0,0 +1,40 @@
1
+ import { useMemo } from 'react';
2
+
3
+ import { MicromagStory } from '../types/micromag';
4
+
5
+ export function useMicromagVideo(story: MicromagStory): {
6
+ url: string | null;
7
+ thumbnail: string | null;
8
+ } {
9
+ const video = useMemo(() => {
10
+ const { components = null, medias = null } = story || {};
11
+ const [firstScreen = null] = components || [];
12
+ const { video = null, background = null } = firstScreen || {};
13
+ const { media: videoMedia = null } = video || {};
14
+
15
+ const { video: backgroundVideo = null } = background || {};
16
+ const { media: backgroundVideoMedia = null } = backgroundVideo || {};
17
+
18
+ const videoId = videoMedia || backgroundVideoMedia || null;
19
+ if (videoId === null) {
20
+ return null;
21
+ }
22
+
23
+ if (medias !== null && typeof medias[videoId] !== 'undefined') {
24
+ return medias[videoId];
25
+ }
26
+
27
+ return null;
28
+ }, [story]);
29
+
30
+ const { files = null, thumbnail_url: thumbnail = null } = video || {};
31
+ const { h264 = null } = files || {};
32
+ const { url = null } = h264 || {};
33
+
34
+ return {
35
+ url,
36
+ thumbnail,
37
+ };
38
+ }
39
+
40
+ export default useMicromagVideo;
@@ -0,0 +1,15 @@
1
+ export function parseFonts(story = null) {
2
+ if (story !== null) {
3
+ // TODO: implement font parsing/replacing logic here if needed
4
+ // const jsonMicromag = JSON.stringify(story);
5
+ // const replaced = jsonMicromag
6
+ // .replace(/Arial/g, 'omnes-semicond')
7
+ // .replace(/Verdana/g, 'omnes-semicond');
8
+ // const finalMicromag = JSON.parse(replaced);
9
+ // return finalMicromag;
10
+ return story;
11
+ }
12
+ return story;
13
+ }
14
+
15
+ export default parseFonts;