Creating Components Creating a new component package Guide

Creating Components

Semantic UI extends native web components to support reactive data, event binding, templating, DOM Querying, keybindings and more to allow you to build complex web applications purely with web components.

Installing Dependencies

The only package necessary to create components is the @semantic-ui/component package.

Terminal window
npm install @semantic-ui/component

Defining Components

defineComponent exported from @semantic-ui/component can be used to create a new web component.

Minimal Component

The minimum requirement to create a component is an html template.

import { defineComponent } from '@semantic-ui/component';
const HelloWorld = defineComponent({
template: `<p>Hello World</p>`,
});

If you specify a tagName your component will be available as a web component allowing you include it in pages in your application.

import { defineComponent } from '@semantic-ui/component';
defineComponent({
tagName: 'hello-world',
template: `<p>Hello World</p>`,
});
<hello-world></hello-world>

Standard Component

In most real world use-cases you will need to provide additional information to defineComponent

// for examples of each config option see below
defineComponent({
createComponent, // function that returns component methods and props stored in DOM
template, // component template
css, // scoped css
pageCSS, // page css added with component
events, // dom events
keys, // keybinding events
state, // private reactive store
settings, // exposed settings
onCreated, // after attached to dom
onRendered, // after shadow dom rendered
onDestroyed, // when removed from dom
onThemeChanged, // callback when component theme changes
});
  • createComponent - An object returned from createComponent defines what methods and properties are attached to the DOM element associated with the component which provide behaviors. For instance a popup might have a show and hide behavior.
  • Template - The logic that controls how your html is rendered including conditionals, loops, subtemplates, and expressions. This can be passed in as a string template or rendered from a precompiled ast.
  • CSS - The css scoped to this component or that should be attached once to the page with the component,
  • Page CSS - The pageCSS scoped to the page that will added to the page when a component is defined.
  • Events - The event listeners attached to your component, passed in as an object literal string events.
  • State - Reactive internal state associated with your component and its default values
  • Settings - Reactive external settings exposed to users as properties or attributes on your tagName
  • Lifecycle Events - Actions that should occur onCreated, onRendered and onDestroyed for your component
  • Keybindings - keys defines keyboard events associated with your component

Destructured Params - Semantic callbacks provide a variety of parameters that are returned from functions called inside the component. For more information see callback arguments

Definition Parts

Create Component

createComponent defines the behaviors associated with your component. These can be called from your template, other components, or using javascript in your page.

Your components state, settings, component instance self and other data sources are passed through to each lifecycle arguments like createComponent.

For more information on createComponent see our dedicated subsection on defining functionality.

const createComponent = ({ state }) => ({
getCounter() {
return state.counter.get();
},
incrementCounter() {
state.counter.increment();
},
});

Template

The template defines the html your component should render from the data present in your component.

For more information on templating see the dedicated subsection for templating

Counter is {counter}
<ui-button class="increment">Increment</ui-button>
<ui-button class="decrement">Decrement</ui-button>

CSS

css defines scoped CSS that will be attached to your web component and not apply to other elements on the page. This is passed as a string and is constructed and attached to the component using adoptedstylesheets.

You can use pageCSS to add additional css that will be included once in the page scope when you component is created.

For more information see the dedicated css styling section.

Events

Most components will need to listen to and react to events triggered from the browser or other components. When creating a component you can assign events that are bound to parts of your component and trigger functionality.

These can be browser events like click, perhaps to save something when a button with class save is clicked.

For more information on events please see the dedicated subsection for events

const events = {
'click ui-button.save'({ self }) {
self.save();
},
};

or custom events like resizestart dispatched from another component

const events = {
'resizestart ui-panel'() {
// do something
},
};

Keys

Components can also include keybindings that will be attached to the page during the lifecycle of the component.

For more information please see the dedicated subsection for keybindings

defineComponent({
keys: {
'up': ({ self }) => self.selectPreviousResult(),
'down': ({ self }) => pl.selectNextResult(),
'esc': ({ self }) => self.blurSearch(),
}
});

Lifecycle Events

Lifecycle events let you run arbitray code during different parts of a components lifecycle either on the client or during server side hydration.

For more information please see the dedicated subsection for lifecycle events

Organizing Code

To keep your code organized you might consider keeping your html and css as separate files with your component.

Browser / Node

In a browser or node you can import static assets using getText a helper that uses fetch.

import { getText } from '@semantic-ui/component';
const template = await getText('./component.html');
const css = await getText('./component.css');

Webpack / Vite / Esbuild etc.

In a project with build tools like you can use the ?raw query parameter to import a plaintext file directly.

import template from './component.html?raw';
import css from './component.css?raw';

Single File Components

If you prefer single file components you can just inline your html and css.

const defineComponent({
tagName: 'ui-counter',
template: `<div class="counter">{counter}</div>`,
css: `
.counter {
color: var(--primary-text-color);
}
`
});