Browse Source

text editor

bianjiang 1 năm trước cách đây
mục cha
commit
86b9eed482

+ 14 - 17
src/modules/editor/components/CompUI/basicUI/Text/TextToolbar.tsx

@@ -9,11 +9,11 @@ import { DesignComp } from "@/modules/editor/objects/DesignTemp/DesignComp";
 import { LinkOutlined } from "@ant-design/icons-vue";
 
 import { css } from "@linaria/core";
-import { Button, Divider } from "ant-design-vue";
+import { Divider } from "ant-design-vue";
 import { defineComponent } from "vue";
 import { any } from "vue-types";
 
-import ToolbarsUI from "./TextToolbarUI";
+import TextToolbarsUI from "./TextToolbarUI";
 import {
   AlignComp,
   FontFamily,
@@ -127,6 +127,10 @@ export const TextToolbar = defineComponent({
         component: (props: any) => (
           <LinkButton icon={<LinkOutlined />} {...props} />
         ),
+        changeExtra: (record: any) => {
+          record.value = record.value.value;
+          return record;
+        },
         itemProps: {
           class: "!mx-2px",
         },
@@ -142,30 +146,23 @@ export const TextToolbar = defineComponent({
     ];
     const changeVal = (e: { dataIndex: string; value: any }) => {
       const editor = controls.textEditor;
-      console.log(e);
       if (!editor) {
         return;
       }
-      // const command = editor ? editor.commands.get(e.dataIndex) : null;
-      // console.log(e, command);
-
-      if (e.dataIndex == "link") {
-        editor.execute(e.dataIndex, e.value);
-      } else {
-        editor.execute(e.dataIndex, { value: e.value });
-      }
-      editor.editing.view.focus();
-
-      // const command =  editor.commands.get(e.commandName)
-      // actions.updateCompData(props.component, e.dataIndex, e.value);
+      editor.execute(e.dataIndex, e.value);
+      console.log("change", e);
+      setTimeout(() => {
+        const selection = window.getSelection();
+        selection?.removeAllRanges();
+        editor.editing.view.focus();
+      }, 100);
     };
     return () => {
       const { component } = props;
       return (
         <div class={[TextToolbarStyle, "flex items-center"]} id="text_toolbar">
-          <ToolbarsUI
+          <TextToolbarsUI
             editor={controls.textEditor}
-            data={component}
             columns={toolbarColumns}
             onChange={changeVal}
           />

+ 91 - 97
src/modules/editor/components/CompUI/basicUI/Text/TextToolbarUI.tsx

@@ -1,32 +1,23 @@
-import { css, cx } from "@linaria/core";
+import { css } from "@linaria/core";
 import { Tooltip } from "ant-design-vue";
-import _ from "lodash";
-import { computed, defineComponent } from "vue";
-import { any, array, bool, func } from "vue-types";
+import { defineComponent, reactive, onMounted, onUnmounted } from "vue";
+import { any, array, func, number, object } from "vue-types";
 
 export interface ColumnItem {
   label?: string;
   component?: ((...args: any[]) => any) | Record<string, any>;
   dataIndex?: string;
-  setterIndex?: string;
   props?: { [name: string]: any };
   itemProps?: { [name: string]: any };
-  getValue?: (v: any, data?: any) => any;
-  isDisable?: (value: any, data: any) => boolean;
-  isLoading?: (value: any, data: any) => boolean;
-  isVisible?: (value: any, data: any) => boolean;
   changeExtra?: (data: any) => any;
-  children?: ColumnItem[];
 }
 
 export default defineComponent({
   props: {
     columns: array<ColumnItem>().isRequired,
     editor: any(),
-    data: any().isRequired,
-    disabled: bool(),
+    data: any(),
     onChange: func(),
-    onChangeEnd: func(),
   },
   setup(props) {
     return () => <FormUI {...props} />;
@@ -35,11 +26,8 @@ export default defineComponent({
 
 const FormUI = (props: {
   columns: ColumnItem[];
-  data: any;
   editor: any;
-  disabled?: boolean;
   onChange?: (...arg: any) => void;
-  onChangeEnd?: (...arg: any) => void;
 }) => {
   const { columns, ...restProps } = props;
   return (
@@ -48,7 +36,7 @@ const FormUI = (props: {
         if (!column.dataIndex) {
           return renderUI({ props: restProps, column, index });
         }
-        return renderFormItem({ column, ...restProps, index });
+        return <RenderFormItem column={column} index={index} {...restProps} />;
       })}
     </>
   );
@@ -73,89 +61,95 @@ const renderUI = ({ props, column, index }: any) => {
   }
 };
 
-export const renderFormItem = (props: {
-  column: ColumnItem;
-  index?: number;
-  data: any;
-  editor: any;
-  disabled?: boolean;
-  onChange?: (...arg: any) => void;
-  onChangeEnd?: (...arg: any) => void;
-}) => {
-  const { column, data, index, onChange, onChangeEnd } = props;
-
-  // const compValue = computed(() => {
-  //   const { data, column } = props;
-  //   if (!column.dataIndex) return;
-  //   const itemValue = _.get(data, column.dataIndex);
-  //   return column.getValue ? column.getValue(itemValue) : itemValue;
-  // });
-
-  const editor = props.editor;
-  const compValue = editor ? editor.commands.get(column.dataIndex) : "";
-  // console.log(column.dataIndex, compValue.value);
-
-  // const compValue = computed(() => {
-  //   const { data, column } = props;
-  //   if (!column.dataIndex) return;
-  //   const itemValue = _.get(data, column.dataIndex);
-  //   return column.getValue ? column.getValue(itemValue, data) : itemValue;
-  // });
-
-  const changeVal = (value: any, ...args: any[]) => {
-    const { column } = props;
-    let params = {
-      dataIndex: column.dataIndex,
-      setterIndex: column.setterIndex,
-      value,
-      ...args,
+export const RenderFormItem = defineComponent({
+  props: {
+    column: object<ColumnItem>(),
+    index: number(),
+    editor: any(),
+    onChange: func(),
+    onChangeEnd: func(),
+  },
+  setup(props) {
+    const state = reactive({
+      value: undefined,
+    });
+    function handleValueChange() {
+      const { column, editor } = props;
+      const command = editor ? editor.commands.get(column?.dataIndex) : "";
+      if (command) {
+        console.log("change==>", column?.dataIndex, state.value);
+        state.value = command.value;
+      }
+    }
+    const initCommands = () => {
+      const { column, editor } = props;
+      const command = editor ? editor.commands.get(column?.dataIndex) : "";
+      if (command) {
+        state.value = command.value;
+
+        command.on("change:value", handleValueChange);
+      }
+    };
+    onMounted(() => {
+      initCommands();
+    });
+    onUnmounted(() => {
+      const { column, editor } = props;
+      const command = editor ? editor.commands.get(column?.dataIndex) : "";
+      if (command) {
+        command.off("change:value", handleValueChange);
+      }
+    });
+
+    const changeVal = (value: any, ...args: any[]) => {
+      const { column } = props;
+      let params = {
+        dataIndex: column?.dataIndex,
+        value: { value },
+        ...args,
+      };
+      if (column?.changeExtra) params = column.changeExtra?.(params);
+      props.onChange?.(params);
+      return params;
     };
-    if (column.changeExtra) params = column.changeExtra?.(params);
-    onChange?.(params);
-    return params;
-  };
-
-  const changeValEnd = (value: any, ...args: any[]) => {
-    const params = changeVal(value, ...args);
-    onChangeEnd?.(params);
-  };
-
-  // const isVisible = column.isVisible?.(compValue.value, data);
-  // if (column.isVisible && !isVisible) return null;
-
-  // const disabled = props.disabled || column.isDisable?.(compValue.value, data);
 
-  const component = column.component;
+    const changeValEnd = (value: any, ...args: any[]) => {
+      const params = changeVal(value, ...args);
+      props.onChangeEnd?.(params);
+    };
 
-  return (
-    <div
-      key={index}
-      class={formItemStyles}
-      {...column.itemProps}
-      onClick={(e) => e.stopPropagation()}
-    >
-      {column.label ? (
-        <Tooltip title={column.label} placement="top">
-          <component
-            value={compValue.value}
-            {...column.props}
-            loading={column.isLoading?.(compValue.value, data)}
-            onChange={changeVal}
-            onChangeEnd={changeValEnd}
-          />
-        </Tooltip>
-      ) : (
-        <component
-          value={compValue.value}
-          {...column.props}
-          loading={column.isLoading?.(compValue.value, data)}
-          onChange={changeVal}
-          onChangeEnd={changeValEnd}
-        />
-      )}
-    </div>
-  );
-};
+    const component = props.column?.component || number;
+    return () => {
+      const { column, index } = props;
+      return (
+        <div
+          key={index}
+          class={formItemStyles}
+          {...column?.itemProps}
+          onClick={(e) => e.stopPropagation()}
+        >
+          {column?.label ? (
+            <Tooltip title={column.label} placement="top">
+              <component
+                value={state.value}
+                {...column.props}
+                onChange={changeVal}
+                onChangeEnd={changeValEnd}
+              />
+            </Tooltip>
+          ) : (
+            <component
+              value={state.value}
+              {...column?.props}
+              onChange={changeVal}
+              onChangeEnd={changeValEnd}
+            />
+          )}
+        </div>
+      );
+    };
+  },
+});
 
 const formItemStyles = css`
   height: 100%;

+ 56 - 42
src/modules/editor/components/CompUI/basicUI/Text/ToolbarComp.tsx

@@ -8,12 +8,12 @@ import {
 import { css } from "@linaria/core";
 import { Button, Dropdown, InputNumber, Menu, Tooltip } from "ant-design-vue";
 
+import Select from "@queenjs-modules/queditor/components/FormUI/Items/Select";
 import Pickr from "@simonwep/pickr";
 import "@simonwep/pickr/dist/themes/nano.min.css";
-import { defineComponent, onMounted, reactive, watch } from "vue";
-import { any, string } from "vue-types";
-import Select from "@queenjs-modules/queditor/components/FormUI/Items/Select";
 import { queenApi } from "queenjs";
+import { defineComponent, onMounted, ref, watch, onUnmounted } from "vue";
+import { any, bool, string } from "vue-types";
 
 export const TextColor = defineComponent({
   props: {
@@ -22,7 +22,7 @@ export const TextColor = defineComponent({
   emits: ["change"],
   setup(props, { emit }) {
     let picker: any = null;
-
+    let emitFlagRef = ref(true);
     function initPicker() {
       picker = Pickr.create({
         el: ".color_picker",
@@ -31,7 +31,6 @@ export const TextColor = defineComponent({
         i18n: {
           "btn:save": "确定",
         },
-        // swatches: defaultColor,
         components: {
           preview: true,
           opacity: false,
@@ -45,26 +44,32 @@ export const TextColor = defineComponent({
         },
       });
 
-      // picker.on("change", (color: any) => {
-      //   const hexa = color.toHEXA().toString();
-      //   console.log("change", hexa);
-      //   // emit("change", hexa);
-      // });
       picker.on("save", (color: any) => {
         picker.hide();
         const hexa = color.toHEXA().toString();
+        if (!emitFlagRef.value) {
+          emitFlagRef.value = true;
+          return;
+        }
         emit("change", hexa);
       });
     }
     watch(
       () => props.value,
       () => {
+        emitFlagRef.value = false;
         picker.setColor(props.value);
       }
     );
     onMounted(() => {
       initPicker();
     });
+    onUnmounted(() => {
+      if (picker) {
+        picker.destroy();
+        picker = null;
+      }
+    });
 
     return () => (
       <div
@@ -135,7 +140,12 @@ export const AlignComp = defineComponent({
       return item ? item.icon : null;
     };
     return () => (
-      <Dropdown overlay={overlay()} trigger={"click"} placement="bottom">
+      <Dropdown
+        overlay={overlay()}
+        overlayClassName={"editor_toolbar_drop"}
+        trigger={"click"}
+        placement="bottom"
+      >
         <Button type="text" icon={currIcon(props.value)}></Button>
       </Dropdown>
     );
@@ -170,7 +180,12 @@ export const LineHeightComp = defineComponent({
     };
 
     return () => (
-      <Dropdown overlay={overlay()} trigger={"click"} placement="bottom">
+      <Dropdown
+        overlay={overlay()}
+        overlayClassName={"editor_toolbar_drop"}
+        trigger={"click"}
+        placement="bottom"
+      >
         <Button type="text" icon={<IconLineHeight />}></Button>
       </Dropdown>
     );
@@ -180,22 +195,17 @@ export const LineHeightComp = defineComponent({
 export const FontStyleComp = defineComponent({
   props: {
     icon: any(),
-    value: any(),
+    value: bool().def(false),
   },
   emits: ["change"],
   setup(props, { emit }) {
-    const state = reactive({
-      isOn: props.value || false,
-    });
-
     const triggerStyle = () => {
-      state.isOn = !state.isOn;
-      emit("change", state.isOn);
+      emit("change", !props.value);
     };
     return () => (
       <Button
         type="text"
-        class={state.isOn ? currStyle : null}
+        class={props.value ? currStyle : null}
         icon={props.icon}
         onClick={triggerStyle}
       ></Button>
@@ -205,7 +215,7 @@ export const FontStyleComp = defineComponent({
 
 export const FontFamily = defineComponent({
   props: {
-    value: any(),
+    value: string().def(""),
   },
   emits: ["change"],
   setup(props, { emit }) {
@@ -216,34 +226,38 @@ export const FontFamily = defineComponent({
       { label: "仿宋", value: "仿宋,FangSong,STFangsong,serif" },
       { label: "楷体", value: "楷体,KaiTi,STKaiti,sans-serif" },
     ];
-    return () => (
-      <Select
-        options={options}
-        value={props.value || ""}
-        onChange={(v) => {
-          emit("change", v);
-        }}
-      ></Select>
-    );
+    return () => {
+      return (
+        <Select
+          options={options}
+          value={props.value || ""}
+          onChange={(v) => {
+            emit("change", v);
+          }}
+        ></Select>
+      );
+    };
   },
 });
 export const FontSize = defineComponent({
   props: {
-    value: any(),
+    value: string().def("12px"),
   },
   emits: ["change"],
   setup(props, { emit }) {
-    return () => (
-      <InputNumber
-        defaultValue={12}
-        min={12}
-        max={60}
-        value={parseInt(props.value) || 12}
-        onChange={(value: any) => {
-          emit("change", value + "px");
-        }}
-      />
-    );
+    return () => {
+      return (
+        <InputNumber
+          defaultValue={12}
+          min={12}
+          max={60}
+          value={parseInt(props.value) || 12}
+          onChange={(value: any) => {
+            emit("change", value + "px");
+          }}
+        />
+      );
+    };
   },
 });
 export const LinkButton = defineComponent({

+ 20 - 3
src/modules/editor/components/CompUI/basicUI/Text/component2.tsx

@@ -1,12 +1,11 @@
 import { useEditor } from "@/modules/editor";
-import HeadlessEditor from "./EditorCustom";
 import { css } from "@linaria/core";
 import { nextTick } from "process";
 import { defineComponent, onMounted, onUnmounted, reactive, ref } from "vue";
 import { string } from "vue-types";
 import { useCompData } from ".";
 import { View } from "../View";
-import { before } from "lodash";
+import HeadlessEditor from "./EditorCustom";
 
 export const Component = defineComponent({
   props: {
@@ -114,6 +113,25 @@ const EditorComp = defineComponent({
           out.stop = false;
           return out;
         }
+        const dropToolbars = document.querySelectorAll(".editor_toolbar_drop");
+        dropToolbars.forEach((e) => {
+          if (e === dom || e?.contains(dom)) {
+            out.in = true;
+            out.stop = false;
+            return out;
+          }
+        });
+        const selectToolbars = document.querySelectorAll(
+          ".ant-select-dropdown"
+        );
+        selectToolbars.forEach((e) => {
+          if (e === dom || e?.contains(dom)) {
+            out.in = true;
+            out.stop = false;
+            return out;
+          }
+        });
+
         const ckBodyWrapper = document.querySelector(".ck-body-wrapper");
         if (ckBodyWrapper === dom || ckBodyWrapper?.contains(dom)) {
           out.in = true;
@@ -193,7 +211,6 @@ const EditorComp = defineComponent({
             );
             helper.extendStreamCard(store.currStreamCardId);
             if (isChange) {
-              console.log("changing=>", isChange);
               actions.selectObjs([]);
               setTimeout(() => {
                 actions.selectObjs([props.compId]);