@@ -105,5 +105,123 @@ of.
105105 ```
106106 3. A simple SVG needs to be added to `src/main/webapp/scripts/tinymce/tinymce516/icons/custom_icons/icons.js`
107107
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+
108226## Step 3: Testing
109227- How will we know if the plugin stops working e.g. due to API changes/services being down?
0 commit comments