ish-ui 1.0.2

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 (126) hide show
  1. package/.eslintrc.json +39 -0
  2. package/.gitattributes +3 -0
  3. package/.github/workflows/release-package.yml +33 -0
  4. package/.prettierrc +5 -0
  5. package/README.md +80 -0
  6. package/assets/fonts/inter/Inter-Italic.var.woff2 +0 -0
  7. package/assets/fonts/inter/Inter-Roman.var.woff2 +0 -0
  8. package/assets/fonts/inter/LICENSE.txt +92 -0
  9. package/assets/fonts/inter/index.d.ts +10 -0
  10. package/assets/fonts/inter/inter.scss +17 -0
  11. package/package.json +108 -0
  12. package/src/actions/FieldProcessing.ts +21 -0
  13. package/src/actions/index.ts +10 -0
  14. package/src/appBar/AppBarHelpMenu.tsx +139 -0
  15. package/src/appBar/index.ts +9 -0
  16. package/src/buttons/AddButton.tsx +30 -0
  17. package/src/buttons/TimetableButton.tsx +19 -0
  18. package/src/buttons/index.ts +10 -0
  19. package/src/colorPicker/ColorPicker.tsx +223 -0
  20. package/src/colorPicker/index.ts +9 -0
  21. package/src/dialog/BrowserWarning.tsx +24 -0
  22. package/src/dialog/confirm/ConfirmBase.tsx +59 -0
  23. package/src/dialog/index.ts +11 -0
  24. package/src/dialog/message/Message.tsx +140 -0
  25. package/src/documents/DocumentIconsChooser.tsx +69 -0
  26. package/src/documents/index.ts +10 -0
  27. package/src/documents/utils/index.tsx +71 -0
  28. package/src/dynamicSizeList/DynamicSizeList.tsx +208 -0
  29. package/src/dynamicSizeList/index.ts +9 -0
  30. package/src/fieldMessage/ErrorMessage.tsx +28 -0
  31. package/src/fieldMessage/WarningMessage.tsx +28 -0
  32. package/src/fieldMessage/index.ts +11 -0
  33. package/src/fieldMessage/styles.ts +21 -0
  34. package/src/fileUploader/FileUploaderDialog.tsx +158 -0
  35. package/src/fileUploader/index.ts +9 -0
  36. package/src/formFields/CheckboxField.tsx +90 -0
  37. package/src/formFields/CodeEditorField.tsx +103 -0
  38. package/src/formFields/ColoredCheckBox.tsx +74 -0
  39. package/src/formFields/DateTimeField.tsx +61 -0
  40. package/src/formFields/EditInPlaceDateTimeField.tsx +285 -0
  41. package/src/formFields/EditInPlaceDurationField.tsx +79 -0
  42. package/src/formFields/EditInPlaceField.tsx +131 -0
  43. package/src/formFields/EditInPlaceFieldBase.tsx +241 -0
  44. package/src/formFields/EditInPlaceFileField.tsx +67 -0
  45. package/src/formFields/EditInPlaceMoneyField.tsx +64 -0
  46. package/src/formFields/EditInPlacePhoneField.tsx +97 -0
  47. package/src/formFields/EditInPlaceSearchSelect.tsx +562 -0
  48. package/src/formFields/FieldAdornments.tsx +70 -0
  49. package/src/formFields/FilePreview.tsx +149 -0
  50. package/src/formFields/FormRadioButtons.tsx +62 -0
  51. package/src/formFields/SelectCustomComponents.tsx +228 -0
  52. package/src/formFields/Switch.tsx +146 -0
  53. package/src/formFields/TextField.tsx +60 -0
  54. package/src/formFields/UneditableBase.tsx +101 -0
  55. package/src/formFields/index.ts +27 -0
  56. package/src/index.ts +26 -0
  57. package/src/layout/InfoPill.tsx +36 -0
  58. package/src/layout/index.ts +10 -0
  59. package/src/layout/resizable/ResizableWrapper.tsx +87 -0
  60. package/src/markdownEditor/HtmlEditor.tsx +44 -0
  61. package/src/markdownEditor/WysiwygEditor.tsx +137 -0
  62. package/src/markdownEditor/index.ts +12 -0
  63. package/src/markdownEditor/style.ts +188 -0
  64. package/src/markdownEditor/utils/index.ts +48 -0
  65. package/src/model/AppBar.ts +20 -0
  66. package/src/model/CommomObjects.ts +8 -0
  67. package/src/model/CommonFunctions.ts +20 -0
  68. package/src/model/Confirm.ts +27 -0
  69. package/src/model/Fields.ts +254 -0
  70. package/src/model/NestedEntity.ts +14 -0
  71. package/src/model/Theme.ts +42 -0
  72. package/src/model/index.ts +16 -0
  73. package/src/styles/GlobalStylesProvider.tsx +520 -0
  74. package/src/styles/StylesProviderCustom.tsx +8 -0
  75. package/src/styles/animateStyles.ts +94 -0
  76. package/src/styles/bootstrap.ts +503 -0
  77. package/src/styles/hooks.ts +44 -0
  78. package/src/styles/index.ts +18 -0
  79. package/src/styles/makeStyles.ts +21 -0
  80. package/src/styles/mixins/common.ts +40 -0
  81. package/src/styles/mixins/keyframes.ts +16 -0
  82. package/src/styles/mixins/prefixer.ts +21 -0
  83. package/src/tagsInput/AddTagMenu.tsx +74 -0
  84. package/src/tagsInput/AddTagMenuItem.tsx +50 -0
  85. package/src/tagsInput/TagInputList.tsx +428 -0
  86. package/src/tagsInput/index.ts +4 -0
  87. package/src/themes/appTheme.ts +324 -0
  88. package/src/themes/index.ts +10 -0
  89. package/src/themes/ishTheme.ts +401 -0
  90. package/src/timetable/datePeriodFilter/DayPeriodIcons.tsx +95 -0
  91. package/src/timetable/datePeriodFilter/index.ts +10 -0
  92. package/src/timetable/index.ts +11 -0
  93. package/src/timetable/miniCalendar/CalendarDay.tsx +109 -0
  94. package/src/timetable/miniCalendar/CalendarHeader.tsx +37 -0
  95. package/src/timetable/miniCalendar/CalendarWeekPanel.tsx +35 -0
  96. package/src/timetable/miniCalendar/WeekDay.tsx +49 -0
  97. package/src/timetable/miniCalendar/index.ts +13 -0
  98. package/src/utils/DOM/Links.ts +17 -0
  99. package/src/utils/DOM/getCaretCoordinates.ts +122 -0
  100. package/src/utils/DOM/getOS.ts +32 -0
  101. package/src/utils/DOM/index.ts +34 -0
  102. package/src/utils/dates/datesNormalizing.ts +4 -0
  103. package/src/utils/dates/format.ts +52 -0
  104. package/src/utils/dates/formatRelative.ts +22 -0
  105. package/src/utils/dates/formatString.ts +233 -0
  106. package/src/utils/dates/formatTimezone.ts +37 -0
  107. package/src/utils/dates/index.ts +15 -0
  108. package/src/utils/dates/timetable.ts +46 -0
  109. package/src/utils/events/index.ts +8 -0
  110. package/src/utils/fields/index.ts +23 -0
  111. package/src/utils/formatting/PhoneMasks.ts +320 -0
  112. package/src/utils/formatting/index.tsx +20 -0
  113. package/src/utils/hooks/index.ts +19 -0
  114. package/src/utils/index.ts +15 -0
  115. package/src/utils/numbers/decimalCalculation.ts +26 -0
  116. package/src/utils/numbers/index.ts +11 -0
  117. package/src/utils/numbers/numbersNormalizing.ts +52 -0
  118. package/src/utils/stubs/index.tsx +12 -0
  119. package/src/utils/tags/index.ts +53 -0
  120. package/tools/webpack/webpack.aliases.js +13 -0
  121. package/tools/webpack/webpack.config.dev.js +29 -0
  122. package/tools/webpack/webpack.config.prod.js +36 -0
  123. package/tools/webpack/webpack.helpers.js +26 -0
  124. package/tools/webpack/webpack.plugins.js +15 -0
  125. package/tools/webpack/webpack.rules.js +51 -0
  126. package/tsconfig.json +24 -0
@@ -0,0 +1,101 @@
1
+ /*
2
+ * Copyright ish group pty ltd 2023.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
+ *
6
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
+ */
8
+
9
+ import clsx from 'clsx';
10
+ import React, { useCallback } from 'react';
11
+ import {
12
+ FormControl, FormHelperText, Input, InputLabel
13
+ } from '@mui/material';
14
+ import InputAdornment from '@mui/material/InputAdornment';
15
+ import { makeAppStyles } from '@src/styles';
16
+ import { LinkAdornment } from './FieldAdornments';
17
+ import { formatCurrency, openInternalLink } from '@src/utils';
18
+
19
+ const useStyles = makeAppStyles({
20
+ rightAlignedLabel: {
21
+ left: 'unset',
22
+ right: 0,
23
+ transformOrigin: '100% 0'
24
+ }
25
+ });
26
+
27
+ interface UneditableProps {
28
+ value: string | number;
29
+ label: string;
30
+ labelAdornment?: any;
31
+ url?: string;
32
+ currencySymbol?: string;
33
+ money?: boolean;
34
+ multiline?: boolean;
35
+ rightAligned?: boolean;
36
+ className?: string;
37
+ placeholder?: string;
38
+ error?: string;
39
+ format?: (value) => any;
40
+ }
41
+
42
+ const UneditableBase = React.memo<UneditableProps>(props => {
43
+ const {
44
+ label, labelAdornment, placeholder = 'No value', rightAligned, value, url, money, currencySymbol, className, format, multiline, error
45
+ } = props;
46
+
47
+ const classes = useStyles();
48
+ const inputId = `input-${label.toLowerCase().replace(' ', '-')}`;
49
+
50
+ const openLink = useCallback(() => {
51
+ openInternalLink(url);
52
+ }, [url]);
53
+
54
+ return (
55
+ <FormControl
56
+ className={clsx(className, money && 'money')}
57
+ error={Boolean(error)}
58
+ variant="standard"
59
+ fullWidth
60
+ >
61
+ <InputLabel
62
+ shrink
63
+ classes={{
64
+ root: rightAligned ? classes.rightAlignedLabel : null
65
+ }}
66
+ htmlFor={inputId}
67
+ >
68
+ {label}
69
+ {url && <LinkAdornment link={url} className="pl-0-5" clickHandler={openLink} />}
70
+ {labelAdornment && (
71
+ <span className="pl-0-5">
72
+ {labelAdornment}
73
+ {' '}
74
+ </span>
75
+ )}
76
+ </InputLabel>
77
+ <Input
78
+ id={inputId}
79
+ startAdornment={money && <InputAdornment position="start">{currencySymbol}</InputAdornment>}
80
+ value={
81
+ money
82
+ ? formatCurrency(value, '')
83
+ : value
84
+ ? (format
85
+ ? (format(value))
86
+ : (value)
87
+ ) : ('')
88
+ }
89
+ multiline={multiline}
90
+ placeholder={placeholder}
91
+ inputProps={{
92
+ className: rightAligned && 'text-end'
93
+ }}
94
+ disabled
95
+ />
96
+ <FormHelperText>{error}</FormHelperText>
97
+ </FormControl>
98
+ );
99
+ });
100
+
101
+ export default UneditableBase;
@@ -0,0 +1,27 @@
1
+ /*
2
+ * Copyright ish group pty ltd 2023.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
+ *
6
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
+ */
8
+
9
+ export * from './CheckboxField';
10
+ export * from './CodeEditorField';
11
+ export * from './ColoredCheckBox';
12
+ export * from './DateTimeField';
13
+ export * from './EditInPlaceDateTimeField';
14
+ export * from './EditInPlaceDurationField';
15
+ export * from './EditInPlaceField';
16
+ export * from './EditInPlaceFieldBase';
17
+ export * from './EditInPlaceFileField';
18
+ export * from './EditInPlaceMoneyField';
19
+ export * from './EditInPlacePhoneField';
20
+ export * from './EditInPlaceSearchSelect';
21
+ export * from './FieldAdornments';
22
+ export * from './FilePreview';
23
+ export * from './FormRadioButtons';
24
+ export * from './SelectCustomComponents';
25
+ export * from './Switch';
26
+ export * from './TextField';
27
+ export * from './UneditableBase';
package/src/index.ts ADDED
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Copyright ish group pty ltd 2023.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
+ *
6
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
+ */
8
+
9
+ export * from './actions';
10
+ export * from './appBar';
11
+ export * from './buttons';
12
+ export * from './colorPicker';
13
+ export * from './dialog';
14
+ export * from './documents';
15
+ export * from './dynamicSizeList';
16
+ export * from './fieldMessage';
17
+ export * from './fileUploader';
18
+ export * from './formFields';
19
+ export * from './layout';
20
+ export * from './markdownEditor';
21
+ export * from './model';
22
+ export * from './styles';
23
+ export * from './tagsInput';
24
+ export * from './themes';
25
+ export * from './utils';
26
+ export * from './timetable';
@@ -0,0 +1,36 @@
1
+ /*
2
+ * Copyright ish group pty ltd 2022.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
+ *
6
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
+ */
8
+
9
+ import { Chip } from '@mui/material';
10
+ import React from 'react';
11
+ import { alpha } from '@mui/material/styles';
12
+ import { makeAppStyles } from '@src/styles';
13
+
14
+ const useStyles = makeAppStyles<Props>(theme => ({
15
+ chip: {
16
+ textTransform: 'uppercase',
17
+ fontWeight: 600,
18
+ fontSize: '12px',
19
+ marginLeft: theme.spacing(1),
20
+ color: ({ color }) => theme.palette[color].light,
21
+ backgroundColor: ({ color }) => alpha(theme.palette[color].light, 0.15)
22
+ }
23
+ }));
24
+
25
+ interface Props {
26
+ label: string;
27
+ color?: 'success' | 'primary';
28
+ }
29
+
30
+ const InfoPill = ({ label, color = label === 'custom' ? 'primary' : 'success' }: Props) => {
31
+ const classes = useStyles({ label, color });
32
+
33
+ return <Chip className={classes.chip} label={label} size="small" />;
34
+ };
35
+
36
+ export default InfoPill;
@@ -0,0 +1,10 @@
1
+ /*
2
+ * Copyright ish group pty ltd 2023.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
+ *
6
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
+ */
8
+
9
+ export * from './resizable/ResizableWrapper';
10
+ export * from './InfoPill';
@@ -0,0 +1,87 @@
1
+ import * as React from 'react';
2
+ import { Resizable } from 're-resizable';
3
+ import { withStyles, createStyles } from '@mui/styles';
4
+ import useMediaQuery from '@mui/material/useMediaQuery';
5
+ import clsx from 'clsx';
6
+ import { AppTheme } from '@src/model';
7
+
8
+ const LIST_SIDE_BAR_DEFAULT_WIDTH = 265;
9
+
10
+ const styles = (theme: AppTheme) =>
11
+ createStyles({
12
+ sideBar: {
13
+ borderRight: `1px solid ${theme.palette.divider}`,
14
+ display: 'flex',
15
+ paddingRight: '1px',
16
+ '&.d-none': {
17
+ display: 'none'
18
+ }
19
+ },
20
+ sideBarWrapper: {
21
+ overflowX: 'hidden',
22
+ overflowY: 'auto',
23
+ flex: 1
24
+ },
25
+ line: {
26
+ height: '100%',
27
+ width: '2px',
28
+ transition: 'background 120ms ease-in-out',
29
+ },
30
+ resizeLine: {
31
+ zIndex: theme.zIndex.drawer,
32
+ display: 'flex',
33
+ justifyContent: 'center',
34
+ '&:active $line, &:hover $line': {
35
+ background: `${theme.palette.secondary.main}`,
36
+ overflow: 'visible'
37
+ }
38
+ }
39
+ });
40
+
41
+ interface Props {
42
+ sidebarWidth: number;
43
+ minWidth?: number | string;
44
+ maxWidth?: number | string;
45
+ onResizeStop?: any;
46
+ onResize?: any;
47
+ classes?: any;
48
+ className?: any;
49
+ ignoreScreenWidth?: boolean;
50
+ children?: any;
51
+ }
52
+
53
+ const ResizableWrapper = (props: Props) => {
54
+ const {
55
+ classes,
56
+ onResizeStop,
57
+ onResize,
58
+ sidebarWidth,
59
+ minWidth,
60
+ maxWidth,
61
+ children,
62
+ className,
63
+ ignoreScreenWidth
64
+ } = props;
65
+
66
+ return useMediaQuery('(min-width:992px)') || ignoreScreenWidth ? (
67
+ <Resizable
68
+ size={{ width: sidebarWidth, height: '100%' }}
69
+ minWidth={minWidth || LIST_SIDE_BAR_DEFAULT_WIDTH}
70
+ maxWidth={maxWidth}
71
+ onResizeStop={onResizeStop}
72
+ onResize={onResize}
73
+ enable={{ right: true }}
74
+ className={clsx(classes.sideBar, className)}
75
+ handleClasses={{ right: classes.resizeLine }}
76
+ handleComponent={{ right: <div className={props.classes.line} /> }}
77
+ >
78
+ <div className={classes.sideBarWrapper}>{children}</div>
79
+ </Resizable>
80
+ ) : (
81
+ children
82
+ );
83
+ };
84
+
85
+ const wrapped: any = (withStyles(styles)(ResizableWrapper) as any);
86
+
87
+ export default wrapped as React.FC<Props>;
@@ -0,0 +1,44 @@
1
+ import React, { FunctionComponent } from 'react';
2
+ import AceEditor from 'react-ace';
3
+ import 'ace-builds/webpack-resolver';
4
+ import 'ace-builds/src-noconflict/mode-html';
5
+ import 'ace-builds/src-noconflict/mode-textile';
6
+ import 'ace-builds/src-noconflict/theme-tomorrow';
7
+ import 'ace-builds/src-noconflict/ext-language_tools';
8
+ import 'ace-builds/src-noconflict/snippets/html';
9
+ import 'ace-builds/src-noconflict/snippets/textile';
10
+
11
+ interface Props {
12
+ value?: string;
13
+ mode?: string;
14
+ onChange?: (html) => void;
15
+ }
16
+
17
+ const HtmlEditor = props => {
18
+ const { value, onChange, mode = 'html' } = props;
19
+
20
+ return (
21
+ <AceEditor
22
+ mode={mode}
23
+ theme="tomorrow"
24
+ fontSize={14}
25
+ height="200px"
26
+ showGutter={false}
27
+ width="100%"
28
+ wrapEnabled
29
+ highlightActiveLine
30
+ enableLiveAutocompletion={mode === 'html'}
31
+ enableBasicAutocompletion={mode === 'html'}
32
+ setOptions={{
33
+ enableSnippets: true,
34
+ showLineNumbers: true,
35
+ tabSize: 2,
36
+ }}
37
+ editorProps={{ $blockScrolling: Infinity }}
38
+ defaultValue={value}
39
+ onChange={onChange}
40
+ />
41
+ );
42
+ };
43
+
44
+ export default HtmlEditor as FunctionComponent<Props>;
@@ -0,0 +1,137 @@
1
+ /*
2
+ * Copyright ish group pty ltd 2022.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
+ *
6
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
+ */
8
+
9
+ import React from 'react';
10
+ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
11
+ import EssentialsPlugin from '@ckeditor/ckeditor5-essentials/src/essentials';
12
+ import AutoformatPlugin from '@ckeditor/ckeditor5-autoformat/src/autoformat';
13
+ import SourceEditing from '@ckeditor/ckeditor5-source-editing/src/sourceediting';
14
+ import BoldPlugin from '@ckeditor/ckeditor5-basic-styles/src/bold';
15
+ import ItalicPlugin from '@ckeditor/ckeditor5-basic-styles/src/italic';
16
+ import HeadingPlugin from '@ckeditor/ckeditor5-heading/src/heading';
17
+ import LinkPlugin from '@ckeditor/ckeditor5-link/src/link';
18
+ import ListPlugin from '@ckeditor/ckeditor5-list/src/list';
19
+ import ParagraphPlugin from '@ckeditor/ckeditor5-paragraph/src/paragraph';
20
+ import Markdown from '@ckeditor/ckeditor5-markdown-gfm/src/markdown';
21
+ import Table from '@ckeditor/ckeditor5-table/src/table';
22
+ import TableToolbar from '@ckeditor/ckeditor5-table/src/tabletoolbar';
23
+ import Image from '@ckeditor/ckeditor5-image/src/image';
24
+ import LinkImage from '@ckeditor/ckeditor5-link/src/linkimage';
25
+ import ImageCaption from '@ckeditor/ckeditor5-image/src/imagecaption';
26
+ import ImageStyle from '@ckeditor/ckeditor5-image/src/imagestyle';
27
+ import { CKEditor } from '@ckeditor/ckeditor5-react/dist/ckeditor';
28
+ import { createRoot } from 'react-dom/client';
29
+ import CodeIcon from '@mui/icons-material/Code';
30
+
31
+ const SourceEditingSwitch = () => (
32
+ <div className="ck_source_edit_custom">
33
+ <CodeIcon className="ck_code_icon_custom" />
34
+ </div>
35
+ );
36
+
37
+ const config = {
38
+ plugins: [
39
+ Markdown,
40
+ SourceEditing,
41
+ EssentialsPlugin,
42
+ AutoformatPlugin,
43
+ BoldPlugin,
44
+ ItalicPlugin,
45
+ HeadingPlugin,
46
+ LinkPlugin,
47
+ ListPlugin,
48
+ ParagraphPlugin,
49
+ Table,
50
+ TableToolbar,
51
+ Image,
52
+ LinkImage,
53
+ ImageStyle,
54
+ ImageCaption,
55
+ ],
56
+ toolbar: [
57
+ 'heading',
58
+ 'bold',
59
+ 'italic',
60
+ 'link',
61
+ 'bulletedList',
62
+ 'numberedList',
63
+ 'insertTable',
64
+ 'sourceEditing',
65
+ ],
66
+ table: {
67
+ defaultHeadings: { rows: 1 },
68
+ contentToolbar: ['tableColumn', 'tableRow']
69
+ },
70
+ heading: {
71
+ options: [
72
+ { model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
73
+ {
74
+ model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1',
75
+ },
76
+ {
77
+ model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2',
78
+ },
79
+ {
80
+ model: 'heading3', view: 'h3', title: 'Heading 3', class: 'ck-heading_heading3',
81
+ },
82
+ {
83
+ model: 'heading4', view: 'h4', title: 'Heading 4', class: 'ck-heading_heading4',
84
+ },
85
+ ],
86
+ },
87
+ };
88
+
89
+ interface Props {
90
+ value?: string;
91
+ onChange?: (val: any) => void;
92
+ wysiwygRef?: any;
93
+ }
94
+
95
+ const WysiwygEditor: React.FC<Props> = ({
96
+ value,
97
+ onChange,
98
+ wysiwygRef
99
+ }) => {
100
+
101
+ const onReady = editor => {
102
+ wysiwygRef.current = editor;
103
+
104
+ const sourceEdit = document.querySelector<any>('.ck-source-editing-button');
105
+ sourceEdit.dataset.ckeTooltipText = 'Edit source';
106
+ sourceEdit.dataset.ckeTooltipPosition = 's';
107
+
108
+ const root = createRoot(sourceEdit);
109
+
110
+ root.render(
111
+ <SourceEditingSwitch />
112
+ );
113
+
114
+ editor.plugins.get('SourceEditing').on('change:isSourceEditingMode', () => {
115
+ const sourceEdit = document.querySelector('.ck-source-editing-button');
116
+ if (sourceEdit) {
117
+ root.render(
118
+ <SourceEditingSwitch/>,
119
+ );
120
+ }
121
+ });
122
+ };
123
+
124
+ const onChangeHandler = (e, editor) => onChange(editor.getData());
125
+
126
+ return (
127
+ <CKEditor
128
+ editor={ClassicEditor}
129
+ config={config}
130
+ data={value}
131
+ onChange={onChangeHandler}
132
+ onReady={onReady}
133
+ />
134
+ );
135
+ };
136
+
137
+ export default WysiwygEditor;
@@ -0,0 +1,12 @@
1
+ /*
2
+ * Copyright ish group pty ltd 2023.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
+ *
6
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
+ */
8
+
9
+ export * from './utils/index';
10
+ export * from './style';
11
+ export * from './HtmlEditor';
12
+ export * from './WysiwygEditor';
@@ -0,0 +1,188 @@
1
+ /*
2
+ * Copyright ish group pty ltd 2022.
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
5
+ *
6
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7
+ */
8
+
9
+ import { makeStyles } from '@mui/styles';
10
+ import { AppTheme } from '@src/model';
11
+
12
+ export const useStyles = makeStyles((theme: AppTheme) => ({
13
+ hoverIcon: {
14
+ opacity: 0.5,
15
+ visibility: 'hidden',
16
+ marginLeft: theme.spacing(1)
17
+ },
18
+ editable: {
19
+ display: 'inline-flex',
20
+ cursor: 'text',
21
+ color: theme.palette.text.primaryEditable,
22
+ minHeight: '32px',
23
+ padding: '4px 0 4px',
24
+ marginTop: theme.spacing(2),
25
+ fontWeight: 400,
26
+ justifyContent: 'space-between',
27
+ alignItems: 'flex-end',
28
+ '&:hover $hoverIcon': {
29
+ visibility: 'visible'
30
+ },
31
+ '&:before': {
32
+ borderBottom: '1px solid transparent',
33
+ left: 0,
34
+ bottom: '4px',
35
+ content: '\' \'',
36
+ position: 'absolute',
37
+ right: 0,
38
+ transition: theme.transitions.create('border-bottom-color', {
39
+ duration: theme.transitions.duration.standard,
40
+ easing: theme.transitions.easing.easeInOut
41
+ }),
42
+ pointerEvents: 'none'
43
+ },
44
+ '&:hover:before': {
45
+ borderBottom: `1px solid ${theme.palette.primary.main}`
46
+ },
47
+ },
48
+ editorArea: {
49
+ '&#editorRoot': {
50
+ '& .ck-dropdown__button .ck-button__label': {
51
+ fontSize: '14px'
52
+ },
53
+ cursor: 'text',
54
+ overflowY: 'auto',
55
+ position: 'relative',
56
+ '& .ck-list__item .ck-button': {
57
+ height: 'unset',
58
+ padding: '5px 10px'
59
+ },
60
+ '& .ck-list__item .ck-heading_heading3': {
61
+ fontSize: '15px'
62
+ },
63
+ '& .ck-list__item .ck-heading_heading4': {
64
+ fontSize: '14px'
65
+ },
66
+ '& .ck-toolbar': {
67
+ height: '45px',
68
+ background: theme.table.contrastRow.main
69
+ },
70
+ '& .ck-list__item': {
71
+ fontSize: '15px'
72
+ },
73
+ '& .ck-dropdown': {
74
+ fontSize: '15px'
75
+ },
76
+ '& .ck.ck-dropdown .ck-button__label': {
77
+ fontFamily: 'Inter, sans-serif',
78
+ overflow: 'visible',
79
+ width: '120px'
80
+ },
81
+ '& .content-mode-wrapper': {
82
+ position: 'absolute',
83
+ right: '10px',
84
+ top: '6px',
85
+ padding: '5px',
86
+ zIndex: 1000,
87
+ '& .content-mode': {
88
+ maxWidth: '85px',
89
+ border: 0,
90
+ boxShadow: 'none',
91
+ backgroundColor: 'black',
92
+ color: 'white',
93
+ padding: '2px',
94
+ fontSize: '9px',
95
+ '&:hover': {
96
+ backgroundColor: theme.palette.primary.main,
97
+ color: theme.palette.primary.contrastText,
98
+ },
99
+ }
100
+ },
101
+ '& .ck-editor': {
102
+ '& .ck-content': {
103
+ resize: 'vertical',
104
+ maxHeight: '80vh',
105
+ minHeight: '200px',
106
+ fontFamily: 'Inter, sans-serif',
107
+ fontWeight: 400,
108
+ fontSize: '14px',
109
+ color: 'black'
110
+ },
111
+ '& .ck-content .table': {
112
+ marginLeft: 0
113
+ },
114
+ '& .ck-toolbar': {
115
+ padding: '3px'
116
+ },
117
+ '& .ck-source-editing-button': {
118
+ marginLeft: 'auto',
119
+ marginRight: '44px'
120
+ },
121
+ '& .ck-source-editing-button > *': {
122
+ visibility: 'hidden'
123
+ },
124
+ '& .ck-source-editing-button .ck_source_edit_custom': {
125
+ visibility: 'visible'
126
+ },
127
+ '& .ck-source-editing-button .ck_code_icon_custom': {
128
+ width: '24px'
129
+ },
130
+ },
131
+ '&.ace-wrapper': {
132
+ border: `1px solid ${theme.palette.divider}`,
133
+ paddingTop: '44px',
134
+ background: theme.table.contrastRow.main,
135
+ '& .ace_editor': {
136
+ borderTop: `1px solid ${theme.palette.divider}`
137
+ }
138
+ }
139
+ }
140
+ },
141
+ previewFrame: {
142
+ width: '100%',
143
+ maxHeight: '300px',
144
+ overflow: 'auto',
145
+ fontSize: '16px',
146
+ '& > div': {
147
+ width: '100%'
148
+ },
149
+ '& h1,h2,h3,h4': {
150
+ all: 'revert'
151
+ },
152
+ '& table': {
153
+ marginLeft: 0,
154
+ marginRight: 'auto',
155
+ borderCollapse: 'collapse',
156
+ borderSpacing: 0,
157
+ border: '1px double #b3b3b3',
158
+ '& th': {
159
+ textAlign: 'left',
160
+ fontWeight: 700,
161
+ background: 'hsla(0,0%,0%,5%)',
162
+ minWidth: '2em',
163
+ padding: '0.4em',
164
+ border: '1px solid #bfbfbf'
165
+ },
166
+ '& td': {
167
+ minWidth: '2em',
168
+ padding: '0.4em',
169
+ border: '1px solid #bfbfbf'
170
+ },
171
+ }
172
+ },
173
+ readonly: {
174
+ fontWeight: 300,
175
+ pointerEvents: 'none'
176
+ },
177
+ textField: {
178
+ paddingLeft: '0',
179
+ // @ts-ignore
180
+ paddingBottom: `${theme.spacing(2) - 3}`,
181
+ margin: 0
182
+ },
183
+ '@global': {
184
+ '.ck.ck-balloon-panel.ck-balloon-panel_visible': {
185
+ zIndex: 2000
186
+ }
187
+ }
188
+ }));