gwchq-textjam 0.5.16 → 0.5.18
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.
- package/README.md +53 -40
- package/dist/index.js +5 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,8 +30,7 @@ You will also see any lint errors in the console.
|
|
|
30
30
|
|
|
31
31
|
### `yarn test`
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
|
33
|
+
Runs the Jest test suite once and exits. Pass `--watch` (e.g. `yarn test --watch`) for interactive watch mode, or `--coverage` to generate a coverage report.
|
|
35
34
|
|
|
36
35
|
### `yarn build:lib`
|
|
37
36
|
|
|
@@ -39,9 +38,7 @@ Builds the lib for production to the `dist` folder.\
|
|
|
39
38
|
It bundles React in production mode and optimizes the build for the best performance.
|
|
40
39
|
|
|
41
40
|
The build is minified and the filenames include the hashes.\
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
|
41
|
+
The library is ready to be published — see [Publishing to npm](#publishing-to-npm) below.
|
|
45
42
|
|
|
46
43
|
## Styling
|
|
47
44
|
|
|
@@ -87,7 +84,7 @@ export function ComponentName() {
|
|
|
87
84
|
|
|
88
85
|
## Testing
|
|
89
86
|
|
|
90
|
-
Automated unit tests can be run via the `yarn test` command. These unit tests are written using the JavaScript testing framework `Jest` and make use of the tools provided by the [React Testing Library](https://testing-library.com/docs/). Automated accessibility testing for components is available via the `jest-axe` library. This can be achieved using the `
|
|
87
|
+
Automated unit tests can be run via the `yarn test` command. These unit tests are written using the JavaScript testing framework `Jest` and make use of the tools provided by the [React Testing Library](https://testing-library.com/docs/). Automated accessibility testing for components is available via the `jest-axe` library. This can be achieved using the `toHaveNoViolations` matcher provided by `jest-axe`, although this does not guarantee that the tested components have no accessibility issues.
|
|
91
88
|
|
|
92
89
|
## Publishing to npm
|
|
93
90
|
|
|
@@ -127,11 +124,12 @@ The following files are included in the npm package (as defined in `package.json
|
|
|
127
124
|
Consumers can import:
|
|
128
125
|
|
|
129
126
|
- Main component: `import { TextJamEditor } from "gwchq-textjam"`
|
|
127
|
+
- `CurriculumDisplayMode` enum and `useCurriculumDisplayMode` hook: `import { CurriculumDisplayMode, useCurriculumDisplayMode } from "gwchq-textjam"`
|
|
130
128
|
- Stylesheet: `import "gwchq-textjam/style.css"`
|
|
131
129
|
|
|
132
130
|
# Using the editor as a React component
|
|
133
131
|
|
|
134
|
-
The editor can be imported and rendered directly inside another React application
|
|
132
|
+
The editor can be imported and rendered directly inside another React application:
|
|
135
133
|
|
|
136
134
|
```tsx
|
|
137
135
|
import { TextJamEditor } from "gwchq-textjam";
|
|
@@ -140,7 +138,23 @@ import "gwchq-textjam/style.css";
|
|
|
140
138
|
export function EditorWrapper() {
|
|
141
139
|
return (
|
|
142
140
|
<TextJamEditor
|
|
143
|
-
project={{
|
|
141
|
+
project={{
|
|
142
|
+
project_type: "python",
|
|
143
|
+
identifier: "my-py-app",
|
|
144
|
+
name: "My Python App",
|
|
145
|
+
rootDirId: "root",
|
|
146
|
+
components: [],
|
|
147
|
+
commits: [],
|
|
148
|
+
}}
|
|
149
|
+
isLoading={false}
|
|
150
|
+
user={{
|
|
151
|
+
userId: 1,
|
|
152
|
+
firstName: "Ada",
|
|
153
|
+
lastName: "Lovelace",
|
|
154
|
+
initials: "AL",
|
|
155
|
+
isFacilitator: false,
|
|
156
|
+
avatarSrc: "",
|
|
157
|
+
}}
|
|
144
158
|
/>
|
|
145
159
|
);
|
|
146
160
|
}
|
|
@@ -209,43 +223,42 @@ The consumer's webpack config should include the following setups
|
|
|
209
223
|
|
|
210
224
|
### Component props
|
|
211
225
|
|
|
212
|
-
`TextJamEditor` accepts the following props (
|
|
226
|
+
`TextJamEditor` accepts the following props (see `TextJamEditorProps` in `src/App.tsx` for the source of truth):
|
|
213
227
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
- `packageApiUrl`: A string with url to download pyodide packages. If not provided - default value is pyodide CDN.
|
|
220
|
-
- `isSharedProject`: a boolean to show a shared project interface instead the regular editor if `true` (`false` by default)
|
|
221
|
-
- `isCodeVisible`: a boolean to show or hide the code panel (`true` by default)
|
|
228
|
+
**Required**
|
|
229
|
+
|
|
230
|
+
- `project` (`IncomingProjectData`): the project data. Contains `project_type` (`"web"` | `"python"`), `identifier`, `name`, `rootDirId`, `components` (files and folders), `commits`, and optionally `author`, `commitId`, `savedAt`, `extension`, etc.
|
|
231
|
+
- `isLoading`: a boolean indicating whether the project is still loading.
|
|
232
|
+
- `user` (`AuthorizedUser`): the authenticated user — `userId`, `firstName`, `lastName`, `initials`, `isFacilitator`, `avatarSrc`.
|
|
222
233
|
|
|
223
|
-
|
|
234
|
+
**Optional**
|
|
235
|
+
|
|
236
|
+
- `packageApiUrl`: A string with url to download pyodide packages. If not provided, the default value is the pyodide CDN.
|
|
237
|
+
- `isSharedProject`: a boolean to show a shared project interface instead of the regular editor if `true` (`false` by default)
|
|
238
|
+
- `isCodeVisible`: a boolean to show or hide the code panel (`true` by default)
|
|
239
|
+
- `template`: a `Project` used as the starter/template content.
|
|
240
|
+
- `curriculum`: a `Curriculum` object (`{ curriculumDisplayMode, curriculumContent }`) controlling the embedded curriculum panel. `curriculumDisplayMode` is one of `CurriculumDisplayMode.HIDDEN | NORMAL | EXPANDED`.
|
|
241
|
+
- `saveProject`: `(options: { project, commitBlob?, hasContentChanges?, hasNameChanges?, skipRedirect? }) => void | Promise<void>` — called by the editor when a save is triggered.
|
|
242
|
+
- `isSaving`: a boolean reflecting whether a save is in progress.
|
|
243
|
+
- `loadProjectContent`: a `LoadProjectContentFunction` used to fetch project content on demand.
|
|
244
|
+
- `projectContent`: pre-loaded project content (a zip `Blob`) to inflate instead of fetching it.
|
|
245
|
+
- `starterCodeContent`: a `Blob | null` with starter code content.
|
|
246
|
+
- `shareLinks`: `{ showCode, hideCode } | null` — links for sharing the project.
|
|
247
|
+
- `isContentLoaded` / `isSaveSuccess`: `boolean | null` flags surfaced by the host app's load/save flow.
|
|
248
|
+
- `loadTemplateProjectData`: callback to trigger loading of template project data.
|
|
249
|
+
- `isTemplateDataLoaded`: a boolean indicating whether template data has finished loading.
|
|
250
|
+
- `navigationGuardCoordinator`: a `NavigationGuardCoordinator` (`{ register(guard, shouldBlock?) }`) the host app can use to intercept navigation while there are unsaved changes.
|
|
251
|
+
- `onLogoutClick` / `onViewProfileClick` / `onHomeClick`: callbacks fired from the editor's auth/nav menu.
|
|
224
252
|
|
|
225
|
-
|
|
226
|
-
- `locale`: Locale for UI elements and to determine the language of projects loaded from the API (defaults to `en`)
|
|
227
|
-
- `outputOnly`: Only display the output panel (defaults to `false`)
|
|
228
|
-
- `outputPanels`: Array of output panel names to display (defaults to `['text', 'visual']`)
|
|
229
|
-
- `outputSplitView`: Start with split view in output panel (defaults to `false`, i.e. tabbed view)
|
|
230
|
-
- `projectNameEditable`: Allow the user to edit the project name in the project bar (defaults to `false`)
|
|
231
|
-
- `readOnly`: Display the editor in read-only mode (defaults to `false`)
|
|
232
|
-
- `sidebarOptions`: Array of strings specifying the panels to be displayed in the sidebar. Options include `"projects"`, `"file"`, `"download"`, `"settings"`.
|
|
253
|
+
`sidebarOptions` (`string[]`, defaults to `["files", "home", "user"]`) is also accepted at runtime and forwarded down to the sidebar
|
|
233
254
|
|
|
234
|
-
|
|
255
|
+
### Client-side storage
|
|
235
256
|
|
|
236
|
-
|
|
257
|
+
**IndexedDB** is the editor's actual project cache. It opens a `textjam-store` database (`src/utils/IndexedDb.ts`) with three object stores — `files` (file blobs), `projects` (project metadata, keyed by project key, stamped with `savedAt`), and `project_files` (the list of file ids belonging to a project). The `useProjectCache` hook reads/writes this cache so a project's latest content survives a reload without a round trip to the host app.
|
|
237
258
|
|
|
238
|
-
|
|
259
|
+
**`localStorage`** is used only for a small cross-tab notification, not for storing project content:
|
|
239
260
|
|
|
240
|
-
- `
|
|
241
|
-
- `
|
|
242
|
-
- `editor-projectOwnerLoaded`
|
|
243
|
-
- `editor-runCompleted`
|
|
244
|
-
- `editor-runStarted`
|
|
245
|
-
- `editor-stepChanged`
|
|
246
|
-
- `editor-logIn`
|
|
247
|
-
- `editor-signUp`
|
|
248
|
-
- `editor-quizReady`
|
|
249
|
-
- `editor-themeUpdated`
|
|
261
|
+
- `src/utils/projectTabSync.ts` writes a `project-updated` key (`{ key, timestamp, source }`) whenever the active project changes.
|
|
262
|
+
- Other open tabs pick this up via the `storage` event (`listenProjectUpdates`) and, through the `useProjectTabSync` hook, show a "made changes in another tab, refresh to see your updates" toast. Preview tabs and the tab that made the change are excluded.
|
|
250
263
|
|
|
251
|
-
|
|
264
|
+
Inside the sandboxed iframe used to run HTML/JS projects, the editor also overrides `window.localStorage` (`src/components/Editor/Runners/HtmlRunner/helpers/scripts.ts`) to block reads/writes/removal of `authKey` and any `oidc.*` key, and disables `clear()` entirely — this prevents user-authored preview code from reading or tampering with the host app's auth tokens.
|
package/dist/index.js
CHANGED
|
@@ -51743,7 +51743,8 @@ var useResizableSeparator = _ref => {
|
|
|
51743
51743
|
applyPixels(nextPx, metrics);
|
|
51744
51744
|
};
|
|
51745
51745
|
var separatorProps = {
|
|
51746
|
-
|
|
51746
|
+
// Not "separator": NVDA stays in browse mode on a splitter and eats arrows.
|
|
51747
|
+
role: "slider",
|
|
51747
51748
|
tabIndex: 0,
|
|
51748
51749
|
"aria-label": separatorLabel !== null && separatorLabel !== void 0 ? separatorLabel : "Resize panels",
|
|
51749
51750
|
"aria-orientation": isVerticalHandle ? "vertical" : "horizontal",
|
|
@@ -82852,9 +82853,10 @@ const useFileTree = ({ projectFiles, onRename, onDrop, onOpenFile, rootId, readO
|
|
|
82852
82853
|
tree.rebuildTree();
|
|
82853
82854
|
}, [projectFiles, tree]);
|
|
82854
82855
|
// A leftover dnd state disables every hotkey; `dragend` never comes when the
|
|
82855
|
-
// dragged row unmounts. Capture + microtask:
|
|
82856
|
+
// dragged row unmounts. Capture + task, not microtask: a native dispatch runs
|
|
82857
|
+
// microtasks between listeners, i.e. before their drop handler reads it.
|
|
82856
82858
|
(0, react_2.useEffect)(() => {
|
|
82857
|
-
const clearDndState = () =>
|
|
82859
|
+
const clearDndState = () => setTimeout(() => tree.applySubStateUpdate("dnd", null));
|
|
82858
82860
|
document.addEventListener("drop", clearDndState, true);
|
|
82859
82861
|
return () => document.removeEventListener("drop", clearDndState, true);
|
|
82860
82862
|
}, [tree]);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gwchq-textjam",
|
|
3
3
|
"description": "Embeddable React editor used in Raspberry Pi text-based projects.",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.18",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/GirlsFirst/gwchq-textjam",
|
|
7
7
|
"author": "Girls Who Code HQ",
|