Skip to content

Editor#601

Draft
ije wants to merge 197 commits into
pierrecomputer:mainfrom
ije:editor
Draft

Editor#601
ije wants to merge 197 commits into
pierrecomputer:mainfrom
ije:editor

Conversation

@ije
Copy link
Copy Markdown

@ije ije commented Apr 23, 2026

Architecture

The editor is a plugable system for the File component. It provides:

  • Text Editing
  • Selection management
  • History (undo, redo)
  • Search
  • Quick Edit
  • Automatic Indentation

The editor adds the contenteditable property to the code line element, that supports native web selection and editing features on mobile phone.

const contentEl = fileContainer.shadowRoot.querySelector("[data-content]")
contentEl.contentEditable = true
contentEl.addEventListener("beforeInput", handleInput)

Selections are created via the native web selection API, multiple cursors has been supported.

document.addEventListener('selectionchange', () => {
  const selectionRaw = document.getSelection();
  const composedRanges = selectionRaw?.getComposedRanges({
    shadowRoots: [fileContainerShadowRoot],
  });
  const selection = convertSelection(composedRanges);
  if (selection) {
    // Text in the editor has been selected.
    // You can now get the `start.line`, `start.column`, `end.line` and `end.column` from the selection
  }
})

API

Vanilla JS:

import { VirtualizedFile } from "@pierre/diffs"
import { Editor } from "@pierre/diffs/editor"

// render a file
const fileInstance = new VirtualizedFile({ ... });
fileInstance.render({ ... });

// make the file editable
const editor = new Editor({
  onChange: (file, lineAnnotations) => console.log("change", file.name, file.contents)
})
const dispose  = editor.edit(fileInstance)
dispose() // or call `editor.cleanUp()`

lazy import (recommended):

import { VirtualizedFile } from "@pierre/diffs"

// render a file
const fileInstance = new VirtualizedFile({ ... });
fileInstance.render({ ... });

const edit = async (file: File) => {
  const { Editor } = await import("@pierre/diffs/editor")
  const editor = new Editor({
    onChange: (file, lineAnnotations) => console.log("change", file.name, file.contents)
  })
  return editor.edit(file)
}

// click to edit (lazy importing the editor.js)
button.addEventListener("click", () => void edit(fileInstance))

React:

import { Editor } from "@pierre/diffs"
import {
  type FileContents,
  File,
  EditorProvider,
} from '@pierre/diffs/react';

const file: FileContents = {
  name: 'example.ts',
  contents: `function greet(name: string) {
  console.log(\`Hello, \${name}!\`);
}

export { greet };`,
};

const editor = new Editor({
  onChange: (file, lineAnnotations) => console.log("change", file.name, file.contents)
})

export function EditCodeFile() {
  const [editable, setEditable] = useState(true)
  return (
    <EditorProvider editor={editor}>
      <File
        file={file}
        options={{
          theme: { dark: 'pierre-dark', light: 'pierre-light' },
        }}
        editable={editable}
      />
    </EditorProvider>
  );
}

TODOS

  • Basic editing
  • Selection & cursor
  • Multiple cursors (Pressing ⌘)
  • History(undo/redo)
  • Search
  • Quick Edit
  • Automatic indentation
  • Shortcuts
    • 'selectAll' ⌘ + A
    • 'copy' ⌘ + C
    • 'cut' ⌘ + X
    • 'paste' ⌘ + V/Y
    • 'findNextMatch' ⌘ + D
    • 'indent' Tab
    • 'outdent' Shift + Tab
    • 'moveCursorToDocStart' ⌘ + ↑
    • 'moveCursorToDocEnd' ⌘ + ↓
    • 'expandSelectionDocStart' ⌘ + Shift + ↑
    • 'expandSelectionDocEnd' ⌘ + Shift + ↓
    • 'undo' ⌘ + Z
    • 'redo' ⌘ + Shift + Z
  • Browser compatibility
    • Chrome
    • Firefox
    • Safari
    • Android Chrome
    • iOS Safari
  • LSP next version

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 23, 2026

@ije is attempting to deploy a commit to the Pierre Computer Company Team on Vercel.

A member of the Team first needs to authorize it.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pierrejs-diff-demo Ready Ready Preview May 21, 2026 12:23am
pierrejs-docs Ready Ready Preview May 21, 2026 12:23am

Request Review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 50 out of 51 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (1)

packages/diffs/src/editor/css.ts:106

  • This color-mix() value is missing the comma between color stops, making the box-shadow value invalid and causing the search panel shadow to be ignored. Add the comma between the foreground and background color stops.
    box-shadow: 0 0 12px 0 color-mix(in lab, var(--diffs-fg) 16% var(--diffs-bg));

Comment thread packages/diffs/src/editor/editor.ts Outdated
Comment thread packages/diffs/src/editor/css.ts Outdated
Comment thread packages/diffs/src/editor/css.ts Outdated
Comment thread apps/demo/vite.config.ts
Comment thread apps/demo/vite.config.ts Outdated
Comment thread apps/demo/vite.config.ts
@ije ije marked this pull request as draft May 19, 2026 05:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants