@churchapps/apphelper 0.1.8 → 0.1.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 (198) hide show
  1. package/.eslintignore +3 -3
  2. package/.eslintrc.json +22 -22
  3. package/LICENSE +21 -21
  4. package/README.md +24 -24
  5. package/dist/components/gallery/GalleryModal.d.ts.map +1 -1
  6. package/dist/components/gallery/GalleryModal.js +13 -2
  7. package/dist/components/gallery/GalleryModal.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/dist/helpers/SlugHelper.d.ts +5 -0
  34. package/dist/helpers/SlugHelper.d.ts.map +1 -0
  35. package/dist/helpers/SlugHelper.js +40 -0
  36. package/dist/helpers/SlugHelper.js.map +1 -0
  37. package/dist/helpers/index.d.ts +1 -0
  38. package/dist/helpers/index.d.ts.map +1 -1
  39. package/dist/helpers/index.js +3 -1
  40. package/dist/helpers/index.js.map +1 -1
  41. package/package.json +88 -86
  42. package/src/components/CreatePerson.tsx +80 -80
  43. package/src/components/DisplayBox.tsx +68 -68
  44. package/src/components/ErrorMessages.tsx +26 -26
  45. package/src/components/ExportLink.tsx +67 -67
  46. package/src/components/FloatingSupport.tsx +16 -16
  47. package/src/components/FormSubmissionEdit.tsx +120 -120
  48. package/src/components/HelpIcon.tsx +10 -10
  49. package/src/components/ImageEditor.tsx +126 -126
  50. package/src/components/InputBox.tsx +73 -73
  51. package/src/components/Loading.tsx +29 -29
  52. package/src/components/PersonAdd.tsx +75 -75
  53. package/src/components/QuestionEdit.tsx +63 -63
  54. package/src/components/SmallButton.tsx +39 -39
  55. package/src/components/SupportModal.tsx +26 -26
  56. package/src/components/TabPanel.tsx +34 -34
  57. package/src/components/gallery/GalleryModal.tsx +119 -102
  58. package/src/components/gallery/StockPhotos.tsx +74 -74
  59. package/src/components/gallery/index.ts +1 -1
  60. package/src/components/iconPicker/IconNamesList.ts +2240 -2240
  61. package/src/components/iconPicker/IconPicker.tsx +153 -153
  62. package/src/components/index.tsx +24 -24
  63. package/src/components/markdownEditor/Editor.tsx +132 -132
  64. package/src/components/markdownEditor/MarkdownEditor.tsx +16 -16
  65. package/src/components/markdownEditor/MarkdownModal.tsx +46 -46
  66. package/src/components/markdownEditor/MarkdownPreview.tsx +14 -14
  67. package/src/components/markdownEditor/editor.css +787 -787
  68. package/src/components/markdownEditor/images/icons/arrow-clockwise.svg +3 -3
  69. package/src/components/markdownEditor/images/icons/arrow-counterclockwise.svg +3 -3
  70. package/src/components/markdownEditor/images/icons/chat-square-quote.svg +3 -3
  71. package/src/components/markdownEditor/images/icons/chevron-down.svg +2 -2
  72. package/src/components/markdownEditor/images/icons/code.svg +2 -2
  73. package/src/components/markdownEditor/images/icons/journal-code.svg +4 -4
  74. package/src/components/markdownEditor/images/icons/journal-text.svg +4 -4
  75. package/src/components/markdownEditor/images/icons/justify.svg +2 -2
  76. package/src/components/markdownEditor/images/icons/link.svg +3 -3
  77. package/src/components/markdownEditor/images/icons/list-ol.svg +3 -3
  78. package/src/components/markdownEditor/images/icons/list-ul.svg +2 -2
  79. package/src/components/markdownEditor/images/icons/pencil-fill.svg +2 -2
  80. package/src/components/markdownEditor/images/icons/text-center.svg +2 -2
  81. package/src/components/markdownEditor/images/icons/text-left.svg +2 -2
  82. package/src/components/markdownEditor/images/icons/text-paragraph.svg +2 -2
  83. package/src/components/markdownEditor/images/icons/text-right.svg +2 -2
  84. package/src/components/markdownEditor/images/icons/type-bold.svg +2 -2
  85. package/src/components/markdownEditor/images/icons/type-h1.svg +2 -2
  86. package/src/components/markdownEditor/images/icons/type-h2.svg +2 -2
  87. package/src/components/markdownEditor/images/icons/type-h3.svg +2 -2
  88. package/src/components/markdownEditor/images/icons/type-h4.svg +12 -12
  89. package/src/components/markdownEditor/images/icons/type-italic.svg +2 -2
  90. package/src/components/markdownEditor/images/icons/type-strikethrough.svg +2 -2
  91. package/src/components/markdownEditor/images/icons/type-underline.svg +2 -2
  92. package/src/components/markdownEditor/index.ts +2 -2
  93. package/src/components/markdownEditor/plugins/AutoLinkPlugin.tsx +35 -35
  94. package/src/components/markdownEditor/plugins/ControlledEditorPlugin.tsx +24 -24
  95. package/src/components/markdownEditor/plugins/ListMaxIndentLevelPlugin.tsx +68 -68
  96. package/src/components/markdownEditor/plugins/MarkdownTransformers.ts +106 -106
  97. package/src/components/markdownEditor/plugins/ReadOnlyPlugin.tsx +15 -15
  98. package/src/components/markdownEditor/plugins/ToolbarPlugin.tsx +401 -401
  99. package/src/components/markdownEditor/plugins/customLink/CustomLinkNode.tsx +224 -224
  100. package/src/components/markdownEditor/plugins/customLink/CustomLinkNodePlugin.tsx +32 -32
  101. package/src/components/markdownEditor/plugins/customLink/CustomLinkNodeTransformer.tsx +102 -102
  102. package/src/components/markdownEditor/plugins/customLink/FloatingLinkEditor.tsx +243 -243
  103. package/src/components/markdownEditor/plugins/customLink/FloatingLinkEditor.types.ts +11 -11
  104. package/src/components/markdownEditor/plugins/emoji/EmojiNode.tsx +95 -95
  105. package/src/components/markdownEditor/plugins/emoji/EmojiNodeTransform.ts +41 -41
  106. package/src/components/markdownEditor/plugins/emoji/EmojiPickerPlugin.tsx +152 -152
  107. package/src/components/markdownEditor/plugins/emoji/EmojisPlugin.tsx +65 -65
  108. package/src/components/markdownEditor/plugins/index.ts +6 -6
  109. package/src/components/markdownEditor/theme.ts +65 -65
  110. package/src/components/notes/AddNote.tsx +90 -90
  111. package/src/components/notes/Conversation.tsx +82 -82
  112. package/src/components/notes/Conversations.tsx +58 -58
  113. package/src/components/notes/NewConversation.tsx +78 -78
  114. package/src/components/notes/Note.tsx +44 -44
  115. package/src/components/notes/Notes.tsx +69 -69
  116. package/src/components/notes/index.ts +5 -5
  117. package/src/components/reporting/ChartReport.tsx +98 -98
  118. package/src/components/reporting/ReportFilter.tsx +54 -54
  119. package/src/components/reporting/ReportFilterField.tsx +160 -160
  120. package/src/components/reporting/ReportOutput.tsx +79 -79
  121. package/src/components/reporting/ReportWithFilter.tsx +70 -70
  122. package/src/components/reporting/TableReport.tsx +57 -57
  123. package/src/components/reporting/TreeReport.tsx +111 -111
  124. package/src/components/reporting/index.ts +4 -4
  125. package/src/components/wrapper/AppList.tsx +20 -20
  126. package/src/components/wrapper/ChurchList.tsx +22 -22
  127. package/src/components/wrapper/Drawers.tsx +60 -60
  128. package/src/components/wrapper/NavItem.tsx +41 -41
  129. package/src/components/wrapper/NewPrivateMessage.tsx +103 -103
  130. package/src/components/wrapper/NotificationMenu.tsx +96 -96
  131. package/src/components/wrapper/Notifications.tsx +53 -53
  132. package/src/components/wrapper/PrivateMessageDetails.tsx +24 -24
  133. package/src/components/wrapper/PrivateMessages.tsx +92 -92
  134. package/src/components/wrapper/SiteWrapper.tsx +99 -99
  135. package/src/components/wrapper/TabPanel.tsx +30 -30
  136. package/src/components/wrapper/UserMenu.tsx +106 -106
  137. package/src/components/wrapper/index.tsx +5 -5
  138. package/src/donationComponents/DonationPage.tsx +136 -136
  139. package/src/donationComponents/components/BankForm.tsx +159 -159
  140. package/src/donationComponents/components/CardForm.tsx +104 -104
  141. package/src/donationComponents/components/DonationForm.tsx +235 -235
  142. package/src/donationComponents/components/FundDonation.tsx +49 -49
  143. package/src/donationComponents/components/FundDonations.tsx +39 -39
  144. package/src/donationComponents/components/NonAuthDonation.tsx +31 -31
  145. package/src/donationComponents/components/NonAuthDonationInner.tsx +259 -259
  146. package/src/donationComponents/components/PaymentMethods.tsx +135 -135
  147. package/src/donationComponents/components/RecurringDonations.tsx +121 -121
  148. package/src/donationComponents/components/RecurringDonationsEdit.tsx +93 -93
  149. package/src/donationComponents/components/index.tsx +9 -9
  150. package/src/donationComponents/index.ts +3 -3
  151. package/src/donationComponents/modals/DonationPreviewModal.tsx +66 -66
  152. package/src/helpers/AnalyticsHelper.ts +33 -33
  153. package/src/helpers/ApiHelper.ts +125 -125
  154. package/src/helpers/AppearanceHelper.ts +69 -69
  155. package/src/helpers/ArrayHelper.ts +81 -81
  156. package/src/helpers/CommonEnvironmentHelper.ts +80 -80
  157. package/src/helpers/CurrencyHelper.ts +10 -10
  158. package/src/helpers/DateHelper.ts +109 -109
  159. package/src/helpers/DonationHelper.ts +26 -26
  160. package/src/helpers/ErrorHelper.ts +36 -36
  161. package/src/helpers/EventHelper.ts +52 -52
  162. package/src/helpers/FileHelper.ts +31 -31
  163. package/src/helpers/PersonHelper.ts +60 -60
  164. package/src/helpers/SlugHelper.ts +38 -0
  165. package/src/helpers/SocketHelper.ts +78 -78
  166. package/src/helpers/Themes.ts +14 -14
  167. package/src/helpers/UniqueIdHelper.ts +36 -36
  168. package/src/helpers/UserHelper.ts +59 -59
  169. package/src/helpers/createEmotionCache.ts +17 -17
  170. package/src/helpers/index.ts +19 -18
  171. package/src/hooks/index.ts +1 -1
  172. package/src/hooks/useMountedState.ts +16 -16
  173. package/src/index.ts +6 -6
  174. package/src/interfaces/Access.ts +24 -24
  175. package/src/interfaces/Attendance.ts +8 -8
  176. package/src/interfaces/Content.ts +10 -10
  177. package/src/interfaces/Doing.ts +24 -24
  178. package/src/interfaces/Donation.ts +45 -45
  179. package/src/interfaces/Error.ts +17 -17
  180. package/src/interfaces/Membership.ts +51 -51
  181. package/src/interfaces/Messaging.ts +11 -11
  182. package/src/interfaces/Permissions.ts +68 -68
  183. package/src/interfaces/Reporting.ts +7 -7
  184. package/src/interfaces/UserContextInterface.ts +13 -13
  185. package/src/interfaces/index.ts +13 -13
  186. package/src/pageComponents/LoginPage.tsx +244 -244
  187. package/src/pageComponents/LogoutPage.tsx +28 -28
  188. package/src/pageComponents/components/Forgot.tsx +79 -79
  189. package/src/pageComponents/components/Login.tsx +54 -54
  190. package/src/pageComponents/components/LoginSetPassword.tsx +63 -63
  191. package/src/pageComponents/components/Register.tsx +107 -107
  192. package/src/pageComponents/components/SelectChurchModal.tsx +41 -41
  193. package/src/pageComponents/components/SelectChurchRegister.tsx +88 -88
  194. package/src/pageComponents/components/SelectChurchSearch.tsx +69 -69
  195. package/src/pageComponents/components/SelectableChurch.tsx +38 -38
  196. package/src/pageComponents/index.ts +3 -3
  197. package/tsconfig.json +34 -34
  198. package/tslint.json +14 -14
@@ -1,153 +1,153 @@
1
- import * as React from "react";
2
- import { styled, Icon, InputBase, Typography, debounce, Grid, IconButton, Pagination, Stack } from "@mui/material";
3
- import MuiPaper from "@mui/material/Paper";
4
- import IconNamesList from "./IconNamesList"
5
-
6
- const UPDATE_SEARCH_INDEX_WAIT_MS = 220;
7
-
8
- const FlexSearch = require("flexsearch");
9
- const StyledIconSpan = styled("span")(({ theme }) => ({
10
- display: "inline-flex",
11
- flexDirection: "column",
12
- color: theme.palette.text.secondary,
13
- margin: "0 4px",
14
- "& > div": {
15
- display: "flex"
16
- },
17
- "& > div > *": {
18
- flexGrow: 1,
19
- fontSize: ".6rem",
20
- overflow: "hidden",
21
- textOverflow: "ellipsis",
22
- textAlign: "center",
23
- width: 0
24
- }
25
- }));
26
-
27
- const StyledIcon: any = styled(Icon)(({ theme }) => ({
28
- boxSizing: "content-box",
29
- cursor: "pointer",
30
- color: theme.palette.text.primary,
31
- borderRadius: theme.shape.borderRadius,
32
- transition: theme.transitions.create(["background-color", "box-shadow"], {
33
- duration: theme.transitions.duration.shortest
34
- }),
35
- padding: theme.spacing(1),
36
- margin: theme.spacing(0.5, 0),
37
- "&:hover": {
38
- backgroundColor: theme.palette.background.paper,
39
- boxShadow: theme.shadows[1]
40
- }
41
- }));
42
-
43
- const Icons = React.memo(function Icons(props: { icons: string[]; handleOpenClick: (name: string) => void; }) {
44
- const { icons, handleOpenClick } = props;
45
-
46
- const handleIconClick = (name: string) => {
47
- const camel = name.substring(0, 1).toLocaleLowerCase() + name.substring(1, name.length);
48
- const underscored = camel.replace(/[A-Z]/g, m => "_" + m.toLowerCase());
49
- handleOpenClick(underscored)
50
- }
51
-
52
- return (
53
- <div>
54
- {icons.map((icon) => (
55
- <StyledIconSpan key={icon}>
56
- <StyledIcon tabIndex={-1} sx={{ fontSize: "34px !important" }} onClick={() => { handleIconClick(icon) }}>
57
- {icon}
58
- </StyledIcon>
59
- </StyledIconSpan>
60
- ))}
61
- </div>
62
- );
63
- });
64
-
65
- const Paper = styled(MuiPaper)(({ theme }) => ({ padding: "2px 4px", display: "flex", alignItems: "center", marginBottom: theme.spacing(2), width: "100%" }));
66
-
67
- const Input = styled(InputBase)({ marginLeft: 8, flex: 1 });
68
-
69
- const searchIndex = new FlexSearch.Index({ tokenize: "full" });
70
-
71
- function createSearchIndex() {
72
- // create component names from icons list
73
- const iconsAndComponentNames = IconNamesList.map(icon => {
74
- const split = icon.split("_");
75
- const capitalizedSplit = split.map(s => {
76
- if (isAlphabet(s[0])) {
77
- s = s[0].toUpperCase() + s.slice(1)
78
- }
79
- return s
80
- })
81
- return {
82
- iconName: icon,
83
- componentName: capitalizedSplit.join("")
84
- };
85
- })
86
-
87
- // create search index
88
- iconsAndComponentNames.forEach(icon => {
89
- let searchTerm = icon.iconName + " " + icon.componentName;
90
-
91
- searchIndex.addAsync(icon.iconName, searchTerm)
92
- })
93
-
94
- }
95
-
96
- function isAlphabet(character: string) {
97
- return /[a-zA-Z]/.test(character);
98
- }
99
-
100
- createSearchIndex();
101
-
102
- type Props = {
103
- onSelect: (iconName: string) => void;
104
- };
105
-
106
- const defaultIcons = ["person", "group", "groups", "contact_mail", "mail", "church", "favorite", "volunteer_activism", "link", "home", "apps", "web", "public", "rss_feed", "videocam", "live_tv", "music_note", "menu_book", "star", "accessible", "woman", "man", "child_care", "handshake", "location_on", "restaurant", "local_cafe" ];
107
-
108
- export function IconPicker(props: Props) {
109
- const pageSize = 27;
110
- const [keys, setKeys] = React.useState<any[] | null>(null);
111
- const [query, setQuery] = React.useState("");
112
- const [page, setPage] = React.useState(1);
113
-
114
- const updateSearchResults = React.useMemo(
115
- () =>
116
- debounce((value) => {
117
- if (value === "") setKeys(defaultIcons);
118
- else searchIndex.searchAsync(value, { limit: 3000 }).then((results: any) => { setKeys(results); setPage(1); });
119
- }, UPDATE_SEARCH_INDEX_WAIT_MS),
120
- []
121
- );
122
-
123
- React.useEffect(() => { updateSearchResults(query); return () => { updateSearchResults.clear(); }; }, [query, updateSearchResults]);
124
-
125
- function paged<T>(array: Array<T>, p: number) {
126
- return array.slice((p - 1) * pageSize, p * pageSize);
127
- }
128
-
129
- const icons = keys || IconNamesList;
130
-
131
- const pagesCount = Math.ceil(icons.length / pageSize);
132
-
133
- return (
134
- <Grid container sx={{ minHeight: 360, padding: "16px" }}>
135
- <Grid item>
136
- <Paper>
137
- <IconButton sx={{ padding: "10px" }} aria-label="search">
138
- <Icon>search</Icon>
139
- </IconButton>
140
- <Input autoFocus value={query} onChange={(event) => setQuery(event.target.value)} placeholder="Search icons…" inputProps={{ "aria-label": "search icons" }} />
141
- </Paper>
142
- {(query === "") && <Typography sx={{ mb: 1 }}>{`${IconNamesList.length} icons available`}</Typography>}
143
- {(query !== "") && <Typography sx={{ mb: 1 }}>{`${icons.length} matching results`}</Typography>}
144
-
145
- <Icons icons={paged(icons, page)} handleOpenClick={props.onSelect} />
146
- </Grid>
147
-
148
- <Stack spacing={2} sx={{ margin: "0 auto" }}>
149
- <Pagination count={pagesCount} page={page} onChange={(_, p) => setPage(p)} size="small" />
150
- </Stack>
151
- </Grid>
152
- );
153
- }
1
+ import * as React from "react";
2
+ import { styled, Icon, InputBase, Typography, debounce, Grid, IconButton, Pagination, Stack } from "@mui/material";
3
+ import MuiPaper from "@mui/material/Paper";
4
+ import IconNamesList from "./IconNamesList"
5
+
6
+ const UPDATE_SEARCH_INDEX_WAIT_MS = 220;
7
+
8
+ const FlexSearch = require("flexsearch");
9
+ const StyledIconSpan = styled("span")(({ theme }) => ({
10
+ display: "inline-flex",
11
+ flexDirection: "column",
12
+ color: theme.palette.text.secondary,
13
+ margin: "0 4px",
14
+ "& > div": {
15
+ display: "flex"
16
+ },
17
+ "& > div > *": {
18
+ flexGrow: 1,
19
+ fontSize: ".6rem",
20
+ overflow: "hidden",
21
+ textOverflow: "ellipsis",
22
+ textAlign: "center",
23
+ width: 0
24
+ }
25
+ }));
26
+
27
+ const StyledIcon: any = styled(Icon)(({ theme }) => ({
28
+ boxSizing: "content-box",
29
+ cursor: "pointer",
30
+ color: theme.palette.text.primary,
31
+ borderRadius: theme.shape.borderRadius,
32
+ transition: theme.transitions.create(["background-color", "box-shadow"], {
33
+ duration: theme.transitions.duration.shortest
34
+ }),
35
+ padding: theme.spacing(1),
36
+ margin: theme.spacing(0.5, 0),
37
+ "&:hover": {
38
+ backgroundColor: theme.palette.background.paper,
39
+ boxShadow: theme.shadows[1]
40
+ }
41
+ }));
42
+
43
+ const Icons = React.memo(function Icons(props: { icons: string[]; handleOpenClick: (name: string) => void; }) {
44
+ const { icons, handleOpenClick } = props;
45
+
46
+ const handleIconClick = (name: string) => {
47
+ const camel = name.substring(0, 1).toLocaleLowerCase() + name.substring(1, name.length);
48
+ const underscored = camel.replace(/[A-Z]/g, m => "_" + m.toLowerCase());
49
+ handleOpenClick(underscored)
50
+ }
51
+
52
+ return (
53
+ <div>
54
+ {icons.map((icon) => (
55
+ <StyledIconSpan key={icon}>
56
+ <StyledIcon tabIndex={-1} sx={{ fontSize: "34px !important" }} onClick={() => { handleIconClick(icon) }}>
57
+ {icon}
58
+ </StyledIcon>
59
+ </StyledIconSpan>
60
+ ))}
61
+ </div>
62
+ );
63
+ });
64
+
65
+ const Paper = styled(MuiPaper)(({ theme }) => ({ padding: "2px 4px", display: "flex", alignItems: "center", marginBottom: theme.spacing(2), width: "100%" }));
66
+
67
+ const Input = styled(InputBase)({ marginLeft: 8, flex: 1 });
68
+
69
+ const searchIndex = new FlexSearch.Index({ tokenize: "full" });
70
+
71
+ function createSearchIndex() {
72
+ // create component names from icons list
73
+ const iconsAndComponentNames = IconNamesList.map(icon => {
74
+ const split = icon.split("_");
75
+ const capitalizedSplit = split.map(s => {
76
+ if (isAlphabet(s[0])) {
77
+ s = s[0].toUpperCase() + s.slice(1)
78
+ }
79
+ return s
80
+ })
81
+ return {
82
+ iconName: icon,
83
+ componentName: capitalizedSplit.join("")
84
+ };
85
+ })
86
+
87
+ // create search index
88
+ iconsAndComponentNames.forEach(icon => {
89
+ let searchTerm = icon.iconName + " " + icon.componentName;
90
+
91
+ searchIndex.addAsync(icon.iconName, searchTerm)
92
+ })
93
+
94
+ }
95
+
96
+ function isAlphabet(character: string) {
97
+ return /[a-zA-Z]/.test(character);
98
+ }
99
+
100
+ createSearchIndex();
101
+
102
+ type Props = {
103
+ onSelect: (iconName: string) => void;
104
+ };
105
+
106
+ const defaultIcons = ["person", "group", "groups", "contact_mail", "mail", "church", "favorite", "volunteer_activism", "link", "home", "apps", "web", "public", "rss_feed", "videocam", "live_tv", "music_note", "menu_book", "star", "accessible", "woman", "man", "child_care", "handshake", "location_on", "restaurant", "local_cafe" ];
107
+
108
+ export function IconPicker(props: Props) {
109
+ const pageSize = 27;
110
+ const [keys, setKeys] = React.useState<any[] | null>(null);
111
+ const [query, setQuery] = React.useState("");
112
+ const [page, setPage] = React.useState(1);
113
+
114
+ const updateSearchResults = React.useMemo(
115
+ () =>
116
+ debounce((value) => {
117
+ if (value === "") setKeys(defaultIcons);
118
+ else searchIndex.searchAsync(value, { limit: 3000 }).then((results: any) => { setKeys(results); setPage(1); });
119
+ }, UPDATE_SEARCH_INDEX_WAIT_MS),
120
+ []
121
+ );
122
+
123
+ React.useEffect(() => { updateSearchResults(query); return () => { updateSearchResults.clear(); }; }, [query, updateSearchResults]);
124
+
125
+ function paged<T>(array: Array<T>, p: number) {
126
+ return array.slice((p - 1) * pageSize, p * pageSize);
127
+ }
128
+
129
+ const icons = keys || IconNamesList;
130
+
131
+ const pagesCount = Math.ceil(icons.length / pageSize);
132
+
133
+ return (
134
+ <Grid container sx={{ minHeight: 360, padding: "16px" }}>
135
+ <Grid item>
136
+ <Paper>
137
+ <IconButton sx={{ padding: "10px" }} aria-label="search">
138
+ <Icon>search</Icon>
139
+ </IconButton>
140
+ <Input autoFocus value={query} onChange={(event) => setQuery(event.target.value)} placeholder="Search icons…" inputProps={{ "aria-label": "search icons" }} />
141
+ </Paper>
142
+ {(query === "") && <Typography sx={{ mb: 1 }}>{`${IconNamesList.length} icons available`}</Typography>}
143
+ {(query !== "") && <Typography sx={{ mb: 1 }}>{`${icons.length} matching results`}</Typography>}
144
+
145
+ <Icons icons={paged(icons, page)} handleOpenClick={props.onSelect} />
146
+ </Grid>
147
+
148
+ <Stack spacing={2} sx={{ margin: "0 auto" }}>
149
+ <Pagination count={pagesCount} page={page} onChange={(_, p) => setPage(p)} size="small" />
150
+ </Stack>
151
+ </Grid>
152
+ );
153
+ }
@@ -1,24 +1,24 @@
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 { IconPicker } from "./iconPicker/IconPicker";
10
- export { InputBox } from "./InputBox";
11
- export { Loading } from "./Loading";
12
- export { Notes } from "./notes/Notes";
13
- export { PersonAdd } from "./PersonAdd";
14
- export { QuestionEdit } from "./QuestionEdit";
15
- export { SmallButton } from "./SmallButton";
16
- export { SupportModal } from "./SupportModal";
17
- export { MarkdownEditor } from "./markdownEditor/MarkdownEditor";
18
- export { MarkdownPreview } from "./markdownEditor/MarkdownPreview";
19
-
20
- export * from "./wrapper";
21
- export * from "./gallery";
22
- export * from "./markdownEditor";
23
- export * from "./notes";
24
- 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 { IconPicker } from "./iconPicker/IconPicker";
10
+ export { InputBox } from "./InputBox";
11
+ export { Loading } from "./Loading";
12
+ export { Notes } from "./notes/Notes";
13
+ export { PersonAdd } from "./PersonAdd";
14
+ export { QuestionEdit } from "./QuestionEdit";
15
+ export { SmallButton } from "./SmallButton";
16
+ export { SupportModal } from "./SupportModal";
17
+ export { MarkdownEditor } from "./markdownEditor/MarkdownEditor";
18
+ export { MarkdownPreview } from "./markdownEditor/MarkdownPreview";
19
+
20
+ export * from "./wrapper";
21
+ export * from "./gallery";
22
+ export * from "./markdownEditor";
23
+ export * from "./notes";
24
+ 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
+ }