@hwp-editor/react 1.0.0 → 1.2.0

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 CHANGED
@@ -1,10 +1,23 @@
1
1
  # @hwp-editor/react
2
2
 
3
3
  Embeddable React UI for Korean HWP/HWPX documents, built on
4
- [`@hwp-editor/core`](../core). All document work (read/render/edit/compose/
4
+ [`@hwp-editor/core`](https://www.npmjs.com/package/@hwp-editor/core). All document work (read/render/edit/compose/
5
5
  validate) goes through the `HwpEngine` interface — this package contains UI
6
6
  only.
7
7
 
8
+ ## Install
9
+
10
+ ```sh
11
+ pnpm add @hwp-editor/react
12
+ ```
13
+
14
+ `@hwp-editor/core` arrives as a peer, deduped to a single copy; you do not name
15
+ it unless your own source imports from it. React 18 or 19 is a peer too.
16
+
17
+ The stylesheet is **not** auto-injected. An install that skips the import below
18
+ produces an editor that loads and renders unstyled, which no import check
19
+ notices.
20
+
8
21
  ## Usage
9
22
 
10
23
  ```tsx
@@ -28,7 +41,9 @@ so referring to them by a fixed label goes stale the moment the copy or the
28
41
  locale changes. Protected/distribution documents open read-only with a notice
29
42
  (engine `capabilities().editable === false`).
30
43
 
31
- Keyboard: `Escape` clears the selection; `Cmd/Ctrl+Enter` applies pending ops.
44
+ Keyboard: `Escape` clears the selection, or closes the new-document dialog
45
+ when it is open (without touching the selection); `Cmd/Ctrl+Enter` applies
46
+ pending ops.
32
47
 
33
48
  ## Props
34
49
 
package/dist/index.cjs CHANGED
@@ -1058,6 +1058,17 @@ function ComposePanel(props) {
1058
1058
  const [body, setBody] = (0, import_react6.useState)("");
1059
1059
  const [busy, setBusy] = (0, import_react6.useState)(false);
1060
1060
  const [error, setError] = (0, import_react6.useState)(null);
1061
+ const { onClose } = props;
1062
+ (0, import_react6.useEffect)(() => {
1063
+ const onKeyDown = (event) => {
1064
+ if (event.key !== "Escape" || event.isComposing || event.defaultPrevented) return;
1065
+ if (busy) return;
1066
+ event.preventDefault();
1067
+ onClose();
1068
+ };
1069
+ document.addEventListener("keydown", onKeyDown);
1070
+ return () => document.removeEventListener("keydown", onKeyDown);
1071
+ }, [busy, onClose]);
1061
1072
  const compose = async () => {
1062
1073
  setBusy(true);
1063
1074
  setError(null);
@@ -1410,14 +1421,14 @@ var HwpEditor = (0, import_react7.forwardRef)(
1410
1421
  (0, import_react7.useEffect)(() => {
1411
1422
  cbRef.current = { onReady, onError, onChange, onDirtyChange };
1412
1423
  });
1413
- const emitReady = (0, import_react7.useCallback)((document) => {
1414
- cbRef.current.onReady?.(document);
1424
+ const emitReady = (0, import_react7.useCallback)((document2) => {
1425
+ cbRef.current.onReady?.(document2);
1415
1426
  }, []);
1416
1427
  const emitError = (0, import_react7.useCallback)((error) => {
1417
1428
  cbRef.current.onError?.(error);
1418
1429
  }, []);
1419
- const emitChange = (0, import_react7.useCallback)((document) => {
1420
- cbRef.current.onChange?.(document);
1430
+ const emitChange = (0, import_react7.useCallback)((document2) => {
1431
+ cbRef.current.onChange?.(document2);
1421
1432
  }, []);
1422
1433
  const emitDirty = (0, import_react7.useCallback)((dirty2) => {
1423
1434
  cbRef.current.onDirtyChange?.(dirty2);
@@ -1585,6 +1596,7 @@ var HwpEditor = (0, import_react7.forwardRef)(
1585
1596
  );
1586
1597
  const onKeyDown = (e) => {
1587
1598
  if (e.key === "Escape") {
1599
+ if (composing) return;
1588
1600
  store.dispatch({ type: "select", selection: null });
1589
1601
  } else if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
1590
1602
  e.preventDefault();
@@ -1724,17 +1736,17 @@ var HwpEditor = (0, import_react7.forwardRef)(
1724
1736
  ComposePanel,
1725
1737
  {
1726
1738
  onClose: () => setComposing(false),
1727
- onComposed: (document) => {
1739
+ onComposed: (document2) => {
1728
1740
  setComposing(false);
1729
- emitChange(document);
1741
+ emitChange(document2);
1730
1742
  void (async () => {
1731
1743
  try {
1732
1744
  const [nextEnvelope, pages] = await Promise.all([
1733
- engine.read(document),
1734
- engine.render(document, RENDER_SVG)
1745
+ engine.read(document2),
1746
+ engine.render(document2, RENDER_SVG)
1735
1747
  ]);
1736
1748
  setEnvelope(nextEnvelope);
1737
- store.dispatch({ type: "load", document, pages });
1749
+ store.dispatch({ type: "load", document: document2, pages });
1738
1750
  } catch (e) {
1739
1751
  setLoadError(toEditorError(e));
1740
1752
  emitError(e);