Dojo NG is being built in the open, one section at a time — follow along on Heptapod.

FRAMEWORKS

Svelte

Svelte 5 needs no setup for custom elements. It passes arrays and objects as properties, and an on attribute listens for any event, including the dj-* events.

Install and register

npm install @dojo-ng/select @dojo-ng/chip @dojo-ng/text-input @dojo-ng/checkbox

Each package registers its tag when you import it. Import the packages once, in your entry file or in the root component's <script>:

// main.js: import the components once
import "@dojo-ng/select";
import "@dojo-ng/chip";
import "@dojo-ng/text-input";
import "@dojo-ng/checkbox";

import { mount } from "svelte";
import App from "./App.svelte";

mount(App, { target: document.getElementById("app") });

An example

<script>
  const plans = [
    { value: "free", label: "Free" },
    { value: "pro", label: "Pro" },
  ];
  let plan = $state("free");
  let name = $state("");
  let agree = $state(false);
  let tags = $state(["design", "docs"]);
</script>

<dj-select
  label="Plan"
  options={plans}
  value={plan}
  onchange={(e) => (plan = e.target.value)}
></dj-select>

<dj-text-input
  label="Name"
  value={name}
  oninput={(e) => (name = e.target.value)}
></dj-text-input>

<dj-checkbox checked={agree} onchange={(e) => (agree = e.target.checked)}>
  I agree
</dj-checkbox>

{#each tags as tag (tag)}
  <dj-chip closeable ondj-close={() => (tags = tags.filter((t) => t !== tag))}>
    {tag}
  </dj-chip>
{/each}

Properties and attributes

  • Svelte sets arrays and objects as properties, such as options={plans}. This works even when the tag renders before its package is imported.
  • Strings and numbers are set as attributes when the element is not yet defined, and as properties when it is. Either way the component receives them.
  • Plain attributes, such as label="Plan" and closeable, work as in HTML.

Events

  • Listen for a Dojo NG event with on followed by its exact name: ondj-close, ondj-submit, ondj-select.
  • Standard events work as usual: oninput, onchange, and onclick.
  • The older on:dj-close directive still compiles, but Svelte 5 marks it as deprecated.
  • The event data is in event.detail. Each component's API page lists its events.

State and forms

  • bind:value on a dj-* tag is a compile error, because Svelte allows it only on <input>, <textarea>, and <select>. Pass the value as a prop and update your $state in oninput or onchange, as in the example.
  • The controls are form-associated, so a plain <form> with an onsubmit handler and new FormData(form) also works. See Forms & validation.
Next: Plain HTML Import maps, properties from JavaScript, and events with no framework.