@textbus/xnote 0.0.2 → 0.0.4
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/bundles/fonts/textbus.svg +71 -69
- package/bundles/fonts/textbus.ttf +0 -0
- package/bundles/fonts/textbus.woff +0 -0
- package/bundles/index.css +2 -2
- package/bundles/index.esm.css +2 -2
- package/bundles/index.esm.js +253 -39
- package/bundles/index.js +251 -37
- package/bundles/textbus/components/step/step-component.view.d.ts +6 -0
- package/bundles/textbus/components/step/step.component.d.ts +15 -0
- package/bundles/textbus/components/timeline/timeline-component.view.d.ts +6 -0
- package/bundles/textbus/components/timeline/timeline.component.d.ts +15 -0
- package/package.json +5 -5
package/bundles/index.esm.js
CHANGED
|
@@ -2,14 +2,14 @@ import { jsxs, jsx, Fragment } from '@viewfly/core/jsx-runtime';
|
|
|
2
2
|
import { withScopedCSS } from '@viewfly/scoped-css';
|
|
3
3
|
import { Injectable, InjectFlags, Injector, inject, createSignal, onUnmounted, createRef, withAnnotation, onUpdated, onMounted, InjectionToken, getCurrentInstance, ReflectiveInjector, createDynamicRef, jsx as jsx$1, viewfly, watch } from '@viewfly/core';
|
|
4
4
|
import { Subject, Selection, fromEvent, Subscription, Attribute, Keyboard, Commander, Controller, useContext, onBreak, onContentInsert, ContentType, merge, createVNode, Slot, Component, Registry, Query, QueryStateType, BehaviorSubject, onSlotApplyFormat, onSlotSetAttribute, onPaste, onFocus, onBlur, useDynamicShortcut, VTextNode, onFocusIn, onFocusOut, onDestroy, onGetRanges, Formatter, onParentSlotUpdated, Textbus, RootComponentRef, filter, map, distinctUntilChanged, sampleTime, debounceTime, throttleTime, delay, onContentInserted, onContentDeleted, switchMap, fromPromise, onCompositionStart } from '@textbus/core';
|
|
5
|
-
import { VIEW_CONTAINER, isMac, DomAdapter, Input, SelectionBridge, BrowserModule, VIEW_DOCUMENT, CollaborateSelectionAwarenessDelegate, isMobileBrowser, Parser } from '@textbus/platform-browser';
|
|
5
|
+
import { VIEW_CONTAINER, isMac, DomAdapter, Input, SelectionBridge, BrowserModule, VIEW_DOCUMENT, CollaborateSelectionAwarenessDelegate, isMobileBrowser, CollaborateCursor, Parser } from '@textbus/platform-browser';
|
|
6
6
|
import { createPortal, createApp, DomRenderer, HTMLRenderer, OutputTranslator } from '@viewfly/platform-browser';
|
|
7
7
|
import { useProduce } from '@viewfly/hooks';
|
|
8
8
|
import highlightjs from 'highlight.js';
|
|
9
9
|
import Katex from 'katex';
|
|
10
10
|
import { ViewflyAdapter, ViewflyVDomAdapter } from '@textbus/adapter-viewfly';
|
|
11
11
|
import { any2Hsl, hsl2Rgb } from '@tanbo/color';
|
|
12
|
-
import { CollaborateModule } from '@textbus/collaborate';
|
|
12
|
+
import { CollaborateModule, UserActivity } from '@textbus/collaborate';
|
|
13
13
|
|
|
14
14
|
var scopedId$n = "vf-d94b56";
|
|
15
15
|
|
|
@@ -177,7 +177,7 @@ function Divider() {
|
|
|
177
177
|
});
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
var scopedId$k = "vf-
|
|
180
|
+
var scopedId$k = "vf-d91ad6";
|
|
181
181
|
|
|
182
182
|
function DragResize(props) {
|
|
183
183
|
const isShow = createSignal(false);
|
|
@@ -459,17 +459,18 @@ const Dropdown = withAnnotation({
|
|
|
459
459
|
}
|
|
460
460
|
},
|
|
461
461
|
$render: withScopedCSS(scopedId$j, () => {
|
|
462
|
-
return (jsxs("div", { class: ['dropdown', props.class], style: props.style, ref: dropdownRef, children: [jsxs("div", { class: "dropdown-btn", ref: triggerRef, children: [jsx("div", { class: "dropdown-btn-inner", children: props.children }), jsx("div", { class: "dropdown-btn-arrow" })] }), isShow() &&
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
462
|
+
return (jsxs("div", { class: ['dropdown', props.class], style: props.style, ref: dropdownRef, children: [jsxs("div", { class: "dropdown-btn", ref: triggerRef, children: [jsx("div", { class: "dropdown-btn-inner", children: props.children }), jsx("div", { class: "dropdown-btn-arrow" })] }), isShow() &&
|
|
463
|
+
jsx(DropdownMenuPortal, { toLeft: props.toLeft, padding: props.padding, noTrigger: props.trigger === 'none', width: props.width, abreast: props.abreast, triggerRef: triggerRef, children: Array.isArray(props.menu) ?
|
|
464
|
+
props.menu.map(menu => {
|
|
465
|
+
return (jsx("div", { class: "dropdown-menu-item", onClick: () => {
|
|
466
|
+
var _a;
|
|
467
|
+
if (menu.disabled) {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
(_a = props.onCheck) === null || _a === void 0 ? void 0 : _a.call(props, menu.value);
|
|
471
|
+
}, children: menu.label }));
|
|
472
|
+
}) :
|
|
473
|
+
props.menu })] }));
|
|
473
474
|
})
|
|
474
475
|
};
|
|
475
476
|
});
|
|
@@ -899,14 +900,14 @@ function HighlightBoxView(props) {
|
|
|
899
900
|
return () => {
|
|
900
901
|
const { state, name } = props.component;
|
|
901
902
|
if (readonly() || output()) {
|
|
902
|
-
return (jsxs("div", { "data-component": name, ref: props.rootRef, "data-icon": state.type, class: "xnote-highlight-box", children: [jsx("div", { class: "xnote-highlight-box-left", children: jsx("div", { class: "xnote-highlight-box-icon", children: jsx("button", { type: "button", children: state.type || '❤️' }) }) }), jsx(SlotRender, { slot: state.slot, class:
|
|
903
|
+
return (jsxs("div", { "data-component": name, ref: props.rootRef, "data-icon": state.type, class: "xnote-highlight-box", children: [jsx("div", { class: "xnote-highlight-box-left", children: jsx("div", { class: "xnote-highlight-box-icon", children: jsx("button", { type: "button", children: state.type || '❤️' }) }) }), jsx(SlotRender, { slot: state.slot, class: "xnote-highlight-box-content", renderEnv: readonly() || output() })] }));
|
|
903
904
|
}
|
|
904
905
|
return (jsxs("div", { "data-component": name, ref: props.rootRef, "data-icon": state.type, class: "xnote-highlight-box", children: [jsx("div", { class: "xnote-highlight-box-left", children: jsx(Dropdown, { trigger: "click", ref: dropdownRef, width: "282px", menu: jsxs("div", { class: "xnote-highlight-box-icons", children: [jsx("div", { class: "xnote-highlight-box-heading", children: "\u5E38\u7528" }), HighlightBoxComponent.defaultTypes.map(icon => {
|
|
905
906
|
return (jsx("button", { onClick: () => setType(icon), type: "button", children: icon }));
|
|
906
907
|
}), jsx("div", { class: "xnote-highlight-box-heading", children: "\u66F4\u591A" }), emoji.map(i => {
|
|
907
908
|
const icon = String.fromCodePoint(i);
|
|
908
909
|
return (jsx("button", { onClick: () => setType(icon), type: "button", children: icon }));
|
|
909
|
-
})] }), children: jsx("div", { class: "xnote-highlight-box-icon", children: jsx("button", { type: "button", children: state.type || '❤️' }) }) }) }), jsx(SlotRender, { slot: state.slot, class:
|
|
910
|
+
})] }), children: jsx("div", { class: "xnote-highlight-box-icon", children: jsx("button", { type: "button", children: state.type || '❤️' }) }) }) }), jsx(SlotRender, { slot: state.slot, class: "xnote-highlight-box-content", renderEnv: readonly() || output() })] }));
|
|
910
911
|
};
|
|
911
912
|
}
|
|
912
913
|
const highlightBoxComponentLoader = {
|
|
@@ -2187,7 +2188,7 @@ function TodolistView(props) {
|
|
|
2187
2188
|
marginLeft: indent * 24 + 'px',
|
|
2188
2189
|
justifyContent: align[component.state.slot.getAttribute(textAlignAttr)],
|
|
2189
2190
|
textAlign: component.state.slot.getAttribute(textAlignAttr) === 'justify' ? 'justify' : void 0
|
|
2190
|
-
}, children: [jsx("div", { class: "xnote-todolist-icon", onClick: toggle, children: jsx("span", { "data-checked": checked, class: [checked ? 'xnote-icon-checkbox-checked' : 'xnote-icon-checkbox-unchecked'] }) }), jsx(SlotRender, { slot: slot, tag:
|
|
2191
|
+
}, children: [jsx("div", { class: "xnote-todolist-icon", onClick: toggle, children: jsx("span", { "data-checked": checked, class: [checked ? 'xnote-icon-checkbox-checked' : 'xnote-icon-checkbox-unchecked'] }) }), jsx(SlotRender, { slot: slot, tag: "div", class: "xnote-todolist-content", renderEnv: readonly() || output() })] }));
|
|
2191
2192
|
};
|
|
2192
2193
|
}
|
|
2193
2194
|
const todolistComponentLoader = {
|
|
@@ -2463,7 +2464,7 @@ function ListComponentView(props) {
|
|
|
2463
2464
|
}, children: [jsx("div", { class: "xnote-list-type", children: (component.state.type === 'UnorderedList' || readonly() || output()) ?
|
|
2464
2465
|
jsx("span", { class: "xnote-order-btn", children: icon })
|
|
2465
2466
|
:
|
|
2466
|
-
jsx(Dropdown, { menu: jsxs(Fragment, { children: [jsx(MenuItem, { onClick: () => reorder(false), children: "\u7EE7\u7EED\u7F16\u53F7" }), jsx(MenuItem, { onClick: () => reorder(true), children: "\u91CD\u65B0\u7F16\u53F7" })] }), children: jsx(Button, { style: { color: 'inherit' }, children: icon }) }) }), jsx(SlotRender, { slot: component.state.slot, class:
|
|
2467
|
+
jsx(Dropdown, { menu: jsxs(Fragment, { children: [jsx(MenuItem, { onClick: () => reorder(false), children: "\u7EE7\u7EED\u7F16\u53F7" }), jsx(MenuItem, { onClick: () => reorder(true), children: "\u91CD\u65B0\u7F16\u53F7" })] }), children: jsx(Button, { style: { color: 'inherit' }, children: icon }) }) }), jsx(SlotRender, { slot: component.state.slot, class: "xnote-list-content", renderEnv: readonly() || output() })] }) }));
|
|
2467
2468
|
};
|
|
2468
2469
|
}
|
|
2469
2470
|
const listComponentLoader = {
|
|
@@ -3500,16 +3501,13 @@ function LinkTool(props) {
|
|
|
3500
3501
|
const editorService = inject(EditorService);
|
|
3501
3502
|
const container = inject(VIEW_CONTAINER);
|
|
3502
3503
|
const isShow = createSignal(false);
|
|
3503
|
-
const
|
|
3504
|
+
const value = createSignal('');
|
|
3504
3505
|
function setLink(ev) {
|
|
3505
3506
|
ev.preventDefault();
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
target: '_blanK'
|
|
3511
|
-
});
|
|
3512
|
-
}
|
|
3507
|
+
commander.applyFormat(linkFormatter, {
|
|
3508
|
+
href: value(),
|
|
3509
|
+
target: '_blanK'
|
|
3510
|
+
});
|
|
3513
3511
|
isShow.set(false);
|
|
3514
3512
|
}
|
|
3515
3513
|
let isClickFromSelf = false;
|
|
@@ -3538,7 +3536,9 @@ function LinkTool(props) {
|
|
|
3538
3536
|
}, children: jsx("span", { class: "xnote-icon-link" }) }), isShow() &&
|
|
3539
3537
|
jsx(Popup, { left: rect.left - containerRect.left, top: rect.top + rect.height - containerRect.top, children: jsxs("form", { onSubmit: setLink, onClick: () => {
|
|
3540
3538
|
isClickFromSelf = true;
|
|
3541
|
-
}, class: "input-group", children: [jsx("input", {
|
|
3539
|
+
}, class: "input-group", children: [jsx("input", { onChange: ev => {
|
|
3540
|
+
value.set(ev.target.value);
|
|
3541
|
+
}, placeholder: "\u8BF7\u8F93\u5165\u94FE\u63A5\u5730\u5740", type: "text" }), jsx(Button, { type: "submit", children: "\u786E\u5B9A" })] }) })] }));
|
|
3542
3542
|
});
|
|
3543
3543
|
}
|
|
3544
3544
|
|
|
@@ -3838,6 +3838,78 @@ const katexComponentLoader = {
|
|
|
3838
3838
|
}
|
|
3839
3839
|
};
|
|
3840
3840
|
|
|
3841
|
+
function createTimelineItem(textbus, theme) {
|
|
3842
|
+
const slot = new Slot([
|
|
3843
|
+
ContentType.BlockComponent,
|
|
3844
|
+
]);
|
|
3845
|
+
const title = new ParagraphComponent(textbus);
|
|
3846
|
+
title.state.slot.insert('时间主题', [
|
|
3847
|
+
[fontSizeFormatter, '18px'],
|
|
3848
|
+
[boldFormatter, true]
|
|
3849
|
+
]);
|
|
3850
|
+
title.state.slot.insert(' 2020-02-02', [
|
|
3851
|
+
[fontSizeFormatter, '15px'],
|
|
3852
|
+
[colorFormatter, '#777']
|
|
3853
|
+
]);
|
|
3854
|
+
const desc = new ParagraphComponent(textbus);
|
|
3855
|
+
desc.state.slot.insert('描述信息...');
|
|
3856
|
+
slot.insert(title);
|
|
3857
|
+
slot.insert(desc);
|
|
3858
|
+
return { theme, slot };
|
|
3859
|
+
}
|
|
3860
|
+
class TimelineComponent extends Component {
|
|
3861
|
+
static fromJSON(textbus, json) {
|
|
3862
|
+
const registry = textbus.get(Registry);
|
|
3863
|
+
return new TimelineComponent(textbus, {
|
|
3864
|
+
items: json.items.map(i => {
|
|
3865
|
+
return {
|
|
3866
|
+
theme: i.theme,
|
|
3867
|
+
slot: registry.createSlot(i.slot)
|
|
3868
|
+
};
|
|
3869
|
+
})
|
|
3870
|
+
});
|
|
3871
|
+
}
|
|
3872
|
+
getSlots() {
|
|
3873
|
+
return this.state.items.map(i => i.slot);
|
|
3874
|
+
}
|
|
3875
|
+
}
|
|
3876
|
+
TimelineComponent.componentName = 'TimelineComponent';
|
|
3877
|
+
TimelineComponent.type = ContentType.BlockComponent;
|
|
3878
|
+
|
|
3879
|
+
function createStepItem(textbus) {
|
|
3880
|
+
const slot = new Slot([
|
|
3881
|
+
ContentType.BlockComponent
|
|
3882
|
+
]);
|
|
3883
|
+
const title = new ParagraphComponent(textbus);
|
|
3884
|
+
title.state.slot.insert('标题', [
|
|
3885
|
+
[fontSizeFormatter, '18px'],
|
|
3886
|
+
[boldFormatter, true]
|
|
3887
|
+
]);
|
|
3888
|
+
const content = new ParagraphComponent(textbus);
|
|
3889
|
+
content.state.slot.insert('描述信息...');
|
|
3890
|
+
slot.insert(title);
|
|
3891
|
+
slot.insert(content);
|
|
3892
|
+
return { slot };
|
|
3893
|
+
}
|
|
3894
|
+
class StepComponent extends Component {
|
|
3895
|
+
static fromJSON(textbus, json) {
|
|
3896
|
+
const registry = textbus.get(Registry);
|
|
3897
|
+
return new StepComponent(textbus, {
|
|
3898
|
+
step: json.step,
|
|
3899
|
+
items: json.items.map(i => {
|
|
3900
|
+
return {
|
|
3901
|
+
slot: registry.createSlot(i.slot)
|
|
3902
|
+
};
|
|
3903
|
+
})
|
|
3904
|
+
});
|
|
3905
|
+
}
|
|
3906
|
+
getSlots() {
|
|
3907
|
+
return this.state.items.map(i => i.slot);
|
|
3908
|
+
}
|
|
3909
|
+
}
|
|
3910
|
+
StepComponent.componentName = 'StepComponent';
|
|
3911
|
+
StepComponent.type = ContentType.BlockComponent;
|
|
3912
|
+
|
|
3841
3913
|
function InsertTool(props) {
|
|
3842
3914
|
const commander = inject(Commander);
|
|
3843
3915
|
const selection = inject(Selection);
|
|
@@ -3977,10 +4049,28 @@ function InsertTool(props) {
|
|
|
3977
4049
|
selection.selectComponent(comp);
|
|
3978
4050
|
}
|
|
3979
4051
|
break;
|
|
4052
|
+
case 'step':
|
|
4053
|
+
{
|
|
4054
|
+
const step = new StepComponent(textbus, {
|
|
4055
|
+
step: 0,
|
|
4056
|
+
items: [createStepItem(textbus)]
|
|
4057
|
+
});
|
|
4058
|
+
insertComponent(step);
|
|
4059
|
+
selection.selectFirstPosition(step, false, true);
|
|
4060
|
+
}
|
|
4061
|
+
break;
|
|
4062
|
+
case 'timeline': {
|
|
4063
|
+
const timeline = new TimelineComponent(textbus, {
|
|
4064
|
+
items: [createTimelineItem(textbus, '#296eff')]
|
|
4065
|
+
});
|
|
4066
|
+
insertComponent(timeline);
|
|
4067
|
+
selection.selectFirstPosition(timeline, false, true);
|
|
4068
|
+
break;
|
|
4069
|
+
}
|
|
3980
4070
|
}
|
|
3981
4071
|
}
|
|
3982
4072
|
return withScopedCSS(scopedId$9, () => {
|
|
3983
|
-
return jsxs(Fragment, { children: [props.hideTitle ? null : jsx(MenuHeading, { children: props.replace ? '替换为' : '在下面添加' }), jsxs("div", { class: "btn-group", children: [jsx(Button, { ordinary: true, onClick: () => insert('paragraph'), children: jsx("span", { class: "xnote-icon-pilcrow" }) }), jsx(Button, { ordinary: true, onClick: () => insert('h1'), children: jsx("span", { class: "xnote-icon-heading-h1" }) }), jsx(Button, { ordinary: true, onClick: () => insert('h2'), children: jsx("span", { class: "xnote-icon-heading-h2" }) }), jsx(Button, { ordinary: true, onClick: () => insert('h3'), children: jsx("span", { class: "xnote-icon-heading-h3" }) }), jsx(Button, { ordinary: true, onClick: () => insert('h4'), children: jsx("span", { class: "xnote-icon-heading-h4" }) }), jsx(Button, { ordinary: true, onClick: () => insert('h5'), children: jsx("span", { class: "xnote-icon-heading-h5" }) }), jsx(Button, { ordinary: true, onClick: () => insert('h6'), children: jsx("span", { class: "xnote-icon-heading-h6" }) }), jsx(Button, { ordinary: true, onClick: () => insert('ol'), children: jsx("span", { class: "xnote-icon-list-numbered" }) }), jsx(Button, { ordinary: true, onClick: () => insert('ul'), children: jsx("span", { class: "xnote-icon-list" }) }), jsx(Button, { ordinary: true, onClick: () => insert('sourceCode'), children: jsx("span", { class: "xnote-icon-source-code" }) })] }), jsx(Divider, {}), jsx(MenuItem, { onClick: () => insert('table'), icon: jsx("span", { class: "xnote-icon-table" }), children: "\u8868\u683C" }), jsx(MenuItem, { onClick: () => insert('todolist'), icon: jsx("span", { class: "xnote-icon-checkbox-checked" }), children: "\u5F85\u529E\u5217\u8868" }), jsx(MenuItem, { onClick: () => insert('image'), icon: jsx("span", { class: "xnote-icon-image" }), children: "\u56FE\u7247" }), jsx(MenuItem, { onClick: () => insert('video'), icon: jsx("span", { class: "xnote-icon-video" }), children: "\u89C6\u9891" }), jsx(MenuItem, { onClick: () => insert('highlightBox'), icon: jsx("span", { class: "xnote-icon-hightlight-box" }), children: "\u9AD8\u4EAE\u5757" }), jsx(MenuItem, { onClick: () => insert('katex'), icon: jsx("span", { class: "xnote-icon-function" }), children: "\u6570\u5B66\u516C\u5F0F" })] });
|
|
4073
|
+
return jsxs(Fragment, { children: [props.hideTitle ? null : jsx(MenuHeading, { children: props.replace ? '替换为' : '在下面添加' }), jsxs("div", { class: "btn-group", children: [jsx(Button, { ordinary: true, onClick: () => insert('paragraph'), children: jsx("span", { class: "xnote-icon-pilcrow" }) }), jsx(Button, { ordinary: true, onClick: () => insert('h1'), children: jsx("span", { class: "xnote-icon-heading-h1" }) }), jsx(Button, { ordinary: true, onClick: () => insert('h2'), children: jsx("span", { class: "xnote-icon-heading-h2" }) }), jsx(Button, { ordinary: true, onClick: () => insert('h3'), children: jsx("span", { class: "xnote-icon-heading-h3" }) }), jsx(Button, { ordinary: true, onClick: () => insert('h4'), children: jsx("span", { class: "xnote-icon-heading-h4" }) }), jsx(Button, { ordinary: true, onClick: () => insert('h5'), children: jsx("span", { class: "xnote-icon-heading-h5" }) }), jsx(Button, { ordinary: true, onClick: () => insert('h6'), children: jsx("span", { class: "xnote-icon-heading-h6" }) }), jsx(Button, { ordinary: true, onClick: () => insert('ol'), children: jsx("span", { class: "xnote-icon-list-numbered" }) }), jsx(Button, { ordinary: true, onClick: () => insert('ul'), children: jsx("span", { class: "xnote-icon-list" }) }), jsx(Button, { ordinary: true, onClick: () => insert('sourceCode'), children: jsx("span", { class: "xnote-icon-source-code" }) })] }), jsx(Divider, {}), jsx(MenuItem, { onClick: () => insert('table'), icon: jsx("span", { class: "xnote-icon-table" }), children: "\u8868\u683C" }), jsx(MenuItem, { onClick: () => insert('todolist'), icon: jsx("span", { class: "xnote-icon-checkbox-checked" }), children: "\u5F85\u529E\u5217\u8868" }), jsx(MenuItem, { onClick: () => insert('image'), icon: jsx("span", { class: "xnote-icon-image" }), children: "\u56FE\u7247" }), jsx(MenuItem, { onClick: () => insert('video'), icon: jsx("span", { class: "xnote-icon-video" }), children: "\u89C6\u9891" }), jsx(MenuItem, { onClick: () => insert('highlightBox'), icon: jsx("span", { class: "xnote-icon-hightlight-box" }), children: "\u9AD8\u4EAE\u5757" }), jsx(MenuItem, { onClick: () => insert('katex'), icon: jsx("span", { class: "xnote-icon-function" }), children: "\u6570\u5B66\u516C\u5F0F" }), jsx(MenuItem, { onClick: () => insert('step'), icon: jsx("span", { class: "xnote-icon-step" }), children: "\u6B65\u9AA4\u6761" }), jsx(MenuItem, { onClick: () => insert('timeline'), icon: jsx("span", { class: "xnote-icon-timeline" }), children: "\u65F6\u95F4\u8F74" })] });
|
|
3984
4074
|
});
|
|
3985
4075
|
}
|
|
3986
4076
|
|
|
@@ -4702,7 +4792,7 @@ function AtComponentView(props) {
|
|
|
4702
4792
|
return (jsxs("div", { class: "xnote-at xnote-at-complete", "data-info": encodeURIComponent(JSON.stringify(userInfo)), ref: props.rootRef, "data-component": props.component.name, children: [jsx("span", { children: "@" }), userInfo.name] }));
|
|
4703
4793
|
}
|
|
4704
4794
|
if (readonly() || output()) {
|
|
4705
|
-
return (jsxs("div", { class: "xnote-at", ref: props.rootRef, "data-component": props.component.name, children: [jsx("span", { children: "@" }), slot && jsx(SlotRender, { slot: slot, class:
|
|
4795
|
+
return (jsxs("div", { class: "xnote-at", ref: props.rootRef, "data-component": props.component.name, children: [jsx("span", { children: "@" }), slot && jsx(SlotRender, { slot: slot, class: "xnote-at-input", tag: "span" })] }));
|
|
4706
4796
|
}
|
|
4707
4797
|
const members = props.component.members();
|
|
4708
4798
|
return (jsx("div", { class: "xnote-at", ref: props.rootRef, "data-component": props.component.name, children: jsxs(Dropdown, { trigger: 'none', ref: dropdownRef, menu: jsx("div", { class: "xnote-at-menu", ref: membersRef, children: members.map((member, index) => {
|
|
@@ -4718,7 +4808,7 @@ function AtComponentView(props) {
|
|
|
4718
4808
|
selection.selectComponentEnd(props.component);
|
|
4719
4809
|
}, class: ['xnote-at-member', { selected: index === selectedIndex }], children: [jsx("div", { class: "xnote-at-member-avatar", children: member.avatar ? jsx("img", { src: member.avatar, alt: member.name }) :
|
|
4720
4810
|
jsx("span", { class: "xnote-at-member-avatar-bg", style: { background: member.color, color }, children: member.name }) }), jsxs("div", { class: "xnote-at-member-info", children: [jsx("div", { class: "xnote-at-member-name", children: member.name }), jsx("div", { class: "xnote-at-member-desc", children: member.groupName })] })] }, member.id));
|
|
4721
|
-
}) }), children: [jsx("span", { children: "@" }), slot && jsx(SlotRender, { slot: slot, tag:
|
|
4811
|
+
}) }), children: [jsx("span", { children: "@" }), slot && jsx(SlotRender, { slot: slot, tag: "span", class: "xnote-at-input" })] }) }));
|
|
4722
4812
|
};
|
|
4723
4813
|
}
|
|
4724
4814
|
const atComponentLoader = {
|
|
@@ -5059,17 +5149,15 @@ function Scroll(props) {
|
|
|
5059
5149
|
draft.rightEnd = el.scrollLeft === el.scrollWidth - el.offsetWidth;
|
|
5060
5150
|
});
|
|
5061
5151
|
}
|
|
5062
|
-
|
|
5152
|
+
update();
|
|
5063
5153
|
const s = fromEvent(el, 'scroll').subscribe(update);
|
|
5064
5154
|
return () => s.unsubscribe();
|
|
5065
5155
|
});
|
|
5066
5156
|
onUpdated(() => {
|
|
5067
5157
|
const el = scrollRef.current;
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
draft.rightEnd = el.scrollLeft === el.scrollWidth - el.offsetWidth;
|
|
5072
|
-
});
|
|
5158
|
+
updateShowShadow(draft => {
|
|
5159
|
+
draft.leftEnd = el.scrollLeft === 0;
|
|
5160
|
+
draft.rightEnd = el.scrollLeft === el.scrollWidth - el.offsetWidth;
|
|
5073
5161
|
});
|
|
5074
5162
|
});
|
|
5075
5163
|
return withScopedCSS(scopedId$3, () => {
|
|
@@ -5619,6 +5707,112 @@ function finedPosition(component, slot) {
|
|
|
5619
5707
|
return null;
|
|
5620
5708
|
}
|
|
5621
5709
|
|
|
5710
|
+
function TimelineComponentView(props) {
|
|
5711
|
+
const adapter = inject(DomAdapter);
|
|
5712
|
+
const textbus = inject(Textbus);
|
|
5713
|
+
const isOutput = useOutput();
|
|
5714
|
+
const isReadonly = useReadonly();
|
|
5715
|
+
return () => {
|
|
5716
|
+
const component = props.component;
|
|
5717
|
+
return (jsx("div", { class: "xnote-timeline", ref: props.rootRef, "data-component": TimelineComponent.componentName, children: component.state.items.map(item => {
|
|
5718
|
+
return (jsxs("div", { class: "xnote-timeline-item", children: [jsx("div", { class: "xnote-timeline-line", style: {
|
|
5719
|
+
borderColor: item.theme,
|
|
5720
|
+
} }), jsx("div", { class: "xnote-timeline-icon", style: {
|
|
5721
|
+
borderColor: item.theme,
|
|
5722
|
+
backgroundColor: item.theme,
|
|
5723
|
+
} }), !isOutput() && !isReadonly() && jsxs("div", { class: "xnote-timeline-tools", children: [jsx(Button, { class: "xnote-timeline-add xnote-icon-plus", onClick: () => {
|
|
5724
|
+
const index = component.state.items.indexOf(item) + 1;
|
|
5725
|
+
component.state.items.splice(index, 0, createTimelineItem(textbus, item.theme));
|
|
5726
|
+
} }), jsx(Button, { class: "xnote-timeline-add xnote-icon-bin", onClick: () => {
|
|
5727
|
+
const index = component.state.items.indexOf(item);
|
|
5728
|
+
component.state.items.splice(index, 1);
|
|
5729
|
+
} })] }), adapter.slotRender(item.slot, children => {
|
|
5730
|
+
return createVNode('div', {
|
|
5731
|
+
class: 'xnote-timeline-item-content',
|
|
5732
|
+
}, children);
|
|
5733
|
+
}, isOutput() || isReadonly())] }, item.slot.id));
|
|
5734
|
+
}) }));
|
|
5735
|
+
};
|
|
5736
|
+
}
|
|
5737
|
+
const timelineComponentLoader = {
|
|
5738
|
+
match(element) {
|
|
5739
|
+
return element.className === 'xnote-timeline';
|
|
5740
|
+
},
|
|
5741
|
+
read(element, context, slotParser) {
|
|
5742
|
+
return new TimelineComponent(context, {
|
|
5743
|
+
items: Array.from(element.children).map(child => {
|
|
5744
|
+
const slot = new Slot([
|
|
5745
|
+
ContentType.BlockComponent
|
|
5746
|
+
]);
|
|
5747
|
+
return {
|
|
5748
|
+
theme: '',
|
|
5749
|
+
slot: slotParser(slot, child.querySelector('div.xnote-timeline-content') || document.createElement('div'))
|
|
5750
|
+
};
|
|
5751
|
+
})
|
|
5752
|
+
});
|
|
5753
|
+
}
|
|
5754
|
+
};
|
|
5755
|
+
|
|
5756
|
+
function StepComponentView(props) {
|
|
5757
|
+
const adapter = inject(DomAdapter);
|
|
5758
|
+
const textbus = inject(Textbus);
|
|
5759
|
+
const isOutput = useOutput();
|
|
5760
|
+
const isReadonly = useReadonly();
|
|
5761
|
+
return () => {
|
|
5762
|
+
const component = props.component;
|
|
5763
|
+
const currentStep = component.state.step;
|
|
5764
|
+
return (jsx("div", { class: "xnote-step", "data-step": currentStep, ref: props.rootRef, "data-component": StepComponent.componentName, children: component.state.items.map((item, index) => {
|
|
5765
|
+
let state = 'xnote-waiting';
|
|
5766
|
+
if (index < currentStep) {
|
|
5767
|
+
state = 'xnote-complete';
|
|
5768
|
+
}
|
|
5769
|
+
else if (index === currentStep) {
|
|
5770
|
+
state = 'xnote-current';
|
|
5771
|
+
}
|
|
5772
|
+
return (jsxs("div", { class: 'xnote-step-item ' + state, children: [jsxs("div", { class: "xnote-step-item-header", children: [jsx("div", { class: "xnote-step-item-line" }), jsx("div", { class: "xnote-step-item-icon", onClick: () => {
|
|
5773
|
+
if (index === currentStep) {
|
|
5774
|
+
component.state.step = index + 1;
|
|
5775
|
+
}
|
|
5776
|
+
else if (index + 1 === currentStep) {
|
|
5777
|
+
component.state.step = index - 1;
|
|
5778
|
+
}
|
|
5779
|
+
else {
|
|
5780
|
+
component.state.step = index;
|
|
5781
|
+
}
|
|
5782
|
+
}, children: index + 1 })] }), !isOutput() && !isReadonly() && jsxs("div", { class: "xnote-step-tools", children: [jsx(Button, { class: "xnote-step-add xnote-icon-plus", onClick: () => {
|
|
5783
|
+
const index = component.state.items.indexOf(item) + 1;
|
|
5784
|
+
component.state.items.splice(index, 0, createStepItem(textbus));
|
|
5785
|
+
} }), jsx(Button, { class: "xnote-step-add xnote-icon-bin", onClick: () => {
|
|
5786
|
+
const index = component.state.items.indexOf(item);
|
|
5787
|
+
component.state.items.splice(index, 1);
|
|
5788
|
+
} })] }), adapter.slotRender(item.slot, children => {
|
|
5789
|
+
return createVNode('div', {
|
|
5790
|
+
class: 'xnote-step-item-content'
|
|
5791
|
+
}, children);
|
|
5792
|
+
}, isOutput() || isReadonly())] }, item.slot.id));
|
|
5793
|
+
}) }));
|
|
5794
|
+
};
|
|
5795
|
+
}
|
|
5796
|
+
const stepComponentLoader = {
|
|
5797
|
+
match(element) {
|
|
5798
|
+
return element.dataset.component === StepComponent.componentName;
|
|
5799
|
+
},
|
|
5800
|
+
read(element, context, slotParser) {
|
|
5801
|
+
return new StepComponent(context, {
|
|
5802
|
+
step: Number(element.dataset.step) || 0,
|
|
5803
|
+
items: Array.from(element.children).map(child => {
|
|
5804
|
+
const slot = new Slot([
|
|
5805
|
+
ContentType.BlockComponent
|
|
5806
|
+
]);
|
|
5807
|
+
return {
|
|
5808
|
+
slot: slotParser(slot, child.querySelector('.xnote-step-item-content') ||
|
|
5809
|
+
document.createElement('div'))
|
|
5810
|
+
};
|
|
5811
|
+
})
|
|
5812
|
+
});
|
|
5813
|
+
}
|
|
5814
|
+
};
|
|
5815
|
+
|
|
5622
5816
|
class Editor extends Textbus {
|
|
5623
5817
|
constructor(editorConfig = {}) {
|
|
5624
5818
|
const adapter = new ViewflyAdapter({
|
|
@@ -5634,6 +5828,8 @@ class Editor extends Textbus {
|
|
|
5634
5828
|
[VideoComponent.componentName]: VideoView,
|
|
5635
5829
|
[AtComponent.componentName]: AtComponentView,
|
|
5636
5830
|
[KatexComponent.componentName]: KatexComponentView,
|
|
5831
|
+
[StepComponent.componentName]: StepComponentView,
|
|
5832
|
+
[TimelineComponent.componentName]: TimelineComponentView,
|
|
5637
5833
|
}, (host, root, injector) => {
|
|
5638
5834
|
const appInjector = new ReflectiveInjector(injector, [{
|
|
5639
5835
|
provide: OutputInjectionToken,
|
|
@@ -5660,6 +5856,8 @@ class Editor extends Textbus {
|
|
|
5660
5856
|
todolistComponentLoader,
|
|
5661
5857
|
katexComponentLoader,
|
|
5662
5858
|
paragraphComponentLoader,
|
|
5859
|
+
stepComponentLoader,
|
|
5860
|
+
timelineComponentLoader
|
|
5663
5861
|
], formatLoaders: [
|
|
5664
5862
|
backgroundColorFormatLoader,
|
|
5665
5863
|
boldFormatLoader,
|
|
@@ -5696,7 +5894,9 @@ class Editor extends Textbus {
|
|
|
5696
5894
|
[ImageComponent.componentName]: ImageView,
|
|
5697
5895
|
[VideoComponent.componentName]: VideoView,
|
|
5698
5896
|
[AtComponent.componentName]: AtComponentView,
|
|
5699
|
-
[KatexComponent.componentName]: KatexComponentView
|
|
5897
|
+
[KatexComponent.componentName]: KatexComponentView,
|
|
5898
|
+
[StepComponent.componentName]: StepComponentView,
|
|
5899
|
+
[TimelineComponent.componentName]: TimelineComponentView,
|
|
5700
5900
|
}, (host, root, injector) => {
|
|
5701
5901
|
const appInjector = new ReflectiveInjector(injector, [{
|
|
5702
5902
|
provide: OutputInjectionToken,
|
|
@@ -5727,7 +5927,9 @@ class Editor extends Textbus {
|
|
|
5727
5927
|
ListComponent,
|
|
5728
5928
|
VideoComponent,
|
|
5729
5929
|
AtComponent,
|
|
5730
|
-
KatexComponent
|
|
5930
|
+
KatexComponent,
|
|
5931
|
+
StepComponent,
|
|
5932
|
+
TimelineComponent
|
|
5731
5933
|
], formatters: [
|
|
5732
5934
|
backgroundColorFormatter,
|
|
5733
5935
|
boldFormatter,
|
|
@@ -5746,7 +5948,19 @@ class Editor extends Textbus {
|
|
|
5746
5948
|
], plugins: [
|
|
5747
5949
|
new LeftToolbarPlugin(),
|
|
5748
5950
|
new ToolbarPlugin(),
|
|
5749
|
-
],
|
|
5951
|
+
], setup(textbus) {
|
|
5952
|
+
if (editorConfig.collaborateConfig) {
|
|
5953
|
+
const activity = textbus.get(UserActivity);
|
|
5954
|
+
const collabCursor = textbus.get(CollaborateCursor);
|
|
5955
|
+
const sub = activity.onStateChange.subscribe(ev => {
|
|
5956
|
+
collabCursor.draw(ev);
|
|
5957
|
+
});
|
|
5958
|
+
return () => {
|
|
5959
|
+
sub.unsubscribe();
|
|
5960
|
+
};
|
|
5961
|
+
}
|
|
5962
|
+
},
|
|
5963
|
+
onAfterStartup(textbus) {
|
|
5750
5964
|
registerBoldShortcut(textbus);
|
|
5751
5965
|
registerCodeShortcut(textbus);
|
|
5752
5966
|
registerItalicShortcut(textbus);
|