Kirby Editor attrs default values

Hello,

we have a new problem :smiley:
We are extending the kirby editor plugin with more elements to get more configurations for the frontend.
The problem is, that the “attrs” are not saving by default. The person who’s editing these elements, needs to open the “settings” for this element, save it again and only then the attrs are showing up correctly.

initial:
Text:

[
    {
        "attrs": [],
        "content": "normal text",
        "id": "_lsmv3q2kc",
        "type": "paragraph"
    },
    {
        "attrs": [],
        "content": "umgewandelt",
        "id": "_4sgs5g6km",
        "type": "extText"
    },
    {
        "attrs": [],
        "content": "extended text",
        "id": "_n84xih8n4",
        "type": "extText"
    }
]

after saving it for the second time, after opening the “settings” dialog.
Text:

[
    {
        "attrs": {
            "marginBottom": true,
            "mobile": true,
            "tablet": true,
            "desktop": true,
            "textAlign": "start",
            "fontSize": "default",
            "fontColor": "---"},
        "content": "normal text",
        "id": "_lsmv3q2kc",
        "type": "paragraph"
    },
    {
        "attrs": {
            "marginBottom": true,
            "mobile": true,
            "tablet": true,
            "desktop": true,
            "textAlign": "start",
            "fontSize": "default",
            "fontColor": "---"}
        "content": "umgewandelt",
        "id": "_4sgs5g6km",
        "type": "extText"
    },
    {
        "attrs": {
            "marginBottom": true,
            "mobile": true,
            "tablet": true,
            "desktop": true,
            "textAlign": "start",
            "fontSize": "default",
            "fontColor": "---"
        },
        "content": "extended text",
        "id": "_n84xih8n4",
        "type": "extText"
    }
]

php plugin file for extended text

    editor.block("extText", {
  label: "Text erweitert",
  icon: "text",
  props: {
    content: String,
    attrs: {
      type: Object,
      default() {
        return {
          "marginBottom": true,
          "mobile": true,
          "tablet": true,
          "desktop": true,
          "textAlign": "start",
          "fontSize": "default",
          "fontColor": "---"};
      },
    },
  },
  data() {
    if (typeof this.attrs.marginBottom === "undefined") {
      this.attrs.marginBottom = true;
    }
    if (typeof this.attrs.mobile === "undefined") {
      this.attrs.mobile = true;
    }
    if (typeof this.attrs.tablet === "undefined") {
      this.attrs.tablet = true;
    }
    if (typeof this.attrs.desktop === "undefined") {
      this.attrs.desktop = true;
    }
    if (typeof this.attrs.textAlign === "undefined") {
      this.attrs.textAlign = "start";
    }
    if (typeof this.attrs.fontSize === "undefined") {
      this.attrs.fontSize = "default";
    }
    if (typeof this.attrs.fontColor === "undefined") {
      this.attrs.fontColor = "---";
    }

    return {
      textAlign: this.attrs.textAlign,
      fontSize: this.attrs.fontSize,
      fontColor: this.attrs.fontColor,
    };
  },
  computed: {
    selectedTextAlign() {
      return this.selectedValue(
        this.$options.textAlignValues,
        this.textAlign,
        "Links"
      );
    },

    selectedFontSize() {
      return this.selectedValue(
        this.$options.fontSizeValues,
        this.fontSize,
        "Standard"
      );
    },

    selectedFontColor() {
      return this.selectedValue(
        this.$options.fontColorValues,
        this.fontColor,
        "---"
      );
    },
  },

  textAlignValues: [
    { id: "start", label: "Links" },
    { id: "center", label: "Zentriert" },
    { id: "end", label: "Rechts" },
    { id: "justify", label: "Block" },
  ],

  fontSizeValues: [
    { id: "smaller", label: "Kleiner" },
    { id: "default", label: "Standard" },
    { id: "bigger", label: "Größer" },
  ],

  fontColorValues: [
    { id: "---", label: "---" },
    { id: "primary", label: "Hauptfarbe" },
    { id: "secondary", label: "Zweitfarbe" },
    { id: "lightgray", label: "Hellgrau" },
    { id: "gray", label: "Grau" },
    { id: "darkgray", label: "Dunkelgrau" },
    { id: "success", label: "Erfolg" },
    { id: "info", label: "Info" },
    { id: "warning", label: "Warning" },
    { id: "error", label: "Error" },
    { id: "black", label: "Schwarz" },
    { id: "white", label: "Weiß" },
  ],

  methods: {
    indent(indent) {
      this.$emit("update", {
        attrs: {
          indent,
        },
      });
    },
    focus(cursor) {
      this.$refs.input.focus(cursor);
    },
    onBack(event) {
      this.$emit("back", event);
    },
    onNext(cursor) {
      this.$emit("next", cursor);
    },
    onPrev(cursor) {
      this.$emit("prev", cursor);
    },
    onSplit(data) {
      this.$emit("split", data);
    },
    onEnter() {
      this.$emit("append", {
        type: "extText",
      });
    },
    selectedValue(values, storedValue, defaultValue) {
      let selectedValueLabel = "";
      const currentValue = storedValue || defaultValue;

      values.forEach((value) => {
        if (value.id === currentValue) {
          selectedValueLabel = value.label;
        }
      });

      return selectedValueLabel;
    },
    setTextAlign(textAlign) {
      this.textAlign = textAlign;
      this.input({ textAlign });
    },
    setFontColor(fontColor) {
      this.fontColor = fontColor;
      this.input({ fontColor });
    },
    setFontSize(fontSize) {
      this.fontSize = fontSize;
      this.input({ fontSize });
    },
    input(data) {
      this.$emit("input", {
        attrs: {
          ...this.attrs,
          ...data,
        },
      });
    },
    menu() {
      return [
        {
          icon: "cog",
          label: this.$t("editor.blocks.settings"),
          click: this.$refs.settings.open,
        },
      ];
    },
    saveSettings() {
      this.$refs.settings.close();
      this.input(this.attrs);
    },
    onCheck(event) {
      switch (event.srcElement.id) {
        case "margin-bottom":
          this.input({ marginBottom: !this.attrs.marginBottom });
          break;
        case "mobile":
          this.input({ mobile: !this.attrs.mobile });
          break;
        case "tablet":
          this.input({ tablet: !this.attrs.tablet });
          break;
        case "desktop":
          this.input({ desktop: !this.attrs.desktop });
          break;
        default:
          console.log("unknown source element");
          break;
      }
    },
    onInputContent(html) {
      this.$emit("input", {
        content: html,
      });
    },
  },
  template: `
    <p>
      <k-editable
        ref="input"
        :content="content"
        @input="onInputContent"
        @back="onBack"
        @enter="onEnter"
        @next="onNext"
        @prev="onPrev"
        @split="onSplit"
      />
      <k-dialog ref="settings" @submit="saveSettings" size="large">

      <!-- text-align -->
      <div class="k-editor-setting-block">
        <label>Text-Ausrichtung</label>
        <k-dropdown style="color: $color-black;" >
          <k-button @click="$refs.textAlign.toggle()">{{ selectedTextAlign }}</k-button>
          <k-dropdown-content ref="textAlign" >
            <k-dropdown-item v-for="textAlignValue in $options.textAlignValues" :key="textAlignValue.id" @click="setTextAlign(textAlignValue.id)">{{ textAlignValue.label }}</k-dropdown-item>
          </k-dropdown-content>
        </k-dropdown>
      </div>

      <!-- font-size -->
      <div class="k-editor-setting-block">
        <label>Schrift-Größe</label>
        <k-dropdown style="color: $color-black;" >
          <k-button @click="$refs.fontSize.toggle()">{{ selectedFontSize }}</k-button>
          <k-dropdown-content ref="fontSize" >
            <k-dropdown-item v-for="fontSizeValue in $options.fontSizeValues" :key="fontSizeValue.id" @click="setFontSize(fontSizeValue.id)">{{ fontSizeValue.label }}</k-dropdown-item>
          </k-dropdown-content>
        </k-dropdown>
      </div>

      <!-- font-color -->
      <div class="k-editor-setting-block">
        <label>Schrift-Farbe</label>
        <k-dropdown style="color: $color-black;" >
          <k-button @click="$refs.fontColor.toggle()">{{ selectedFontColor }}</k-button>
          <k-dropdown-content ref="fontColor" >
            <k-dropdown-item v-for="fontColorValue in $options.fontColorValues" :key="fontColorValue.id" @click="setFontColor(fontColorValue.id)">{{ fontColorValue.label }}</k-dropdown-item>
          </k-dropdown-content>
        </k-dropdown>
      </div>

      <!-- margin-bottom -->
      <div class="k-editor-setting-block">
          <input
            type="checkbox"
            id="margin-bottom" name="margin-bottom" value="marginBottom"
            :checked="attrs.marginBottom"
            @change="onCheck"
          />
          <label for="margin-bottom">Abstand nach unten</label>
        </div>

        <!-- Mobile -->
        <div class="k-editor-setting-block">
          <input
            type="checkbox"
            id="mobile" name="mobile" value="mobile"
            :checked="attrs.mobile"
            @change="onCheck"
          />
          <label for="mobile">Mobile</label>
        </div>

        <!-- Tablet -->
        <div class="k-editor-setting-block">
          <input
            type="checkbox"
            id="tablet" name="tablet" value="tablet"
            :checked="attrs.tablet"
            @change="onCheck"
          />
          <label for="tablet">Tablet</label>
        </div>

        <!-- Desktop -->
        <div class="k-editor-setting-block">
          <input
            type="checkbox"
            id="desktop" name="desktop" value="desktop"
            :checked="attrs.desktop"
            @change="onCheck"
          />
          <label for="desktop">Desktop</label>
        </div>
      </k-dialog>
    </p>`,
});