seemore 1.2.0 → 1.3.1

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
@@ -103,7 +103,7 @@ Install **seemore** from the [VS Code Marketplace](https://marketplace.visualstu
103
103
 
104
104
  ## Edit your files from the browser
105
105
 
106
- The preview is not just for reading — it is the fastest way to fix what you are reading. Double-click any paragraph, heading, list item, quote or table cell and it opens in a small editor holding that block's **Markdown source**: `**bold**` stays `**bold**`, links stay links, tables stay tables. Fix the text and hit **Save** and the change is written to the file on disk. Nothing is written until you say so: clicking away leaves the editor open rather than saving behind your back. It works the same in the VS Code panel, which runs the same dev server.
106
+ The preview is not just for reading — it is the fastest way to fix what you are reading. Double-click any paragraph, heading, list item, quote or table cell and it opens in a small editor holding that block's **Markdown source**: `**bold**` stays `**bold**`, links stay links, tables stay tables. Fix the text and hit **Save** and the change is written to the file on disk.
107
107
 
108
108
  Inline editing is for local previews only — `seemore build` output is static, so nothing is emitted there. It is on by default in dev; switch it off with the `!` prefix:
109
109
 
@@ -113,9 +113,6 @@ export default defineConfig({
113
113
  });
114
114
  ```
115
115
 
116
- > [!NOTE]
117
- > The dev server binds to localhost, so only your machine can reach the endpoint that writes. If you serve the site to your network with `--host`, anyone who can open the site can also edit your files — pass `features: ['!content.edit']` when you do that.
118
-
119
116
  ## Publish it to the web
120
117
 
121
118
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "seemore",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "Let AI write the Markdown. Let seemore show it better — zero config documentation framework.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -135,6 +135,32 @@ export function InlineEditor({ entry }: { entry: RouteEntry }) {
135
135
  editingRef.current = editing;
136
136
  }, [editing]);
137
137
 
138
+ // The editor is a floating box over the page, so a press that lands anywhere else is a
139
+ // press away from it. That closes the editor only while nothing has been typed — the same
140
+ // rule the double-click handler uses, so a stray click can never discard an edit; with
141
+ // unsaved text the box stays put and Save or Cancel decides. The error message counts as
142
+ // part of the editor: a click on it is a click to dismiss it.
143
+ useEffect(() => {
144
+ if (editing === undefined) return;
145
+
146
+ const onPointerDown = (event: PointerEvent) => {
147
+ const target = event.target as HTMLElement | null;
148
+ if (target === null || saving) return;
149
+ if (target.closest('.seemore-editor, .seemore-editor-error') !== null) return;
150
+
151
+ const field = textarea.current;
152
+ if (field !== null) {
153
+ const typed = field.value.replace(/\r\n/g, '\n');
154
+ if (typed !== editing.original.replace(/\r\n/g, '\n')) return;
155
+ }
156
+ close();
157
+ };
158
+
159
+ // Captured, so a handler that stops the press on its way up cannot hold the editor open.
160
+ document.addEventListener('pointerdown', onPointerDown, true);
161
+ return () => document.removeEventListener('pointerdown', onPointerDown, true);
162
+ }, [editing, saving, close]);
163
+
138
164
  // The block is hidden rather than removed while it is edited, so the page does not jump.
139
165
  // If this component goes away mid-edit — a navigation, a hot reload — put it back.
140
166
  useEffect(() => () => editing?.element.classList.remove('seemore-editing'), [editing]);
@@ -228,8 +254,9 @@ export function InlineEditor({ entry }: { entry: RouteEntry }) {
228
254
  </span>
229
255
  {/*
230
256
  `onMouseDown` is prevented on both buttons so focus never leaves the textarea.
231
- Taking focus would fire its blur handler, which saves so a click on Cancel
232
- would commit the very edit it is meant to discard.
257
+ Nothing is committed on blur, but the caret and the selection are: a click on
258
+ Save that a stale file refuses leaves the text exactly where it was, still
259
+ typed into and still listening for Escape.
233
260
  */}
234
261
  <button
235
262
  type="button"
@@ -303,6 +303,15 @@
303
303
  box-shadow: 0 0 0 4px var(--color-fd-muted);
304
304
  }
305
305
 
306
+ /* Written as a plain `.dark` rule rather than `dark:` on the `@apply` above: Tailwind
307
+ wraps a `dark:` variant reached through `@apply` in `:where(.dark, .dark *)`, which
308
+ carries no specificity of its own and loses the tie to the plain `box-shadow` line
309
+ and the `bg-fd-muted/40` utility above regardless of source order. */
310
+ .dark .seemore-editable [data-seemore-pos]:hover {
311
+ background-color: transparent;
312
+ box-shadow: none;
313
+ }
314
+
306
315
  .seemore-editable .seemore-editing {
307
316
  @apply invisible;
308
317
  }