Gelişmiş

Transport ve TransportTo

İçeriği kendi ağacının dışındaki bir yuvada gösterme; Transport yuvası, TransportTo göndereni, replace/merge kipleri ve programatik taşıma için Transporter.

Bir bileşenin içeriğini kendi ağacının dışındaki bir yerde göstermek için kullanılır. Tipik örnek: sayfaya özel komut düğmelerinin layout'taki üst çubukta görünmesi. İki parçadan oluşur:

Kullanım

Örnekte üst çubuk bir yuva taşır; açık notun sabitleme düğmesi not sayfasından o yuvaya gönderilir. Yuva:

import { Component, Transport } from "@motifx/core";

export class PageBar extends Component<HTMLElement> {
  static override elementTag = "header";

  override onConfigured() {
    this.class.add("pagebar");
  }

  override view() {
    return (
      <>
        <h1>Notlar</h1>
        <Transport name="page-actions" />
      </>
    );
  }
}
import { Component, ComponentBase, Transport, motifComponent, motifFragment } from "@motifx/core";

export class PageBar extends Component<HTMLElement> {
  static override elementTag = "header";

  override onConfigured() {
    this.class.add("pagebar");
  }

  override view() {
    const title = motifComponent("h1", (h1: ComponentBase) => h1.setText("Notlar"));
    return motifFragment({ childs: [title, new Transport({ name: "page-actions" })] });
  }
}
import { Transport } from "@motifx/core";

export function PageBar() {
  return (
    <header class="pagebar">
      <h1>Notlar</h1>
      <Transport name="page-actions" />
    </header>
  );
}
import { ComponentBase, Transport, motifComponent } from "@motifx/core";

export function PageBar() {
  return motifComponent("header", (header: ComponentBase) => {
    header.class.add("pagebar");
    const title = motifComponent("h1", (h1: ComponentBase) => h1.setText("Notlar"));
    header.controls.add(title, new Transport({ name: "page-actions" }));
  });
}
import { Transport, motifOptions } from "@motifx/core";

export const PageBar = () => motifOptions({
  el: "header",

  onConfigured() {
    this.class.add("pagebar");
  },

  view() {
    return (
      <>
        <h1>Notlar</h1>
        <Transport name="page-actions" />
      </>
    );
  },
});
import { ComponentBase, Transport, motifComponent, motifFragment, motifOptions } from "@motifx/core";

export const PageBar = () => motifOptions({
  el: "header",

  onConfigured() {
    this.class.add("pagebar");
  },

  view() {
    const title = motifComponent("h1", (h1: ComponentBase) => h1.setText("Notlar"));
    return motifFragment({ childs: [title, new Transport({ name: "page-actions" })] });
  },
});
import { Component, Transport } from "@motifx/core";

export class PageBar extends Component {
  static elementTag = "header";

  onConfigured() {
    this.class.add("pagebar");
  }

  view() {
    return (
      <>
        <h1>Notlar</h1>
        <Transport name="page-actions" />
      </>
    );
  }
}
import { Component, Transport, motifComponent, motifFragment } from "@motifx/core";

export class PageBar extends Component {
  static elementTag = "header";

  onConfigured() {
    this.class.add("pagebar");
  }

  view() {
    const title = motifComponent("h1", (h1) => h1.setText("Notlar"));
    return motifFragment({ childs: [title, new Transport({ name: "page-actions" })] });
  }
}
import { Transport } from "@motifx/core";

export function PageBar() {
  return (
    <header class="pagebar">
      <h1>Notlar</h1>
      <Transport name="page-actions" />
    </header>
  );
}
import { Transport, motifComponent } from "@motifx/core";

export function PageBar() {
  return motifComponent("header", (header) => {
    header.class.add("pagebar");
    const title = motifComponent("h1", (h1) => h1.setText("Notlar"));
    header.controls.add(title, new Transport({ name: "page-actions" }));
  });
}
import { Transport, motifOptions } from "@motifx/core";

export const PageBar = () => motifOptions({
  el: "header",

  onConfigured() {
    this.class.add("pagebar");
  },

  view() {
    return (
      <>
        <h1>Notlar</h1>
        <Transport name="page-actions" />
      </>
    );
  },
});
import { Transport, motifComponent, motifFragment, motifOptions } from "@motifx/core";

export const PageBar = () => motifOptions({
  el: "header",

  onConfigured() {
    this.class.add("pagebar");
  },

  view() {
    const title = motifComponent("h1", (h1) => h1.setText("Notlar"));
    return motifFragment({ childs: [title, new Transport({ name: "page-actions" })] });
  },
});

Gönderen:

import { Component, TransportTo } from "@motifx/core";
import { NotesService, type Note } from "../services/notes";

export class PinAction extends Component<any, { note: Note }> {
  notes = this.getService(NotesService)!;

  override view() {
    const { note } = this.props;
    return (
      <TransportTo name="page-actions">
        <button type="button" class="button--sm ghost" aria-pressed={() => note.pinned} onclick={() => this.notes.togglePin(note)}>
          {() => (note.pinned ? "Sabitlendi" : "Sabitle")}
        </button>
      </TransportTo>
    );
  }
}
import { Component, ComponentBase, TransportTo, motifComponent } from "@motifx/core";
import { NotesService, type Note } from "../services/notes";

export class PinAction extends Component<any, { note: Note }> {
  notes = this.getService(NotesService)!;

  override view() {
    const { note } = this.props;
    const pin = motifComponent("button", (button: ComponentBase) => {
      button.attr.add({ type: "button", "aria-pressed": () => note.pinned });
      button.class.add("button--sm ghost");
      button.motif.on("click", () => this.notes.togglePin(note));
      button.bindings.text(() => (note.pinned ? "Sabitlendi" : "Sabitle"));
    });
    return motifComponent(TransportTo, { name: "page-actions", childs: [pin] });
  }
}
import { FromService, TransportTo } from "@motifx/core";
import { NotesService, type Note } from "../services/notes";

export function PinAction(props: { note: Note }) {
  const notes = FromService(NotesService)!;
  const { note } = props;

  return (
    <TransportTo name="page-actions">
      <button type="button" class="button--sm ghost" aria-pressed={() => note.pinned} onclick={() => notes.togglePin(note)}>
        {() => (note.pinned ? "Sabitlendi" : "Sabitle")}
      </button>
    </TransportTo>
  );
}
import { ComponentBase, FromService, TransportTo, motifComponent } from "@motifx/core";
import { NotesService, type Note } from "../services/notes";

export function PinAction(props: { note: Note }) {
  const notes = FromService(NotesService)!;
  const { note } = props;

  const pin = motifComponent("button", (button: ComponentBase) => {
    button.attr.add({ type: "button", "aria-pressed": () => note.pinned });
    button.class.add("button--sm ghost");
    button.motif.on("click", () => notes.togglePin(note));
    button.bindings.text(() => (note.pinned ? "Sabitlendi" : "Sabitle"));
  });
  return motifComponent(TransportTo, { name: "page-actions", childs: [pin] });
}
import { TransportTo, motifOptions } from "@motifx/core";
import { NotesService, type Note } from "../services/notes";

export const PinAction = (props: { note: Note }) => motifOptions({
  el: null,

  view() {
    const notes = this.getService(NotesService)!;
    const { note } = props;
    return (
      <TransportTo name="page-actions">
        <button type="button" class="button--sm ghost" aria-pressed={() => note.pinned} onclick={() => notes.togglePin(note)}>
          {() => (note.pinned ? "Sabitlendi" : "Sabitle")}
        </button>
      </TransportTo>
    );
  },
});
import { ComponentBase, TransportTo, motifComponent, motifOptions } from "@motifx/core";
import { NotesService, type Note } from "../services/notes";

export const PinAction = (props: { note: Note }) => motifOptions({
  el: null,

  view() {
    const notes = this.getService(NotesService)!;
    const { note } = props;
    const pin = motifComponent("button", (button: ComponentBase) => {
      button.attr.add({ type: "button", "aria-pressed": () => note.pinned });
      button.class.add("button--sm ghost");
      button.motif.on("click", () => notes.togglePin(note));
      button.bindings.text(() => (note.pinned ? "Sabitlendi" : "Sabitle"));
    });
    return motifComponent(TransportTo, { name: "page-actions", childs: [pin] });
  },
});
import { Component, TransportTo } from "@motifx/core";
import { NotesService } from "../services/notes";

export class PinAction extends Component {
  notes = this.getService(NotesService);

  view() {
    const { note } = this.props;
    return (
      <TransportTo name="page-actions">
        <button type="button" class="button--sm ghost" aria-pressed={() => note.pinned} onclick={() => this.notes.togglePin(note)}>
          {() => (note.pinned ? "Sabitlendi" : "Sabitle")}
        </button>
      </TransportTo>
    );
  }
}
import { Component, TransportTo, motifComponent } from "@motifx/core";
import { NotesService } from "../services/notes";

export class PinAction extends Component {
  notes = this.getService(NotesService);

  view() {
    const { note } = this.props;
    const pin = motifComponent("button", (button) => {
      button.attr.add({ type: "button", "aria-pressed": () => note.pinned });
      button.class.add("button--sm ghost");
      button.motif.on("click", () => this.notes.togglePin(note));
      button.bindings.text(() => (note.pinned ? "Sabitlendi" : "Sabitle"));
    });
    return motifComponent(TransportTo, { name: "page-actions", childs: [pin] });
  }
}
import { FromService, TransportTo } from "@motifx/core";
import { NotesService } from "../services/notes";

export function PinAction(props) {
  const notes = FromService(NotesService);
  const { note } = props;

  return (
    <TransportTo name="page-actions">
      <button type="button" class="button--sm ghost" aria-pressed={() => note.pinned} onclick={() => notes.togglePin(note)}>
        {() => (note.pinned ? "Sabitlendi" : "Sabitle")}
      </button>
    </TransportTo>
  );
}
import { FromService, TransportTo, motifComponent } from "@motifx/core";
import { NotesService } from "../services/notes";

export function PinAction(props) {
  const notes = FromService(NotesService);
  const { note } = props;

  const pin = motifComponent("button", (button) => {
    button.attr.add({ type: "button", "aria-pressed": () => note.pinned });
    button.class.add("button--sm ghost");
    button.motif.on("click", () => notes.togglePin(note));
    button.bindings.text(() => (note.pinned ? "Sabitlendi" : "Sabitle"));
  });
  return motifComponent(TransportTo, { name: "page-actions", childs: [pin] });
}
import { TransportTo, motifOptions } from "@motifx/core";
import { NotesService } from "../services/notes";

export const PinAction = (props) => motifOptions({
  el: null,

  view() {
    const notes = this.getService(NotesService);
    const { note } = props;
    return (
      <TransportTo name="page-actions">
        <button type="button" class="button--sm ghost" aria-pressed={() => note.pinned} onclick={() => notes.togglePin(note)}>
          {() => (note.pinned ? "Sabitlendi" : "Sabitle")}
        </button>
      </TransportTo>
    );
  },
});
import { TransportTo, motifComponent, motifOptions } from "@motifx/core";
import { NotesService } from "../services/notes";

export const PinAction = (props) => motifOptions({
  el: null,

  view() {
    const notes = this.getService(NotesService);
    const { note } = props;
    const pin = motifComponent("button", (button) => {
      button.attr.add({ type: "button", "aria-pressed": () => note.pinned });
      button.class.add("button--sm ghost");
      button.motif.on("click", () => notes.togglePin(note));
      button.bindings.text(() => (note.pinned ? "Sabitlendi" : "Sabitle"));
    });
    return motifComponent(TransportTo, { name: "page-actions", childs: [pin] });
  },
});

Layout çubuğu <PageBar /> ile, not sayfası düğmeyi <PinAction note={note} /> ile yerleştirir.

Layout çubuğu new PageBar() ile, not sayfası düğmeyi new PinAction({ note }) ile yerleştirir.

Layout çubuğu motifComponent(PageBar) ile, not sayfası düğmeyi motifComponent(PinAction, { note }) ile yerleştirir.

Transport ve TransportTo çekirdeğin sınıflarıdır. JSX'siz yazımda yuva new Transport({ name }), gönderen derleyicinin ürettiği gibi motifComponent(TransportTo, { name, childs }) ile kurulur.

Prop'lar

Bileşen Prop Açıklama
Transport name Yuvanın adı (zorunlu).
Transport mode 'replace' (varsayılan) veya 'merge'; bkz. Yuvada birden çok gönderen.
TransportTo name İçeriğin gönderileceği yuvanın adı.

Davranış

Yuvada birden çok gönderen — mode

Aynı yuvaya birden çok TransportTo içerik gönderdiğinde mode belirleyicidir. Yuvanın gönderenlerden önce ya da sonra kurulması sonucu değiştirmez:

Birden çok bloğun birlikte doldurduğu, gövdede biriken bir alan isteniyorsa ContentBody ve ContentBlock bunun için tasarlanmıştır.

Programatik taşıma — Transporter

Transport/TransportTo çiftinin altındaki yardımcı dışa açıktır; bir bileşeni JSX olmadan başka bir ebeveyne taşımak için kullanılır:

import { Transporter } from '@motifx/core';

Transporter.transport(child, newParent);                 // sona ekle
Transporter.transport(child, newParent, { index: 0 });   // verilen dizine ekle
Transporter.transportMany([a, b], newParent);
import { Transporter } from '@motifx/core';

Transporter.transport(child, newParent);                 // sona ekle
Transporter.transport(child, newParent, { index: 0 });   // verilen dizine ekle
Transporter.transportMany([a, b], newParent);

transport çocuğu eski ebeveyninden çıkış geçişi oynatmadan ayırır, yeni ebeveynin controls'una ekler ve bağlarını yeniden etkinleştirir (reState). TransportOptions: index (ekleme dizini; transportMany çocukları bu dizinden başlayarak verilen sırayla yerleştirir), keepState: true (bağları yeniden etkinleştirme), owner (taşıyanı motif.options.ownerTransporter'a yazar). Çocuk zaten o ebeveyndeyse hiçbir şey yapmaz.

Sonraki adım

Birden çok kaynaktan birikerek dolan gövde için ContentBody ve ContentBlock; controls koleksiyonunun geri kalanı için Bileşenler - controls.