docusaurus-live-brython 3.0.0-beta.8 → 3.0.1

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 (175) hide show
  1. package/.devcontainer/devcontainer.json +38 -0
  2. package/.prettierignore +17 -0
  3. package/.prettierrc +9 -8
  4. package/CHANGELOG.md +5 -0
  5. package/README.md +7 -4
  6. package/lib/assets/py_back_trace.py +2 -1
  7. package/lib/index.d.ts +1 -7
  8. package/lib/index.d.ts.map +1 -0
  9. package/lib/index.js +94 -16
  10. package/lib/options.d.ts +1 -0
  11. package/lib/options.d.ts.map +1 -0
  12. package/lib/options.js +2 -2
  13. package/lib/theme/CodeBlock/index.d.ts +3 -3
  14. package/lib/theme/CodeBlock/index.d.ts.map +1 -0
  15. package/lib/theme/CodeBlock/index.jsx +24 -14
  16. package/lib/theme/CodeEditor/Actions/DownloadCode.d.ts +1 -0
  17. package/lib/theme/CodeEditor/Actions/DownloadCode.d.ts.map +1 -0
  18. package/lib/theme/CodeEditor/Actions/DownloadCode.jsx +8 -8
  19. package/lib/theme/CodeEditor/Actions/Reset.d.ts +1 -0
  20. package/lib/theme/CodeEditor/Actions/Reset.d.ts.map +1 -0
  21. package/lib/theme/CodeEditor/Actions/Reset.jsx +5 -5
  22. package/lib/theme/CodeEditor/Actions/RunCode.d.ts +2 -1
  23. package/lib/theme/CodeEditor/Actions/RunCode.d.ts.map +1 -0
  24. package/lib/theme/CodeEditor/Actions/RunCode.jsx +4 -4
  25. package/lib/theme/CodeEditor/Actions/ShowRaw.d.ts +1 -0
  26. package/lib/theme/CodeEditor/Actions/ShowRaw.d.ts.map +1 -0
  27. package/lib/theme/CodeEditor/Actions/ShowRaw.jsx +13 -7
  28. package/lib/theme/CodeEditor/Actions/ShowSyncStatus.d.ts +1 -0
  29. package/lib/theme/CodeEditor/Actions/ShowSyncStatus.d.ts.map +1 -0
  30. package/lib/theme/CodeEditor/Actions/ShowSyncStatus.jsx +21 -16
  31. package/lib/theme/CodeEditor/Actions/styles.module.css +2 -3
  32. package/lib/theme/CodeEditor/BrythonCommunicator.d.ts +2 -1
  33. package/lib/theme/CodeEditor/BrythonCommunicator.d.ts.map +1 -0
  34. package/lib/theme/CodeEditor/BrythonCommunicator.jsx +13 -9
  35. package/lib/theme/CodeEditor/Button/index.d.ts +3 -2
  36. package/lib/theme/CodeEditor/Button/index.d.ts.map +1 -0
  37. package/lib/theme/CodeEditor/Button/index.jsx +1 -1
  38. package/lib/theme/CodeEditor/Button/styles.module.css +1 -1
  39. package/lib/theme/CodeEditor/CodeHistory/index.d.ts +1 -0
  40. package/lib/theme/CodeEditor/CodeHistory/index.d.ts.map +1 -0
  41. package/lib/theme/CodeEditor/CodeHistory/index.jsx +26 -15
  42. package/lib/theme/CodeEditor/CodeHistory/styles.module.css +31 -31
  43. package/lib/theme/CodeEditor/ContextEditor/index.d.ts +22 -0
  44. package/lib/theme/CodeEditor/ContextEditor/index.d.ts.map +1 -0
  45. package/lib/theme/CodeEditor/ContextEditor/index.jsx +36 -0
  46. package/lib/theme/CodeEditor/Editor/EditorAce.d.ts +2 -1
  47. package/lib/theme/CodeEditor/Editor/EditorAce.d.ts.map +1 -0
  48. package/lib/theme/CodeEditor/Editor/EditorAce.jsx +17 -14
  49. package/lib/theme/CodeEditor/Editor/Header/index.d.ts +2 -1
  50. package/lib/theme/CodeEditor/Editor/Header/index.d.ts.map +1 -0
  51. package/lib/theme/CodeEditor/Editor/Header/index.jsx +12 -12
  52. package/lib/theme/CodeEditor/Editor/Header/styles.module.css +7 -7
  53. package/lib/theme/CodeEditor/Editor/HiddenCode/index.d.ts +8 -0
  54. package/lib/theme/CodeEditor/Editor/HiddenCode/index.d.ts.map +1 -0
  55. package/lib/theme/CodeEditor/Editor/HiddenCode/index.jsx +27 -0
  56. package/lib/theme/CodeEditor/Editor/HiddenCode/styles.module.css +52 -0
  57. package/lib/theme/CodeEditor/Editor/Result/Graphics/Canvas.d.ts +1 -0
  58. package/lib/theme/CodeEditor/Editor/Result/Graphics/Canvas.d.ts.map +1 -0
  59. package/lib/theme/CodeEditor/Editor/Result/Graphics/Canvas.jsx +8 -9
  60. package/lib/theme/CodeEditor/Editor/Result/Graphics/Turtle.d.ts +1 -0
  61. package/lib/theme/CodeEditor/Editor/Result/Graphics/Turtle.d.ts.map +1 -0
  62. package/lib/theme/CodeEditor/Editor/Result/Graphics/Turtle.jsx +11 -11
  63. package/lib/theme/CodeEditor/Editor/Result/Graphics/index.d.ts +4 -3
  64. package/lib/theme/CodeEditor/Editor/Result/Graphics/index.d.ts.map +1 -0
  65. package/lib/theme/CodeEditor/Editor/Result/Graphics/index.jsx +12 -10
  66. package/lib/theme/CodeEditor/Editor/Result/Graphics/styles.module.css +2 -2
  67. package/lib/theme/CodeEditor/Editor/Result/index.d.ts +2 -3
  68. package/lib/theme/CodeEditor/Editor/Result/index.d.ts.map +1 -0
  69. package/lib/theme/CodeEditor/Editor/Result/index.jsx +6 -9
  70. package/lib/theme/CodeEditor/Editor/Result/styles.module.css +15 -10
  71. package/lib/theme/CodeEditor/Editor/index.d.ts +6 -3
  72. package/lib/theme/CodeEditor/Editor/index.d.ts.map +1 -0
  73. package/lib/theme/CodeEditor/Editor/index.jsx +34 -28
  74. package/lib/theme/CodeEditor/Editor/styles.module.css +15 -7
  75. package/lib/theme/CodeEditor/Editor/utils/checkForButtonClick.d.ts +1 -0
  76. package/lib/theme/CodeEditor/Editor/utils/checkForButtonClick.d.ts.map +1 -0
  77. package/lib/theme/CodeEditor/Editor/utils/saveSvg.d.ts +1 -0
  78. package/lib/theme/CodeEditor/Editor/utils/saveSvg.d.ts.map +1 -0
  79. package/lib/theme/CodeEditor/Editor/utils/saveSvg.js +19 -8
  80. package/lib/theme/CodeEditor/Editor/utils/svgWithoutAnimations.d.ts +1 -0
  81. package/lib/theme/CodeEditor/Editor/utils/svgWithoutAnimations.d.ts.map +1 -0
  82. package/lib/theme/CodeEditor/Editor/utils/svgWithoutAnimations.js +43 -49
  83. package/lib/theme/CodeEditor/Icon/icons.d.ts +4 -1
  84. package/lib/theme/CodeEditor/Icon/icons.d.ts.map +1 -0
  85. package/lib/theme/CodeEditor/Icon/icons.js +3 -1
  86. package/lib/theme/CodeEditor/Icon/index.d.ts +4 -2
  87. package/lib/theme/CodeEditor/Icon/index.d.ts.map +1 -0
  88. package/lib/theme/CodeEditor/Icon/index.jsx +10 -3
  89. package/lib/theme/CodeEditor/Icon/styles.module.css +1 -1
  90. package/lib/theme/CodeEditor/WithScript/ScriptContext.d.ts +8 -0
  91. package/lib/theme/CodeEditor/WithScript/ScriptContext.d.ts.map +1 -0
  92. package/lib/theme/CodeEditor/WithScript/ScriptContext.jsx +27 -0
  93. package/lib/theme/CodeEditor/WithScript/Storage.d.ts +2 -1
  94. package/lib/theme/CodeEditor/WithScript/Storage.d.ts.map +1 -0
  95. package/lib/theme/CodeEditor/WithScript/Types.d.ts +12 -4
  96. package/lib/theme/CodeEditor/WithScript/Types.d.ts.map +1 -0
  97. package/lib/theme/CodeEditor/WithScript/bryRunner.d.ts +3 -0
  98. package/lib/theme/CodeEditor/WithScript/bryRunner.d.ts.map +1 -0
  99. package/lib/theme/CodeEditor/WithScript/bryRunner.js +29 -0
  100. package/lib/theme/CodeEditor/WithScript/createStore.d.ts +4 -0
  101. package/lib/theme/CodeEditor/WithScript/createStore.d.ts.map +1 -0
  102. package/lib/theme/CodeEditor/WithScript/{Store.jsx → createStore.js} +62 -74
  103. package/lib/theme/CodeEditor/WithScript/helpers.d.ts +1 -4
  104. package/lib/theme/CodeEditor/WithScript/helpers.d.ts.map +1 -0
  105. package/lib/theme/CodeEditor/WithScript/helpers.js +4 -14
  106. package/lib/theme/CodeEditor/constants.d.ts +1 -0
  107. package/lib/theme/CodeEditor/constants.d.ts.map +1 -0
  108. package/lib/theme/CodeEditor/hooks/index.d.ts +3 -0
  109. package/lib/theme/CodeEditor/hooks/index.d.ts.map +1 -0
  110. package/lib/theme/CodeEditor/hooks/index.js +2 -0
  111. package/lib/theme/CodeEditor/hooks/useScript.d.ts +3 -0
  112. package/lib/theme/CodeEditor/hooks/useScript.d.ts.map +1 -0
  113. package/lib/theme/CodeEditor/hooks/useScript.js +4 -0
  114. package/lib/theme/CodeEditor/hooks/useStore.d.ts +3 -0
  115. package/lib/theme/CodeEditor/hooks/useStore.d.ts.map +1 -0
  116. package/lib/theme/CodeEditor/hooks/useStore.js +10 -0
  117. package/lib/theme/CodeEditor/index.d.ts +24 -5
  118. package/lib/theme/CodeEditor/index.d.ts.map +1 -0
  119. package/lib/theme/CodeEditor/index.jsx +17 -16
  120. package/lib/theme/CodeEditor/styles.module.css +28 -30
  121. package/og-image.md +23 -0
  122. package/package.json +39 -20
  123. package/src/assets/py_back_trace.py +2 -1
  124. package/src/index.ts +96 -25
  125. package/src/options.ts +12 -12
  126. package/src/theme/CodeBlock/index.tsx +44 -68
  127. package/src/theme/CodeEditor/Actions/DownloadCode.tsx +23 -22
  128. package/src/theme/CodeEditor/Actions/Reset.tsx +14 -12
  129. package/src/theme/CodeEditor/Actions/RunCode.tsx +14 -11
  130. package/src/theme/CodeEditor/Actions/ShowRaw.tsx +17 -11
  131. package/src/theme/CodeEditor/Actions/ShowSyncStatus.tsx +32 -27
  132. package/src/theme/CodeEditor/Actions/styles.module.css +2 -3
  133. package/src/theme/CodeEditor/BrythonCommunicator.tsx +16 -19
  134. package/src/theme/CodeEditor/Button/index.tsx +17 -13
  135. package/src/theme/CodeEditor/Button/styles.module.css +1 -1
  136. package/src/theme/CodeEditor/CodeHistory/index.tsx +32 -20
  137. package/src/theme/CodeEditor/CodeHistory/styles.module.css +31 -31
  138. package/src/theme/CodeEditor/ContextEditor/index.tsx +74 -0
  139. package/src/theme/CodeEditor/Editor/EditorAce.tsx +20 -16
  140. package/src/theme/CodeEditor/Editor/Header/index.tsx +13 -19
  141. package/src/theme/CodeEditor/Editor/Header/styles.module.css +7 -7
  142. package/src/theme/CodeEditor/Editor/HiddenCode/index.tsx +49 -0
  143. package/src/theme/CodeEditor/Editor/HiddenCode/styles.module.css +52 -0
  144. package/src/theme/CodeEditor/Editor/Result/Graphics/Canvas.tsx +25 -22
  145. package/src/theme/CodeEditor/Editor/Result/Graphics/Turtle.tsx +23 -19
  146. package/src/theme/CodeEditor/Editor/Result/Graphics/index.tsx +16 -16
  147. package/src/theme/CodeEditor/Editor/Result/Graphics/styles.module.css +2 -2
  148. package/src/theme/CodeEditor/Editor/Result/index.tsx +7 -13
  149. package/src/theme/CodeEditor/Editor/Result/styles.module.css +15 -10
  150. package/src/theme/CodeEditor/Editor/index.tsx +67 -65
  151. package/src/theme/CodeEditor/Editor/styles.module.css +15 -7
  152. package/src/theme/CodeEditor/Editor/utils/checkForButtonClick.ts +5 -5
  153. package/src/theme/CodeEditor/Editor/utils/saveSvg.ts +63 -53
  154. package/src/theme/CodeEditor/Editor/utils/svgWithoutAnimations.ts +182 -201
  155. package/src/theme/CodeEditor/Icon/icons.ts +27 -13
  156. package/src/theme/CodeEditor/Icon/index.tsx +31 -11
  157. package/src/theme/CodeEditor/Icon/styles.module.css +1 -1
  158. package/src/theme/CodeEditor/WithScript/ScriptContext.tsx +36 -0
  159. package/src/theme/CodeEditor/WithScript/Storage.ts +3 -3
  160. package/src/theme/CodeEditor/WithScript/Types.ts +17 -11
  161. package/src/theme/CodeEditor/WithScript/bryRunner.ts +39 -0
  162. package/src/theme/CodeEditor/WithScript/createStore.ts +276 -0
  163. package/src/theme/CodeEditor/WithScript/helpers.ts +16 -26
  164. package/src/theme/CodeEditor/constants.ts +9 -11
  165. package/src/theme/CodeEditor/hooks/index.ts +2 -0
  166. package/src/theme/CodeEditor/hooks/useScript.ts +9 -0
  167. package/src/theme/CodeEditor/hooks/useStore.ts +15 -0
  168. package/src/theme/CodeEditor/index.tsx +45 -31
  169. package/src/theme/CodeEditor/styles.module.css +28 -30
  170. package/src/typings.d.ts +11 -0
  171. package/lib/theme/CodeEditor/WithScript/Store.d.ts +0 -15
  172. package/lib/types.d.ts +0 -28
  173. package/lib/types.js +0 -1
  174. package/src/theme/CodeEditor/WithScript/Store.tsx +0 -294
  175. package/src/types.ts +0 -29
@@ -1,41 +1,46 @@
1
1
  import * as React from 'react';
2
- import { useScript, useStore } from 'docusaurus-live-brython/theme/CodeEditor/WithScript/Store';
3
- import Icon, { Color } from 'docusaurus-live-brython/theme/CodeEditor/Icon';
4
- import { Status } from 'docusaurus-live-brython/theme/CodeEditor/WithScript/Types';
2
+ import { useStore, useScript } from '@theme/CodeEditor/hooks';
3
+ import Icon, { Color } from '@theme/CodeEditor/Icon';
4
+ import { Status } from '@theme/CodeEditor/WithScript/Types';
5
+ import BrowserOnly from '@docusaurus/BrowserOnly';
5
6
 
6
7
  const ShowSyncStatus = () => {
7
- const { store } = useScript();
8
- const isLoaded = useStore(store, (state) => state.isLoaded);
9
- const status = useStore(store, (state) => state.status);
8
+ const store = useStore();
9
+ const isLoaded = useScript(store, 'isLoaded');
10
+ const status = useScript(store, 'status');
10
11
 
11
12
  React.useEffect(() => {
12
13
  if (status !== Status.IDLE) {
13
14
  const disposer = setTimeout(() => {
14
- store.setState((state) => ({ ...state, status: Status.IDLE }));
15
+ store.setStatus(Status.IDLE);
15
16
  }, 1200);
16
17
  return () => clearTimeout(disposer);
17
18
  }
18
19
  }, [status, store]);
19
20
 
20
21
  return (
21
- <>
22
- {!isLoaded && (
23
- <Icon icon='Sync' spin size={'1.2em'} color={Color.Primary}/>
24
- )}
25
- <div style={{flexGrow: 1, flexShrink: 1, flexBasis: 0}}></div>
26
- <span style={{ minWidth: '1em' }}>
27
- {status === Status.SYNCING && (
28
- <Icon icon='Sync' spin size={'1.2em'} color={Color.Primary}/>
29
- )}
30
- {status === Status.SUCCESS && (
31
- <Icon icon='Check' size={'1.2em'} color={Color.Success}/>
32
- )}
33
- {status === Status.ERROR && (
34
- <Icon icon='Close' size={'1.2em'} color={Color.Danger}/>
35
- )}
36
- </span>
37
- </>
38
- )
39
- }
22
+ <BrowserOnly fallback={null}>
23
+ {() => {
24
+ return (
25
+ <>
26
+ {!isLoaded && <Icon icon="Sync" spin size={'1.2em'} color={Color.Primary} />}
27
+ <div style={{ flexGrow: 1, flexShrink: 1, flexBasis: 0 }}></div>
28
+ <span style={{ minWidth: '1em' }}>
29
+ {status === Status.SYNCING && (
30
+ <Icon icon="Sync" spin size={'1.2em'} color={Color.Primary} />
31
+ )}
32
+ {status === Status.SUCCESS && (
33
+ <Icon icon="Check" size={'1.2em'} color={Color.Success} />
34
+ )}
35
+ {status === Status.ERROR && (
36
+ <Icon icon="Close" size={'1.2em'} color={Color.Danger} />
37
+ )}
38
+ </span>
39
+ </>
40
+ );
41
+ }}
42
+ </BrowserOnly>
43
+ );
44
+ };
40
45
 
41
- export default ShowSyncStatus;
46
+ export default ShowSyncStatus;
@@ -9,6 +9,5 @@
9
9
  }
10
10
 
11
11
  html[data-theme='dark'] .runCode {
12
- color: white
13
- }
14
-
12
+ color: white;
13
+ }
@@ -1,12 +1,11 @@
1
- import * as React from "react";
2
- import { BRYTHON_NOTIFICATION_EVENT, DOM_ELEMENT_IDS } from "docusaurus-live-brython/theme/CodeEditor/constants";
3
- import { useScript, useStore } from 'docusaurus-live-brython/theme/CodeEditor/WithScript/Store';
4
- import { type LogMessage } from 'docusaurus-live-brython/theme/CodeEditor/WithScript/Types';
1
+ import * as React from 'react';
2
+ import { BRYTHON_NOTIFICATION_EVENT, DOM_ELEMENT_IDS } from '@theme/CodeEditor/constants';
3
+ import { useStore, useScript } from '@theme/CodeEditor/hooks';
4
+ import { type LogMessage } from '@theme/CodeEditor/WithScript/Types';
5
5
 
6
6
  const BrythonCommunicator = () => {
7
- const { store } = useScript();
8
- const codeId = useStore(store, (state) => state.codeId);
9
-
7
+ const store = useStore();
8
+ const codeId = useScript(store, 'codeId');
10
9
 
11
10
  const ref = React.useRef<HTMLDivElement>(null);
12
11
  React.useEffect(() => {
@@ -18,32 +17,30 @@ const BrythonCommunicator = () => {
18
17
  if (event.detail) {
19
18
  const data = event.detail as LogMessage;
20
19
  switch (data.type) {
21
- case "start":
20
+ case 'start':
22
21
  store.clearLogMessages();
23
22
  store.setExecuting(true);
24
23
  break;
25
- case "done":
24
+ case 'done':
26
25
  store.setExecuting(false);
27
26
  break;
28
27
  default:
29
- store.addLogMessage(data);
28
+ store.addLogMessage({
29
+ type: data.type,
30
+ output: data.output,
31
+ timeStamp: data.timeStamp
32
+ });
30
33
  break;
31
34
  }
32
35
  }
33
36
  };
34
37
  current.addEventListener(BRYTHON_NOTIFICATION_EVENT, onBryNotify as EventListener);
35
38
  return () => {
36
- current.removeEventListener(BRYTHON_NOTIFICATION_EVENT, onBryNotify as EventListener)
37
- }
38
-
39
+ current.removeEventListener(BRYTHON_NOTIFICATION_EVENT, onBryNotify as EventListener);
40
+ };
39
41
  }, [ref, store]);
40
42
 
41
- return (
42
- <div
43
- id={DOM_ELEMENT_IDS.communicator(codeId)}
44
- ref={ref}
45
- ></div>
46
- );
43
+ return <div id={DOM_ELEMENT_IDS.communicator(codeId)} ref={ref}></div>;
47
44
  };
48
45
 
49
46
  export default BrythonCommunicator;
@@ -1,8 +1,8 @@
1
1
  import * as React from 'react';
2
- import * as Icons from 'docusaurus-live-brython/theme/CodeEditor/Icon/icons';
2
+ import * as Icons from '@theme/CodeEditor/Icon/icons';
3
3
  import styles from './styles.module.css';
4
4
  import clsx from 'clsx';
5
- import Icon from 'docusaurus-live-brython/theme/CodeEditor/Icon';
5
+ import Icon from '@theme/CodeEditor/Icon';
6
6
 
7
7
  export enum Color {
8
8
  Primary = 'button--primary',
@@ -11,14 +11,14 @@ export enum Color {
11
11
  Info = 'button--info',
12
12
  Warning = 'button--warning',
13
13
  Danger = 'button--danger',
14
- Link = 'button--link',
14
+ Link = 'button--link'
15
15
  }
16
16
  export enum Size {
17
17
  Small = 'button--sm',
18
- Large = 'button--lg',
18
+ Large = 'button--lg'
19
19
  }
20
20
 
21
- interface Props {
21
+ export interface Props {
22
22
  icon: keyof typeof Icons;
23
23
  title?: string;
24
24
  onClick?: React.MouseEventHandler<HTMLButtonElement>;
@@ -29,23 +29,27 @@ interface Props {
29
29
  className?: string;
30
30
  }
31
31
 
32
-
33
32
  const Button = (props: Props) => {
34
-
35
33
  return (
36
- <button
37
- className={clsx('button', props.color || Color.Secondary, props.size || Size.Small, styles.button, props.className)}
34
+ <button
35
+ className={clsx(
36
+ 'button',
37
+ props.color || Color.Secondary,
38
+ props.size || Size.Small,
39
+ styles.button,
40
+ props.className
41
+ )}
38
42
  onClick={props.onClick}
39
43
  title={props.title}
40
44
  >
41
- <Icon
45
+ <Icon
42
46
  icon={props.icon}
43
47
  className={styles.icon}
44
48
  spin={props.spin}
45
49
  size={props.iconSize || '1.6em'}
46
50
  />
47
51
  </button>
48
- )
49
- }
52
+ );
53
+ };
50
54
 
51
- export default Button;
55
+ export default Button;
@@ -6,4 +6,4 @@
6
6
  cursor: pointer;
7
7
  margin: 0px 2px;
8
8
  padding: 4px 10px;
9
- }
9
+ }
@@ -4,10 +4,10 @@ import styles from './styles.module.css';
4
4
  import { Prism } from 'prism-react-renderer';
5
5
  import Slider from 'rc-slider';
6
6
  import 'rc-slider/assets/index.css';
7
- import { useScript, useStore } from 'docusaurus-live-brython/theme/CodeEditor/WithScript/Store';
7
+ import { useStore, useScript } from '@theme/CodeEditor/hooks';
8
8
  import Translate, { translate } from '@docusaurus/Translate';
9
- import Button from 'docusaurus-live-brython/theme/CodeEditor/Button';
10
- import DiffViewer from 'react-diff-viewer';
9
+ import Button from '@theme/CodeEditor/Button';
10
+ import DiffViewer from 'react-diff-viewer-continued';
11
11
  import Details from '@theme/Details';
12
12
 
13
13
  const highlightSyntax = (str: string) => {
@@ -17,7 +17,7 @@ const highlightSyntax = (str: string) => {
17
17
  return (
18
18
  <span
19
19
  dangerouslySetInnerHTML={{
20
- __html: Prism.highlight(str, Prism.languages.python, 'python'),
20
+ __html: Prism.highlight(str, Prism.languages.python, 'python')
21
21
  }}
22
22
  />
23
23
  );
@@ -25,13 +25,13 @@ const highlightSyntax = (str: string) => {
25
25
 
26
26
  const CodeHistory = () => {
27
27
  const [version, setVersion] = React.useState(1);
28
- const { store } = useScript();
29
- const versions = useStore(store, (state) => state.versions);
30
- const versionsLoaded = useStore(store, (state) => state.versionsLoaded);
31
-
28
+ const store = useStore();
29
+ const versions = useScript(store, 'versions');
30
+ const versionsLoaded = useScript(store, 'versionsLoaded');
32
31
  if (versions?.length < 2) {
33
32
  return null;
34
33
  }
34
+
35
35
  return (
36
36
  <div className={clsx(styles.codeHistory)}>
37
37
  <Details
@@ -40,16 +40,26 @@ const CodeHistory = () => {
40
40
  <summary>
41
41
  <div className={clsx(styles.summary)}>
42
42
  <span className="badge badge--secondary">
43
- {
44
- versionsLoaded
45
- ? translate({message: '{n} Versions', id: 'CodeHistory.nVersions.text'}, {n: versions.length})
46
- : translate({message: 'Load Versions', id: 'CodeHistory.LoadVersions.text'})
47
- }
43
+ {versionsLoaded
44
+ ? translate(
45
+ {
46
+ message: '{n} Versions',
47
+ id: 'CodeHistory.nVersions.text'
48
+ },
49
+ { n: versions.length }
50
+ )
51
+ : translate({
52
+ message: 'Load Versions',
53
+ id: 'CodeHistory.LoadVersions.text'
54
+ })}
48
55
  </span>
49
56
  <span className={clsx(styles.spacer)}></span>
50
57
  <Button
51
- icon='Sync'
52
- title={translate({message: 'Sync Versions', id: 'CodeHistory.LoadVersions.text'})}
58
+ icon="Sync"
59
+ title={translate({
60
+ message: 'Sync Versions',
61
+ id: 'CodeHistory.LoadVersions.text'
62
+ })}
53
63
  onClick={(e) => {
54
64
  e.preventDefault();
55
65
  e.stopPropagation();
@@ -80,9 +90,7 @@ const CodeHistory = () => {
80
90
  max={versions.length - 1}
81
91
  dots={versions.length < 50}
82
92
  />
83
- <span className="badge badge--primary">
84
- V{version}
85
- </span>
93
+ <span className="badge badge--primary">V{version}</span>
86
94
  </div>
87
95
  <div className={clsx(styles.diffViewer)}>
88
96
  {versions.length > 1 && (
@@ -95,7 +103,9 @@ const CodeHistory = () => {
95
103
  {`V${version}`}
96
104
  {versions[version].pasted && (
97
105
  <span className={clsx('badge', 'badge--danger')}>
98
- <Translate id="CodeHistory.PastedBadge.Text">Pasted</Translate>
106
+ <Translate id="CodeHistory.PastedBadge.Text">
107
+ Pasted
108
+ </Translate>
99
109
  </span>
100
110
  )}
101
111
  </div>
@@ -105,7 +115,9 @@ const CodeHistory = () => {
105
115
  {`V${version}`}
106
116
  {versions[version].pasted && (
107
117
  <span className={clsx('badge', 'badge--danger')}>
108
- <Translate id="CodeHistory.PastedBadge.Text">Pasted</Translate>
118
+ <Translate id="CodeHistory.PastedBadge.Text">
119
+ Pasted
120
+ </Translate>
109
121
  </span>
110
122
  )}
111
123
  </div>
@@ -1,54 +1,54 @@
1
- .codeHistory>.historyDetails {
2
- cursor: pointer;
3
- margin-bottom: 0;
4
- border-top-left-radius: 0;
5
- border-top-right-radius: 0;
1
+ .codeHistory > .historyDetails {
2
+ cursor: pointer;
3
+ margin-bottom: 0;
4
+ border-top-left-radius: 0;
5
+ border-top-right-radius: 0;
6
6
  }
7
7
  .summary {
8
- display: flex;
9
- align-items: center;
8
+ display: flex;
9
+ align-items: center;
10
10
  }
11
11
  .spacer {
12
- flex-grow: 1;
13
- flex-shrink: 1;
14
- flex-basis: 0;
15
- }
12
+ flex-grow: 1;
13
+ flex-shrink: 1;
14
+ flex-basis: 0;
15
+ }
16
16
 
17
17
  .versionControl {
18
- padding: 1em 2em;
19
- box-shadow: var(--ifm-global-shadow-lw);
20
- border-radius: var(--ifm-global-radius);
18
+ padding: 1em 2em;
19
+ box-shadow: var(--ifm-global-shadow-lw);
20
+ border-radius: var(--ifm-global-radius);
21
21
  }
22
22
 
23
23
  .faButton {
24
- margin-left: 1em;
24
+ margin-left: 1em;
25
25
  }
26
26
 
27
27
  .faButton:hover {
28
- transform: scale(1.2);
28
+ transform: scale(1.2);
29
29
  }
30
30
 
31
31
  .diffViewer {
32
- --ifm-pre-background: rgba(255, 255, 255, 0);
33
- --ifm-alert-background-color: rgba(255, 255, 255, 0);
34
- --ifm-alert-background-color-highlight: rgba(255, 255, 255, 0);
35
- --ifm-table-stripe-background: rgba(255, 255, 255, 0);
36
- font-family: monospace;
37
- overflow: auto;
32
+ --ifm-pre-background: rgba(255, 255, 255, 0);
33
+ --ifm-alert-background-color: rgba(255, 255, 255, 0);
34
+ --ifm-alert-background-color-highlight: rgba(255, 255, 255, 0);
35
+ --ifm-table-stripe-background: rgba(255, 255, 255, 0);
36
+ font-family: monospace;
37
+ overflow: auto;
38
38
  }
39
39
 
40
40
  .diffViewer table tbody tr td {
41
- padding-top: 0;
42
- padding-bottom: 0;
41
+ padding-top: 0;
42
+ padding-bottom: 0;
43
43
  }
44
44
 
45
45
  .diffViewer table tbody tr td pre {
46
- white-space: nowrap;
47
- padding-top: 0;
48
- padding-bottom: 0;
49
- line-height: 18px;
46
+ white-space: nowrap;
47
+ padding-top: 0;
48
+ padding-bottom: 0;
49
+ line-height: 18px;
50
50
  }
51
51
  .diffHeader {
52
- display: flex;
53
- justify-content: space-between;
54
- }
52
+ display: flex;
53
+ justify-content: space-between;
54
+ }
@@ -0,0 +1,74 @@
1
+ import React from 'react';
2
+ import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
3
+ import CodeEditor, { type MetaProps } from '@theme/CodeEditor';
4
+ import ScriptContext from '@theme/CodeEditor/WithScript/ScriptContext';
5
+ import CodeBlock from '@theme/CodeBlock';
6
+
7
+ interface Props extends MetaProps {
8
+ className?: string;
9
+ title?: string;
10
+ children: string | React.ReactNode;
11
+ onChange?: (code: string) => void;
12
+ }
13
+
14
+ const SPLIT_CODE_REGEX = /^(?:(?<pre>.*?)\n###\s*PRE\s*)?(?<code>.*?)(?:\n###\s*POST\s*(?<post>.*))?$/s;
15
+ export const splitCode = (rawCode: string) => {
16
+ const { pre, code, post } = rawCode.replace(/\s*\n$/, '').match(SPLIT_CODE_REGEX).groups || {};
17
+ return {
18
+ pre: pre || '',
19
+ code: code || '',
20
+ post: post || ''
21
+ };
22
+ };
23
+
24
+ /**
25
+ * Use this component when you want a working CodeEditor.
26
+ * The CodeEditor must be wrapped in a ScriptContext - this component does that.
27
+ * wraps it in a ScriptContext and initializes the CodeEditor with the given
28
+ * params.
29
+ */
30
+ const ContextEditor = (props: Props) => {
31
+ const langMatch = ((props.className || '') as string).match(/language-(?<lang>\w*)/);
32
+ let lang = langMatch?.groups?.lang?.toLocaleLowerCase() ?? '';
33
+ if (lang === 'py') {
34
+ lang = 'python';
35
+ }
36
+ if (ExecutionEnvironment.canUseDOM) {
37
+ const title = props.title || lang;
38
+ const { pre, code, post } = splitCode((props.children as string) || '');
39
+ return (
40
+ <ScriptContext
41
+ id={props.id}
42
+ lang={lang}
43
+ title={title}
44
+ code={code}
45
+ preCode={pre}
46
+ postCode={post}
47
+ readonly={!!props.readonly}
48
+ versioned={!!props.versioned}
49
+ >
50
+ <CodeEditor
51
+ code={code}
52
+ lang={lang}
53
+ preCode={pre}
54
+ postCode={post}
55
+ maxLines={props.maxLines && Number.parseInt(props.maxLines, 10)}
56
+ readonly={!!props.readonly}
57
+ resettable={!props.noReset}
58
+ download={!props.versioned && !props.noDownload}
59
+ slim={!!props.slim}
60
+ showLineNumbers={!(!!props.slim && !/\n/.test(code))}
61
+ versioned={!!props.versioned}
62
+ noHistory={!!props.noHistory}
63
+ noCompare={!!props.noCompare}
64
+ title={title}
65
+ className={props.className}
66
+ onChange={props.onChange}
67
+ />
68
+ </ScriptContext>
69
+ );
70
+ }
71
+ return <CodeBlock {...props} />;
72
+ };
73
+
74
+ export default ContextEditor;
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import clsx from 'clsx';
3
3
  import styles from './styles.module.css';
4
- import { DOM_ELEMENT_IDS } from 'docusaurus-live-brython/theme/CodeEditor/constants';
4
+ import { DOM_ELEMENT_IDS } from '@theme/CodeEditor/constants';
5
5
  import AceEditor from 'react-ace';
6
6
  import 'ace-builds/src-noconflict/ext-searchbox';
7
7
  import 'ace-builds/src-noconflict/mode-python';
@@ -10,7 +10,7 @@ import 'ace-builds/src-noconflict/mode-svg';
10
10
  import 'ace-builds/src-noconflict/theme-dracula';
11
11
  import 'ace-builds/src-noconflict/ext-language_tools';
12
12
  import 'ace-builds/webpack-resolver';
13
- import { useScript, useStore } from 'docusaurus-live-brython/theme/CodeEditor/WithScript/Store';
13
+ import { useStore, useScript } from '@theme/CodeEditor/hooks';
14
14
  // import 'ace-builds/src-noconflict/theme-textmate';
15
15
  // import('ace-builds/src-noconflict/snippets/python'),
16
16
 
@@ -18,20 +18,21 @@ export interface Props {
18
18
  versioned?: boolean;
19
19
  showLineNumbers: boolean;
20
20
  maxLines?: number;
21
+ onChange?: (code: string) => void;
21
22
  }
22
23
 
23
24
  const ALIAS_LANG_MAP_ACE = {
24
- mpy: 'python',
25
- }
25
+ mpy: 'python'
26
+ };
26
27
 
27
28
  const EditorAce = (props: Props) => {
28
29
  const eRef = React.useRef<AceEditor>(null);
29
- const { store } = useScript();
30
- const code = useStore(store, (state) => state.code);
31
- const pristineCode = useStore(store, (state) => state.pristineCode);
32
- const lang = useStore(store, (state) => state.lang);
33
- const codeId = useStore(store, (state) => state.codeId);
34
- const showRaw = useStore(store, (state) => state.showRaw);
30
+ const store = useStore();
31
+ const code = useScript(store, 'code');
32
+ const pristineCode = useScript(store, 'pristineCode');
33
+ const lang = useScript(store, 'lang');
34
+ const codeId = useScript(store, 'codeId');
35
+ const showRaw = useScript(store, 'showRaw');
35
36
 
36
37
  React.useEffect(() => {
37
38
  if (eRef && eRef.current) {
@@ -41,7 +42,7 @@ const EditorAce = (props: Props) => {
41
42
  // commands is array of key bindings.
42
43
  name: 'execute',
43
44
  bindKey: { win: 'Ctrl-Enter', mac: 'Command-Enter' },
44
- exec: () => store.execScript(),
45
+ exec: () => store.execScript()
45
46
  });
46
47
  }
47
48
  node.editor.commands.addCommand({
@@ -50,7 +51,7 @@ const EditorAce = (props: Props) => {
50
51
  bindKey: { win: 'Ctrl-s', mac: 'Command-s' },
51
52
  exec: () => {
52
53
  store.saveNow();
53
- },
54
+ }
54
55
  });
55
56
  return () => {
56
57
  if (node && node.editor) {
@@ -65,7 +66,7 @@ const EditorAce = (props: Props) => {
65
66
  }
66
67
  };
67
68
  }
68
- }, [eRef, lang]);
69
+ }, [eRef, lang, store]);
69
70
 
70
71
  return (
71
72
  <div className={clsx(styles.editor)}>
@@ -83,7 +84,7 @@ const EditorAce = (props: Props) => {
83
84
  /**
84
85
  * Save immediately as pasted content
85
86
  */
86
- store.setState((s) => ({ ...s, isPasted: true }));
87
+ store.setIsPasted(true);
87
88
  }
88
89
  }}
89
90
  focus={false}
@@ -92,8 +93,11 @@ const EditorAce = (props: Props) => {
92
93
  ref={eRef}
93
94
  mode={ALIAS_LANG_MAP_ACE[lang as keyof typeof ALIAS_LANG_MAP_ACE] ?? lang}
94
95
  theme="dracula"
95
- onChange={(value: string, e: {action: 'insert' | 'remove'}) => {
96
+ onChange={(value: string, e: { action: 'insert' | 'remove' }) => {
96
97
  store.setCode(value, e.action);
98
+ if (props.onChange) {
99
+ props.onChange(value);
100
+ }
97
101
  }}
98
102
  readOnly={showRaw}
99
103
  value={showRaw ? pristineCode : code}
@@ -103,7 +107,7 @@ const EditorAce = (props: Props) => {
103
107
  setOptions={{
104
108
  displayIndentGuides: true,
105
109
  vScrollBarAlwaysVisible: false,
106
- highlightGutterLine: false,
110
+ highlightGutterLine: false
107
111
  }}
108
112
  showPrintMargin={false}
109
113
  highlightActiveLine={false}
@@ -1,14 +1,14 @@
1
1
  import * as React from 'react';
2
2
  import clsx from 'clsx';
3
3
  import styles from './styles.module.css';
4
- import { useScript, useStore } from 'docusaurus-live-brython/theme/CodeEditor/WithScript/Store';
5
- import ShowSyncStatus from 'docusaurus-live-brython/theme/CodeEditor/Actions/ShowSyncStatus';
6
- import Reset from 'docusaurus-live-brython/theme/CodeEditor/Actions/Reset';
7
- import DownloadCode from 'docusaurus-live-brython/theme/CodeEditor/Actions/DownloadCode';
8
- import ShowRaw from 'docusaurus-live-brython/theme/CodeEditor/Actions/ShowRaw';
9
- import RunCode from 'docusaurus-live-brython/theme/CodeEditor/Actions/RunCode';
4
+ import { useStore, useScript } from '@theme/CodeEditor/hooks';
5
+ import ShowSyncStatus from '@theme/CodeEditor/Actions/ShowSyncStatus';
6
+ import Reset from '@theme/CodeEditor/Actions/Reset';
7
+ import DownloadCode from '@theme/CodeEditor/Actions/DownloadCode';
8
+ import ShowRaw from '@theme/CodeEditor/Actions/ShowRaw';
9
+ import RunCode from '@theme/CodeEditor/Actions/RunCode';
10
10
 
11
- interface Props {
11
+ export interface Props {
12
12
  slim: boolean;
13
13
  title: string;
14
14
  resettable: boolean;
@@ -17,25 +17,19 @@ interface Props {
17
17
  }
18
18
 
19
19
  const Header = (props: Props) => {
20
- const { store } = useScript();
20
+ const store = useStore();
21
21
 
22
- const hasEdits = useStore(store, (state) => state.hasEdits);
23
- const lang = useStore(store, (state) => state.lang);
22
+ const hasEdits = useScript(store, 'hasEdits');
23
+ const lang = useScript(store, 'lang');
24
24
  return (
25
25
  <div className={clsx(styles.controls, props.slim && styles.slim)}>
26
26
  {!props.slim && (
27
27
  <React.Fragment>
28
28
  <div className={styles.title}>{props.title}</div>
29
29
  <ShowSyncStatus />
30
- {hasEdits && props.resettable && (
31
- <Reset />
32
- )}
33
- {props.download && (
34
- <DownloadCode title={props.title} />
35
- )}
36
- {hasEdits && !props.noCompare && (
37
- <ShowRaw />
38
- )}
30
+ {hasEdits && props.resettable && <Reset />}
31
+ {props.download && <DownloadCode title={props.title} />}
32
+ {hasEdits && !props.noCompare && <ShowRaw />}
39
33
  </React.Fragment>
40
34
  )}
41
35
  {lang === 'python' && <RunCode title={props.title} slim={props.slim} />}