@dxos/plugin-presenter 0.6.8-main.046e6cf
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/LICENSE +8 -0
- package/README.md +3 -0
- package/dist/lib/browser/MarkdownSlide-RIKDY66R.mjs +313 -0
- package/dist/lib/browser/MarkdownSlide-RIKDY66R.mjs.map +7 -0
- package/dist/lib/browser/PresenterMain-J5Y5ND2S.mjs +228 -0
- package/dist/lib/browser/PresenterMain-J5Y5ND2S.mjs.map +7 -0
- package/dist/lib/browser/RevealMain-3KPVP35M.mjs +170 -0
- package/dist/lib/browser/RevealMain-3KPVP35M.mjs.map +7 -0
- package/dist/lib/browser/chunk-KWRWOGSM.mjs +20 -0
- package/dist/lib/browser/chunk-KWRWOGSM.mjs.map +7 -0
- package/dist/lib/browser/chunk-XDACGTXJ.mjs +18 -0
- package/dist/lib/browser/chunk-XDACGTXJ.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +216 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/lib/browser/meta.mjs +9 -0
- package/dist/lib/browser/meta.mjs.map +7 -0
- package/dist/types/src/PresenterPlugin.d.ts +4 -0
- package/dist/types/src/PresenterPlugin.d.ts.map +1 -0
- package/dist/types/src/components/Markdown/Container.d.ts +8 -0
- package/dist/types/src/components/Markdown/Container.d.ts.map +1 -0
- package/dist/types/src/components/Markdown/Container.stories.d.ts +34 -0
- package/dist/types/src/components/Markdown/Container.stories.d.ts.map +1 -0
- package/dist/types/src/components/Markdown/Slide.d.ts +10 -0
- package/dist/types/src/components/Markdown/Slide.d.ts.map +1 -0
- package/dist/types/src/components/Markdown/Slide.stories.d.ts +15 -0
- package/dist/types/src/components/Markdown/Slide.stories.d.ts.map +1 -0
- package/dist/types/src/components/Markdown/index.d.ts +3 -0
- package/dist/types/src/components/Markdown/index.d.ts.map +1 -0
- package/dist/types/src/components/Markdown/theme.d.ts +16 -0
- package/dist/types/src/components/Markdown/theme.d.ts.map +1 -0
- package/dist/types/src/components/MarkdownSlide.d.ts +7 -0
- package/dist/types/src/components/MarkdownSlide.d.ts.map +1 -0
- package/dist/types/src/components/Presenter/Layout.d.ts +11 -0
- package/dist/types/src/components/Presenter/Layout.d.ts.map +1 -0
- package/dist/types/src/components/Presenter/Pager.d.ts +19 -0
- package/dist/types/src/components/Presenter/Pager.d.ts.map +1 -0
- package/dist/types/src/components/Presenter/Pager.stories.d.ts +14 -0
- package/dist/types/src/components/Presenter/Pager.stories.d.ts.map +1 -0
- package/dist/types/src/components/Presenter/index.d.ts +3 -0
- package/dist/types/src/components/Presenter/index.d.ts.map +1 -0
- package/dist/types/src/components/PresenterMain.d.ts +7 -0
- package/dist/types/src/components/PresenterMain.d.ts.map +1 -0
- package/dist/types/src/components/PresenterSettings.d.ts +6 -0
- package/dist/types/src/components/PresenterSettings.d.ts.map +1 -0
- package/dist/types/src/components/Reveal/Reveal.d.ts +10 -0
- package/dist/types/src/components/Reveal/Reveal.d.ts.map +1 -0
- package/dist/types/src/components/Reveal/index.d.ts +2 -0
- package/dist/types/src/components/Reveal/index.d.ts.map +1 -0
- package/dist/types/src/components/Reveal.stories.d.ts +9 -0
- package/dist/types/src/components/Reveal.stories.d.ts.map +1 -0
- package/dist/types/src/components/RevealMain.d.ts +7 -0
- package/dist/types/src/components/RevealMain.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +12 -0
- package/dist/types/src/components/index.d.ts.map +1 -0
- package/dist/types/src/hooks/index.d.ts +2 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -0
- package/dist/types/src/hooks/useControlledValue.d.ts +3 -0
- package/dist/types/src/hooks/useControlledValue.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +5 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/meta.d.ts +15 -0
- package/dist/types/src/meta.d.ts.map +1 -0
- package/dist/types/src/testing.d.ts +10 -0
- package/dist/types/src/testing.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +11 -0
- package/dist/types/src/translations.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +14 -0
- package/dist/types/src/types.d.ts.map +1 -0
- package/package.json +80 -0
- package/src/PresenterPlugin.tsx +158 -0
- package/src/components/Markdown/Container.stories.tsx +54 -0
- package/src/components/Markdown/Container.tsx +81 -0
- package/src/components/Markdown/Slide.stories.tsx +22 -0
- package/src/components/Markdown/Slide.tsx +218 -0
- package/src/components/Markdown/index.ts +6 -0
- package/src/components/Markdown/theme.ts +26 -0
- package/src/components/MarkdownSlide.tsx +24 -0
- package/src/components/Presenter/Layout.tsx +33 -0
- package/src/components/Presenter/Pager.stories.tsx +32 -0
- package/src/components/Presenter/Pager.tsx +124 -0
- package/src/components/Presenter/index.ts +6 -0
- package/src/components/PresenterMain.tsx +85 -0
- package/src/components/PresenterSettings.tsx +26 -0
- package/src/components/Reveal/Reveal.tsx +136 -0
- package/src/components/Reveal/index.ts +5 -0
- package/src/components/Reveal.stories.tsx +32 -0
- package/src/components/RevealMain.tsx +49 -0
- package/src/components/index.ts +12 -0
- package/src/hooks/index.ts +5 -0
- package/src/hooks/useControlledValue.ts +14 -0
- package/src/index.ts +11 -0
- package/src/meta.tsx +18 -0
- package/src/testing.ts +48 -0
- package/src/translations.ts +17 -0
- package/src/types.ts +39 -0
- package/src/typings.d.ts +15 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { type FC, useContext, useState } from 'react';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
Surface,
|
|
9
|
+
useIntentDispatcher,
|
|
10
|
+
useResolvePlugin,
|
|
11
|
+
parseLayoutPlugin,
|
|
12
|
+
NavigationAction,
|
|
13
|
+
} from '@dxos/app-framework';
|
|
14
|
+
import { type CollectionType } from '@dxos/plugin-space/types';
|
|
15
|
+
import { fullyQualifiedId } from '@dxos/react-client/echo';
|
|
16
|
+
import { Main } from '@dxos/react-ui';
|
|
17
|
+
import {
|
|
18
|
+
baseSurface,
|
|
19
|
+
topbarBlockPaddingStart,
|
|
20
|
+
fixedInsetFlexLayout,
|
|
21
|
+
bottombarBlockPaddingEnd,
|
|
22
|
+
} from '@dxos/react-ui-theme';
|
|
23
|
+
|
|
24
|
+
import { Layout, PageNumber, Pager, StartButton } from './Presenter';
|
|
25
|
+
import { PRESENTER_PLUGIN } from '../meta';
|
|
26
|
+
import { PresenterContext, TOGGLE_PRESENTATION } from '../types';
|
|
27
|
+
|
|
28
|
+
const PresenterMain: FC<{ collection: CollectionType }> = ({ collection }) => {
|
|
29
|
+
const [slide, setSlide] = useState(0);
|
|
30
|
+
|
|
31
|
+
// TODO(burdon): Should not depend on split screen.
|
|
32
|
+
const layoutPlugin = useResolvePlugin(parseLayoutPlugin);
|
|
33
|
+
const fullscreen = layoutPlugin?.provides.layout.layoutMode === 'fullscreen';
|
|
34
|
+
const { running } = useContext(PresenterContext);
|
|
35
|
+
|
|
36
|
+
// TODO(burdon): Currently conflates fullscreen and running.
|
|
37
|
+
const dispatch = useIntentDispatcher();
|
|
38
|
+
const handleSetRunning = (running: boolean) => {
|
|
39
|
+
void dispatch([
|
|
40
|
+
{
|
|
41
|
+
plugin: PRESENTER_PLUGIN,
|
|
42
|
+
action: TOGGLE_PRESENTATION,
|
|
43
|
+
data: { state: running },
|
|
44
|
+
},
|
|
45
|
+
...(!running
|
|
46
|
+
? [
|
|
47
|
+
{
|
|
48
|
+
action: NavigationAction.CLOSE,
|
|
49
|
+
data: { activeParts: { fullScreen: fullyQualifiedId(collection) } },
|
|
50
|
+
},
|
|
51
|
+
]
|
|
52
|
+
: []),
|
|
53
|
+
]);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<Main.Content
|
|
58
|
+
classNames={[
|
|
59
|
+
baseSurface,
|
|
60
|
+
fixedInsetFlexLayout,
|
|
61
|
+
!fullscreen && topbarBlockPaddingStart,
|
|
62
|
+
!fullscreen && bottombarBlockPaddingEnd,
|
|
63
|
+
]}
|
|
64
|
+
>
|
|
65
|
+
<Layout
|
|
66
|
+
topRight={<StartButton running={running} onClick={(running) => handleSetRunning(running)} />}
|
|
67
|
+
bottomRight={<PageNumber index={slide} count={collection.objects.length} />}
|
|
68
|
+
bottomLeft={
|
|
69
|
+
<Pager
|
|
70
|
+
index={slide}
|
|
71
|
+
count={collection.objects.length}
|
|
72
|
+
keys={running}
|
|
73
|
+
onChange={setSlide}
|
|
74
|
+
onExit={() => handleSetRunning(false)}
|
|
75
|
+
/>
|
|
76
|
+
}
|
|
77
|
+
>
|
|
78
|
+
{/* TODO(wittjosiah): Better slide placeholder. */}
|
|
79
|
+
<Surface role='slide' data={{ slide: collection.objects[slide] }} placeholder={<></>} />
|
|
80
|
+
</Layout>
|
|
81
|
+
</Main.Content>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export default PresenterMain;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import { SettingsValue } from '@dxos/plugin-settings';
|
|
8
|
+
import { Input, useTranslation } from '@dxos/react-ui';
|
|
9
|
+
|
|
10
|
+
import { PRESENTER_PLUGIN } from '../meta';
|
|
11
|
+
import { type PresenterSettingsProps } from '../types';
|
|
12
|
+
|
|
13
|
+
export const PresenterSettings = ({ settings }: { settings: PresenterSettingsProps }) => {
|
|
14
|
+
const { t } = useTranslation(PRESENTER_PLUGIN);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<>
|
|
18
|
+
<SettingsValue label={t('present collections label')}>
|
|
19
|
+
<Input.Switch
|
|
20
|
+
checked={settings.presentCollections}
|
|
21
|
+
onCheckedChange={(checked) => (settings.presentCollections = !!checked)}
|
|
22
|
+
/>
|
|
23
|
+
</SettingsValue>
|
|
24
|
+
</>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
// eslint-disable-next-line no-restricted-imports
|
|
6
|
+
import 'reveal.js/dist/reveal.css';
|
|
7
|
+
// eslint-disable-next-line no-restricted-imports
|
|
8
|
+
import 'reveal.js/dist/theme/black.css';
|
|
9
|
+
|
|
10
|
+
import React, { useEffect, useRef } from 'react';
|
|
11
|
+
import Reveal from 'reveal.js';
|
|
12
|
+
import Markdown from 'reveal.js/plugin/markdown/plugin.js';
|
|
13
|
+
// import Notes from 'reveal.js/plugin/notes/notes.js';
|
|
14
|
+
|
|
15
|
+
const styles = `
|
|
16
|
+
<style type="text/css">
|
|
17
|
+
.reveal h1 {
|
|
18
|
+
font-weight: 100;
|
|
19
|
+
padding-left: 36px;
|
|
20
|
+
opacity: 0.5;
|
|
21
|
+
}
|
|
22
|
+
.reveal h2 {
|
|
23
|
+
font-weight: 100;
|
|
24
|
+
padding-top: 60px;
|
|
25
|
+
padding-left: 40px;
|
|
26
|
+
font-size: 48px;
|
|
27
|
+
opacity: 0.3;
|
|
28
|
+
}
|
|
29
|
+
.reveal h1, h2, p {
|
|
30
|
+
font-family: "Raleway", sans-serif;
|
|
31
|
+
text-align: left;
|
|
32
|
+
font-weight: 200;
|
|
33
|
+
}
|
|
34
|
+
.reveal ul {
|
|
35
|
+
font-family: "Raleway", sans-serif;
|
|
36
|
+
display: block;
|
|
37
|
+
list-style: "- ";
|
|
38
|
+
}
|
|
39
|
+
.reveal blockquote p {
|
|
40
|
+
text-align: center;
|
|
41
|
+
font-weight: 100;
|
|
42
|
+
padding: 32px;
|
|
43
|
+
}
|
|
44
|
+
</style>
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
export type RevealProps = {
|
|
48
|
+
content: string;
|
|
49
|
+
slide?: number;
|
|
50
|
+
onExit?: () => void;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// https://revealjs.com/react
|
|
54
|
+
export const RevealPlayer = ({ content, slide, onExit }: RevealProps) => {
|
|
55
|
+
const deckDivRef = useRef<HTMLDivElement>(null);
|
|
56
|
+
const deckRef = useRef<Reveal.Api | null>(null);
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
if (deckRef.current) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
setTimeout(async () => {
|
|
63
|
+
// https://revealjs.com/config
|
|
64
|
+
// https://github.com/hakimel/reveal.js
|
|
65
|
+
// TODO(burdon): Fragments and scroll view steps 2 at a time (safe mode?)
|
|
66
|
+
deckRef.current = new Reveal(deckDivRef.current!, {
|
|
67
|
+
// view: 'scroll',
|
|
68
|
+
progress: false,
|
|
69
|
+
transition: 'none',
|
|
70
|
+
slideNumber: false,
|
|
71
|
+
embedded: true,
|
|
72
|
+
// https://revealjs.com/speaker-view
|
|
73
|
+
showNotes: false,
|
|
74
|
+
|
|
75
|
+
center: true,
|
|
76
|
+
margin: 0.01,
|
|
77
|
+
minScale: 0.2,
|
|
78
|
+
maxScale: 1.4,
|
|
79
|
+
|
|
80
|
+
// https://revealjs.com/markdown
|
|
81
|
+
plugins: [
|
|
82
|
+
Markdown,
|
|
83
|
+
// TODO(burdon): Requires server to serve popout window.
|
|
84
|
+
// Notes
|
|
85
|
+
],
|
|
86
|
+
|
|
87
|
+
// See https://marked.js.org/using_advanced#options
|
|
88
|
+
markdown: {
|
|
89
|
+
gfm: true,
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
await deckRef.current.initialize();
|
|
94
|
+
if (slide !== undefined) {
|
|
95
|
+
deckRef.current.slide(slide < 0 ? deckRef.current?.getTotalSlides() + slide : slide - 1);
|
|
96
|
+
}
|
|
97
|
+
// TODO(burdon): Translation.
|
|
98
|
+
deckRef.current.addKeyBinding({ keyCode: 27, key: 'Escape', description: 'Exit full screen' }, () => {
|
|
99
|
+
onExit?.();
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
return () => {
|
|
104
|
+
try {
|
|
105
|
+
if (deckRef.current) {
|
|
106
|
+
deckRef.current.destroy();
|
|
107
|
+
deckRef.current = null;
|
|
108
|
+
}
|
|
109
|
+
} catch (err) {
|
|
110
|
+
// Ignore.
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
<div className='absolute inset-0 h-full'>
|
|
117
|
+
<div ref={deckDivRef} className='reveal'>
|
|
118
|
+
{/* TODO(burdon): Must be in head. */}
|
|
119
|
+
<style>
|
|
120
|
+
<link rel='preconnect' href='https://fonts.googleapis.com' />
|
|
121
|
+
<link rel='preconnect' href='https://fonts.gstatic.com' {...{ crossOrigin: '' }} />
|
|
122
|
+
<link
|
|
123
|
+
href='https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,100..900;1,100..900&display=swap'
|
|
124
|
+
rel='stylesheet'
|
|
125
|
+
/>
|
|
126
|
+
</style>
|
|
127
|
+
<div className='slides'>
|
|
128
|
+
<div className='!text-center' />
|
|
129
|
+
<section {...{ 'data-markdown': [] }}>
|
|
130
|
+
<textarea {...{ 'data-template': true }} defaultValue={[styles, content].join('\n')}></textarea>
|
|
131
|
+
</section>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
);
|
|
136
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import '@dxosTheme';
|
|
6
|
+
|
|
7
|
+
import React from 'react';
|
|
8
|
+
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
// eslint-disable-next-line import/order
|
|
11
|
+
import CONTENT from '../../testing/deck.md?raw';
|
|
12
|
+
|
|
13
|
+
// eslint-disable-next-line import/order
|
|
14
|
+
import { RevealPlayer } from './Reveal';
|
|
15
|
+
|
|
16
|
+
// https://revealjs.com/markdown
|
|
17
|
+
// https://developer.mozilla.org/en-US/docs/Web/CSS/background-position
|
|
18
|
+
// https://colorhunt.co/palettes/dark
|
|
19
|
+
// https://colorhunt.co/palette/ff204ea0153e5d0e4100224d
|
|
20
|
+
// https://colorhunt.co/palette/27374d526d829db2bfdde6ed
|
|
21
|
+
// https://fontsource.org/fonts
|
|
22
|
+
// https://fonts.google.com
|
|
23
|
+
const Story = () => {
|
|
24
|
+
return <RevealPlayer content={CONTENT} />;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default {
|
|
28
|
+
title: 'plugin-presenter/Reveal',
|
|
29
|
+
render: Story,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const Default = {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { type FC } from 'react';
|
|
6
|
+
|
|
7
|
+
import { NavigationAction, useIntentDispatcher, useResolvePlugin, parseLayoutPlugin } from '@dxos/app-framework';
|
|
8
|
+
import { type DocumentType } from '@dxos/plugin-markdown/types';
|
|
9
|
+
import { fullyQualifiedId } from '@dxos/react-client/echo';
|
|
10
|
+
import { Main } from '@dxos/react-ui';
|
|
11
|
+
import { topbarBlockPaddingStart, fixedInsetFlexLayout, bottombarBlockPaddingEnd } from '@dxos/react-ui-theme';
|
|
12
|
+
|
|
13
|
+
import { RevealPlayer } from './Reveal';
|
|
14
|
+
import { PRESENTER_PLUGIN } from '../meta';
|
|
15
|
+
import { TOGGLE_PRESENTATION } from '../types';
|
|
16
|
+
|
|
17
|
+
const PresenterMain: FC<{ document: DocumentType }> = ({ document }) => {
|
|
18
|
+
const fullscreen = useResolvePlugin(parseLayoutPlugin)?.provides.layout.layoutMode === 'fullscreen';
|
|
19
|
+
const dispatch = useIntentDispatcher();
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<Main.Content
|
|
23
|
+
classNames={[
|
|
24
|
+
fixedInsetFlexLayout,
|
|
25
|
+
!fullscreen && topbarBlockPaddingStart,
|
|
26
|
+
!fullscreen && bottombarBlockPaddingEnd,
|
|
27
|
+
]}
|
|
28
|
+
>
|
|
29
|
+
<RevealPlayer
|
|
30
|
+
content={document.content?.content ?? ''}
|
|
31
|
+
onExit={() => {
|
|
32
|
+
void dispatch([
|
|
33
|
+
{
|
|
34
|
+
plugin: PRESENTER_PLUGIN,
|
|
35
|
+
action: TOGGLE_PRESENTATION,
|
|
36
|
+
data: { state: false },
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
action: NavigationAction.CLOSE,
|
|
40
|
+
data: { activeParts: { fullScreen: fullyQualifiedId(document) } },
|
|
41
|
+
},
|
|
42
|
+
]);
|
|
43
|
+
}}
|
|
44
|
+
/>
|
|
45
|
+
</Main.Content>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default PresenterMain;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
export * from './PresenterSettings';
|
|
8
|
+
|
|
9
|
+
// Lazily load components for content surfaces.
|
|
10
|
+
export const RevealMain = React.lazy(() => import('./RevealMain'));
|
|
11
|
+
export const PresenterMain = React.lazy(() => import('./PresenterMain'));
|
|
12
|
+
export const MarkdownSlide = React.lazy(() => import('./MarkdownSlide'));
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Dispatch, type SetStateAction, useEffect, useState } from 'react';
|
|
6
|
+
|
|
7
|
+
// TODO(burdon): Factor out.
|
|
8
|
+
export const useControlledValue = <TValue>(controlledValue: TValue): [TValue, Dispatch<SetStateAction<TValue>>] => {
|
|
9
|
+
const [value, setValue] = useState<TValue>(controlledValue);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
setValue(controlledValue);
|
|
12
|
+
}, [controlledValue]);
|
|
13
|
+
return [value, setValue];
|
|
14
|
+
};
|
package/src/index.ts
ADDED
package/src/meta.tsx
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Presentation, type IconProps } from '@phosphor-icons/react';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
import { pluginMeta } from '@dxos/app-framework';
|
|
9
|
+
|
|
10
|
+
export const PRESENTER_PLUGIN = 'dxos.org/plugin/presenter';
|
|
11
|
+
|
|
12
|
+
export default pluginMeta({
|
|
13
|
+
id: PRESENTER_PLUGIN,
|
|
14
|
+
name: 'Presenter',
|
|
15
|
+
description: 'Present documents as slideshows.',
|
|
16
|
+
iconComponent: (props: IconProps) => <Presentation {...props} />,
|
|
17
|
+
iconSymbol: 'ph--presentation--regular',
|
|
18
|
+
});
|
package/src/testing.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { faker } from '@dxos/random';
|
|
6
|
+
|
|
7
|
+
type SlideOptions = {
|
|
8
|
+
number?: number;
|
|
9
|
+
code?: boolean;
|
|
10
|
+
list?: number;
|
|
11
|
+
ordered?: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const createSlide = (options: SlideOptions = {}) => {
|
|
15
|
+
const num = options.number === undefined ? '' : `${options.number}. `;
|
|
16
|
+
|
|
17
|
+
const code = () =>
|
|
18
|
+
[
|
|
19
|
+
'```tsx',
|
|
20
|
+
'const x = [1, 2, 3];',
|
|
21
|
+
'const f = (x: number[]) => x.reduce((acc, value) => acc + value, 0)',
|
|
22
|
+
'const y = f(x)',
|
|
23
|
+
'```',
|
|
24
|
+
].join('\n');
|
|
25
|
+
|
|
26
|
+
const list = (length = 3) =>
|
|
27
|
+
Array.from({ length })
|
|
28
|
+
.map(() => `- ${faker.lorem.sentence(3)}`)
|
|
29
|
+
.join('\n');
|
|
30
|
+
|
|
31
|
+
const ordered = (length = 3) =>
|
|
32
|
+
Array.from({ length })
|
|
33
|
+
.map((_, i) => `${i + 1}. ${faker.lorem.sentence(3)}`)
|
|
34
|
+
.join('\n');
|
|
35
|
+
|
|
36
|
+
return [
|
|
37
|
+
`# ${num}${faker.lorem.sentence(3)}`,
|
|
38
|
+
faker.lorem.sentences(),
|
|
39
|
+
options.code && code(),
|
|
40
|
+
options.list && list(options.list),
|
|
41
|
+
options.ordered && ordered(options.ordered),
|
|
42
|
+
faker.lorem.sentences(),
|
|
43
|
+
]
|
|
44
|
+
.filter(Boolean)
|
|
45
|
+
.join('\n\r');
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const createSlides = (length = 1) => Array.from({ length }).map((_, i) => createSlide({ number: i + 1 }));
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { PRESENTER_PLUGIN } from './meta';
|
|
6
|
+
|
|
7
|
+
export default [
|
|
8
|
+
{
|
|
9
|
+
'en-US': {
|
|
10
|
+
[PRESENTER_PLUGIN]: {
|
|
11
|
+
'plugin name': 'Presenter',
|
|
12
|
+
'toggle presentation label': 'Present',
|
|
13
|
+
'present collections label': 'Present collections (experimental)',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
];
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type Context, createContext } from 'react';
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
GraphBuilderProvides,
|
|
9
|
+
IntentResolverProvides,
|
|
10
|
+
SettingsProvides,
|
|
11
|
+
SurfaceProvides,
|
|
12
|
+
TranslationsProvides,
|
|
13
|
+
} from '@dxos/app-framework';
|
|
14
|
+
|
|
15
|
+
import { PRESENTER_PLUGIN } from './meta';
|
|
16
|
+
|
|
17
|
+
export type PresenterContextType = {
|
|
18
|
+
running: boolean;
|
|
19
|
+
start: () => void;
|
|
20
|
+
stop: () => void;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const PresenterContext: Context<PresenterContextType> = createContext<PresenterContextType>({
|
|
24
|
+
running: false,
|
|
25
|
+
start: () => {},
|
|
26
|
+
stop: () => {},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export type PresenterSettingsProps = {
|
|
30
|
+
presentCollections?: boolean;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type PresenterPluginProvides = SurfaceProvides &
|
|
34
|
+
IntentResolverProvides &
|
|
35
|
+
GraphBuilderProvides &
|
|
36
|
+
TranslationsProvides &
|
|
37
|
+
SettingsProvides<PresenterSettingsProps>;
|
|
38
|
+
|
|
39
|
+
export const TOGGLE_PRESENTATION = `${PRESENTER_PLUGIN}/toggle-presentation`;
|
package/src/typings.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2022 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
declare module 'rehype-add-classes' {
|
|
6
|
+
export default function Module();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
declare module 'reveal.js/plugin/markdown/plugin.js' {
|
|
10
|
+
export default function Plugin();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
declare module 'reveal.js/plugin/notes/notes.js' {
|
|
14
|
+
export default function Plugin();
|
|
15
|
+
}
|