tosijs-ui 1.6.7 → 1.6.10
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 +1 -1
- package/dist/code-editor.d.ts +6 -0
- package/dist/code-editor.js +43 -0
- package/dist/diff.d.ts +61 -0
- package/dist/diff.js +132 -0
- package/dist/doc-browser.js +347 -29
- package/dist/doc-system/doc-system-styles.js +4 -1
- package/dist/doc-system/doc-system.js +8 -0
- package/dist/doc-system/routing.d.ts +8 -0
- package/dist/doc-system/routing.js +13 -0
- package/dist/doc-system/site/dev-server.js +56 -0
- package/dist/doc-system/site/generate-site.js +14 -2
- package/dist/doc-system/site/orchestrator.js +3 -1
- package/dist/doc-system/site/site-config.d.ts +7 -0
- package/dist/iife.js +87 -78
- package/dist/iife.js.map +19 -16
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/live-example/code-transform.d.ts +44 -7
- package/dist/live-example/code-transform.js +0 -0
- package/dist/live-example/component.d.ts +53 -2
- package/dist/live-example/component.js +477 -27
- package/dist/live-example/example-store.d.ts +12 -0
- package/dist/live-example/example-store.js +47 -0
- package/dist/live-example/insert-examples.d.ts +1 -1
- package/dist/live-example/insert-examples.js +24 -2
- package/dist/live-example/save-to-source.d.ts +23 -0
- package/dist/live-example/save-to-source.js +104 -0
- package/dist/live-example/styles.d.ts +22 -0
- package/dist/live-example/styles.js +26 -0
- package/dist/live-example/test-harness.js +2 -2
- package/dist/live-example/types.d.ts +2 -1
- package/dist/menu.js +14 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/llms.txt +3 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ npm add tosijs-ui
|
|
|
67
67
|
Then import the component `elementCreator` and create elements. A `tosijs`
|
|
68
68
|
`elementCreator` is syntax sugar around `document.createElement()`.
|
|
69
69
|
|
|
70
|
-
```
|
|
70
|
+
```typescript
|
|
71
71
|
import { tosiTable } from 'tosijs-ui'
|
|
72
72
|
|
|
73
73
|
document.body.append(tosiTable())
|
package/dist/code-editor.d.ts
CHANGED
|
@@ -4,6 +4,12 @@ export declare class CodeEditor extends WebComponent {
|
|
|
4
4
|
private source;
|
|
5
5
|
get value(): string;
|
|
6
6
|
set value(text: string);
|
|
7
|
+
private _original;
|
|
8
|
+
get original(): string;
|
|
9
|
+
set original(text: string);
|
|
10
|
+
private diffOverlay;
|
|
11
|
+
get showingDiff(): boolean;
|
|
12
|
+
showDiff(on: boolean): void;
|
|
7
13
|
static initAttributes: {
|
|
8
14
|
mode: string;
|
|
9
15
|
theme: string;
|
package/dist/code-editor.js
CHANGED
|
@@ -23,6 +23,7 @@ and an `ace` property that returns the `ace` module, giving you complete access
|
|
|
23
23
|
/*{ "parent": "Components" }*/
|
|
24
24
|
import { Component as WebComponent } from 'tosijs';
|
|
25
25
|
import { scriptTag } from './via-tag';
|
|
26
|
+
import { tosiDiff } from './diff';
|
|
26
27
|
const ACE_BASE_URL = 'https://cdnjs.cloudflare.com/ajax/libs/ace/1.23.2/';
|
|
27
28
|
const DEFAULT_THEME = 'ace/theme/tomorrow';
|
|
28
29
|
const getAce = async () => {
|
|
@@ -37,6 +38,10 @@ const makeCodeEditor = async (codeElement, mode = 'html', options = {}, theme =
|
|
|
37
38
|
tabSize: 2,
|
|
38
39
|
useSoftTabs: true,
|
|
39
40
|
useWorker: false,
|
|
41
|
+
// Wrap wide lines instead of scrolling horizontally; indentedSoftWrap keeps
|
|
42
|
+
// wrapped continuations aligned under the line's indent.
|
|
43
|
+
wrap: true,
|
|
44
|
+
indentedSoftWrap: true,
|
|
40
45
|
...options,
|
|
41
46
|
});
|
|
42
47
|
editor.setTheme(theme);
|
|
@@ -58,6 +63,44 @@ export class CodeEditor extends WebComponent {
|
|
|
58
63
|
this.editor.session.getUndoManager().reset();
|
|
59
64
|
}
|
|
60
65
|
}
|
|
66
|
+
// Baseline for `showDiff()` — the version to diff the current `value` against.
|
|
67
|
+
// Defaults to the current value (no diff) until a caller sets it.
|
|
68
|
+
_original;
|
|
69
|
+
get original() {
|
|
70
|
+
return this._original ?? this.value;
|
|
71
|
+
}
|
|
72
|
+
set original(text) {
|
|
73
|
+
this._original = text;
|
|
74
|
+
}
|
|
75
|
+
// Diff overlay — deliberately built only on the editor's public surface
|
|
76
|
+
// (`value` + `original`) and the tosi-diff component, never the underlying
|
|
77
|
+
// editor's API, so it survives a future Ace → CodeMirror swap untouched.
|
|
78
|
+
diffOverlay;
|
|
79
|
+
get showingDiff() {
|
|
80
|
+
return this.diffOverlay !== undefined && !this.diffOverlay.hidden;
|
|
81
|
+
}
|
|
82
|
+
showDiff(on) {
|
|
83
|
+
if (on) {
|
|
84
|
+
if (this.diffOverlay === undefined) {
|
|
85
|
+
this.diffOverlay = tosiDiff({
|
|
86
|
+
style: {
|
|
87
|
+
position: 'absolute',
|
|
88
|
+
inset: '0',
|
|
89
|
+
zIndex: '5',
|
|
90
|
+
overflow: 'auto',
|
|
91
|
+
background: 'var(--tosi-diff-bg, var(--background, #fff))',
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
this.append(this.diffOverlay);
|
|
95
|
+
}
|
|
96
|
+
this.diffOverlay.original = this.original;
|
|
97
|
+
this.diffOverlay.modified = this.value;
|
|
98
|
+
this.diffOverlay.hidden = false;
|
|
99
|
+
}
|
|
100
|
+
else if (this.diffOverlay !== undefined) {
|
|
101
|
+
this.diffOverlay.hidden = true;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
61
104
|
static initAttributes = {
|
|
62
105
|
mode: 'javascript',
|
|
63
106
|
theme: DEFAULT_THEME,
|
package/dist/diff.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Component, ElementCreator, PartsMap } from 'tosijs';
|
|
2
|
+
export type DiffOp = 'context' | 'add' | 'remove';
|
|
3
|
+
export interface DiffLine {
|
|
4
|
+
op: DiffOp;
|
|
5
|
+
text: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Line-level diff of two strings via longest-common-subsequence, returning each
|
|
9
|
+
* line tagged `context` (unchanged), `remove` (only in `before`), or `add` (only
|
|
10
|
+
* in `after`), in display order.
|
|
11
|
+
*/
|
|
12
|
+
export declare function diffLines(before: string, after: string): DiffLine[];
|
|
13
|
+
interface DiffParts extends PartsMap {
|
|
14
|
+
body: HTMLElement;
|
|
15
|
+
}
|
|
16
|
+
export declare class TosiDiff extends Component<DiffParts> {
|
|
17
|
+
static preferredTagName: string;
|
|
18
|
+
static initAttributes: {
|
|
19
|
+
original: string;
|
|
20
|
+
modified: string;
|
|
21
|
+
};
|
|
22
|
+
static shadowStyleSpec: {
|
|
23
|
+
':host': {
|
|
24
|
+
display: string;
|
|
25
|
+
overflow: string;
|
|
26
|
+
font: string;
|
|
27
|
+
background: string;
|
|
28
|
+
color: string;
|
|
29
|
+
};
|
|
30
|
+
':host([hidden])': {
|
|
31
|
+
display: string;
|
|
32
|
+
};
|
|
33
|
+
'.diff-line': {
|
|
34
|
+
display: string;
|
|
35
|
+
gridTemplateColumns: string;
|
|
36
|
+
whiteSpace: string;
|
|
37
|
+
wordBreak: string;
|
|
38
|
+
};
|
|
39
|
+
'.diff-line .marker': {
|
|
40
|
+
textAlign: string;
|
|
41
|
+
userSelect: string;
|
|
42
|
+
opacity: string;
|
|
43
|
+
};
|
|
44
|
+
'.diff-add': {
|
|
45
|
+
background: string;
|
|
46
|
+
};
|
|
47
|
+
'.diff-add .marker': {
|
|
48
|
+
color: string;
|
|
49
|
+
};
|
|
50
|
+
'.diff-remove': {
|
|
51
|
+
background: string;
|
|
52
|
+
};
|
|
53
|
+
'.diff-remove .marker': {
|
|
54
|
+
color: string;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
content: () => HTMLDivElement[];
|
|
58
|
+
render(): void;
|
|
59
|
+
}
|
|
60
|
+
export declare const tosiDiff: ElementCreator<TosiDiff>;
|
|
61
|
+
export {};
|
package/dist/diff.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/*#
|
|
2
|
+
# diff
|
|
3
|
+
|
|
4
|
+
`<tosi-diff>` renders a unified, line-by-line diff between two strings — the kind
|
|
5
|
+
of view you'd see in a code review, with removed lines marked `-` and added
|
|
6
|
+
lines marked `+`.
|
|
7
|
+
|
|
8
|
+
Set its `original` and `modified` properties (or attributes) to the two versions
|
|
9
|
+
of the text; it recomputes and re-renders. (They're named `original`/`modified`
|
|
10
|
+
rather than `before`/`after` to avoid the native `Element.before()`/`after()`
|
|
11
|
+
methods.)
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
const { tosiDiff } = tosijsui
|
|
15
|
+
|
|
16
|
+
preview.append(
|
|
17
|
+
tosiDiff({
|
|
18
|
+
original: 'one\ntwo\nthree\nfour',
|
|
19
|
+
modified: 'one\nTWO\nthree\nfour\nfive',
|
|
20
|
+
style: { width: '100%', height: '100%' },
|
|
21
|
+
})
|
|
22
|
+
)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The diff is computed with a longest-common-subsequence pass over the lines, so
|
|
26
|
+
unchanged lines are shown as context and only genuine insertions/deletions are
|
|
27
|
+
highlighted. The pure `diffLines(before, after)` function is exported too, if you
|
|
28
|
+
just want the data.
|
|
29
|
+
*/
|
|
30
|
+
/*{ "parent": "Components" }*/
|
|
31
|
+
import { Component, elements } from 'tosijs';
|
|
32
|
+
const { div, span } = elements;
|
|
33
|
+
/**
|
|
34
|
+
* Line-level diff of two strings via longest-common-subsequence, returning each
|
|
35
|
+
* line tagged `context` (unchanged), `remove` (only in `before`), or `add` (only
|
|
36
|
+
* in `after`), in display order.
|
|
37
|
+
*/
|
|
38
|
+
export function diffLines(before, after) {
|
|
39
|
+
const a = before.split('\n');
|
|
40
|
+
const b = after.split('\n');
|
|
41
|
+
const m = a.length;
|
|
42
|
+
const n = b.length;
|
|
43
|
+
// lcs[i][j] = length of the LCS of a[i:] and b[j:]
|
|
44
|
+
const lcs = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
|
|
45
|
+
for (let i = m - 1; i >= 0; i -= 1) {
|
|
46
|
+
for (let j = n - 1; j >= 0; j -= 1) {
|
|
47
|
+
lcs[i][j] =
|
|
48
|
+
a[i] === b[j]
|
|
49
|
+
? lcs[i + 1][j + 1] + 1
|
|
50
|
+
: Math.max(lcs[i + 1][j], lcs[i][j + 1]);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const out = [];
|
|
54
|
+
let i = 0;
|
|
55
|
+
let j = 0;
|
|
56
|
+
while (i < m && j < n) {
|
|
57
|
+
if (a[i] === b[j]) {
|
|
58
|
+
out.push({ op: 'context', text: a[i] });
|
|
59
|
+
i += 1;
|
|
60
|
+
j += 1;
|
|
61
|
+
}
|
|
62
|
+
else if (lcs[i + 1][j] >= lcs[i][j + 1]) {
|
|
63
|
+
out.push({ op: 'remove', text: a[i] });
|
|
64
|
+
i += 1;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
out.push({ op: 'add', text: b[j] });
|
|
68
|
+
j += 1;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
while (i < m) {
|
|
72
|
+
out.push({ op: 'remove', text: a[i] });
|
|
73
|
+
i += 1;
|
|
74
|
+
}
|
|
75
|
+
while (j < n) {
|
|
76
|
+
out.push({ op: 'add', text: b[j] });
|
|
77
|
+
j += 1;
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
81
|
+
const MARKER = { context: ' ', add: '+', remove: '-' };
|
|
82
|
+
export class TosiDiff extends Component {
|
|
83
|
+
static preferredTagName = 'tosi-diff';
|
|
84
|
+
// `before`/`after` would collide with the native Element.before()/after()
|
|
85
|
+
// methods, so the component props are `original`/`modified`.
|
|
86
|
+
static initAttributes = {
|
|
87
|
+
original: '',
|
|
88
|
+
modified: '',
|
|
89
|
+
};
|
|
90
|
+
static shadowStyleSpec = {
|
|
91
|
+
':host': {
|
|
92
|
+
display: 'block',
|
|
93
|
+
overflow: 'auto',
|
|
94
|
+
font: 'var(--tosi-code-font, 12px/1.5 monospace)',
|
|
95
|
+
background: 'var(--tosi-diff-bg, #fff)',
|
|
96
|
+
color: 'var(--tosi-diff-color, #222)',
|
|
97
|
+
},
|
|
98
|
+
// `:host{display:block}` would otherwise beat the UA `[hidden]` rule, so the
|
|
99
|
+
// element couldn't be hidden via the attribute — restore that.
|
|
100
|
+
':host([hidden])': {
|
|
101
|
+
display: 'none',
|
|
102
|
+
},
|
|
103
|
+
'.diff-line': {
|
|
104
|
+
display: 'grid',
|
|
105
|
+
gridTemplateColumns: '1.5em 1fr',
|
|
106
|
+
whiteSpace: 'pre-wrap',
|
|
107
|
+
wordBreak: 'break-word',
|
|
108
|
+
},
|
|
109
|
+
'.diff-line .marker': {
|
|
110
|
+
textAlign: 'center',
|
|
111
|
+
userSelect: 'none',
|
|
112
|
+
opacity: '0.5',
|
|
113
|
+
},
|
|
114
|
+
'.diff-add': {
|
|
115
|
+
background: 'var(--tosi-diff-add-bg, #e6ffed)',
|
|
116
|
+
},
|
|
117
|
+
'.diff-add .marker': { color: 'var(--tosi-diff-add-color, #22863a)' },
|
|
118
|
+
'.diff-remove': {
|
|
119
|
+
background: 'var(--tosi-diff-remove-bg, #ffeef0)',
|
|
120
|
+
},
|
|
121
|
+
'.diff-remove .marker': { color: 'var(--tosi-diff-remove-color, #cb2431)' },
|
|
122
|
+
};
|
|
123
|
+
content = () => [div({ part: 'body' })];
|
|
124
|
+
render() {
|
|
125
|
+
super.render();
|
|
126
|
+
const lines = diffLines(this.original, this.modified);
|
|
127
|
+
this.parts.body.replaceChildren(...lines.map((line) => div({ class: `diff-line diff-${line.op}` }, span({ class: 'marker' }, MARKER[line.op]),
|
|
128
|
+
// Non-breaking fallback so empty lines keep their row height.
|
|
129
|
+
span({ class: 'text' }, line.text === '' ? ' ' : line.text))));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export const tosiDiff = TosiDiff.elementCreator();
|