gwchq-textjam 0.2.19 → 0.2.21

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/dist/index.js CHANGED
@@ -68344,8 +68344,8 @@ __webpack_require__.r(__webpack_exports__);
68344
68344
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
68345
68345
  /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
68346
68346
  /* harmony export */ });
68347
- /* harmony import */ var C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(89379);
68348
- /* harmony import */ var C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectWithoutProperties_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(53986);
68347
+ /* harmony import */ var D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(89379);
68348
+ /* harmony import */ var D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectWithoutProperties_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(53986);
68349
68349
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(51649);
68350
68350
  /* harmony import */ var _hello_pangea_dnd__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(98850);
68351
68351
  /* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(14062);
@@ -68369,7 +68369,7 @@ var DraggableTab = _ref => {
68369
68369
  panelIndex,
68370
68370
  fileIndex
68371
68371
  } = _ref,
68372
- otherProps = (0,C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectWithoutProperties_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)(_ref, _excluded);
68372
+ otherProps = (0,D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectWithoutProperties_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)(_ref, _excluded);
68373
68373
  var openFiles = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useSelector)(state => state.editor.openedFiles);
68374
68374
  var openFilesCount = openFiles[panelIndex].length;
68375
68375
  var dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useDispatch)();
@@ -68386,7 +68386,7 @@ var DraggableTab = _ref => {
68386
68386
  switchToFileTab(panelIndex, (fileIndex + openFilesCount - 1) % openFilesCount);
68387
68387
  }
68388
68388
  };
68389
- var InnerTab = () => /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(react_tabs__WEBPACK_IMPORTED_MODULE_2__.Tab, (0,C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A)((0,C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A)({
68389
+ var InnerTab = () => /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(react_tabs__WEBPACK_IMPORTED_MODULE_2__.Tab, (0,D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A)((0,D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A)({
68390
68390
  onClick: e => {
68391
68391
  e.stopPropagation();
68392
68392
  switchToFileTab(panelIndex, fileIndex);
@@ -68404,7 +68404,7 @@ var DraggableTab = _ref => {
68404
68404
  draggableProps,
68405
68405
  dragHandleProps
68406
68406
  } = _ref2;
68407
- return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", (0,C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A)((0,C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A)((0,C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A)({
68407
+ return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", (0,D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A)((0,D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A)((0,D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A)({
68408
68408
  className: "draggable-tab",
68409
68409
  ref: innerRef
68410
68410
  }, draggableProps), dragHandleProps), {}, {
@@ -68426,8 +68426,8 @@ __webpack_require__.r(__webpack_exports__);
68426
68426
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
68427
68427
  /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
68428
68428
  /* harmony export */ });
68429
- /* harmony import */ var C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(89379);
68430
- /* harmony import */ var C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectWithoutProperties_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(53986);
68429
+ /* harmony import */ var D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(89379);
68430
+ /* harmony import */ var D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectWithoutProperties_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(53986);
68431
68431
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(51649);
68432
68432
  /* harmony import */ var _hello_pangea_dnd__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(98850);
68433
68433
  /* harmony import */ var react_tabs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(39243);
@@ -68446,8 +68446,8 @@ var DroppableTabList = _ref => {
68446
68446
  children: _children,
68447
68447
  index
68448
68448
  } = _ref,
68449
- otherProps = (0,C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectWithoutProperties_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A)(_ref, _excluded);
68450
- return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)(react_tabs__WEBPACK_IMPORTED_MODULE_1__.TabList, (0,C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)((0,C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)({}, otherProps), {}, {
68449
+ otherProps = (0,D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectWithoutProperties_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A)(_ref, _excluded);
68450
+ return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)(react_tabs__WEBPACK_IMPORTED_MODULE_1__.TabList, (0,D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)((0,D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)({}, otherProps), {}, {
68451
68451
  children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)(_hello_pangea_dnd__WEBPACK_IMPORTED_MODULE_6__.Droppable, {
68452
68452
  direction: "horizontal",
68453
68453
  droppableId: index.toString(),
@@ -68457,7 +68457,7 @@ var DroppableTabList = _ref => {
68457
68457
  droppableProps,
68458
68458
  placeholder
68459
68459
  } = _ref2;
68460
- return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxs)("div", (0,C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)((0,C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)({
68460
+ return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxs)("div", (0,D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)((0,D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .A)({
68461
68461
  className: "droppable-tab-list"
68462
68462
  }, droppableProps), {}, {
68463
68463
  ref: innerRef,
@@ -103011,7 +103011,7 @@ __webpack_require__.r(__webpack_exports__);
103011
103011
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
103012
103012
  /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
103013
103013
  /* harmony export */ });
103014
- /* harmony import */ var C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(89379);
103014
+ /* harmony import */ var D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(89379);
103015
103015
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(51649);
103016
103016
  /* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(14062);
103017
103017
  /* harmony import */ var _redux_EditorSlice__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(68512);
@@ -103031,6 +103031,8 @@ __webpack_require__.r(__webpack_exports__);
103031
103031
 
103032
103032
 
103033
103033
 
103034
+ var defaultProjectName = "New project";
103035
+ var getProjectName = project => (project === null || project === void 0 ? void 0 : project.name) || defaultProjectName;
103034
103036
  var ProjectName = _ref => {
103035
103037
  var {
103036
103038
  className = null,
@@ -103038,17 +103040,23 @@ var ProjectName = _ref => {
103038
103040
  editable = true
103039
103041
  } = _ref;
103040
103042
  var project = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useSelector)(state => state.editor.project, react_redux__WEBPACK_IMPORTED_MODULE_1__.shallowEqual);
103043
+ var projectName = getProjectName(project);
103041
103044
  var dispatch = (0,react_redux__WEBPACK_IMPORTED_MODULE_1__.useDispatch)();
103042
103045
  var {
103043
103046
  hovered,
103044
103047
  hoverProps
103045
103048
  } = (0,_hooks_useHover__WEBPACK_IMPORTED_MODULE_5__.useHover)();
103046
103049
  var nameInput = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
103050
+ var nameBeforeEditingRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(projectName);
103047
103051
  var [isEditing, setEditing] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
103048
- var [name, setName] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(project.name || "New project");
103052
+ var [name, setName] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(projectName);
103049
103053
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
103050
- setName(project.name);
103051
- }, [project.name]);
103054
+ if (!isEditing) {
103055
+ setName(projectName);
103056
+ nameBeforeEditingRef.current = projectName;
103057
+ dispatch((0,_redux_EditorSlice__WEBPACK_IMPORTED_MODULE_6__.setProjectNameDraft)(null));
103058
+ }
103059
+ }, [projectName, isEditing, dispatch]);
103052
103060
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
103053
103061
  if (isEditing) {
103054
103062
  var _nameInput$current, _nameInput$current2;
@@ -103057,33 +103065,59 @@ var ProjectName = _ref => {
103057
103065
  }
103058
103066
  }, [isEditing]);
103059
103067
  var startEditing = () => {
103060
- if (!editable) return;
103068
+ if (!editable || isEditing) return;
103069
+ nameBeforeEditingRef.current = projectName;
103061
103070
  setEditing(true);
103062
103071
  };
103063
103072
  var saveName = () => {
103064
103073
  var newName = nameInput.current.value.trim();
103065
- if (newName && newName !== project.name) {
103074
+ dispatch((0,_redux_EditorSlice__WEBPACK_IMPORTED_MODULE_6__.setProjectNameDraft)(null));
103075
+ if (!newName) {
103076
+ setName(projectName);
103077
+ } else if (newName !== projectName) {
103066
103078
  dispatch((0,_redux_EditorSlice__WEBPACK_IMPORTED_MODULE_6__.updateProjectName)(newName));
103079
+ setName(newName);
103067
103080
  }
103068
103081
  setEditing(false);
103069
103082
  };
103070
103083
  var cancelEditing = () => {
103071
- setName(project.name);
103084
+ var previousName = nameBeforeEditingRef.current;
103085
+ dispatch((0,_redux_EditorSlice__WEBPACK_IMPORTED_MODULE_6__.setProjectNameDraft)(null));
103086
+ setName(previousName);
103087
+ if (previousName !== projectName) {
103088
+ dispatch((0,_redux_EditorSlice__WEBPACK_IMPORTED_MODULE_6__.updateProjectName)(previousName));
103089
+ }
103072
103090
  setEditing(false);
103073
103091
  };
103074
103092
  var handleOnChange = () => {
103075
- setName(nameInput.current.value);
103093
+ var nextName = nameInput.current.value;
103094
+ var trimmedName = nextName.trim();
103095
+ setName(nextName);
103096
+ dispatch((0,_redux_EditorSlice__WEBPACK_IMPORTED_MODULE_6__.setProjectNameDraft)(trimmedName && trimmedName !== projectName ? trimmedName : null));
103097
+ };
103098
+ var handleOnBlur = () => {
103099
+ saveName();
103100
+ };
103101
+ var stopKeyboardEventPropagation = event => {
103102
+ var _event$nativeEvent;
103103
+ if (!isEditing) return;
103104
+ event.stopPropagation();
103105
+ if ((_event$nativeEvent = event.nativeEvent) !== null && _event$nativeEvent !== void 0 && _event$nativeEvent.stopImmediatePropagation) {
103106
+ event.nativeEvent.stopImmediatePropagation();
103107
+ }
103076
103108
  };
103077
103109
  var handleKeyDown = event => {
103110
+ stopKeyboardEventPropagation(event);
103078
103111
  if (event.key === "Enter") {
103079
103112
  event.preventDefault();
103080
103113
  saveName();
103081
103114
  } else if (event.key === "Escape") {
103115
+ event.preventDefault();
103082
103116
  cancelEditing();
103083
103117
  }
103084
103118
  };
103085
- var handleOnBlur = () => {
103086
- saveName();
103119
+ var handleKeyUp = event => {
103120
+ stopKeyboardEventPropagation(event);
103087
103121
  };
103088
103122
  return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
103089
103123
  children: [showLabel && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("label", {
@@ -103091,7 +103125,7 @@ var ProjectName = _ref => {
103091
103125
  id: "project_name_label",
103092
103126
  className: _styles_module_scss__WEBPACK_IMPORTED_MODULE_3__["default"].projectLabel,
103093
103127
  children: "Project Name"
103094
- }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", (0,C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A)((0,C_Project_source_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A)({
103128
+ }), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", (0,D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A)((0,D_gwc2_gwchq_textjam_node_modules_babel_runtime_helpers_esm_objectSpread2_js__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .A)({
103095
103129
  className: classnames__WEBPACK_IMPORTED_MODULE_2___default()(_styles_module_scss__WEBPACK_IMPORTED_MODULE_3__["default"].projectName, className)
103096
103130
  }, hoverProps), {}, {
103097
103131
  children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)((components_Tooltip_Tooltip__WEBPACK_IMPORTED_MODULE_8___default()), {
@@ -103106,6 +103140,7 @@ var ProjectName = _ref => {
103106
103140
  onFocus: startEditing,
103107
103141
  onClick: startEditing,
103108
103142
  onKeyDown: handleKeyDown,
103143
+ onKeyUp: handleKeyUp,
103109
103144
  value: name,
103110
103145
  readOnly: !isEditing,
103111
103146
  onChange: handleOnChange,
@@ -103392,9 +103427,16 @@ var types = __webpack_require__(92932);
103392
103427
  var SpinnerDotted = __webpack_require__(79458);
103393
103428
  ;// ./src/components/SaveButton/styles.module.scss
103394
103429
  // extracted by mini-css-extract-plugin
103395
- /* harmony default export */ const styles_module = ({"grey-rpi-grey-15":"#d5d7dc","grey-rpi-grey-40":"#9497a4","grey-rpi-grey-5":"#f1f2f3","grey-rpi-grey-70":"#4a4d59","grey-rpf-white":"#fff","content":"styles-module__content--Cgvxl","icon":"styles-module__icon--y9Z7a"});
103430
+ /* harmony default export */ const styles_module = ({"grey-rpi-grey-15":"#d5d7dc","grey-rpi-grey-40":"#9497a4","grey-rpi-grey-5":"#f1f2f3","grey-rpi-grey-70":"#4a4d59","grey-rpf-white":"#fff","wrapper":"styles-module__wrapper--U1NAt","content":"styles-module__content--Cgvxl","icon":"styles-module__icon--y9Z7a"});
103396
103431
  // EXTERNAL MODULE: ./src/components/shared/SvgIcon/index.tsx
103397
103432
  var SvgIcon = __webpack_require__(82917);
103433
+ // EXTERNAL MODULE: ./src/components/Tooltip/Tooltip.tsx
103434
+ var Tooltip = __webpack_require__(26982);
103435
+ var Tooltip_default = /*#__PURE__*/__webpack_require__.n(Tooltip);
103436
+ // EXTERNAL MODULE: ./src/hooks/useHover.ts
103437
+ var useHover = __webpack_require__(78556);
103438
+ // EXTERNAL MODULE: ./src/redux/selectors.ts
103439
+ var selectors = __webpack_require__(43551);
103398
103440
  // EXTERNAL MODULE: ./node_modules/react/jsx-runtime.js
103399
103441
  var jsx_runtime = __webpack_require__(74848);
103400
103442
  ;// ./src/components/SaveButton/SaveButton.jsx
@@ -103410,14 +103452,26 @@ var jsx_runtime = __webpack_require__(74848);
103410
103452
 
103411
103453
 
103412
103454
 
103455
+
103456
+
103457
+
103458
+ var NO_CHANGES_TO_SAVE_MESSAGE = "No new changes to save!";
103413
103459
  var SaveButton = props => {
103414
103460
  var dispatch = (0,external_react_redux_.useDispatch)();
103461
+ var {
103462
+ hovered,
103463
+ hoverProps
103464
+ } = (0,useHover.useHover)();
103415
103465
  var loading = (0,external_react_redux_.useSelector)(state => state.editor.loading);
103416
103466
  var saving = (0,external_react_redux_.useSelector)(state => state.editor.saving);
103467
+ var hasContentChanges = (0,external_react_redux_.useSelector)(selectors.selectProjectHasContentChanges);
103468
+ var hasNameChanges = (0,external_react_redux_.useSelector)(selectors.selectProjectHasNameChanges);
103417
103469
  var onClickSave = (0,external_react_.useCallback)(/*#__PURE__*/_asyncToGenerator(function* () {
103418
103470
  dispatch((0,EditorSlice.setSaveTriggered)(true));
103419
103471
  }), [dispatch]);
103420
103472
  var isSaving = saving === types.SavingState.PROCESS;
103473
+ var hasChangesToSave = hasContentChanges || hasNameChanges;
103474
+ var isDisabled = isSaving || !hasChangesToSave;
103421
103475
  var buttonIcon = isSaving ? null : () => /*#__PURE__*/(0,jsx_runtime.jsx)(SvgIcon.SvgIcon, {
103422
103476
  size: 24,
103423
103477
  SvgElement: save["default"],
@@ -103427,14 +103481,22 @@ var SaveButton = props => {
103427
103481
  className: styles_module.content,
103428
103482
  children: [/*#__PURE__*/(0,jsx_runtime.jsx)(SpinnerDotted.SpinnerDotted, {}), " Saving..."]
103429
103483
  }) : "Save";
103430
- return loading === types.LoadingState.SUCCESS && /*#__PURE__*/(0,jsx_runtime.jsx)(Button["default"], (0,objectSpread2/* default */.A)({
103431
- buttonText: buttonText,
103432
- ButtonIcon: buttonIcon,
103433
- buttonIconPosition: "left",
103434
- variant: "secondary",
103435
- onClickHandler: onClickSave,
103436
- disabled: saving === types.SavingState.PROCESS
103437
- }, props));
103484
+ return loading === types.LoadingState.SUCCESS && /*#__PURE__*/(0,jsx_runtime.jsxs)("span", (0,objectSpread2/* default */.A)((0,objectSpread2/* default */.A)({
103485
+ className: styles_module.wrapper
103486
+ }, hoverProps), {}, {
103487
+ children: [/*#__PURE__*/(0,jsx_runtime.jsx)((Tooltip_default()), {
103488
+ message: NO_CHANGES_TO_SAVE_MESSAGE,
103489
+ visible: !hasChangesToSave && hovered,
103490
+ position: "bottom"
103491
+ }), /*#__PURE__*/(0,jsx_runtime.jsx)(Button["default"], (0,objectSpread2/* default */.A)({
103492
+ buttonText: buttonText,
103493
+ ButtonIcon: buttonIcon,
103494
+ buttonIconPosition: "left",
103495
+ variant: "secondary",
103496
+ onClickHandler: onClickSave,
103497
+ disabled: isDisabled
103498
+ }, props))]
103499
+ }));
103438
103500
  };
103439
103501
  /* harmony default export */ const SaveButton_SaveButton = (SaveButton);
103440
103502
 
@@ -373515,7 +373577,7 @@ const useProjectCache_1 = __webpack_require__(69557);
373515
373577
  const helpers_1 = __webpack_require__(59578);
373516
373578
  const sendToast_1 = __webpack_require__(50068);
373517
373579
  const useUnsavedDraftResolution_1 = __webpack_require__(61171);
373518
- const buildProjectSnapshot_1 = __webpack_require__(10533);
373580
+ const projectSnapshotHelpers_1 = __webpack_require__(22390);
373519
373581
  const isFinalLoadingState = (state) => state === types_1.LoadingState.SUCCESS || state === types_1.LoadingState.FAILED;
373520
373582
  const useProject = ({ projectData, projectContent = null, isContentLoaded = null, isLoading = false, loadProjectContent, loadTemplateProjectData, isTemplateDataLoaded, }) => {
373521
373583
  const project = (0, stores_1.useAppSelector)((state) => state.editor.project);
@@ -373561,7 +373623,10 @@ const useProject = ({ projectData, projectContent = null, isContentLoaded = null
373561
373623
  components: preparedComponents,
373562
373624
  commitId: null,
373563
373625
  };
373564
- dispatch((0, EditorSlice_1.setProject)(projectToSet));
373626
+ dispatch((0, EditorSlice_1.setProject)({
373627
+ ...projectToSet,
373628
+ lastSavedSnapshot: (0, projectSnapshotHelpers_1.buildProjectSnapshot)(projectToSet),
373629
+ }));
373565
373630
  }, [dispatch]);
373566
373631
  // set initial project data on first load
373567
373632
  (0, react_1.useEffect)(() => {
@@ -373618,10 +373683,8 @@ const useProject = ({ projectData, projectContent = null, isContentLoaded = null
373618
373683
  dispatch((0, EditorSlice_1.setCommits)({ commits: projectData?.commits ?? [] }));
373619
373684
  return;
373620
373685
  }
373621
- const isSaveInProgressOrSettling = saveTriggered ||
373622
- savingState === types_1.SavingState.PROCESS ||
373623
- savingState === types_1.SavingState.SUCCESS;
373624
- if (isSaveInProgressOrSettling) {
373686
+ const isSaveInProgress = saveTriggered || savingState === types_1.SavingState.PROCESS;
373687
+ if (isSaveInProgress) {
373625
373688
  return;
373626
373689
  }
373627
373690
  // if no local data found or cache should not be used, and commitId provided, try to load from commit
@@ -373721,7 +373784,7 @@ const useProject = ({ projectData, projectContent = null, isContentLoaded = null
373721
373784
  };
373722
373785
  dispatch((0, EditorSlice_1.setProject)({
373723
373786
  ...projectToSet,
373724
- lastSavedSnapshot: (0, buildProjectSnapshot_1.buildProjectSnapshot)(projectToSet),
373787
+ lastSavedSnapshot: (0, projectSnapshotHelpers_1.buildProjectSnapshot)(projectToSet),
373725
373788
  }));
373726
373789
  dispatch((0, EditorSlice_1.setCommits)({ commits: commits ?? [] }));
373727
373790
  })
@@ -373833,7 +373896,8 @@ const constants_1 = __webpack_require__(16287);
373833
373896
  const sendToast_1 = __webpack_require__(50068);
373834
373897
  const projectTabSync_1 = __webpack_require__(48235);
373835
373898
  const LeaveFlowSlice_1 = __webpack_require__(52990);
373836
- const buildProjectSnapshot_1 = __webpack_require__(10533);
373899
+ const projectSnapshotHelpers_1 = __webpack_require__(22390);
373900
+ const selectors_1 = __webpack_require__(43551);
373837
373901
  const AUTO_SAVE_INTERVAL = 2000;
373838
373902
  const useProjectPersistence = ({ user, projectData, hasShownSavePrompt, saveProject, isShared, }) => {
373839
373903
  const project = (0, stores_1.useAppSelector)((state) => state.editor.project);
@@ -373843,13 +373907,35 @@ const useProjectPersistence = ({ user, projectData, hasShownSavePrompt, saveProj
373843
373907
  const leaveFlow = (0, stores_1.useAppSelector)((state) => state.leaveFlow);
373844
373908
  const codeRunTriggered = (0, stores_1.useAppSelector)((state) => state.editor.codeRunTriggered);
373845
373909
  const existingCommits = (0, stores_1.useAppSelector)((state) => state.editor.commits);
373910
+ const hasContentChanges = (0, stores_1.useAppSelector)(selectors_1.selectProjectHasContentChanges);
373911
+ const hasNameChanges = (0, stores_1.useAppSelector)(selectors_1.selectProjectHasNameChanges);
373846
373912
  const dispatch = (0, react_redux_1.useDispatch)();
373847
373913
  const { deleteValueFromCache, upsertCacheValue } = (0, useProjectCache_1.useProjectCache)();
373848
373914
  const handleSave = (0, react_1.useCallback)(async () => {
373849
373915
  if (!project?.components?.length)
373850
373916
  return;
373851
- dispatch((0, EditorSlice_1.setSaving)(types_1.SavingState.PROCESS));
373852
373917
  try {
373918
+ const isInitialSave = !project.commitId;
373919
+ // Nothing to persist. The save button is disabled in this state,
373920
+ // but keep this guard for programmatic save triggers.
373921
+ if (!hasContentChanges && !hasNameChanges && !isInitialSave) {
373922
+ dispatch((0, EditorSlice_1.setSaveTriggered)(false));
373923
+ dispatch((0, EditorSlice_1.setSaving)(types_1.SavingState.IDLE));
373924
+ console.warn("No changes detected. Save won't be processed.");
373925
+ return;
373926
+ }
373927
+ // Name-only save: patch repository name, but do not create/upload a new commit.
373928
+ // Do not set PROCESS here because no archive is being created.
373929
+ if (!hasContentChanges && hasNameChanges && !isInitialSave) {
373930
+ await saveProject?.({
373931
+ project,
373932
+ commitBlob: null,
373933
+ hasContentChanges: false,
373934
+ hasNameChanges: true,
373935
+ });
373936
+ return;
373937
+ }
373938
+ dispatch((0, EditorSlice_1.setSaving)(types_1.SavingState.PROCESS));
373853
373939
  const { zipBlob, unzipSize } = await (0, createProjectArchive_1.createProjectArchive)(project);
373854
373940
  if (unzipSize > constants_1.MAX_PROJECT_TOTAL_SIZE_MB * 1024 * 1024) {
373855
373941
  (0, sendToast_1.showError)(`The project exceeds the ${constants_1.MAX_PROJECT_TOTAL_SIZE_MB} MB maximum allowed size. Please reduce the project size to save successfully.`);
@@ -373859,7 +373945,13 @@ const useProjectPersistence = ({ user, projectData, hasShownSavePrompt, saveProj
373859
373945
  }
373860
373946
  // should skip redirect to project on the first save to avoid conflicts with leave flow
373861
373947
  const skipRedirect = project?.commits?.length === 0;
373862
- await saveProject?.(project, zipBlob, skipRedirect);
373948
+ await saveProject?.({
373949
+ project,
373950
+ commitBlob: zipBlob,
373951
+ hasContentChanges: true,
373952
+ hasNameChanges,
373953
+ skipRedirect,
373954
+ });
373863
373955
  }
373864
373956
  catch (e) {
373865
373957
  console.error(e);
@@ -373874,6 +373966,8 @@ const useProjectPersistence = ({ user, projectData, hasShownSavePrompt, saveProj
373874
373966
  project.name,
373875
373967
  project.commitId,
373876
373968
  project.identifier,
373969
+ hasContentChanges,
373970
+ hasNameChanges,
373877
373971
  ]);
373878
373972
  // finish the process if save failed
373879
373973
  (0, react_1.useEffect)(() => {
@@ -373889,12 +373983,9 @@ const useProjectPersistence = ({ user, projectData, hasShownSavePrompt, saveProj
373889
373983
  }, [dispatch, leaveFlow.requestId, leaveFlow.status, saving]);
373890
373984
  // handle successful saving update
373891
373985
  (0, react_1.useEffect)(() => {
373892
- if (!projectData?.commitId ||
373893
- projectData.commitId === project.commitId ||
373894
- !saveTriggered ||
373895
- saving !== types_1.SavingState.SUCCESS)
373986
+ if (!saveTriggered || saving !== types_1.SavingState.SUCCESS)
373896
373987
  return;
373897
- const incomingCommits = projectData.commits ?? [];
373988
+ const incomingCommits = projectData?.commits ?? [];
373898
373989
  const commitsById = new Map();
373899
373990
  [...existingCommits, ...incomingCommits].forEach((commit) => {
373900
373991
  if (!commit?.id)
@@ -373909,18 +374000,25 @@ const useProjectPersistence = ({ user, projectData, hasShownSavePrompt, saveProj
373909
374000
  const bTime = new Date(b.createdAt || 0).getTime();
373910
374001
  return bTime - aTime;
373911
374002
  });
374003
+ const incomingCommitId = projectData?.commitId;
374004
+ const incomingIdentifier = projectData?.identifier;
374005
+ if (!incomingIdentifier)
374006
+ return;
373912
374007
  // first save: new commitId incoming, but no commitId were set before
373913
- const isFirstSave = commits.length === 1 && !project.commitId && projectData.commitId;
374008
+ const isFirstSave = commits.length === 1 && !project.commitId && projectData?.commitId;
373914
374009
  // commit different: new commitId incoming, but another commitId is set before
373915
- const isCommitDifferent = projectData.commitId &&
374010
+ const isCommitDifferent = projectData?.commitId &&
373916
374011
  project.commitId &&
373917
374012
  project.commitId !== projectData.commitId;
373918
- if (!isFirstSave && !isCommitDifferent)
373919
- return;
373920
- dispatch((0, EditorSlice_1.updateProjectCommits)({ commitId: projectData.commitId, commits }));
374013
+ if ((isFirstSave || isCommitDifferent) && projectData?.commitId) {
374014
+ dispatch((0, EditorSlice_1.updateProjectCommits)({
374015
+ commitId: projectData.commitId,
374016
+ commits,
374017
+ }));
374018
+ }
373921
374019
  // remove old cached project on the first save
373922
374020
  if (isFirstSave &&
373923
- projectData.identifier &&
374021
+ projectData?.identifier &&
373924
374022
  project.identifier !== projectData.identifier) {
373925
374023
  dispatch((0, EditorSlice_1.updateProjectIdentifier)(projectData.identifier));
373926
374024
  deleteValueFromCache(project.identifier);
@@ -373935,16 +374033,16 @@ const useProjectPersistence = ({ user, projectData, hasShownSavePrompt, saveProj
373935
374033
  ...project,
373936
374034
  hasStructureChanges: false,
373937
374035
  components: cleanedComponents,
373938
- identifier: projectData.identifier,
373939
- commitId: projectData.commitId,
374036
+ identifier: incomingIdentifier,
374037
+ commitId: incomingCommitId ?? project.commitId,
373940
374038
  commits,
373941
374039
  };
373942
- const newLastSavedSnapshot = (0, buildProjectSnapshot_1.buildProjectSnapshot)(cleanedProject);
374040
+ const newLastSavedSnapshot = (0, projectSnapshotHelpers_1.buildProjectSnapshot)(cleanedProject);
373943
374041
  const updatedProjectSnapshot = {
373944
374042
  components: cleanedComponents,
373945
374043
  hasStructureChanges: false,
373946
374044
  lastSavedSnapshot: newLastSavedSnapshot,
373947
- identifier: projectData.identifier,
374045
+ identifier: incomingIdentifier,
373948
374046
  };
373949
374047
  dispatch((0, EditorSlice_1.updateProjectSnapshot)(updatedProjectSnapshot));
373950
374048
  upsertCacheValue(cleanedProject.identifier, {
@@ -374045,9 +374143,14 @@ const useProjectRemix = ({ projectData, saveProject, }) => {
374045
374143
  const remixName = `Remix of ${project.name}`;
374046
374144
  const { zipBlob } = await (0, createProjectArchive_1.createProjectArchive)(project);
374047
374145
  await saveProject?.({
374048
- ...project,
374049
- name: remixName,
374050
- }, zipBlob);
374146
+ project: {
374147
+ ...project,
374148
+ name: remixName,
374149
+ },
374150
+ commitBlob: zipBlob,
374151
+ hasContentChanges: true,
374152
+ hasNameChanges: false,
374153
+ });
374051
374154
  }
374052
374155
  catch (e) {
374053
374156
  console.error(e);
@@ -374142,6 +374245,7 @@ const react_1 = __webpack_require__(51649);
374142
374245
  const react_redux_1 = __webpack_require__(14062);
374143
374246
  const EditorSlice_1 = __webpack_require__(68512);
374144
374247
  const types_1 = __webpack_require__(92932);
374248
+ const projectSnapshotHelpers_1 = __webpack_require__(22390);
374145
374249
  // check if incoming and cached projects are the same draft
374146
374250
  const isSameDraftProjectType = (incomingProject, cachedProject) => {
374147
374251
  if (!incomingProject || !cachedProject)
@@ -374151,12 +374255,34 @@ const isSameDraftProjectType = (incomingProject, cachedProject) => {
374151
374255
  cachedProject.project_type === incomingProject.project_type &&
374152
374256
  cachedProject.extension === incomingProject.extension);
374153
374257
  };
374258
+ const buildTemplateSnapshotFromIncomingProject = (cachedProject, incomingProject) => {
374259
+ if (!incomingProject?.components?.length)
374260
+ return null;
374261
+ return (0, projectSnapshotHelpers_1.buildProjectSnapshot)({
374262
+ ...cachedProject,
374263
+ ...incomingProject,
374264
+ components: incomingProject.components,
374265
+ commitId: null,
374266
+ });
374267
+ };
374268
+ const hasCachedDraftChanges = (cachedProject, incomingProject) => {
374269
+ if (!cachedProject)
374270
+ return false;
374271
+ const cachedSnapshot = (0, projectSnapshotHelpers_1.buildProjectSnapshot)(cachedProject);
374272
+ const baselineSnapshot = cachedProject.lastSavedSnapshot ??
374273
+ buildTemplateSnapshotFromIncomingProject(cachedProject, incomingProject);
374274
+ if (!baselineSnapshot) {
374275
+ return true;
374276
+ }
374277
+ return !(0, projectSnapshotHelpers_1.areProjectSnapshotsEqual)(cachedSnapshot, baselineSnapshot);
374278
+ };
374154
374279
  // handles unsaved draft logic and modal decision
374155
374280
  const useUnsavedDraftResolution = ({ projectData, cachedProject, isCurrentOutdated, }) => {
374156
374281
  const dispatch = (0, react_redux_1.useDispatch)();
374157
374282
  // flag to ignore cached draft after Start New
374158
374283
  const [shouldBypassCachedDraft, setShouldBypassCachedDraft] = (0, react_1.useState)(false);
374159
374284
  const isSameDraftType = (0, react_1.useMemo)(() => isSameDraftProjectType(projectData, cachedProject), [projectData, cachedProject]);
374285
+ const hasDraftChanges = (0, react_1.useMemo)(() => hasCachedDraftChanges(cachedProject, projectData), [cachedProject, projectData]);
374160
374286
  (0, react_1.useEffect)(() => {
374161
374287
  if (projectData?.commitId && shouldBypassCachedDraft) {
374162
374288
  setShouldBypassCachedDraft(false);
@@ -374166,7 +374292,8 @@ const useUnsavedDraftResolution = ({ projectData, cachedProject, isCurrentOutdat
374166
374292
  const shouldShowUnsavedDraftModal = !!cachedProject &&
374167
374293
  !isCurrentOutdated &&
374168
374294
  !shouldBypassCachedDraft &&
374169
- isSameDraftType;
374295
+ isSameDraftType &&
374296
+ hasDraftChanges;
374170
374297
  const openUnsavedDraftModal = (0, react_1.useCallback)(() => {
374171
374298
  dispatch((0, EditorSlice_1.showModal)({
374172
374299
  modal: types_1.ModalType.DRAFT_UNSAVED_CHANGES,
@@ -374194,8 +374321,8 @@ exports.useUnsavedDraftResolution = useUnsavedDraftResolution;
374194
374321
 
374195
374322
  var _a;
374196
374323
  Object.defineProperty(exports, "__esModule", ({ value: true }));
374197
- exports.revertProject = exports.setRemixTriggered = exports.setIsLoadingCommit = exports.setCommitIdLoadTriggered = exports.setShareLinks = exports.setCommits = exports.setSharedStatus = exports.setCodeVisibility = exports.applyComponentsPatch = exports.setSaving = exports.disableTheming = exports.hideSidebar = exports.showSidebar = exports.closeModal = exports.showModal = exports.closeErrorModal = exports.showErrorModal = exports.updateProjectName = exports.setSaveTriggered = exports.triggerDraw = exports.triggerCodeRun = exports.stopDraw = exports.stopCodeRun = exports.setLoading = exports.setReadOnly = exports.updateProjectIdentifier = exports.updateProjectCommits = exports.updateProjectSnapshot = exports.setProject = exports.setHasShownSavePrompt = exports.setError = exports.setCascadeUpdate = exports.setIsOutputOnly = exports.setAutorunEnabled = exports.setPage = exports.setFocussedFileIndex = exports.addFilePanel = exports.setOpenedFiles = exports.openFile = exports.closeFile = exports.expireJustLoaded = exports.codeRunHandled = exports.resetRunner = exports.setLoadedRunner = exports.loadingRunner = exports.updateProjectComponent = exports.addProjectComponent = exports.resetState = exports.EditorSlice = exports.editorInitialState = void 0;
374198
- exports.queueBinaryWrites = void 0;
374324
+ exports.setRemixTriggered = exports.setIsLoadingCommit = exports.setCommitIdLoadTriggered = exports.setShareLinks = exports.setCommits = exports.setSharedStatus = exports.setCodeVisibility = exports.applyComponentsPatch = exports.setSaving = exports.disableTheming = exports.hideSidebar = exports.showSidebar = exports.closeModal = exports.showModal = exports.closeErrorModal = exports.showErrorModal = exports.updateProjectName = exports.setProjectNameDraft = exports.setSaveTriggered = exports.triggerDraw = exports.triggerCodeRun = exports.stopDraw = exports.stopCodeRun = exports.setLoading = exports.setReadOnly = exports.updateProjectIdentifier = exports.updateProjectCommits = exports.updateProjectSnapshot = exports.setProject = exports.setHasShownSavePrompt = exports.setError = exports.setCascadeUpdate = exports.setIsOutputOnly = exports.setAutorunEnabled = exports.setPage = exports.setFocussedFileIndex = exports.addFilePanel = exports.setOpenedFiles = exports.openFile = exports.closeFile = exports.expireJustLoaded = exports.codeRunHandled = exports.resetRunner = exports.setLoadedRunner = exports.loadingRunner = exports.updateProjectComponent = exports.addProjectComponent = exports.resetState = exports.EditorSlice = exports.editorInitialState = void 0;
374325
+ exports.queueBinaryWrites = exports.revertProject = void 0;
374199
374326
  const toolkit_1 = __webpack_require__(12069);
374200
374327
  const ProjectTypes_1 = __webpack_require__(27130);
374201
374328
  const types_1 = __webpack_require__(92932);
@@ -374243,6 +374370,7 @@ exports.editorInitialState = {
374243
374370
  isSharedProject: false,
374244
374371
  shareLinks: null,
374245
374372
  remixTriggered: false,
374373
+ projectNameDraft: null,
374246
374374
  };
374247
374375
  exports.EditorSlice = (0, toolkit_1.createSlice)({
374248
374376
  name: "editor",
@@ -374349,6 +374477,7 @@ exports.EditorSlice = (0, toolkit_1.createSlice)({
374349
374477
  },
374350
374478
  setProject: (state, action) => {
374351
374479
  state.project = action.payload;
374480
+ state.projectNameDraft = null;
374352
374481
  state.loading = types_1.LoadingState.SUCCESS;
374353
374482
  state.openedFiles = [[]];
374354
374483
  state.focussedFileIndices = [0];
@@ -374397,8 +374526,12 @@ exports.EditorSlice = (0, toolkit_1.createSlice)({
374397
374526
  setSaving: (state, action) => {
374398
374527
  state.saving = action.payload;
374399
374528
  },
374529
+ setProjectNameDraft: (state, action) => {
374530
+ state.projectNameDraft = action.payload;
374531
+ },
374400
374532
  updateProjectName: (state, action) => {
374401
374533
  state.project.name = action.payload;
374534
+ state.projectNameDraft = null;
374402
374535
  state.saving = types_1.SavingState.IDLE;
374403
374536
  },
374404
374537
  updateProjectComponent: (state, action) => {
@@ -374439,6 +374572,7 @@ exports.EditorSlice = (0, toolkit_1.createSlice)({
374439
374572
  state.project.components = action.payload.components;
374440
374573
  state.project.hasStructureChanges = action.payload.hasStructureChanges;
374441
374574
  state.project.lastSavedSnapshot = action.payload.lastSavedSnapshot;
374575
+ state.projectNameDraft = null;
374442
374576
  if (action.payload.identifier) {
374443
374577
  state.project.identifier = action.payload.identifier;
374444
374578
  }
@@ -374522,7 +374656,7 @@ exports.EditorSlice = (0, toolkit_1.createSlice)({
374522
374656
  },
374523
374657
  });
374524
374658
  // Action creators are generated for each case reducer function
374525
- _a = exports.EditorSlice.actions, exports.resetState = _a.resetState, exports.addProjectComponent = _a.addProjectComponent, exports.updateProjectComponent = _a.updateProjectComponent, exports.loadingRunner = _a.loadingRunner, exports.setLoadedRunner = _a.setLoadedRunner, exports.resetRunner = _a.resetRunner, exports.codeRunHandled = _a.codeRunHandled, exports.expireJustLoaded = _a.expireJustLoaded, exports.closeFile = _a.closeFile, exports.openFile = _a.openFile, exports.setOpenedFiles = _a.setOpenedFiles, exports.addFilePanel = _a.addFilePanel, exports.setFocussedFileIndex = _a.setFocussedFileIndex, exports.setPage = _a.setPage, exports.setAutorunEnabled = _a.setAutorunEnabled, exports.setIsOutputOnly = _a.setIsOutputOnly, exports.setCascadeUpdate = _a.setCascadeUpdate, exports.setError = _a.setError, exports.setHasShownSavePrompt = _a.setHasShownSavePrompt, exports.setProject = _a.setProject, exports.updateProjectSnapshot = _a.updateProjectSnapshot, exports.updateProjectCommits = _a.updateProjectCommits, exports.updateProjectIdentifier = _a.updateProjectIdentifier, exports.setReadOnly = _a.setReadOnly, exports.setLoading = _a.setLoading, exports.stopCodeRun = _a.stopCodeRun, exports.stopDraw = _a.stopDraw, exports.triggerCodeRun = _a.triggerCodeRun, exports.triggerDraw = _a.triggerDraw, exports.setSaveTriggered = _a.setSaveTriggered, exports.updateProjectName = _a.updateProjectName, exports.showErrorModal = _a.showErrorModal, exports.closeErrorModal = _a.closeErrorModal, exports.showModal = _a.showModal, exports.closeModal = _a.closeModal, exports.showSidebar = _a.showSidebar, exports.hideSidebar = _a.hideSidebar, exports.disableTheming = _a.disableTheming, exports.setSaving = _a.setSaving, exports.applyComponentsPatch = _a.applyComponentsPatch, exports.setCodeVisibility = _a.setCodeVisibility, exports.setSharedStatus = _a.setSharedStatus, exports.setCommits = _a.setCommits, exports.setShareLinks = _a.setShareLinks, exports.setCommitIdLoadTriggered = _a.setCommitIdLoadTriggered, exports.setIsLoadingCommit = _a.setIsLoadingCommit, exports.setRemixTriggered = _a.setRemixTriggered, exports.revertProject = _a.revertProject;
374659
+ _a = exports.EditorSlice.actions, exports.resetState = _a.resetState, exports.addProjectComponent = _a.addProjectComponent, exports.updateProjectComponent = _a.updateProjectComponent, exports.loadingRunner = _a.loadingRunner, exports.setLoadedRunner = _a.setLoadedRunner, exports.resetRunner = _a.resetRunner, exports.codeRunHandled = _a.codeRunHandled, exports.expireJustLoaded = _a.expireJustLoaded, exports.closeFile = _a.closeFile, exports.openFile = _a.openFile, exports.setOpenedFiles = _a.setOpenedFiles, exports.addFilePanel = _a.addFilePanel, exports.setFocussedFileIndex = _a.setFocussedFileIndex, exports.setPage = _a.setPage, exports.setAutorunEnabled = _a.setAutorunEnabled, exports.setIsOutputOnly = _a.setIsOutputOnly, exports.setCascadeUpdate = _a.setCascadeUpdate, exports.setError = _a.setError, exports.setHasShownSavePrompt = _a.setHasShownSavePrompt, exports.setProject = _a.setProject, exports.updateProjectSnapshot = _a.updateProjectSnapshot, exports.updateProjectCommits = _a.updateProjectCommits, exports.updateProjectIdentifier = _a.updateProjectIdentifier, exports.setReadOnly = _a.setReadOnly, exports.setLoading = _a.setLoading, exports.stopCodeRun = _a.stopCodeRun, exports.stopDraw = _a.stopDraw, exports.triggerCodeRun = _a.triggerCodeRun, exports.triggerDraw = _a.triggerDraw, exports.setSaveTriggered = _a.setSaveTriggered, exports.setProjectNameDraft = _a.setProjectNameDraft, exports.updateProjectName = _a.updateProjectName, exports.showErrorModal = _a.showErrorModal, exports.closeErrorModal = _a.closeErrorModal, exports.showModal = _a.showModal, exports.closeModal = _a.closeModal, exports.showSidebar = _a.showSidebar, exports.hideSidebar = _a.hideSidebar, exports.disableTheming = _a.disableTheming, exports.setSaving = _a.setSaving, exports.applyComponentsPatch = _a.applyComponentsPatch, exports.setCodeVisibility = _a.setCodeVisibility, exports.setSharedStatus = _a.setSharedStatus, exports.setCommits = _a.setCommits, exports.setShareLinks = _a.setShareLinks, exports.setCommitIdLoadTriggered = _a.setCommitIdLoadTriggered, exports.setIsLoadingCommit = _a.setIsLoadingCommit, exports.setRemixTriggered = _a.setRemixTriggered, exports.revertProject = _a.revertProject;
374526
374660
  exports.queueBinaryWrites = (0, toolkit_1.createAction)("editor/queueBinaryWrites");
374527
374661
  exports["default"] = exports.EditorSlice.reducer;
374528
374662
 
@@ -374867,20 +375001,28 @@ exports.startAppListening = exports.listenerMiddleware.startListening;
374867
375001
 
374868
375002
 
374869
375003
  Object.defineProperty(exports, "__esModule", ({ value: true }));
374870
- exports.selectProjectDirtyState = void 0;
375004
+ exports.selectProjectDirtyState = exports.selectProjectHasNameChanges = exports.selectProjectHasContentChanges = void 0;
374871
375005
  const toolkit_1 = __webpack_require__(12069);
374872
- exports.selectProjectDirtyState = (0, toolkit_1.createSelector)([
375006
+ exports.selectProjectHasContentChanges = (0, toolkit_1.createSelector)([
374873
375007
  (state) => state.editor.project?.hasStructureChanges,
374874
- (state) => state.editor.project?.name,
374875
- (state) => state.editor.project?.lastSavedSnapshot?.name,
374876
375008
  (state) => state.editor.project?.components,
374877
375009
  (state) => state.editor.commits,
374878
- ], (hasStructureChanges, projectName, snapshotName, components, commits) => {
375010
+ ], (hasStructureChanges, components, commits) => {
374879
375011
  return (Boolean(hasStructureChanges) ||
374880
- (Boolean(snapshotName) && projectName !== snapshotName) ||
374881
- (components?.some((c) => c.isDirty) ?? false) ||
375012
+ (components?.some((component) => component.isDirty) ?? false) ||
374882
375013
  commits.length === 0);
374883
375014
  });
375015
+ exports.selectProjectHasNameChanges = (0, toolkit_1.createSelector)([
375016
+ (state) => state.editor.project?.name,
375017
+ (state) => state.editor.project?.lastSavedSnapshot?.name,
375018
+ (state) => state.editor.projectNameDraft,
375019
+ ], (projectName, snapshotName, projectNameDraft) => {
375020
+ const effectiveProjectName = projectNameDraft || projectName;
375021
+ return Boolean(snapshotName) && effectiveProjectName !== snapshotName;
375022
+ });
375023
+ exports.selectProjectDirtyState = (0, toolkit_1.createSelector)([exports.selectProjectHasContentChanges, exports.selectProjectHasNameChanges], (hasContentChanges, hasNameChanges) => {
375024
+ return hasContentChanges || hasNameChanges;
375025
+ });
374884
375026
 
374885
375027
 
374886
375028
  /***/ }),
@@ -375389,32 +375531,6 @@ class BinaryStore {
375389
375531
  exports.binaryStore = new BinaryStore();
375390
375532
 
375391
375533
 
375392
- /***/ }),
375393
-
375394
- /***/ 10533:
375395
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
375396
-
375397
-
375398
- Object.defineProperty(exports, "__esModule", ({ value: true }));
375399
- exports.buildProjectSnapshot = void 0;
375400
- const ProjectTypes_1 = __webpack_require__(27130);
375401
- const signatureHelpers_1 = __webpack_require__(41835);
375402
- const buildProjectSnapshot = (project) => {
375403
- return {
375404
- name: project.name,
375405
- identifier: project.identifier,
375406
- components: Object.fromEntries(project.components.map((c) => [
375407
- c.path,
375408
- c.type === ProjectTypes_1.ProjectComponentType.FILE
375409
- ? c.content
375410
- : undefined,
375411
- ])),
375412
- structureSignature: (0, signatureHelpers_1.buildSignature)(project.components),
375413
- };
375414
- };
375415
- exports.buildProjectSnapshot = buildProjectSnapshot;
375416
-
375417
-
375418
375534
  /***/ }),
375419
375535
 
375420
375536
  /***/ 56469:
@@ -375983,6 +376099,49 @@ const getAuthorName = (author) => {
375983
376099
  exports.getAuthorName = getAuthorName;
375984
376100
 
375985
376101
 
376102
+ /***/ }),
376103
+
376104
+ /***/ 22390:
376105
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
376106
+
376107
+
376108
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
376109
+ exports.areProjectSnapshotsEqual = exports.buildProjectSnapshot = void 0;
376110
+ const ProjectTypes_1 = __webpack_require__(27130);
376111
+ const signatureHelpers_1 = __webpack_require__(41835);
376112
+ const buildProjectSnapshot = (project) => {
376113
+ return {
376114
+ name: project.name,
376115
+ identifier: project.identifier,
376116
+ components: Object.fromEntries(project.components.map((c) => [
376117
+ c.path,
376118
+ c.type === ProjectTypes_1.ProjectComponentType.FILE
376119
+ ? c.content
376120
+ : undefined,
376121
+ ])),
376122
+ structureSignature: (0, signatureHelpers_1.buildSignature)(project.components),
376123
+ };
376124
+ };
376125
+ exports.buildProjectSnapshot = buildProjectSnapshot;
376126
+ const areProjectSnapshotsEqual = (first, second) => {
376127
+ if (!first || !second)
376128
+ return false;
376129
+ if (first.name !== second.name)
376130
+ return false;
376131
+ if ((0, signatureHelpers_1.isSignatureDifferent)(first.structureSignature, second.structureSignature)) {
376132
+ return false;
376133
+ }
376134
+ const firstComponentPaths = Object.keys(first.components);
376135
+ const secondComponentPaths = Object.keys(second.components);
376136
+ if (firstComponentPaths.length !== secondComponentPaths.length) {
376137
+ return false;
376138
+ }
376139
+ return firstComponentPaths.every((path) => Object.prototype.hasOwnProperty.call(second.components, path) &&
376140
+ first.components[path] === second.components[path]);
376141
+ };
376142
+ exports.areProjectSnapshotsEqual = areProjectSnapshotsEqual;
376143
+
376144
+
375986
376145
  /***/ }),
375987
376146
 
375988
376147
  /***/ 48235:
package/dist/style.css CHANGED
@@ -682,7 +682,7 @@
682
682
  :root{--rpf-white: #ffffff}.styles-module__tooltip--7XFyr{position:absolute;background-color:#242424;color:#e5e5e5;padding:calc(.25rem*var(--scale-factor, 1)) calc(.5rem*var(--scale-factor, 1));border-radius:calc(.25rem*var(--scale-factor, 1));font-size:calc(.75rem*var(--scale-factor, 1));line-height:calc(1rem*var(--scale-factor, 1));min-inline-size:calc(10.25rem*var(--scale-factor, 1));z-index:650;pointer-events:none;white-space:pre-wrap;opacity:0;visibility:hidden;transition:opacity .2s ease,transform .2s ease}.styles-module__tooltip--7XFyr.styles-module__visible--wGPCM{opacity:1;visibility:visible}.styles-module__position-bottom--Lwi\+l{inset-block-start:100%;inset-inline-end:0;margin-block-start:calc(.25rem*var(--scale-factor, 1))}.styles-module__position-fixed--t8yrP{position:fixed;margin-top:calc(.625rem*var(--scale-factor, 1));margin-right:calc(2rem*var(--scale-factor, 1))}
683
683
  :root{--rpf-white: #ffffff}.styles-module__btn--0Px6W{align-items:center;border-radius:calc(.75rem*var(--scale-factor, 1));border:0;box-sizing:border-box;padding:calc(.75rem*var(--scale-factor, 1)) calc(1.25rem*var(--scale-factor, 1));color:#003046;cursor:pointer;display:inline-flex;font-family:var(--wc-font-family-sans-serif);font-size:inherit;font-weight:500;gap:calc(.5rem*var(--scale-factor, 1));justify-content:center;position:relative;text-align:center;text-decoration:none;transition:all .2s ease}.styles-module__btn--0Px6W:disabled{background-color:#4a4d59;color:#69746d;cursor:default}.styles-module__btn--0Px6W:focus-visible{border:3px solid #cd2356;outline:none}.styles-module__btn--primary--k7oQ0{background-color:var(--rpf-button-primary-background-color);border-radius:calc(.5rem*var(--scale-factor, 1));color:var(--rpf-button-primary-text-color)}.styles-module__btn--primary--k7oQ0 svg{fill:var(--rpf-button-primary-text-color)}.styles-module__btn--primary--k7oQ0:active,.styles-module__btn-outer--4KgkG:active .styles-module__btn--primary--k7oQ0{background-color:var(--rpf-button-primary-background-color-active)}.styles-module__btn--primary--k7oQ0:focus-visible,.styles-module__btn-outer--4KgkG:focus-visible .styles-module__btn--primary--k7oQ0{background-color:var(--rpf-button-primary-background-color-focus)}.styles-module__btn--primary--k7oQ0:hover,.styles-module__btn-outer--4KgkG:hover .styles-module__btn--primary--k7oQ0{background-color:var(--rpf-button-primary-background-color-hover);border-radius:calc(.5rem*var(--scale-factor, 1))}.styles-module__btn--primary--k7oQ0:disabled{background-color:var(--rpf-button-primary-background-color-disabled);color:var(--rpf-button-primary-color-disabled)}.styles-module__btn--primary--k7oQ0:disabled svg{fill:var(--rpf-button-primary-color-disabled)}.styles-module__btn--primary--k7oQ0:disabled:hover,.styles-module__btn-outer--4KgkG:hover .styles-module__btn--primary--k7oQ0:disabled{background-color:var(--rpf-button-primary-background-color-disabled)}.styles-module__btn--secondary--tK09f{background-color:inherit;color:var(--rpf-button-secondary-text-color);border:2px solid var(--rpf-button-primary-background-color)}.styles-module__btn--secondary--tK09f svg{fill:var(--rpf-button-secondary-text-color)}.styles-module__btn--secondary--tK09f:active,.styles-module__btn-outer--4KgkG:active .styles-module__btn--secondary--tK09f{background-color:inherit}.styles-module__btn--secondary--tK09f:focus-visible,.styles-module__btn-outer--4KgkG:focus-visible .styles-module__btn--secondary--tK09f{background-color:inherit}.styles-module__btn--secondary--tK09f:hover,.styles-module__btn-outer--4KgkG:hover .styles-module__btn--secondary--tK09f{background-color:inherit}.styles-module__btn--secondary--tK09f:disabled{background-color:var(--rpf-button-secondary-background-color-disabled);color:var(--rpf-button-secondary-background-color-active)}.styles-module__btn--secondary--tK09f:disabled svg{fill:var(--rpf-button-secondary-background-color-active)}.styles-module__btn--secondary--tK09f:disabled:hover,.styles-module__btn-outer--4KgkG:hover .styles-module__btn--secondary--tK09f:disabled{background-color:var(--rpf-button-secondary-background-color-disabled)}.styles-module__btn--secondary--tK09f:active{border:2px solid var(--rpf-button-secondary-background-color-active)}.styles-module__btn--secondary--tK09f:hover{background-color:var(--rpf-button-secondary-background-color-hover);color:var(--rpf-button-secondary-text-color-hover);border-color:var(--rpf-button-secondary-border-color-hover) !important}.styles-module__btn--secondary--tK09f:hover svg{fill:var(--rpf-button-secondary-text-color-hover)}.styles-module__btn--secondary--tK09f:focus-visible{outline:3px solid var(--rpf-button-secondary-background-color-focus)}.styles-module__btn--tertiary--jf5po{background-color:inherit;color:inherit}.styles-module__btn--tertiary--jf5po:active,.styles-module__btn-outer--4KgkG:active .styles-module__btn--tertiary--jf5po{background-color:inherit}.styles-module__btn--tertiary--jf5po:focus-visible,.styles-module__btn-outer--4KgkG:focus-visible .styles-module__btn--tertiary--jf5po{background-color:inherit}.styles-module__btn--tertiary--jf5po:hover,.styles-module__btn-outer--4KgkG:hover .styles-module__btn--tertiary--jf5po{background-color:inherit}.styles-module__btn--tertiary--jf5po:disabled{background-color:inherit;color:#4a4d59}.styles-module__btn--tertiary--jf5po:disabled svg{fill:#4a4d59}.styles-module__btn--tertiary--jf5po:disabled:hover,.styles-module__btn-outer--4KgkG:hover .styles-module__btn--tertiary--jf5po:disabled{background-color:inherit}.styles-module__btn--tertiary--jf5po:active{color:#0e857a}.styles-module__btn--tertiary--jf5po:active svg{fill:#0e857a}.styles-module__btn--tertiary--jf5po:hover{color:var(--rpf-button-tertiary-text-color-hover)}.styles-module__btn--tertiary--jf5po:hover svg{fill:var(--rpf-button-tertiary-text-color-hover)}.styles-module__btn--tertiaryGray--gFHKt{background-color:inherit;color:inherit}.styles-module__btn--tertiaryGray--gFHKt:active,.styles-module__btn-outer--4KgkG:active .styles-module__btn--tertiaryGray--gFHKt{background-color:inherit}.styles-module__btn--tertiaryGray--gFHKt:focus-visible,.styles-module__btn-outer--4KgkG:focus-visible .styles-module__btn--tertiaryGray--gFHKt{background-color:inherit}.styles-module__btn--tertiaryGray--gFHKt:hover,.styles-module__btn-outer--4KgkG:hover .styles-module__btn--tertiaryGray--gFHKt{background-color:inherit}.styles-module__btn--tertiaryGray--gFHKt:disabled{background-color:inherit;color:#4a4d59}.styles-module__btn--tertiaryGray--gFHKt:disabled svg{fill:#4a4d59}.styles-module__btn--tertiaryGray--gFHKt:disabled:hover,.styles-module__btn-outer--4KgkG:hover .styles-module__btn--tertiaryGray--gFHKt:disabled{background-color:inherit}.styles-module__btn--tertiaryGray--gFHKt:active{color:#43d6b9}.styles-module__btn--tertiaryGray--gFHKt:active svg{fill:#43d6b9}.styles-module__btn--tertiaryGray--gFHKt:hover{color:var(#4a4d59)}.styles-module__btn--tertiaryGray--gFHKt:hover svg{fill:var(#4a4d59)}.styles-module__btn--danger--SmsoX{background-color:#9e0a0a;color:#fff}.styles-module__btn--danger--SmsoX svg{fill:#fff}.styles-module__btn--danger--SmsoX:active,.styles-module__btn-outer--4KgkG:active .styles-module__btn--danger--SmsoX{background-color:#9e0a0a}.styles-module__btn--danger--SmsoX:focus-visible,.styles-module__btn-outer--4KgkG:focus-visible .styles-module__btn--danger--SmsoX{background-color:#9e0a0a}.styles-module__btn--danger--SmsoX:hover,.styles-module__btn-outer--4KgkG:hover .styles-module__btn--danger--SmsoX{background-color:#86151e}.styles-module__btn--danger--SmsoX:disabled{background-color:#9e0a0a;color:#fff}.styles-module__btn--danger--SmsoX:disabled svg{fill:#fff}.styles-module__btn--danger--SmsoX:disabled:hover,.styles-module__btn-outer--4KgkG:hover .styles-module__btn--danger--SmsoX:disabled{background-color:#9e0a0a}.styles-module__btn--danger--SmsoX:focus-visible{background-clip:padding-box;border:2px solid rgba(0,0,0,0);outline:3px solid #cd2356}.styles-module__btn--small--cJ2bM{min-block-size:unset;min-inline-size:unset;padding:calc(.25rem*var(--scale-factor, 1))}.styles-module__btnOuter--ip64U{background:rgba(0,0,0,0);border-radius:calc(.5rem*var(--scale-factor, 1));cursor:pointer;padding:calc(.5rem*var(--scale-factor, 1)) 0;display:flex;align-items:center;justify-content:center}.styles-module__btnOuter--ip64U:focus-visible{outline:none}.styles-module__btnOuter--ip64U:focus-visible .styles-module__btn--0Px6W{border:3px solid #cd2356}.styles-module__btnOuter--ip64U:has(.styles-module__btn--0Px6W:disabled){cursor:default}.styles-module__svgOnly--eXeyf{background-color:#43d6b9}.styles-module__svgOnly--eXeyf svg{margin:0}.styles-module__primary--AeI1M{background:#fde246}.styles-module__primary--AeI1M:hover{background:#edce22}.styles-module__primary--AeI1M:active{background:#fff;border:1px solid #003046}.styles-module__primary--AeI1M:disabled{background:#fffbe3;color:#69746d}.styles-module__secondary--tAMJR{background:linear-gradient(139deg, rgba(185, 230, 238, 0.8) 9.38%, rgba(113, 235, 188, 0.8) 45.1%, rgba(113, 235, 188, 0.8) 59.39%, rgba(185, 230, 238, 0.8) 88.77%),#fff;border:none}.styles-module__secondary--tAMJR:hover{background:linear-gradient(0deg, hsla(0, 0%, 34%, 0.15), hsla(0, 0%, 34%, 0.15)),linear-gradient(320deg, #B9E6EE 17.77%, #71EBBC 47.58%, #71EBBC 59.5%, #B9E6EE 84%)}.styles-module__secondary--tAMJR:active{background:#fff;border:1px solid #003046}.styles-module__secondary--tAMJR:disabled{background:linear-gradient(135deg, #B9E6EE, #71EBBC, #71EBBC, #B9E6EE),linear-gradient(139deg, #B9E6EE 9.38%, #71EBBC 45.1%, #71EBBC 59.39%, #B9E6EE 88.77%),#fff}.styles-module__tertiary--Kr5w9{background:#43d6b9;color:#003046}.styles-module__tertiary--Kr5w9:hover{background:#cbcbcb}.styles-module__tertiary--Kr5w9:active{background:#fff}.styles-module__tertiary--Kr5w9:disabled{background:#e5e5e5;color:#69746d}.styles-module__tertiaryGray--gVUq6{background:#e5e5e5;color:#33625e}.styles-module__tertiaryGray--gVUq6:hover{background:#cbcbcb}.styles-module__tertiaryGray--gVUq6:disabled{background:#d5d7dc;color:#69746d}.styles-module__iconed--AMs-c{padding-top:10px;padding-bottom:10px}.styles-module__icon--C2jj1{padding:0px}
684
684
  :root{--rpf-white: #ffffff}.styles-module__spinnerDotted--tTFFI{position:relative;inline-size:1.125rem;block-size:1.125rem}.styles-module__spinnerDotted--tTFFI span{position:absolute;inset-block-start:40%;inset-inline-start:25%;inline-size:.225rem;block-size:.225rem;background-color:#69746d;border-radius:50%;transform-origin:center;transform:rotate(var(--angle)) translateY(-0.5625rem);opacity:.2;animation:styles-module__fade--jNeB5 1s linear infinite;--angle: calc(var(--itemIndex) * 45deg);animation-delay:calc(var(--itemIndex)*.125s)}@keyframes styles-module__fade--jNeB5{0%{opacity:1}100%{opacity:.2}}
685
- :root{--rpf-white: #ffffff}.styles-module__content--Cgvxl{display:flex;gap:calc(.5rem*var(--scale-factor, 1))}.styles-module__icon--y9Z7a{color:#003046}
685
+ :root{--rpf-white: #ffffff}.styles-module__wrapper--U1NAt{display:inline-flex;position:relative}.styles-module__content--Cgvxl{display:flex;gap:calc(.5rem*var(--scale-factor, 1))}.styles-module__icon--y9Z7a{color:#003046}
686
686
  .styles-module__shareButtonWrapper--wEN8e{position:relative}
687
687
  :root{--rpf-white: #ffffff}.styles-module__historyActive--aOVxD{background-color:#fff}.styles-module__historyButton--LInbn{color:#003046}.styles-module__commitHoverElement--foGWE{color:#33625e;display:flex;align-items:center;gap:calc(.25rem*var(--scale-factor, 1))}.styles-module__btnContainer--OlkJ2{position:relative}
688
688
  :root{--rpf-white: #ffffff}.styles-module__contextMenu--HNX6Z{list-style-type:none;padding:0;margin-inline:calc(.5rem*var(--scale-factor, 1)) 0;margin-block:0;border-radius:calc(.25rem*var(--scale-factor, 1));display:flex;flex-direction:column;background-color:#fff;border:1px solid #e5e5e5;box-shadow:0 calc(.25rem*var(--scale-factor, 1)) calc(.5rem*var(--scale-factor, 1)) 0 rgba(0,0,0,.25);overflow:auto;z-index:700}.styles-module__contextMenu--HNX6Z .styles-module__hoverElement--GLCJ0{visibility:hidden;margin-left:calc(1rem*var(--scale-factor, 1))}.styles-module__contextMenu--HNX6Z .styles-module__contextItem--9nzMH{display:flex;justify-content:space-between;font-size:calc(.875rem*var(--scale-factor, 1));line-height:calc(1.25rem*var(--scale-factor, 1));color:#69746d;padding:calc(1rem*var(--scale-factor, 1));white-space:nowrap;inline-size:100%;gap:calc(.5rem*var(--scale-factor, 1));transition:all .2s ease}.styles-module__contextMenu--HNX6Z .styles-module__contextItem--9nzMH .styles-module__optionContent--3E8Zt{display:flex;align-items:center;gap:calc(.5rem*var(--scale-factor, 1));justify-items:start}.styles-module__contextMenu--HNX6Z .styles-module__contextItem--9nzMH:hover{background-color:#e5f6f1;cursor:pointer;color:#003046}.styles-module__contextMenu--HNX6Z .styles-module__contextItem--9nzMH:hover .styles-module__hoverElement--GLCJ0{visibility:visible}.styles-module__contextMenu--HNX6Z .styles-module__contextItemActive--KkppO{background-color:#c5ffe8;color:#003046}.styles-module__contextMenu--HNX6Z .styles-module__contextHeader--jA59O{font-size:calc(.625rem*var(--scale-factor, 1));line-height:calc(1rem*var(--scale-factor, 1));font-weight:500;padding:calc(.5rem*var(--scale-factor, 1)) calc(1rem*var(--scale-factor, 1)) calc(.25rem*var(--scale-factor, 1));color:#33625e}.styles-module__contextMenu--HNX6Z svg{inline-size:calc(1.125rem*var(--scale-factor, 1))}.styles-module__contextMenu--HNX6Z .styles-module__withDivider--X54Sw{border-bottom:1px solid #e5e5e5}.styles-module__visibleScrollbar--PEea9::-webkit-scrollbar{width:calc(.25rem*var(--scale-factor, 1));display:block}.styles-module__visibleScrollbar--PEea9::-webkit-scrollbar-thumb{background-color:HSL(0, 0%, 14%, 10%);border-radius:calc(1.125rem*var(--scale-factor, 1))}
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.2.19",
4
+ "version": "0.2.21",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/GirlsFirst/gwchq-textjam",
7
7
  "author": "Girls Who Code HQ",