@churchapps/apphelper 0.0.8 → 0.0.10

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 (185) hide show
  1. package/.eslintignore +3 -3
  2. package/.eslintrc.json +22 -22
  3. package/LICENSE +21 -21
  4. package/README.md +16 -16
  5. package/dist/components/ExportLink.d.ts.map +1 -1
  6. package/dist/components/ExportLink.js +10 -7
  7. package/dist/components/ExportLink.js.map +1 -1
  8. package/dist/components/markdownEditor/editor.css +787 -787
  9. package/dist/components/markdownEditor/images/icons/arrow-clockwise.svg +3 -3
  10. package/dist/components/markdownEditor/images/icons/arrow-counterclockwise.svg +3 -3
  11. package/dist/components/markdownEditor/images/icons/chat-square-quote.svg +3 -3
  12. package/dist/components/markdownEditor/images/icons/chevron-down.svg +2 -2
  13. package/dist/components/markdownEditor/images/icons/code.svg +2 -2
  14. package/dist/components/markdownEditor/images/icons/journal-code.svg +4 -4
  15. package/dist/components/markdownEditor/images/icons/journal-text.svg +4 -4
  16. package/dist/components/markdownEditor/images/icons/justify.svg +2 -2
  17. package/dist/components/markdownEditor/images/icons/link.svg +3 -3
  18. package/dist/components/markdownEditor/images/icons/list-ol.svg +3 -3
  19. package/dist/components/markdownEditor/images/icons/list-ul.svg +2 -2
  20. package/dist/components/markdownEditor/images/icons/pencil-fill.svg +2 -2
  21. package/dist/components/markdownEditor/images/icons/text-center.svg +2 -2
  22. package/dist/components/markdownEditor/images/icons/text-left.svg +2 -2
  23. package/dist/components/markdownEditor/images/icons/text-paragraph.svg +2 -2
  24. package/dist/components/markdownEditor/images/icons/text-right.svg +2 -2
  25. package/dist/components/markdownEditor/images/icons/type-bold.svg +2 -2
  26. package/dist/components/markdownEditor/images/icons/type-h1.svg +2 -2
  27. package/dist/components/markdownEditor/images/icons/type-h2.svg +2 -2
  28. package/dist/components/markdownEditor/images/icons/type-h3.svg +2 -2
  29. package/dist/components/markdownEditor/images/icons/type-h4.svg +12 -12
  30. package/dist/components/markdownEditor/images/icons/type-italic.svg +2 -2
  31. package/dist/components/markdownEditor/images/icons/type-strikethrough.svg +2 -2
  32. package/dist/components/markdownEditor/images/icons/type-underline.svg +2 -2
  33. package/package.json +84 -84
  34. package/src/components/CreatePerson.tsx +80 -80
  35. package/src/components/DisplayBox.tsx +68 -68
  36. package/src/components/ErrorMessages.tsx +26 -26
  37. package/src/components/ExportLink.tsx +67 -61
  38. package/src/components/FloatingSupport.tsx +16 -16
  39. package/src/components/FormSubmissionEdit.tsx +120 -120
  40. package/src/components/HelpIcon.tsx +10 -10
  41. package/src/components/ImageEditor.tsx +126 -126
  42. package/src/components/InputBox.tsx +73 -73
  43. package/src/components/Loading.tsx +29 -29
  44. package/src/components/PersonAdd.tsx +75 -75
  45. package/src/components/QuestionEdit.tsx +62 -62
  46. package/src/components/SmallButton.tsx +39 -39
  47. package/src/components/SupportModal.tsx +26 -26
  48. package/src/components/TabPanel.tsx +34 -34
  49. package/src/components/gallery/GalleryModal.tsx +102 -102
  50. package/src/components/gallery/StockPhotos.tsx +74 -74
  51. package/src/components/gallery/index.ts +1 -1
  52. package/src/components/index.tsx +23 -23
  53. package/src/components/markdownEditor/Editor.tsx +132 -132
  54. package/src/components/markdownEditor/MarkdownEditor.tsx +16 -16
  55. package/src/components/markdownEditor/MarkdownModal.tsx +46 -46
  56. package/src/components/markdownEditor/MarkdownPreview.tsx +14 -14
  57. package/src/components/markdownEditor/editor.css +787 -787
  58. package/src/components/markdownEditor/images/icons/arrow-clockwise.svg +3 -3
  59. package/src/components/markdownEditor/images/icons/arrow-counterclockwise.svg +3 -3
  60. package/src/components/markdownEditor/images/icons/chat-square-quote.svg +3 -3
  61. package/src/components/markdownEditor/images/icons/chevron-down.svg +2 -2
  62. package/src/components/markdownEditor/images/icons/code.svg +2 -2
  63. package/src/components/markdownEditor/images/icons/journal-code.svg +4 -4
  64. package/src/components/markdownEditor/images/icons/journal-text.svg +4 -4
  65. package/src/components/markdownEditor/images/icons/justify.svg +2 -2
  66. package/src/components/markdownEditor/images/icons/link.svg +3 -3
  67. package/src/components/markdownEditor/images/icons/list-ol.svg +3 -3
  68. package/src/components/markdownEditor/images/icons/list-ul.svg +2 -2
  69. package/src/components/markdownEditor/images/icons/pencil-fill.svg +2 -2
  70. package/src/components/markdownEditor/images/icons/text-center.svg +2 -2
  71. package/src/components/markdownEditor/images/icons/text-left.svg +2 -2
  72. package/src/components/markdownEditor/images/icons/text-paragraph.svg +2 -2
  73. package/src/components/markdownEditor/images/icons/text-right.svg +2 -2
  74. package/src/components/markdownEditor/images/icons/type-bold.svg +2 -2
  75. package/src/components/markdownEditor/images/icons/type-h1.svg +2 -2
  76. package/src/components/markdownEditor/images/icons/type-h2.svg +2 -2
  77. package/src/components/markdownEditor/images/icons/type-h3.svg +2 -2
  78. package/src/components/markdownEditor/images/icons/type-h4.svg +12 -12
  79. package/src/components/markdownEditor/images/icons/type-italic.svg +2 -2
  80. package/src/components/markdownEditor/images/icons/type-strikethrough.svg +2 -2
  81. package/src/components/markdownEditor/images/icons/type-underline.svg +2 -2
  82. package/src/components/markdownEditor/index.ts +2 -2
  83. package/src/components/markdownEditor/plugins/AutoLinkPlugin.tsx +35 -35
  84. package/src/components/markdownEditor/plugins/ControlledEditorPlugin.tsx +24 -24
  85. package/src/components/markdownEditor/plugins/ListMaxIndentLevelPlugin.tsx +68 -68
  86. package/src/components/markdownEditor/plugins/MarkdownTransformers.ts +106 -106
  87. package/src/components/markdownEditor/plugins/ReadOnlyPlugin.tsx +15 -15
  88. package/src/components/markdownEditor/plugins/ToolbarPlugin.tsx +401 -401
  89. package/src/components/markdownEditor/plugins/customLink/CustomLinkNode.tsx +224 -224
  90. package/src/components/markdownEditor/plugins/customLink/CustomLinkNodePlugin.tsx +32 -32
  91. package/src/components/markdownEditor/plugins/customLink/CustomLinkNodeTransformer.tsx +102 -102
  92. package/src/components/markdownEditor/plugins/customLink/FloatingLinkEditor.tsx +243 -243
  93. package/src/components/markdownEditor/plugins/customLink/FloatingLinkEditor.types.ts +11 -11
  94. package/src/components/markdownEditor/plugins/emoji/EmojiNode.tsx +95 -95
  95. package/src/components/markdownEditor/plugins/emoji/EmojiNodeTransform.ts +41 -41
  96. package/src/components/markdownEditor/plugins/emoji/EmojiPickerPlugin.tsx +152 -152
  97. package/src/components/markdownEditor/plugins/emoji/EmojisPlugin.tsx +65 -65
  98. package/src/components/markdownEditor/plugins/index.ts +6 -6
  99. package/src/components/markdownEditor/theme.ts +65 -65
  100. package/src/components/material/AppList.tsx +20 -20
  101. package/src/components/material/ChurchList.tsx +22 -22
  102. package/src/components/material/NavItem.tsx +41 -41
  103. package/src/components/material/NewPrivateMessage.tsx +103 -103
  104. package/src/components/material/PrivateMessageDetails.tsx +23 -23
  105. package/src/components/material/PrivateMessages.tsx +87 -87
  106. package/src/components/material/SiteWrapper.tsx +140 -140
  107. package/src/components/material/UserMenu.tsx +141 -141
  108. package/src/components/material/iconPicker/IconNamesList.ts +2240 -2240
  109. package/src/components/material/iconPicker/IconPicker.tsx +153 -153
  110. package/src/components/material/index.tsx +6 -6
  111. package/src/components/notes/AddNote.tsx +90 -90
  112. package/src/components/notes/Conversation.tsx +82 -82
  113. package/src/components/notes/Conversations.tsx +58 -58
  114. package/src/components/notes/NewConversation.tsx +78 -78
  115. package/src/components/notes/Note.tsx +44 -44
  116. package/src/components/notes/Notes.tsx +52 -52
  117. package/src/components/notes/index.ts +5 -5
  118. package/src/components/reporting/ChartReport.tsx +98 -98
  119. package/src/components/reporting/ReportFilter.tsx +54 -54
  120. package/src/components/reporting/ReportFilterField.tsx +160 -160
  121. package/src/components/reporting/ReportOutput.tsx +79 -79
  122. package/src/components/reporting/ReportWithFilter.tsx +70 -70
  123. package/src/components/reporting/TableReport.tsx +57 -57
  124. package/src/components/reporting/TreeReport.tsx +111 -111
  125. package/src/components/reporting/index.ts +4 -4
  126. package/src/donationComponents/DonationPage.tsx +136 -136
  127. package/src/donationComponents/components/BankForm.tsx +159 -159
  128. package/src/donationComponents/components/CardForm.tsx +104 -104
  129. package/src/donationComponents/components/DonationForm.tsx +235 -235
  130. package/src/donationComponents/components/FundDonation.tsx +49 -49
  131. package/src/donationComponents/components/FundDonations.tsx +39 -39
  132. package/src/donationComponents/components/NonAuthDonation.tsx +31 -31
  133. package/src/donationComponents/components/NonAuthDonationInner.tsx +259 -259
  134. package/src/donationComponents/components/PaymentMethods.tsx +135 -135
  135. package/src/donationComponents/components/RecurringDonations.tsx +121 -121
  136. package/src/donationComponents/components/RecurringDonationsEdit.tsx +93 -93
  137. package/src/donationComponents/components/index.tsx +9 -9
  138. package/src/donationComponents/index.ts +3 -3
  139. package/src/donationComponents/modals/DonationPreviewModal.tsx +66 -66
  140. package/src/helpers/AnalyticsHelper.ts +33 -33
  141. package/src/helpers/ApiHelper.ts +125 -125
  142. package/src/helpers/AppearanceHelper.ts +69 -69
  143. package/src/helpers/ArrayHelper.ts +81 -81
  144. package/src/helpers/CommonEnvironmentHelper.ts +80 -80
  145. package/src/helpers/CurrencyHelper.ts +10 -10
  146. package/src/helpers/DateHelper.ts +108 -108
  147. package/src/helpers/DonationHelper.ts +26 -26
  148. package/src/helpers/ErrorHelper.ts +36 -36
  149. package/src/helpers/EventHelper.ts +52 -52
  150. package/src/helpers/FileHelper.ts +31 -31
  151. package/src/helpers/PersonHelper.ts +60 -60
  152. package/src/helpers/SocketHelper.ts +76 -76
  153. package/src/helpers/Themes.ts +14 -14
  154. package/src/helpers/UniqueIdHelper.ts +36 -36
  155. package/src/helpers/UserHelper.ts +59 -59
  156. package/src/helpers/createEmotionCache.ts +17 -17
  157. package/src/helpers/index.ts +18 -18
  158. package/src/hooks/index.ts +1 -1
  159. package/src/hooks/useMountedState.ts +16 -16
  160. package/src/index.ts +6 -6
  161. package/src/interfaces/Access.ts +24 -24
  162. package/src/interfaces/Attendance.ts +8 -8
  163. package/src/interfaces/Content.ts +10 -10
  164. package/src/interfaces/Doing.ts +24 -24
  165. package/src/interfaces/Donation.ts +45 -45
  166. package/src/interfaces/Error.ts +17 -17
  167. package/src/interfaces/Membership.ts +51 -51
  168. package/src/interfaces/Messaging.ts +20 -20
  169. package/src/interfaces/Permissions.ts +68 -68
  170. package/src/interfaces/Reporting.ts +7 -7
  171. package/src/interfaces/UserContextInterface.ts +13 -13
  172. package/src/interfaces/index.ts +13 -13
  173. package/src/pageComponents/LoginPage.tsx +244 -244
  174. package/src/pageComponents/LogoutPage.tsx +28 -28
  175. package/src/pageComponents/components/Forgot.tsx +79 -79
  176. package/src/pageComponents/components/Login.tsx +54 -54
  177. package/src/pageComponents/components/LoginSetPassword.tsx +63 -63
  178. package/src/pageComponents/components/Register.tsx +107 -107
  179. package/src/pageComponents/components/SelectChurchModal.tsx +41 -41
  180. package/src/pageComponents/components/SelectChurchRegister.tsx +88 -88
  181. package/src/pageComponents/components/SelectChurchSearch.tsx +69 -69
  182. package/src/pageComponents/components/SelectableChurch.tsx +38 -38
  183. package/src/pageComponents/index.ts +3 -3
  184. package/tsconfig.json +34 -34
  185. package/tslint.json +14 -14
@@ -1,74 +1,74 @@
1
- import { Button, Grid, TextField } from "@mui/material";
2
- import React, { useState } from "react";
3
- import { ApiHelper } from "../../helpers";
4
- import { CommonEnvironmentHelper } from "../../helpers/CommonEnvironmentHelper";
5
-
6
- interface Props {
7
- aspectRatio: number,
8
- onSelect: (img: string) => void,
9
- onStockSelect: (img: string) => void
10
- }
11
-
12
- interface SearchResult { description: string, url: string, photographer: string, photographerUrl: string, large: string, thumbnail: string }
13
-
14
- export const StockPhotos: React.FC<Props> = (props: Props) => {
15
- const [images, setImages] = useState<string[]>([]);
16
- const [searchText, setSearchText] = useState("");
17
- const [searchResults, setSearchResults] = useState<SearchResult[]>(null);
18
-
19
- const loadData = () => { ApiHelper.getAnonymous("/gallery/stock/" + props.aspectRatio.toString(), "ContentApi").then(data => setImages(data.images)); }
20
-
21
- React.useEffect(loadData, [props.aspectRatio]); //eslint-disable-line
22
-
23
- const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { e.preventDefault(); setSearchText(e.currentTarget.value); }
24
-
25
- const handleSearch = (e: React.MouseEvent) => {
26
- if (e !== null) e.preventDefault();
27
- let term = searchText.trim();
28
- ApiHelper.post("/stock/search", { term: term }, "ContentApi").then((data: SearchResult[]) => { setSearchResults(data) });
29
- }
30
-
31
- const getImages = () => {
32
- if (searchResults) return getResults();
33
- else return getSuggested();
34
- }
35
-
36
- const getResults = () => {
37
- let result: JSX.Element[] = [];
38
- searchResults.forEach(p => {
39
- result.push(<Grid item md={4} xs={12}>
40
- <a href="about:blank" onClick={(e) => { e.preventDefault(); props.onStockSelect(p.large) }}>
41
- <img src={p.thumbnail} className="img-fluid" alt="stock" />
42
- </a>
43
- <div>
44
- <i style={{ fontSize: 12 }}>
45
- <a href={p.url} target="_blank" rel="noreferrer noopener">Photo</a> by: <a href={p.photographerUrl} target="_blank" rel="noreferrer noopener">{p.photographer}</a></i>
46
- </div>
47
- </Grid>);
48
- })
49
- return result;
50
- }
51
-
52
- const getSuggested = () => {
53
- let result: JSX.Element[] = [];
54
- images.forEach(img => {
55
- result.push(<Grid item md={4} xs={12}>
56
- <a href="about:blank" onClick={(e) => { e.preventDefault(); props.onSelect(CommonEnvironmentHelper.ContentRoot + "/" + img) }}>
57
- <img src={CommonEnvironmentHelper.ContentRoot + "/" + img} className="img-fluid" alt="stock" />
58
- </a>
59
- </Grid>);
60
- })
61
- return result;
62
- }
63
-
64
- return (<>
65
- <TextField fullWidth name="personAddText" label="Search Term" value={searchText} onChange={handleChange}
66
- InputProps={{ endAdornment: <Button variant="contained" id="searchButton" data-cy="search-button" onClick={handleSearch}>Search</Button> }}
67
- />
68
- {searchResults && <div>Stock photos provided by <a href="https://pexels.com">Pexels</a>.</div>}
69
- <Grid container spacing={3} alignItems="center">
70
- {getImages()}
71
- </Grid>
72
-
73
- </>);
74
- };
1
+ import { Button, Grid, TextField } from "@mui/material";
2
+ import React, { useState } from "react";
3
+ import { ApiHelper } from "../../helpers";
4
+ import { CommonEnvironmentHelper } from "../../helpers/CommonEnvironmentHelper";
5
+
6
+ interface Props {
7
+ aspectRatio: number,
8
+ onSelect: (img: string) => void,
9
+ onStockSelect: (img: string) => void
10
+ }
11
+
12
+ interface SearchResult { description: string, url: string, photographer: string, photographerUrl: string, large: string, thumbnail: string }
13
+
14
+ export const StockPhotos: React.FC<Props> = (props: Props) => {
15
+ const [images, setImages] = useState<string[]>([]);
16
+ const [searchText, setSearchText] = useState("");
17
+ const [searchResults, setSearchResults] = useState<SearchResult[]>(null);
18
+
19
+ const loadData = () => { ApiHelper.getAnonymous("/gallery/stock/" + props.aspectRatio.toString(), "ContentApi").then(data => setImages(data.images)); }
20
+
21
+ React.useEffect(loadData, [props.aspectRatio]); //eslint-disable-line
22
+
23
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { e.preventDefault(); setSearchText(e.currentTarget.value); }
24
+
25
+ const handleSearch = (e: React.MouseEvent) => {
26
+ if (e !== null) e.preventDefault();
27
+ let term = searchText.trim();
28
+ ApiHelper.post("/stock/search", { term: term }, "ContentApi").then((data: SearchResult[]) => { setSearchResults(data) });
29
+ }
30
+
31
+ const getImages = () => {
32
+ if (searchResults) return getResults();
33
+ else return getSuggested();
34
+ }
35
+
36
+ const getResults = () => {
37
+ let result: JSX.Element[] = [];
38
+ searchResults.forEach(p => {
39
+ result.push(<Grid item md={4} xs={12}>
40
+ <a href="about:blank" onClick={(e) => { e.preventDefault(); props.onStockSelect(p.large) }}>
41
+ <img src={p.thumbnail} className="img-fluid" alt="stock" />
42
+ </a>
43
+ <div>
44
+ <i style={{ fontSize: 12 }}>
45
+ <a href={p.url} target="_blank" rel="noreferrer noopener">Photo</a> by: <a href={p.photographerUrl} target="_blank" rel="noreferrer noopener">{p.photographer}</a></i>
46
+ </div>
47
+ </Grid>);
48
+ })
49
+ return result;
50
+ }
51
+
52
+ const getSuggested = () => {
53
+ let result: JSX.Element[] = [];
54
+ images.forEach(img => {
55
+ result.push(<Grid item md={4} xs={12}>
56
+ <a href="about:blank" onClick={(e) => { e.preventDefault(); props.onSelect(CommonEnvironmentHelper.ContentRoot + "/" + img) }}>
57
+ <img src={CommonEnvironmentHelper.ContentRoot + "/" + img} className="img-fluid" alt="stock" />
58
+ </a>
59
+ </Grid>);
60
+ })
61
+ return result;
62
+ }
63
+
64
+ return (<>
65
+ <TextField fullWidth name="personAddText" label="Search Term" value={searchText} onChange={handleChange}
66
+ InputProps={{ endAdornment: <Button variant="contained" id="searchButton" data-cy="search-button" onClick={handleSearch}>Search</Button> }}
67
+ />
68
+ {searchResults && <div>Stock photos provided by <a href="https://pexels.com">Pexels</a>.</div>}
69
+ <Grid container spacing={3} alignItems="center">
70
+ {getImages()}
71
+ </Grid>
72
+
73
+ </>);
74
+ };
@@ -1 +1 @@
1
- export { GalleryModal } from "./GalleryModal";
1
+ export { GalleryModal } from "./GalleryModal";
@@ -1,23 +1,23 @@
1
- export { CreatePerson } from "./CreatePerson";
2
- export { ErrorMessages } from "./ErrorMessages";
3
- export { ExportLink } from "./ExportLink";
4
- export { DisplayBox } from "./DisplayBox";
5
- export { FloatingSupport } from "./FloatingSupport";
6
- export { FormSubmissionEdit } from "./FormSubmissionEdit";
7
- export { HelpIcon } from "./HelpIcon";
8
- export { ImageEditor } from "./ImageEditor";
9
- export { InputBox } from "./InputBox";
10
- export { Loading } from "./Loading";
11
- export { Notes } from "./notes/Notes";
12
- export { PersonAdd } from "./PersonAdd";
13
- export { QuestionEdit } from "./QuestionEdit";
14
- export { SmallButton } from "./SmallButton";
15
- export { SupportModal } from "./SupportModal";
16
- export { MarkdownEditor } from "./markdownEditor/MarkdownEditor";
17
- export { MarkdownPreview } from "./markdownEditor/MarkdownPreview";
18
-
19
- export * from "./material";
20
- export * from "./gallery";
21
- export * from "./markdownEditor";
22
- export * from "./notes";
23
- export * from "./reporting";
1
+ export { CreatePerson } from "./CreatePerson";
2
+ export { ErrorMessages } from "./ErrorMessages";
3
+ export { ExportLink } from "./ExportLink";
4
+ export { DisplayBox } from "./DisplayBox";
5
+ export { FloatingSupport } from "./FloatingSupport";
6
+ export { FormSubmissionEdit } from "./FormSubmissionEdit";
7
+ export { HelpIcon } from "./HelpIcon";
8
+ export { ImageEditor } from "./ImageEditor";
9
+ export { InputBox } from "./InputBox";
10
+ export { Loading } from "./Loading";
11
+ export { Notes } from "./notes/Notes";
12
+ export { PersonAdd } from "./PersonAdd";
13
+ export { QuestionEdit } from "./QuestionEdit";
14
+ export { SmallButton } from "./SmallButton";
15
+ export { SupportModal } from "./SupportModal";
16
+ export { MarkdownEditor } from "./markdownEditor/MarkdownEditor";
17
+ export { MarkdownPreview } from "./markdownEditor/MarkdownPreview";
18
+
19
+ export * from "./material";
20
+ export * from "./gallery";
21
+ export * from "./markdownEditor";
22
+ export * from "./notes";
23
+ export * from "./reporting";
@@ -1,132 +1,132 @@
1
- import React, {useCallback, useMemo} from "react";
2
- import { LexicalComposer } from "@lexical/react/LexicalComposer";
3
- import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
4
- import { ContentEditable } from "@lexical/react/LexicalContentEditable";
5
- import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
6
- import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin";
7
- import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
8
- import LexicalErrorBoundary from "@lexical/react/LexicalErrorBoundary";
9
- import { ListPlugin } from "@lexical/react/LexicalListPlugin";
10
- import { LexicalNode } from "lexical";
11
- import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
12
- import { TRANSFORMERS, $convertToMarkdownString, $convertFromMarkdownString } from "@lexical/markdown";
13
- import { HeadingNode, QuoteNode } from "@lexical/rich-text";
14
- import { ListItemNode, ListNode } from "@lexical/list";
15
- import { TableCellNode, TableNode, TableRowNode } from "@lexical/table";
16
- import { AutoLinkNode, LinkNode } from "@lexical/link";
17
- import { CodeHighlightNode, CodeNode } from "@lexical/code";
18
- import { theme } from "./theme";
19
- import { ToolbarPlugin, CustomAutoLinkPlugin, ListMaxIndentLevelPlugin, PLAYGROUND_TRANSFORMERS, ReadOnlyPlugin, ControlledEditorPlugin } from "./plugins";
20
- import { MarkdownModal } from "./MarkdownModal";
21
- import CustomLinkNodePlugin from "./plugins/customLink/CustomLinkNodePlugin";
22
- import { CustomLinkNode } from "./plugins/customLink/CustomLinkNode";
23
- import EmojisPlugin from "./plugins/emoji/EmojisPlugin";
24
- import { EmojiNode } from "./plugins/emoji/EmojiNode";
25
- import EmojiPickerPlugin from "./plugins/emoji/EmojiPickerPlugin";
26
-
27
- interface Props {
28
- value: string;
29
- onChange?: (value: string) => void;
30
- mode?: "interactive" | "preview";
31
- style?: any;
32
- textAlign?: "left" | "center" | "right";
33
- placeholder?: string;
34
- }
35
-
36
- function Editor({ value, onChange = () => { }, mode = "interactive", textAlign = "left", style, placeholder = "Enter some text..." }: Props) {
37
- const [fullScreen, setFullScreen] = React.useState(false);
38
-
39
- const handleChange = (editorState: any) => {
40
- editorState.read(() => {
41
- const markdown = $convertToMarkdownString(PLAYGROUND_TRANSFORMERS);
42
- onChange(markdown);
43
- });
44
- };
45
-
46
- const onError = (error: any) => {
47
- console.error(error);
48
- };
49
-
50
- const handleModalOnChange = (value : string) => {
51
- onChange(value);
52
- };
53
-
54
- const handleCloseFullScreen = () => {
55
- setFullScreen(false);
56
- };
57
-
58
- const initialConfig = {
59
- editorState: () => $convertFromMarkdownString(value, PLAYGROUND_TRANSFORMERS),
60
- namespace: "editor",
61
- theme,
62
- onError,
63
- nodes: [
64
- HeadingNode,
65
- ListNode,
66
- ListItemNode,
67
- QuoteNode,
68
- CodeNode,
69
- CodeHighlightNode,
70
- TableNode,
71
- TableCellNode,
72
- TableRowNode,
73
- AutoLinkNode,
74
- LinkNode,
75
- CustomLinkNode,
76
- EmojiNode,
77
- {
78
- replace: LinkNode,
79
- with: (node: LexicalNode) => (
80
- new CustomLinkNode(node.__url, node.__target, [])
81
- )
82
- }
83
- ]
84
- };
85
-
86
- let textAlignClass = ""
87
- switch (textAlign) {
88
- case "center":
89
- textAlignClass = "text-center"
90
- break;
91
- case "right":
92
- textAlignClass = "text-right"
93
- break;
94
- case "left":
95
- default:
96
- textAlignClass = "text-left"
97
- break;
98
- }
99
-
100
- return (
101
- <>
102
- <LexicalComposer initialConfig={initialConfig}>
103
- <div className={(mode === "preview") ? `editor-container preview ${textAlignClass}` : `editor-container ${textAlignClass}`} style={Object.assign({ border: mode === "preview" ? "none" : "1px solid lightgray" }, style)}>
104
- {mode !== "preview" && <ToolbarPlugin goFullScreen={() => { setFullScreen(true) }} />}
105
- <div className="editor-inner">
106
- {!fullScreen && <RichTextPlugin
107
- contentEditable={<ContentEditable className="editor-input" style={{ minHeight: mode === "preview" ? "auto" : "150px" }} />}
108
- placeholder={mode !== "preview" ? <div className="editor-placeholder">{placeholder}</div> : null}
109
- ErrorBoundary={LexicalErrorBoundary}
110
- /> }
111
- <CustomLinkNodePlugin />
112
- {mode !== "preview" && <EmojiPickerPlugin />}
113
- <EmojisPlugin />
114
- <OnChangePlugin onChange={handleChange} />
115
- {mode !== "preview" && <AutoFocusPlugin />}
116
- <HistoryPlugin />
117
- <ListPlugin />
118
- <CustomAutoLinkPlugin />
119
-
120
- <ListMaxIndentLevelPlugin maxDepth={7} />
121
- <ReadOnlyPlugin isDisabled={mode === "preview"} />
122
- <ControlledEditorPlugin isFullscreen={fullScreen} value={value} isPreview={mode === "preview"} />
123
- <MarkdownShortcutPlugin transformers={TRANSFORMERS} />
124
- </div>
125
- </div>
126
- </LexicalComposer>
127
- {fullScreen && <MarkdownModal onChange={handleModalOnChange} value={value} hideModal={handleCloseFullScreen} />}
128
- </>
129
- );
130
- }
131
-
132
- export default Editor;
1
+ import React, {useCallback, useMemo} from "react";
2
+ import { LexicalComposer } from "@lexical/react/LexicalComposer";
3
+ import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
4
+ import { ContentEditable } from "@lexical/react/LexicalContentEditable";
5
+ import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
6
+ import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin";
7
+ import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
8
+ import LexicalErrorBoundary from "@lexical/react/LexicalErrorBoundary";
9
+ import { ListPlugin } from "@lexical/react/LexicalListPlugin";
10
+ import { LexicalNode } from "lexical";
11
+ import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
12
+ import { TRANSFORMERS, $convertToMarkdownString, $convertFromMarkdownString } from "@lexical/markdown";
13
+ import { HeadingNode, QuoteNode } from "@lexical/rich-text";
14
+ import { ListItemNode, ListNode } from "@lexical/list";
15
+ import { TableCellNode, TableNode, TableRowNode } from "@lexical/table";
16
+ import { AutoLinkNode, LinkNode } from "@lexical/link";
17
+ import { CodeHighlightNode, CodeNode } from "@lexical/code";
18
+ import { theme } from "./theme";
19
+ import { ToolbarPlugin, CustomAutoLinkPlugin, ListMaxIndentLevelPlugin, PLAYGROUND_TRANSFORMERS, ReadOnlyPlugin, ControlledEditorPlugin } from "./plugins";
20
+ import { MarkdownModal } from "./MarkdownModal";
21
+ import CustomLinkNodePlugin from "./plugins/customLink/CustomLinkNodePlugin";
22
+ import { CustomLinkNode } from "./plugins/customLink/CustomLinkNode";
23
+ import EmojisPlugin from "./plugins/emoji/EmojisPlugin";
24
+ import { EmojiNode } from "./plugins/emoji/EmojiNode";
25
+ import EmojiPickerPlugin from "./plugins/emoji/EmojiPickerPlugin";
26
+
27
+ interface Props {
28
+ value: string;
29
+ onChange?: (value: string) => void;
30
+ mode?: "interactive" | "preview";
31
+ style?: any;
32
+ textAlign?: "left" | "center" | "right";
33
+ placeholder?: string;
34
+ }
35
+
36
+ function Editor({ value, onChange = () => { }, mode = "interactive", textAlign = "left", style, placeholder = "Enter some text..." }: Props) {
37
+ const [fullScreen, setFullScreen] = React.useState(false);
38
+
39
+ const handleChange = (editorState: any) => {
40
+ editorState.read(() => {
41
+ const markdown = $convertToMarkdownString(PLAYGROUND_TRANSFORMERS);
42
+ onChange(markdown);
43
+ });
44
+ };
45
+
46
+ const onError = (error: any) => {
47
+ console.error(error);
48
+ };
49
+
50
+ const handleModalOnChange = (value : string) => {
51
+ onChange(value);
52
+ };
53
+
54
+ const handleCloseFullScreen = () => {
55
+ setFullScreen(false);
56
+ };
57
+
58
+ const initialConfig = {
59
+ editorState: () => $convertFromMarkdownString(value, PLAYGROUND_TRANSFORMERS),
60
+ namespace: "editor",
61
+ theme,
62
+ onError,
63
+ nodes: [
64
+ HeadingNode,
65
+ ListNode,
66
+ ListItemNode,
67
+ QuoteNode,
68
+ CodeNode,
69
+ CodeHighlightNode,
70
+ TableNode,
71
+ TableCellNode,
72
+ TableRowNode,
73
+ AutoLinkNode,
74
+ LinkNode,
75
+ CustomLinkNode,
76
+ EmojiNode,
77
+ {
78
+ replace: LinkNode,
79
+ with: (node: LexicalNode) => (
80
+ new CustomLinkNode(node.__url, node.__target, [])
81
+ )
82
+ }
83
+ ]
84
+ };
85
+
86
+ let textAlignClass = ""
87
+ switch (textAlign) {
88
+ case "center":
89
+ textAlignClass = "text-center"
90
+ break;
91
+ case "right":
92
+ textAlignClass = "text-right"
93
+ break;
94
+ case "left":
95
+ default:
96
+ textAlignClass = "text-left"
97
+ break;
98
+ }
99
+
100
+ return (
101
+ <>
102
+ <LexicalComposer initialConfig={initialConfig}>
103
+ <div className={(mode === "preview") ? `editor-container preview ${textAlignClass}` : `editor-container ${textAlignClass}`} style={Object.assign({ border: mode === "preview" ? "none" : "1px solid lightgray" }, style)}>
104
+ {mode !== "preview" && <ToolbarPlugin goFullScreen={() => { setFullScreen(true) }} />}
105
+ <div className="editor-inner">
106
+ {!fullScreen && <RichTextPlugin
107
+ contentEditable={<ContentEditable className="editor-input" style={{ minHeight: mode === "preview" ? "auto" : "150px" }} />}
108
+ placeholder={mode !== "preview" ? <div className="editor-placeholder">{placeholder}</div> : null}
109
+ ErrorBoundary={LexicalErrorBoundary}
110
+ /> }
111
+ <CustomLinkNodePlugin />
112
+ {mode !== "preview" && <EmojiPickerPlugin />}
113
+ <EmojisPlugin />
114
+ <OnChangePlugin onChange={handleChange} />
115
+ {mode !== "preview" && <AutoFocusPlugin />}
116
+ <HistoryPlugin />
117
+ <ListPlugin />
118
+ <CustomAutoLinkPlugin />
119
+
120
+ <ListMaxIndentLevelPlugin maxDepth={7} />
121
+ <ReadOnlyPlugin isDisabled={mode === "preview"} />
122
+ <ControlledEditorPlugin isFullscreen={fullScreen} value={value} isPreview={mode === "preview"} />
123
+ <MarkdownShortcutPlugin transformers={TRANSFORMERS} />
124
+ </div>
125
+ </div>
126
+ </LexicalComposer>
127
+ {fullScreen && <MarkdownModal onChange={handleModalOnChange} value={value} hideModal={handleCloseFullScreen} />}
128
+ </>
129
+ );
130
+ }
131
+
132
+ export default Editor;
@@ -1,16 +1,16 @@
1
- import React from "react";
2
- import { lazy, Suspense } from 'react';
3
- import { Loading } from "../Loading";
4
- const Editor = lazy(() => import('./Editor'));
5
-
6
- interface Props {
7
- value: string;
8
- onChange?: (newValue: string) => void;
9
- style?: any;
10
- textAlign?: "left" | "center" | "right";
11
- placeholder?: string;
12
- }
13
-
14
- export function MarkdownEditor({ value: markdownString = "", onChange, style, textAlign, placeholder }: Props) {
15
- return <Suspense fallback={<Loading />}><Editor value={markdownString} onChange={onChange} style={style} textAlign={textAlign} placeholder={placeholder} /></Suspense>
16
- }
1
+ import React from "react";
2
+ import { lazy, Suspense } from 'react';
3
+ import { Loading } from "../Loading";
4
+ const Editor = lazy(() => import('./Editor'));
5
+
6
+ interface Props {
7
+ value: string;
8
+ onChange?: (newValue: string) => void;
9
+ style?: any;
10
+ textAlign?: "left" | "center" | "right";
11
+ placeholder?: string;
12
+ }
13
+
14
+ export function MarkdownEditor({ value: markdownString = "", onChange, style, textAlign, placeholder }: Props) {
15
+ return <Suspense fallback={<Loading />}><Editor value={markdownString} onChange={onChange} style={style} textAlign={textAlign} placeholder={placeholder} /></Suspense>
16
+ }
@@ -1,46 +1,46 @@
1
- import React, { useEffect, useState } from "react";
2
- import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Grid, TextField } from "@mui/material";
3
- import { MarkdownPreview } from "./MarkdownPreview";
4
-
5
- interface Props {
6
- hideModal: () => void
7
- onChange: (newValue: string) => void
8
- value?: string;
9
- }
10
-
11
- const guideLink = <a href="https://www.markdownguide.org/cheat-sheet/" target="_blank" rel="noopener noreferrer" style={{ float: "right" }}>Markdown Guide</a>;
12
-
13
-
14
- export const MarkdownModal: React.FC<Props> = ({ value, onChange, hideModal }) => {
15
- const [inputVal, setInputVal] = useState(value);
16
-
17
-
18
- useEffect(() => {
19
- if (value.trim() === inputVal.trim()) return;
20
- setInputVal(value);
21
- }, [value, inputVal]);
22
-
23
- useEffect(() => { onChange(inputVal); }, [inputVal, onChange]);
24
-
25
- return (<Dialog open={true} onClose={() => { hideModal() }} fullScreen={true}>
26
- <DialogTitle>Markdown Editor</DialogTitle>
27
- <DialogContent>
28
- <Grid container spacing={3}>
29
- <Grid item xs={6}>
30
- <TextField fullWidth multiline label={<>Content &nbsp; {guideLink}</>} name="modalMarkdown" className="modalMarkdown" InputProps={{ style: { height: "80vh" } }} value={inputVal} onChange={(e) => {
31
- setInputVal(e.target.value);
32
- }} placeholder="" />
33
- </Grid>
34
- <Grid item xs={6}>
35
- <div style={{ border: "1px solid #BBB", borderRadius: 5, marginTop: 15, padding: 10, height: "80vh", overflowY: "scroll" }} id="markdownPreview">
36
- <div style={{ marginTop: -20, marginBottom: -10, position: "absolute" }}><span style={{ backgroundColor: "#FFFFFF", color: "#999", fontSize: 13 }}> &nbsp; Preview &nbsp; </span></div>
37
- <MarkdownPreview value={inputVal} />
38
- </div>
39
- </Grid>
40
- </Grid>
41
- </DialogContent>
42
- <DialogActions sx={{ paddingX: "16px", paddingBottom: "12px" }}>
43
- <Button variant="outlined" onClick={() => { hideModal() }}>Close</Button>
44
- </DialogActions>
45
- </Dialog>)
46
- };
1
+ import React, { useEffect, useState } from "react";
2
+ import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Grid, TextField } from "@mui/material";
3
+ import { MarkdownPreview } from "./MarkdownPreview";
4
+
5
+ interface Props {
6
+ hideModal: () => void
7
+ onChange: (newValue: string) => void
8
+ value?: string;
9
+ }
10
+
11
+ const guideLink = <a href="https://www.markdownguide.org/cheat-sheet/" target="_blank" rel="noopener noreferrer" style={{ float: "right" }}>Markdown Guide</a>;
12
+
13
+
14
+ export const MarkdownModal: React.FC<Props> = ({ value, onChange, hideModal }) => {
15
+ const [inputVal, setInputVal] = useState(value);
16
+
17
+
18
+ useEffect(() => {
19
+ if (value.trim() === inputVal.trim()) return;
20
+ setInputVal(value);
21
+ }, [value, inputVal]);
22
+
23
+ useEffect(() => { onChange(inputVal); }, [inputVal, onChange]);
24
+
25
+ return (<Dialog open={true} onClose={() => { hideModal() }} fullScreen={true}>
26
+ <DialogTitle>Markdown Editor</DialogTitle>
27
+ <DialogContent>
28
+ <Grid container spacing={3}>
29
+ <Grid item xs={6}>
30
+ <TextField fullWidth multiline label={<>Content &nbsp; {guideLink}</>} name="modalMarkdown" className="modalMarkdown" InputProps={{ style: { height: "80vh" } }} value={inputVal} onChange={(e) => {
31
+ setInputVal(e.target.value);
32
+ }} placeholder="" />
33
+ </Grid>
34
+ <Grid item xs={6}>
35
+ <div style={{ border: "1px solid #BBB", borderRadius: 5, marginTop: 15, padding: 10, height: "80vh", overflowY: "scroll" }} id="markdownPreview">
36
+ <div style={{ marginTop: -20, marginBottom: -10, position: "absolute" }}><span style={{ backgroundColor: "#FFFFFF", color: "#999", fontSize: 13 }}> &nbsp; Preview &nbsp; </span></div>
37
+ <MarkdownPreview value={inputVal} />
38
+ </div>
39
+ </Grid>
40
+ </Grid>
41
+ </DialogContent>
42
+ <DialogActions sx={{ paddingX: "16px", paddingBottom: "12px" }}>
43
+ <Button variant="outlined" onClick={() => { hideModal() }}>Close</Button>
44
+ </DialogActions>
45
+ </Dialog>)
46
+ };
@@ -1,14 +1,14 @@
1
- import React, { Suspense } from "react";
2
- import { lazy } from 'react';
3
- const Editor = lazy(() => import('./Editor'));
4
-
5
- interface Props {
6
- value: string;
7
- textAlign?: "left" | "center" | "right"
8
- }
9
-
10
- export function MarkdownPreview({ value: markdownString = "", textAlign }: Props) {
11
- return <Suspense fallback={<div>{markdownString || ""}</div>}>
12
- <Editor mode="preview" value={markdownString || ""} textAlign={textAlign} />
13
- </Suspense>
14
- }
1
+ import React, { Suspense } from "react";
2
+ import { lazy } from 'react';
3
+ const Editor = lazy(() => import('./Editor'));
4
+
5
+ interface Props {
6
+ value: string;
7
+ textAlign?: "left" | "center" | "right"
8
+ }
9
+
10
+ export function MarkdownPreview({ value: markdownString = "", textAlign }: Props) {
11
+ return <Suspense fallback={<div>{markdownString || ""}</div>}>
12
+ <Editor mode="preview" value={markdownString || ""} textAlign={textAlign} />
13
+ </Suspense>
14
+ }