@@ -105,5 +105,123 @@ of.
105
105
```
106
106
3. A simple SVG needs to be added to `src/main/webapp/scripts/tinymce/tinymce516/icons/custom_icons/icons.js`
107
107
108
+ ### Step 2.2: Rendering a react component
109
+ The three `onAction` handlers should render a react component. Whilst the
110
+ document editor is not currently implemented in react, we intend to migrate to a
111
+ react-based tech stack in the future and all new development should be forwards
112
+ compatible to minimise the disruption of the migration. Furthermore, each of our
113
+ recently developed integrations utilise the branding colours of the
114
+ organisations that develop and maintain the APIs that provide the source of the
115
+ data to help users to visually recognise the point at which RSpace is
116
+ interoperating with other systems. This is implemented using an accented theme
117
+ that is applied to all of the UI elements, most notably the header where we
118
+ consistently provide a link to the documentation for the integration.
119
+
120
+ In the constructor of our new plugin, we want to define a generator function
121
+ that with each call re-renders the react component, allowing us to change the
122
+ `open` state.
123
+ ```
124
+ function* renderNewPlugin(domContainer) {
125
+ const root = createRoot(domContainer);
126
+ while (true) {
127
+ const newProps = yield;
128
+ root.render(
129
+ <StyledEngineProvider injectFirst >
130
+ <ThemeProvider theme ={createAccentedTheme(COLOR)} >
131
+ <NewPluginDialog
132
+ editor={editor}
133
+ open={false}
134
+ onClose={() => {}}
135
+ {...newProps}
136
+ />
137
+ </ThemeProvider >
138
+ </StyledEngineProvider >
139
+ );
140
+ }
141
+ }
142
+ ```
143
+
144
+ We then want to add this dialog to the DOM, but initially hidden. The
145
+ conditional logic is to make sure the dialog isn't added repeatedly every time
146
+ the plugin is instantiated.
147
+ ```
148
+ if (!document.getElementById("tinymce-new-plugin")) {
149
+ const div = document.createElement("div");
150
+ div.id = "tinymce-new-plugin";
151
+ document.body.appendChild(div);
152
+ }
153
+ const newPluginRenderer = renderNewPlugin(document.getElementById("tinymce-new-plugin"));
154
+ newPluginRenderer.next({ open: false });
155
+ ```
156
+
157
+ Finally we return to the `onAction`s, where we can call
158
+ ```
159
+ newPluginRenderer.next({
160
+ open: true,
161
+ onClose: () => {
162
+ newPluginRenderer.next({ open: false });
163
+ },
164
+ });
165
+ ```
166
+
167
+ Note that the imports required at this point are
168
+ ```
169
+ import React from "react";
170
+ import { ThemeProvider } from "@mui/material /styles";
171
+ import StyledEngineProvider from "@mui/styled-engine /StyledEngineProvider";
172
+ import { createRoot } from "react-dom/client";
173
+ import createAccentedTheme from "../../accentedTheme";
174
+ ```
175
+
176
+ Now we just have two things to define `COLOR` and `NewPluginDialog`.
177
+
178
+ ### Step 2.3: Setting the colour of the accented theme
179
+ This is much the same colour as set on the apps page, but with a few variations
180
+ to be able to style all of the possible UI elements. There are five colours
181
+ which need defining `main`, `darker`, `contrastText`, `background`, and
182
+ `backgroundContrastText`. To find out more about how each is used, check out
183
+ `src/main/webapp/ui/src/accentedTheme.js`. For a initial value, start by using
184
+ this defining as a template, setting the hue to the same value used on the apps
185
+ page, above.
186
+ ```
187
+ const COLOR = {
188
+ main: {
189
+ hue: HUE,
190
+ saturation: 46,
191
+ lightness: 70,
192
+ },
193
+ darker: {
194
+ hue: HUE,
195
+ saturation: 93,
196
+ lightness: 33,
197
+ },
198
+ contrastText: {
199
+ hue: HUE,
200
+ saturation: 35,
201
+ lightness: 26,
202
+ },
203
+ background: {
204
+ hue: HUE,
205
+ saturation: 25,
206
+ lightness: 71,
207
+ },
208
+ backgroundContrastText: {
209
+ hue: HUE,
210
+ saturation: 11,
211
+ lightness: 24,
212
+ },
213
+ };
214
+ ```
215
+
216
+ Once we've implemented the dialog and any UI elements within you may need to
217
+ tweak the saturation and lightness values to ensure there is sufficient contrast
218
+ between all textual elements and the background they are shown on. To find out
219
+ more about accessibility and contrast ratios, see the section titled "Colour
220
+ Contrast" in `./Accessibility.md`. Whilst mentioning accessibility, it is worth
221
+ pointing out that by using an accented theme, we automatically get a high
222
+ contrast mode that stips out all of the superfluous colour, should the user wish
223
+ to enable it (this is mentioned in the section titled "Accented Theme").
224
+
225
+
108
226
## Step 3: Testing
109
227
- How will we know if the plugin stops working e.g. due to API changes/services being down?
0 commit comments