Concorde guide — Legacy: My first subscriber component. > New projects: use My first component (@ancestorAttribute, @subscribe + DataProviderKey, .items on lists) and Data flow. This page documents the Subscriber mixin used by older apps and core component Doc ID: docs/_getting-started/my-first-subscriber. Keywords: Concorde, supersoniks, docs/_getting-started/my-first-subscriber, my-first-subscriber, Legacy: My first subscriber component, guide, @ancestorAttribute, @subscribe, DataProviderKey, .items, ${unsafeCSS(tailwindImport)}. URL: https://concorde.supersoniks.org/crawl/docs/_getting-started/my-first-subscriber.html.
Legacy: My first subscriber component
New projects: use My first component (
@ancestorAttribute,@subscribe+DataProviderKey,.itemson lists) and Data flow. This page documents the Subscriber mixin used by older apps and core components.
Learn how to build a component with the Subscriber mixin, styled with Tailwind, filled from a DataProvider via automatic property mapping.
Create a classic lit component
import { html, LitElement, nothing } from "lit";
import { customElement, property } from "lit/decorators.js";
@customElement("docs-user")
export class user extends LitElement {
@property({ type: String }) first_name = "";
@property({ type: String }) last_name = "";
@property({ type: String }) avatar = "";
@property({ type: String }) email = "";
render() {
return html`
<img src="${this.avatar}" /> <br>
${this.first_name} ${this.last_name} <br>
${this.email}`;
}
}
Style with tailwind and ui components
import { css, unsafeCSS } from "lit";
import tailwindImport from "./css/tailwind.css?inline";
export const tailwind = css`${unsafeCSS(tailwindImport)}`;
import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators.js";
import { tailwind } from "../tailwind";
import '@supersoniks/concode/ui/image'
import '@supersoniks/concode/ui/button'
import '@supersoniks/concode/ui/icon'
@customElement("docs-user")
export class user extends LitElement {
static styles = [tailwind];
@property({ type: String }) first_name = "";
@property({ type: String }) last_name = "";
@property({ type: String }) avatar = "";
@property({ type: String }) email = "";
render() {
return html`<div class="flex items-center gap-3 p-2">
<sonic-image src=${this.avatar} rounded="md" ratio="1/1" class="w-16"></sonic-image>
<div>${this.first_name} <span class="font-bold">${this.last_name}</span></div>
<div class="text-sm text-neutral-400">${this.email}</div>
</div>`;
}
}
Add Subscriber mixin
import Subscriber from "@supersoniks/concorde/core/mixins/Subscriber";
@customElement("docs-user")
export class user extends Subscriber(LitElement) {
// properties auto-filled from DataProvider when names match
}
Autofill from a dataProvider
<docs-demo-sources for="list-users-fetch"></docs-demo-sources>
<div serviceURL="/docs-mock-api">
<sonic-fetch
serviceURL="/docs-mock-api"
dataProvider="api/users/3"
key="data">
<docs-user></docs-user>
</sonic-fetch>
</div>
<sonic-fetch
serviceURL="/docs-mock-api"
dataProvider="api/users/2"
key="data"></sonic-fetch>
<docs-user dataProvider="api/users/2" ></docs-user>
<div class="grid grid-cols-1 gap-4">
<form formDataProvider="userPreview" class="grid grid-cols-4 gap-3" >
<sonic-input label="First name" type="text" name="first_name" value="Paul" size="sm"></sonic-input>
<sonic-input label="Last name" type="text" name="last_name" value="Metrand" size="sm"></sonic-input>
<sonic-input class="col-span-2" label="email" type="text" name="email" value="paul@example.com" size="sm"></sonic-input>
<sonic-input label="Image url" type="text" name="avatar" value="https://i.pravatar.cc/150?u=paul" size="sm"></sonic-input>
</form>
<sonic-divider align="left">Preview before submit</sonic-divider>
<div dataProvider="userPreview">
<docs-user></docs-user>
</div>
</div>