tsquare 0.12.0 → 0.12.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.12.1
4
+
5
+ The language and the renderer haven't changed: every wireframe renders exactly as in 0.12.0, and render URLs give the same images.
6
+
7
+ - **`tsquare/editor` can wrap long lines:** `lineWrapping: true` wraps instead of scrolling sideways, with each wrapped line's continuation rows indented 4 spaces past its own indentation (2 would look like a child element). Off by default, so the playground is unchanged; `@tsquare-js/react` turns it on, because its editors are often narrow.
8
+
3
9
  ## 0.12.0
4
10
 
5
11
  The language and the renderer haven't changed: every wireframe renders exactly as in 0.11.0, and render URLs give the same images.
package/README.md CHANGED
@@ -145,7 +145,7 @@ const editor = createEditor(document.getElementById("code")!, {
145
145
  });
146
146
  ```
147
147
 
148
- Give the element a height; the editor fills it. Options: `doc`, `data`, `onChange`, `lineNumbers` (default `true`) and `ariaLabel` (default "Wireframe text"). The editor has `getText()`, `setText(text)` (one undoable step), `setIssues(issues)`, `goToLine(n)`, `focus()`, `dom` and `destroy()`.
148
+ Give the element a height; the editor fills it. Options: `doc`, `data`, `onChange`, `lineNumbers` (default `true`), `lineWrapping` (default `false`: wrap long lines instead of scrolling sideways, continuation rows indented 4 spaces past their line's indentation, so they don't look like a child element) and `ariaLabel` (default "Wireframe text"). The editor has `getText()`, `setText(text)` (one undoable step), `setIssues(issues)`, `goToLine(n)`, `focus()`, `dom` and `destroy()`.
149
149
 
150
150
  Its colors are CSS variables, light or dark by the page's `color-scheme`, defaulting to the playground's:
151
151
 
package/dist/editor.js CHANGED
@@ -9434,9 +9434,9 @@ var LineGap = class {
9434
9434
  }
9435
9435
  return true;
9436
9436
  }
9437
- draw(viewState, wrapping) {
9437
+ draw(viewState, wrapping2) {
9438
9438
  return Decoration.replace({
9439
- widget: new LineGapWidget(this.displaySize * (wrapping ? viewState.scaleY : viewState.scaleX), wrapping)
9439
+ widget: new LineGapWidget(this.displaySize * (wrapping2 ? viewState.scaleY : viewState.scaleX), wrapping2)
9440
9440
  }).range(this.from, this.to);
9441
9441
  }
9442
9442
  };
@@ -9732,9 +9732,9 @@ var ViewState = class {
9732
9732
  // predictable. Relies on generous margins (see LG.Margin) to hide
9733
9733
  // the artifacts this might produce from the user.
9734
9734
  ensureLineGaps(current, mayMeasure) {
9735
- let wrapping = this.heightOracle.lineWrapping;
9736
- let margin = wrapping ? 1e4 : 2e3, halfMargin = margin >> 1, doubleMargin = margin << 1;
9737
- if (this.defaultTextDirection != Direction.LTR && !wrapping)
9735
+ let wrapping2 = this.heightOracle.lineWrapping;
9736
+ let margin = wrapping2 ? 1e4 : 2e3, halfMargin = margin >> 1, doubleMargin = margin << 1;
9737
+ if (this.defaultTextDirection != Direction.LTR && !wrapping2)
9738
9738
  return [];
9739
9739
  let gaps = [];
9740
9740
  let addGap = (from, to, line, structure) => {
@@ -9752,13 +9752,13 @@ var ViewState = class {
9752
9752
  }
9753
9753
  let gap = find(current, (gap2) => gap2.from >= line.from && gap2.to <= line.to && Math.abs(gap2.from - from) < halfMargin && Math.abs(gap2.to - to) < halfMargin && !avoid.some((pos) => gap2.from < pos && gap2.to > pos));
9754
9754
  if (!gap) {
9755
- if (to < line.to && mayMeasure && wrapping && mayMeasure.visibleRanges.some((r) => r.from <= to && r.to >= to)) {
9755
+ if (to < line.to && mayMeasure && wrapping2 && mayMeasure.visibleRanges.some((r) => r.from <= to && r.to >= to)) {
9756
9756
  let lineStart = mayMeasure.moveToLineBoundary(EditorSelection.cursor(to), false, true).head;
9757
9757
  if (lineStart > from)
9758
9758
  to = lineStart;
9759
9759
  }
9760
9760
  let size = this.gapSize(line, from, to, structure);
9761
- let displaySize = wrapping || size < 2e6 ? size : 2e6;
9761
+ let displaySize = wrapping2 || size < 2e6 ? size : 2e6;
9762
9762
  gap = new LineGap(from, to, size, displaySize);
9763
9763
  }
9764
9764
  gaps.push(gap);
@@ -9771,7 +9771,7 @@ var ViewState = class {
9771
9771
  return;
9772
9772
  let target = this.scrollTarget ? this.scrollTarget.range.head : null;
9773
9773
  let viewFrom, viewTo;
9774
- if (wrapping) {
9774
+ if (wrapping2) {
9775
9775
  let marginHeight = margin / this.heightOracle.lineLength * this.heightOracle.lineHeight;
9776
9776
  let top2, bot;
9777
9777
  if (target != null) {
@@ -22575,6 +22575,32 @@ var pasteFencedBlock = EditorView.domEventHandlers({
22575
22575
  return true;
22576
22576
  }
22577
22577
  });
22578
+ var CONTINUATION = 4;
22579
+ var hangingIndent = ViewPlugin.fromClass(
22580
+ class {
22581
+ decorations;
22582
+ constructor(view) {
22583
+ this.decorations = this.build(view);
22584
+ }
22585
+ update(u) {
22586
+ if (u.docChanged || u.viewportChanged) this.decorations = this.build(u.view);
22587
+ }
22588
+ build(view) {
22589
+ const builder = new RangeSetBuilder();
22590
+ for (const { from, to } of view.visibleRanges) {
22591
+ for (let pos = from; pos <= to; ) {
22592
+ const line = view.state.doc.lineAt(pos);
22593
+ const indent = line.text.match(/^ */)[0].length;
22594
+ builder.add(line.from, line.from, Decoration.line({ attributes: { style: `padding-left: calc(6px + ${indent + CONTINUATION}ch); text-indent: -${indent + CONTINUATION}ch` } }));
22595
+ pos = line.to + 1;
22596
+ }
22597
+ }
22598
+ return builder.finish();
22599
+ }
22600
+ },
22601
+ { decorations: (p) => p.decorations }
22602
+ );
22603
+ var wrapping = [EditorView.lineWrapping, hangingIndent];
22578
22604
  function createEditor(parent, opts = {}) {
22579
22605
  const extensions = [
22580
22606
  opts.lineNumbers === false ? [] : [lineNumbers(), highlightActiveLineGutter()],
@@ -22592,6 +22618,7 @@ function createEditor(parent, opts = {}) {
22592
22618
  keymap.of([{ key: "Enter", run: newlineKeepIndent }, ...closeBracketsKeymap, ...completionKeymap, ...searchKeymap, ...historyKeymap, indentWithTab, ...defaultKeymap]),
22593
22619
  theme2,
22594
22620
  pasteFencedBlock,
22621
+ opts.lineWrapping ? wrapping : [],
22595
22622
  EditorView.contentAttributes.of({ "aria-label": opts.ariaLabel ?? "Wireframe text", spellcheck: "false", autocapitalize: "off" }),
22596
22623
  EditorView.updateListener.of((u) => {
22597
22624
  if (u.docChanged) opts.onChange?.(u.state.doc.toString());
@@ -8,6 +8,8 @@ export interface EditorOptions {
8
8
  onChange?: (text: string) => void;
9
9
  /** Line numbers in a gutter. Default true. */
10
10
  lineNumbers?: boolean;
11
+ /** Wrap long lines instead of scrolling sideways; continuation rows are indented under their line. Default false. */
12
+ lineWrapping?: boolean;
11
13
  /** The editable area's accessible name. Default "Wireframe text". */
12
14
  ariaLabel?: string;
13
15
  }