@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/index.js CHANGED
@@ -179,7 +179,7 @@ function Divider() {
179
179
  });
180
180
  }
181
181
 
182
- var scopedId$k = "vf-8abf2c";
182
+ var scopedId$k = "vf-d91ad6";
183
183
 
184
184
  function DragResize(props) {
185
185
  const isShow = core.createSignal(false);
@@ -461,17 +461,18 @@ const Dropdown = core.withAnnotation({
461
461
  }
462
462
  },
463
463
  $render: scopedCss.withScopedCSS(scopedId$j, () => {
464
- return (jsxRuntime.jsxs("div", { class: ['dropdown', props.class], style: props.style, ref: dropdownRef, children: [jsxRuntime.jsxs("div", { class: "dropdown-btn", ref: triggerRef, children: [jsxRuntime.jsx("div", { class: "dropdown-btn-inner", children: props.children }), jsxRuntime.jsx("div", { class: "dropdown-btn-arrow" })] }), isShow() && jsxRuntime.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) ?
465
- props.menu.map(menu => {
466
- return (jsxRuntime.jsx("div", { class: "dropdown-menu-item", onClick: () => {
467
- var _a;
468
- if (menu.disabled) {
469
- return;
470
- }
471
- (_a = props.onCheck) === null || _a === void 0 ? void 0 : _a.call(props, menu.value);
472
- }, children: menu.label }));
473
- }) :
474
- props.menu })] }));
464
+ return (jsxRuntime.jsxs("div", { class: ['dropdown', props.class], style: props.style, ref: dropdownRef, children: [jsxRuntime.jsxs("div", { class: "dropdown-btn", ref: triggerRef, children: [jsxRuntime.jsx("div", { class: "dropdown-btn-inner", children: props.children }), jsxRuntime.jsx("div", { class: "dropdown-btn-arrow" })] }), isShow() &&
465
+ jsxRuntime.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) ?
466
+ props.menu.map(menu => {
467
+ return (jsxRuntime.jsx("div", { class: "dropdown-menu-item", onClick: () => {
468
+ var _a;
469
+ if (menu.disabled) {
470
+ return;
471
+ }
472
+ (_a = props.onCheck) === null || _a === void 0 ? void 0 : _a.call(props, menu.value);
473
+ }, children: menu.label }));
474
+ }) :
475
+ props.menu })] }));
475
476
  })
476
477
  };
477
478
  });
@@ -901,14 +902,14 @@ function HighlightBoxView(props) {
901
902
  return () => {
902
903
  const { state, name } = props.component;
903
904
  if (readonly() || output()) {
904
- return (jsxRuntime.jsxs("div", { "data-component": name, ref: props.rootRef, "data-icon": state.type, class: "xnote-highlight-box", children: [jsxRuntime.jsx("div", { class: "xnote-highlight-box-left", children: jsxRuntime.jsx("div", { class: "xnote-highlight-box-icon", children: jsxRuntime.jsx("button", { type: "button", children: state.type || '❤️' }) }) }), jsxRuntime.jsx(SlotRender, { slot: state.slot, class: 'xnote-highlight-box-content', renderEnv: readonly() || output() })] }));
905
+ return (jsxRuntime.jsxs("div", { "data-component": name, ref: props.rootRef, "data-icon": state.type, class: "xnote-highlight-box", children: [jsxRuntime.jsx("div", { class: "xnote-highlight-box-left", children: jsxRuntime.jsx("div", { class: "xnote-highlight-box-icon", children: jsxRuntime.jsx("button", { type: "button", children: state.type || '❤️' }) }) }), jsxRuntime.jsx(SlotRender, { slot: state.slot, class: "xnote-highlight-box-content", renderEnv: readonly() || output() })] }));
905
906
  }
906
907
  return (jsxRuntime.jsxs("div", { "data-component": name, ref: props.rootRef, "data-icon": state.type, class: "xnote-highlight-box", children: [jsxRuntime.jsx("div", { class: "xnote-highlight-box-left", children: jsxRuntime.jsx(Dropdown, { trigger: "click", ref: dropdownRef, width: "282px", menu: jsxRuntime.jsxs("div", { class: "xnote-highlight-box-icons", children: [jsxRuntime.jsx("div", { class: "xnote-highlight-box-heading", children: "\u5E38\u7528" }), HighlightBoxComponent.defaultTypes.map(icon => {
907
908
  return (jsxRuntime.jsx("button", { onClick: () => setType(icon), type: "button", children: icon }));
908
909
  }), jsxRuntime.jsx("div", { class: "xnote-highlight-box-heading", children: "\u66F4\u591A" }), emoji.map(i => {
909
910
  const icon = String.fromCodePoint(i);
910
911
  return (jsxRuntime.jsx("button", { onClick: () => setType(icon), type: "button", children: icon }));
911
- })] }), children: jsxRuntime.jsx("div", { class: "xnote-highlight-box-icon", children: jsxRuntime.jsx("button", { type: "button", children: state.type || '❤️' }) }) }) }), jsxRuntime.jsx(SlotRender, { slot: state.slot, class: 'xnote-highlight-box-content', renderEnv: readonly() || output() })] }));
912
+ })] }), children: jsxRuntime.jsx("div", { class: "xnote-highlight-box-icon", children: jsxRuntime.jsx("button", { type: "button", children: state.type || '❤️' }) }) }) }), jsxRuntime.jsx(SlotRender, { slot: state.slot, class: "xnote-highlight-box-content", renderEnv: readonly() || output() })] }));
912
913
  };
913
914
  }
914
915
  const highlightBoxComponentLoader = {
@@ -2189,7 +2190,7 @@ function TodolistView(props) {
2189
2190
  marginLeft: indent * 24 + 'px',
2190
2191
  justifyContent: align[component.state.slot.getAttribute(textAlignAttr)],
2191
2192
  textAlign: component.state.slot.getAttribute(textAlignAttr) === 'justify' ? 'justify' : void 0
2192
- }, children: [jsxRuntime.jsx("div", { class: "xnote-todolist-icon", onClick: toggle, children: jsxRuntime.jsx("span", { "data-checked": checked, class: [checked ? 'xnote-icon-checkbox-checked' : 'xnote-icon-checkbox-unchecked'] }) }), jsxRuntime.jsx(SlotRender, { slot: slot, tag: 'div', class: 'xnote-todolist-content', renderEnv: readonly() || output() })] }));
2193
+ }, children: [jsxRuntime.jsx("div", { class: "xnote-todolist-icon", onClick: toggle, children: jsxRuntime.jsx("span", { "data-checked": checked, class: [checked ? 'xnote-icon-checkbox-checked' : 'xnote-icon-checkbox-unchecked'] }) }), jsxRuntime.jsx(SlotRender, { slot: slot, tag: "div", class: "xnote-todolist-content", renderEnv: readonly() || output() })] }));
2193
2194
  };
2194
2195
  }
2195
2196
  const todolistComponentLoader = {
@@ -2465,7 +2466,7 @@ function ListComponentView(props) {
2465
2466
  }, children: [jsxRuntime.jsx("div", { class: "xnote-list-type", children: (component.state.type === 'UnorderedList' || readonly() || output()) ?
2466
2467
  jsxRuntime.jsx("span", { class: "xnote-order-btn", children: icon })
2467
2468
  :
2468
- jsxRuntime.jsx(Dropdown, { menu: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(MenuItem, { onClick: () => reorder(false), children: "\u7EE7\u7EED\u7F16\u53F7" }), jsxRuntime.jsx(MenuItem, { onClick: () => reorder(true), children: "\u91CD\u65B0\u7F16\u53F7" })] }), children: jsxRuntime.jsx(Button, { style: { color: 'inherit' }, children: icon }) }) }), jsxRuntime.jsx(SlotRender, { slot: component.state.slot, class: 'xnote-list-content', renderEnv: readonly() || output() })] }) }));
2469
+ jsxRuntime.jsx(Dropdown, { menu: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(MenuItem, { onClick: () => reorder(false), children: "\u7EE7\u7EED\u7F16\u53F7" }), jsxRuntime.jsx(MenuItem, { onClick: () => reorder(true), children: "\u91CD\u65B0\u7F16\u53F7" })] }), children: jsxRuntime.jsx(Button, { style: { color: 'inherit' }, children: icon }) }) }), jsxRuntime.jsx(SlotRender, { slot: component.state.slot, class: "xnote-list-content", renderEnv: readonly() || output() })] }) }));
2469
2470
  };
2470
2471
  }
2471
2472
  const listComponentLoader = {
@@ -3502,16 +3503,13 @@ function LinkTool(props) {
3502
3503
  const editorService = core.inject(exports.EditorService);
3503
3504
  const container = core.inject(platformBrowser.VIEW_CONTAINER);
3504
3505
  const isShow = core.createSignal(false);
3505
- const inputRef = core.createRef();
3506
+ const value = core.createSignal('');
3506
3507
  function setLink(ev) {
3507
3508
  ev.preventDefault();
3508
- const value = inputRef.current.value;
3509
- if (value) {
3510
- commander.applyFormat(linkFormatter, {
3511
- href: value,
3512
- target: '_blanK'
3513
- });
3514
- }
3509
+ commander.applyFormat(linkFormatter, {
3510
+ href: value(),
3511
+ target: '_blanK'
3512
+ });
3515
3513
  isShow.set(false);
3516
3514
  }
3517
3515
  let isClickFromSelf = false;
@@ -3540,7 +3538,9 @@ function LinkTool(props) {
3540
3538
  }, children: jsxRuntime.jsx("span", { class: "xnote-icon-link" }) }), isShow() &&
3541
3539
  jsxRuntime.jsx(Popup, { left: rect.left - containerRect.left, top: rect.top + rect.height - containerRect.top, children: jsxRuntime.jsxs("form", { onSubmit: setLink, onClick: () => {
3542
3540
  isClickFromSelf = true;
3543
- }, class: "input-group", children: [jsxRuntime.jsx("input", { ref: inputRef, placeholder: "\u8BF7\u8F93\u5165\u94FE\u63A5\u5730\u5740", type: "text" }), jsxRuntime.jsx(Button, { type: "submit", children: "\u786E\u5B9A" })] }) })] }));
3541
+ }, class: "input-group", children: [jsxRuntime.jsx("input", { onChange: ev => {
3542
+ value.set(ev.target.value);
3543
+ }, placeholder: "\u8BF7\u8F93\u5165\u94FE\u63A5\u5730\u5740", type: "text" }), jsxRuntime.jsx(Button, { type: "submit", children: "\u786E\u5B9A" })] }) })] }));
3544
3544
  });
3545
3545
  }
3546
3546
 
@@ -3840,6 +3840,78 @@ const katexComponentLoader = {
3840
3840
  }
3841
3841
  };
3842
3842
 
3843
+ function createTimelineItem(textbus, theme) {
3844
+ const slot = new core$1.Slot([
3845
+ core$1.ContentType.BlockComponent,
3846
+ ]);
3847
+ const title = new ParagraphComponent(textbus);
3848
+ title.state.slot.insert('时间主题', [
3849
+ [fontSizeFormatter, '18px'],
3850
+ [boldFormatter, true]
3851
+ ]);
3852
+ title.state.slot.insert(' 2020-02-02', [
3853
+ [fontSizeFormatter, '15px'],
3854
+ [colorFormatter, '#777']
3855
+ ]);
3856
+ const desc = new ParagraphComponent(textbus);
3857
+ desc.state.slot.insert('描述信息...');
3858
+ slot.insert(title);
3859
+ slot.insert(desc);
3860
+ return { theme, slot };
3861
+ }
3862
+ class TimelineComponent extends core$1.Component {
3863
+ static fromJSON(textbus, json) {
3864
+ const registry = textbus.get(core$1.Registry);
3865
+ return new TimelineComponent(textbus, {
3866
+ items: json.items.map(i => {
3867
+ return {
3868
+ theme: i.theme,
3869
+ slot: registry.createSlot(i.slot)
3870
+ };
3871
+ })
3872
+ });
3873
+ }
3874
+ getSlots() {
3875
+ return this.state.items.map(i => i.slot);
3876
+ }
3877
+ }
3878
+ TimelineComponent.componentName = 'TimelineComponent';
3879
+ TimelineComponent.type = core$1.ContentType.BlockComponent;
3880
+
3881
+ function createStepItem(textbus) {
3882
+ const slot = new core$1.Slot([
3883
+ core$1.ContentType.BlockComponent
3884
+ ]);
3885
+ const title = new ParagraphComponent(textbus);
3886
+ title.state.slot.insert('标题', [
3887
+ [fontSizeFormatter, '18px'],
3888
+ [boldFormatter, true]
3889
+ ]);
3890
+ const content = new ParagraphComponent(textbus);
3891
+ content.state.slot.insert('描述信息...');
3892
+ slot.insert(title);
3893
+ slot.insert(content);
3894
+ return { slot };
3895
+ }
3896
+ class StepComponent extends core$1.Component {
3897
+ static fromJSON(textbus, json) {
3898
+ const registry = textbus.get(core$1.Registry);
3899
+ return new StepComponent(textbus, {
3900
+ step: json.step,
3901
+ items: json.items.map(i => {
3902
+ return {
3903
+ slot: registry.createSlot(i.slot)
3904
+ };
3905
+ })
3906
+ });
3907
+ }
3908
+ getSlots() {
3909
+ return this.state.items.map(i => i.slot);
3910
+ }
3911
+ }
3912
+ StepComponent.componentName = 'StepComponent';
3913
+ StepComponent.type = core$1.ContentType.BlockComponent;
3914
+
3843
3915
  function InsertTool(props) {
3844
3916
  const commander = core.inject(core$1.Commander);
3845
3917
  const selection = core.inject(core$1.Selection);
@@ -3979,10 +4051,28 @@ function InsertTool(props) {
3979
4051
  selection.selectComponent(comp);
3980
4052
  }
3981
4053
  break;
4054
+ case 'step':
4055
+ {
4056
+ const step = new StepComponent(textbus, {
4057
+ step: 0,
4058
+ items: [createStepItem(textbus)]
4059
+ });
4060
+ insertComponent(step);
4061
+ selection.selectFirstPosition(step, false, true);
4062
+ }
4063
+ break;
4064
+ case 'timeline': {
4065
+ const timeline = new TimelineComponent(textbus, {
4066
+ items: [createTimelineItem(textbus, '#296eff')]
4067
+ });
4068
+ insertComponent(timeline);
4069
+ selection.selectFirstPosition(timeline, false, true);
4070
+ break;
4071
+ }
3982
4072
  }
3983
4073
  }
3984
4074
  return scopedCss.withScopedCSS(scopedId$9, () => {
3985
- return jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [props.hideTitle ? null : jsxRuntime.jsx(MenuHeading, { children: props.replace ? '替换为' : '在下面添加' }), jsxRuntime.jsxs("div", { class: "btn-group", children: [jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('paragraph'), children: jsxRuntime.jsx("span", { class: "xnote-icon-pilcrow" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('h1'), children: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h1" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('h2'), children: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h2" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('h3'), children: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h3" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('h4'), children: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h4" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('h5'), children: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h5" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('h6'), children: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h6" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('ol'), children: jsxRuntime.jsx("span", { class: "xnote-icon-list-numbered" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('ul'), children: jsxRuntime.jsx("span", { class: "xnote-icon-list" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('sourceCode'), children: jsxRuntime.jsx("span", { class: "xnote-icon-source-code" }) })] }), jsxRuntime.jsx(Divider, {}), jsxRuntime.jsx(MenuItem, { onClick: () => insert('table'), icon: jsxRuntime.jsx("span", { class: "xnote-icon-table" }), children: "\u8868\u683C" }), jsxRuntime.jsx(MenuItem, { onClick: () => insert('todolist'), icon: jsxRuntime.jsx("span", { class: "xnote-icon-checkbox-checked" }), children: "\u5F85\u529E\u5217\u8868" }), jsxRuntime.jsx(MenuItem, { onClick: () => insert('image'), icon: jsxRuntime.jsx("span", { class: "xnote-icon-image" }), children: "\u56FE\u7247" }), jsxRuntime.jsx(MenuItem, { onClick: () => insert('video'), icon: jsxRuntime.jsx("span", { class: "xnote-icon-video" }), children: "\u89C6\u9891" }), jsxRuntime.jsx(MenuItem, { onClick: () => insert('highlightBox'), icon: jsxRuntime.jsx("span", { class: "xnote-icon-hightlight-box" }), children: "\u9AD8\u4EAE\u5757" }), jsxRuntime.jsx(MenuItem, { onClick: () => insert('katex'), icon: jsxRuntime.jsx("span", { class: "xnote-icon-function" }), children: "\u6570\u5B66\u516C\u5F0F" })] });
4075
+ return jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [props.hideTitle ? null : jsxRuntime.jsx(MenuHeading, { children: props.replace ? '替换为' : '在下面添加' }), jsxRuntime.jsxs("div", { class: "btn-group", children: [jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('paragraph'), children: jsxRuntime.jsx("span", { class: "xnote-icon-pilcrow" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('h1'), children: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h1" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('h2'), children: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h2" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('h3'), children: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h3" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('h4'), children: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h4" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('h5'), children: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h5" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('h6'), children: jsxRuntime.jsx("span", { class: "xnote-icon-heading-h6" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('ol'), children: jsxRuntime.jsx("span", { class: "xnote-icon-list-numbered" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('ul'), children: jsxRuntime.jsx("span", { class: "xnote-icon-list" }) }), jsxRuntime.jsx(Button, { ordinary: true, onClick: () => insert('sourceCode'), children: jsxRuntime.jsx("span", { class: "xnote-icon-source-code" }) })] }), jsxRuntime.jsx(Divider, {}), jsxRuntime.jsx(MenuItem, { onClick: () => insert('table'), icon: jsxRuntime.jsx("span", { class: "xnote-icon-table" }), children: "\u8868\u683C" }), jsxRuntime.jsx(MenuItem, { onClick: () => insert('todolist'), icon: jsxRuntime.jsx("span", { class: "xnote-icon-checkbox-checked" }), children: "\u5F85\u529E\u5217\u8868" }), jsxRuntime.jsx(MenuItem, { onClick: () => insert('image'), icon: jsxRuntime.jsx("span", { class: "xnote-icon-image" }), children: "\u56FE\u7247" }), jsxRuntime.jsx(MenuItem, { onClick: () => insert('video'), icon: jsxRuntime.jsx("span", { class: "xnote-icon-video" }), children: "\u89C6\u9891" }), jsxRuntime.jsx(MenuItem, { onClick: () => insert('highlightBox'), icon: jsxRuntime.jsx("span", { class: "xnote-icon-hightlight-box" }), children: "\u9AD8\u4EAE\u5757" }), jsxRuntime.jsx(MenuItem, { onClick: () => insert('katex'), icon: jsxRuntime.jsx("span", { class: "xnote-icon-function" }), children: "\u6570\u5B66\u516C\u5F0F" }), jsxRuntime.jsx(MenuItem, { onClick: () => insert('step'), icon: jsxRuntime.jsx("span", { class: "xnote-icon-step" }), children: "\u6B65\u9AA4\u6761" }), jsxRuntime.jsx(MenuItem, { onClick: () => insert('timeline'), icon: jsxRuntime.jsx("span", { class: "xnote-icon-timeline" }), children: "\u65F6\u95F4\u8F74" })] });
3986
4076
  });
3987
4077
  }
3988
4078
 
@@ -4704,7 +4794,7 @@ function AtComponentView(props) {
4704
4794
  return (jsxRuntime.jsxs("div", { class: "xnote-at xnote-at-complete", "data-info": encodeURIComponent(JSON.stringify(userInfo)), ref: props.rootRef, "data-component": props.component.name, children: [jsxRuntime.jsx("span", { children: "@" }), userInfo.name] }));
4705
4795
  }
4706
4796
  if (readonly() || output()) {
4707
- return (jsxRuntime.jsxs("div", { class: "xnote-at", ref: props.rootRef, "data-component": props.component.name, children: [jsxRuntime.jsx("span", { children: "@" }), slot && jsxRuntime.jsx(SlotRender, { slot: slot, class: 'xnote-at-input', tag: "span" })] }));
4797
+ return (jsxRuntime.jsxs("div", { class: "xnote-at", ref: props.rootRef, "data-component": props.component.name, children: [jsxRuntime.jsx("span", { children: "@" }), slot && jsxRuntime.jsx(SlotRender, { slot: slot, class: "xnote-at-input", tag: "span" })] }));
4708
4798
  }
4709
4799
  const members = props.component.members();
4710
4800
  return (jsxRuntime.jsx("div", { class: "xnote-at", ref: props.rootRef, "data-component": props.component.name, children: jsxRuntime.jsxs(Dropdown, { trigger: 'none', ref: dropdownRef, menu: jsxRuntime.jsx("div", { class: "xnote-at-menu", ref: membersRef, children: members.map((member, index) => {
@@ -4720,7 +4810,7 @@ function AtComponentView(props) {
4720
4810
  selection.selectComponentEnd(props.component);
4721
4811
  }, class: ['xnote-at-member', { selected: index === selectedIndex }], children: [jsxRuntime.jsx("div", { class: "xnote-at-member-avatar", children: member.avatar ? jsxRuntime.jsx("img", { src: member.avatar, alt: member.name }) :
4722
4812
  jsxRuntime.jsx("span", { class: "xnote-at-member-avatar-bg", style: { background: member.color, color: color$1 }, children: member.name }) }), jsxRuntime.jsxs("div", { class: "xnote-at-member-info", children: [jsxRuntime.jsx("div", { class: "xnote-at-member-name", children: member.name }), jsxRuntime.jsx("div", { class: "xnote-at-member-desc", children: member.groupName })] })] }, member.id));
4723
- }) }), children: [jsxRuntime.jsx("span", { children: "@" }), slot && jsxRuntime.jsx(SlotRender, { slot: slot, tag: 'span', class: 'xnote-at-input' })] }) }));
4813
+ }) }), children: [jsxRuntime.jsx("span", { children: "@" }), slot && jsxRuntime.jsx(SlotRender, { slot: slot, tag: "span", class: "xnote-at-input" })] }) }));
4724
4814
  };
4725
4815
  }
4726
4816
  const atComponentLoader = {
@@ -5061,17 +5151,15 @@ function Scroll(props) {
5061
5151
  draft.rightEnd = el.scrollLeft === el.scrollWidth - el.offsetWidth;
5062
5152
  });
5063
5153
  }
5064
- setTimeout(update);
5154
+ update();
5065
5155
  const s = core$1.fromEvent(el, 'scroll').subscribe(update);
5066
5156
  return () => s.unsubscribe();
5067
5157
  });
5068
5158
  core.onUpdated(() => {
5069
5159
  const el = scrollRef.current;
5070
- setTimeout(() => {
5071
- updateShowShadow(draft => {
5072
- draft.leftEnd = el.scrollLeft === 0;
5073
- draft.rightEnd = el.scrollLeft === el.scrollWidth - el.offsetWidth;
5074
- });
5160
+ updateShowShadow(draft => {
5161
+ draft.leftEnd = el.scrollLeft === 0;
5162
+ draft.rightEnd = el.scrollLeft === el.scrollWidth - el.offsetWidth;
5075
5163
  });
5076
5164
  });
5077
5165
  return scopedCss.withScopedCSS(scopedId$3, () => {
@@ -5621,6 +5709,112 @@ function finedPosition(component, slot) {
5621
5709
  return null;
5622
5710
  }
5623
5711
 
5712
+ function TimelineComponentView(props) {
5713
+ const adapter = core.inject(platformBrowser.DomAdapter);
5714
+ const textbus = core.inject(core$1.Textbus);
5715
+ const isOutput = useOutput();
5716
+ const isReadonly = useReadonly();
5717
+ return () => {
5718
+ const component = props.component;
5719
+ return (jsxRuntime.jsx("div", { class: "xnote-timeline", ref: props.rootRef, "data-component": TimelineComponent.componentName, children: component.state.items.map(item => {
5720
+ return (jsxRuntime.jsxs("div", { class: "xnote-timeline-item", children: [jsxRuntime.jsx("div", { class: "xnote-timeline-line", style: {
5721
+ borderColor: item.theme,
5722
+ } }), jsxRuntime.jsx("div", { class: "xnote-timeline-icon", style: {
5723
+ borderColor: item.theme,
5724
+ backgroundColor: item.theme,
5725
+ } }), !isOutput() && !isReadonly() && jsxRuntime.jsxs("div", { class: "xnote-timeline-tools", children: [jsxRuntime.jsx(Button, { class: "xnote-timeline-add xnote-icon-plus", onClick: () => {
5726
+ const index = component.state.items.indexOf(item) + 1;
5727
+ component.state.items.splice(index, 0, createTimelineItem(textbus, item.theme));
5728
+ } }), jsxRuntime.jsx(Button, { class: "xnote-timeline-add xnote-icon-bin", onClick: () => {
5729
+ const index = component.state.items.indexOf(item);
5730
+ component.state.items.splice(index, 1);
5731
+ } })] }), adapter.slotRender(item.slot, children => {
5732
+ return core$1.createVNode('div', {
5733
+ class: 'xnote-timeline-item-content',
5734
+ }, children);
5735
+ }, isOutput() || isReadonly())] }, item.slot.id));
5736
+ }) }));
5737
+ };
5738
+ }
5739
+ const timelineComponentLoader = {
5740
+ match(element) {
5741
+ return element.className === 'xnote-timeline';
5742
+ },
5743
+ read(element, context, slotParser) {
5744
+ return new TimelineComponent(context, {
5745
+ items: Array.from(element.children).map(child => {
5746
+ const slot = new core$1.Slot([
5747
+ core$1.ContentType.BlockComponent
5748
+ ]);
5749
+ return {
5750
+ theme: '',
5751
+ slot: slotParser(slot, child.querySelector('div.xnote-timeline-content') || document.createElement('div'))
5752
+ };
5753
+ })
5754
+ });
5755
+ }
5756
+ };
5757
+
5758
+ function StepComponentView(props) {
5759
+ const adapter = core.inject(platformBrowser.DomAdapter);
5760
+ const textbus = core.inject(core$1.Textbus);
5761
+ const isOutput = useOutput();
5762
+ const isReadonly = useReadonly();
5763
+ return () => {
5764
+ const component = props.component;
5765
+ const currentStep = component.state.step;
5766
+ return (jsxRuntime.jsx("div", { class: "xnote-step", "data-step": currentStep, ref: props.rootRef, "data-component": StepComponent.componentName, children: component.state.items.map((item, index) => {
5767
+ let state = 'xnote-waiting';
5768
+ if (index < currentStep) {
5769
+ state = 'xnote-complete';
5770
+ }
5771
+ else if (index === currentStep) {
5772
+ state = 'xnote-current';
5773
+ }
5774
+ return (jsxRuntime.jsxs("div", { class: 'xnote-step-item ' + state, children: [jsxRuntime.jsxs("div", { class: "xnote-step-item-header", children: [jsxRuntime.jsx("div", { class: "xnote-step-item-line" }), jsxRuntime.jsx("div", { class: "xnote-step-item-icon", onClick: () => {
5775
+ if (index === currentStep) {
5776
+ component.state.step = index + 1;
5777
+ }
5778
+ else if (index + 1 === currentStep) {
5779
+ component.state.step = index - 1;
5780
+ }
5781
+ else {
5782
+ component.state.step = index;
5783
+ }
5784
+ }, children: index + 1 })] }), !isOutput() && !isReadonly() && jsxRuntime.jsxs("div", { class: "xnote-step-tools", children: [jsxRuntime.jsx(Button, { class: "xnote-step-add xnote-icon-plus", onClick: () => {
5785
+ const index = component.state.items.indexOf(item) + 1;
5786
+ component.state.items.splice(index, 0, createStepItem(textbus));
5787
+ } }), jsxRuntime.jsx(Button, { class: "xnote-step-add xnote-icon-bin", onClick: () => {
5788
+ const index = component.state.items.indexOf(item);
5789
+ component.state.items.splice(index, 1);
5790
+ } })] }), adapter.slotRender(item.slot, children => {
5791
+ return core$1.createVNode('div', {
5792
+ class: 'xnote-step-item-content'
5793
+ }, children);
5794
+ }, isOutput() || isReadonly())] }, item.slot.id));
5795
+ }) }));
5796
+ };
5797
+ }
5798
+ const stepComponentLoader = {
5799
+ match(element) {
5800
+ return element.dataset.component === StepComponent.componentName;
5801
+ },
5802
+ read(element, context, slotParser) {
5803
+ return new StepComponent(context, {
5804
+ step: Number(element.dataset.step) || 0,
5805
+ items: Array.from(element.children).map(child => {
5806
+ const slot = new core$1.Slot([
5807
+ core$1.ContentType.BlockComponent
5808
+ ]);
5809
+ return {
5810
+ slot: slotParser(slot, child.querySelector('.xnote-step-item-content') ||
5811
+ document.createElement('div'))
5812
+ };
5813
+ })
5814
+ });
5815
+ }
5816
+ };
5817
+
5624
5818
  class Editor extends core$1.Textbus {
5625
5819
  constructor(editorConfig = {}) {
5626
5820
  const adapter = new adapterViewfly.ViewflyAdapter({
@@ -5636,6 +5830,8 @@ class Editor extends core$1.Textbus {
5636
5830
  [VideoComponent.componentName]: VideoView,
5637
5831
  [AtComponent.componentName]: AtComponentView,
5638
5832
  [KatexComponent.componentName]: KatexComponentView,
5833
+ [StepComponent.componentName]: StepComponentView,
5834
+ [TimelineComponent.componentName]: TimelineComponentView,
5639
5835
  }, (host, root, injector) => {
5640
5836
  const appInjector = new core.ReflectiveInjector(injector, [{
5641
5837
  provide: OutputInjectionToken,
@@ -5662,6 +5858,8 @@ class Editor extends core$1.Textbus {
5662
5858
  todolistComponentLoader,
5663
5859
  katexComponentLoader,
5664
5860
  paragraphComponentLoader,
5861
+ stepComponentLoader,
5862
+ timelineComponentLoader
5665
5863
  ], formatLoaders: [
5666
5864
  backgroundColorFormatLoader,
5667
5865
  boldFormatLoader,
@@ -5698,7 +5896,9 @@ class Editor extends core$1.Textbus {
5698
5896
  [ImageComponent.componentName]: ImageView,
5699
5897
  [VideoComponent.componentName]: VideoView,
5700
5898
  [AtComponent.componentName]: AtComponentView,
5701
- [KatexComponent.componentName]: KatexComponentView
5899
+ [KatexComponent.componentName]: KatexComponentView,
5900
+ [StepComponent.componentName]: StepComponentView,
5901
+ [TimelineComponent.componentName]: TimelineComponentView,
5702
5902
  }, (host, root, injector) => {
5703
5903
  const appInjector = new core.ReflectiveInjector(injector, [{
5704
5904
  provide: OutputInjectionToken,
@@ -5729,7 +5929,9 @@ class Editor extends core$1.Textbus {
5729
5929
  ListComponent,
5730
5930
  VideoComponent,
5731
5931
  AtComponent,
5732
- KatexComponent
5932
+ KatexComponent,
5933
+ StepComponent,
5934
+ TimelineComponent
5733
5935
  ], formatters: [
5734
5936
  backgroundColorFormatter,
5735
5937
  boldFormatter,
@@ -5748,7 +5950,19 @@ class Editor extends core$1.Textbus {
5748
5950
  ], plugins: [
5749
5951
  new LeftToolbarPlugin(),
5750
5952
  new ToolbarPlugin(),
5751
- ], onAfterStartup(textbus) {
5953
+ ], setup(textbus) {
5954
+ if (editorConfig.collaborateConfig) {
5955
+ const activity = textbus.get(collaborate.UserActivity);
5956
+ const collabCursor = textbus.get(platformBrowser.CollaborateCursor);
5957
+ const sub = activity.onStateChange.subscribe(ev => {
5958
+ collabCursor.draw(ev);
5959
+ });
5960
+ return () => {
5961
+ sub.unsubscribe();
5962
+ };
5963
+ }
5964
+ },
5965
+ onAfterStartup(textbus) {
5752
5966
  registerBoldShortcut(textbus);
5753
5967
  registerCodeShortcut(textbus);
5754
5968
  registerItalicShortcut(textbus);
@@ -0,0 +1,6 @@
1
+ import { ViewComponentProps } from '@textbus/adapter-viewfly';
2
+ import { ComponentLoader } from '@textbus/platform-browser';
3
+ import { StepComponent } from './step.component';
4
+ import './step.component.scss';
5
+ export declare function StepComponentView(props: ViewComponentProps<StepComponent>): () => any;
6
+ export declare const stepComponentLoader: ComponentLoader;
@@ -0,0 +1,15 @@
1
+ import { Component, ComponentStateLiteral, ContentType, Slot, Textbus } from '@textbus/core';
2
+ export interface StepComponentItem {
3
+ slot: Slot;
4
+ }
5
+ export interface StepComponentState {
6
+ step: number;
7
+ items: StepComponentItem[];
8
+ }
9
+ export declare function createStepItem(textbus: Textbus): StepComponentItem;
10
+ export declare class StepComponent extends Component<StepComponentState> {
11
+ static componentName: string;
12
+ static type: ContentType;
13
+ static fromJSON(textbus: Textbus, json: ComponentStateLiteral<StepComponentState>): StepComponent;
14
+ getSlots(): Slot[];
15
+ }
@@ -0,0 +1,6 @@
1
+ import { ViewComponentProps } from '@textbus/adapter-viewfly';
2
+ import { ComponentLoader } from '@textbus/platform-browser';
3
+ import { TimelineComponent } from './timeline.component';
4
+ import './timeline.component.scss';
5
+ export declare function TimelineComponentView(props: ViewComponentProps<TimelineComponent>): () => any;
6
+ export declare const timelineComponentLoader: ComponentLoader;
@@ -0,0 +1,15 @@
1
+ import { Component, ComponentStateLiteral, ContentType, Slot, Textbus } from '@textbus/core';
2
+ export interface TimelineComponentItem {
3
+ theme: string;
4
+ slot: Slot;
5
+ }
6
+ export interface TimelineComponentState {
7
+ items: TimelineComponentItem[];
8
+ }
9
+ export declare function createTimelineItem(textbus: Textbus, theme: string): TimelineComponentItem;
10
+ export declare class TimelineComponent extends Component<TimelineComponentState> {
11
+ static componentName: string;
12
+ static type: ContentType;
13
+ static fromJSON(textbus: Textbus, json: ComponentStateLiteral<TimelineComponentState>): TimelineComponent;
14
+ getSlots(): Slot[];
15
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@textbus/xnote",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "A high-performance rich text editor that supports multiplayer online collaboration.",
5
5
  "main": "./bundles/index.js",
6
6
  "module": "./bundles/index.esm.js",
@@ -27,10 +27,10 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@tanbo/color": "^0.1.1",
30
- "@textbus/adapter-viewfly": "^4.0.0",
31
- "@textbus/collaborate": "^4.0.0",
32
- "@textbus/core": "^4.0.0",
33
- "@textbus/platform-browser": "^4.0.0",
30
+ "@textbus/adapter-viewfly": "^4.0.2",
31
+ "@textbus/collaborate": "^4.0.2",
32
+ "@textbus/core": "^4.0.1",
33
+ "@textbus/platform-browser": "^4.0.2",
34
34
  "@viewfly/core": "^1.0.0-alpha.22",
35
35
  "@viewfly/hooks": "^1.0.0-alpha.22",
36
36
  "@viewfly/platform-browser": "^1.0.0-alpha.22",