| name | use-swim-ui |
| description | Use Swimlane swim-ui (swim-* custom elements) when building custom solutions, record widgets, or report widgets for Turbine. Covers properties, events, slots, imperative APIs, and CDN usage. Apply this skill when using generate-swimlane-lit-solution (it depends on use-swim-ui for component list, API, and design). Use when authoring or modifying Turbine widgets, custom solutions, or any UI that uses @swimlane/swim-ui components. |
Using Swimlane swim-ui
Use this skill when building custom solutions or widgets for Swimlane Turbine with Swimlane swim-ui (swim-* web components). All UI must use these elements; do not invent tag names or assume other component libraries.
Base and runtime
- Custom elements: Extend SwimlaneElement (from
@swimlane/swimlane-element@2), not raw LitElement. Use css, html, svg, unsafeCSS from that package.
- Widget docs: Turbine Widgets — record widgets and report widgets; implementations are web components / custom elements.
- Component source: Full APIs (properties, events, slots) live in
projects/swimlane/swim-ui/src/components/<name>/. For precise attribute names and event payloads, read the component .component.ts and index.ts files.
CDN usage (solutions without build)
import { SwimlaneElement, css, html } from '@swimlane/swimlane-element@2';
import 'https://cdn.jsdelivr.net/gh/surya-pabbineedi/swim-ui@gh-pages/swim-ui.js?v=1';
Ensure the lit specifier is available (e.g. via import map) so the swim-ui bundle resolves. Load SwimlaneElement (or Lit) before the swim-ui bundle.
Attribute naming
- Lit properties are exposed as kebab-case attributes:
sectionCollapsed → section-collapsed, closeOnOutsideClick → close-on-outside-click, fontIcon → font-icon.
- Booleans: presence = true; use
attribute="false" or close-on-outside-click="false" where the component uses a custom converter for false.
Events
Host-only custom events (confirmed contract)
Swim-ui custom events are dispatched only on the swim-* element host (the custom element node: event.target is that element). They use bubbles: false and composed: false, so they do not propagate to ancestors, document, or past shadow boundaries.
How to listen
- Lit: use
@event on the swim-* node that emits it (for example @change on swim-input, @close on swim-dialog), not on a wrapping div expecting the event to bubble up.
- Vanilla:
element.addEventListener('change', ...) where element is the swim-* reference from querySelector, ref, or createElement.
Do not rely on event delegation on a parent, document, or window for these custom events—they will not fire there. (Native click on swim-button is separate: it behaves like a normal control.)
Naming: Because custom events stay on the host, conventional names (change, close, open, select, etc.) are safe. If a future API ever required bubbles: true, prefer a non-generic, swim-specific event name to avoid clashes.
Use event.detail for payloads where the component defines it.
Propagation summary (bubbles / composed)
| Value | Meaning |
|---|
| Custom events | bubbles: false, composed: false | Host-only; listen on that swim-* element. |
Repro: The swim-ui demo Event propagation (#event-bubbling-matrix) shows swim-checkbox in light DOM vs inside another shadow root.
Per-event reference
| Element | Event | Bubbles | Composed | Detail |
|---|
| swim-button | click | native | native | — |
| swim-input | input, change, focus, blur | no | no | value / validation |
| swim-select | change, filter-change | no | no | value / { query } |
| swim-select | dropdown-open, dropdown-close | no | no | panel open state |
| swim-checkbox | change, checked-change, indeterminate-change, focus, blur | no | no | checked / indeterminate |
| swim-toggle | change, focus, blur | no | no | checked |
| swim-radio | change, focus, blur | no | no | value |
| swim-radio-group | change, blur | no | no | selected value |
| swim-button-toggle | value-change | no | no | value |
| swim-button-toggle-group | value-change | no | no | selected value |
| swim-slider | change | no | no | { value, percent } |
| swim-calendar | change, day-key-enter | no | no | value / keyboard |
| swim-date-time | change, value-change, input-change, date-time-selected, focus, blur | no | no | value / segments |
| swim-tabs | select-tab, select | no | no | { tab } |
| swim-tab | swim-tab-active-change | no | no | — |
| swim-section | toggle | no | no | collapsed boolean |
| swim-dialog | open, close | no | no | optional detail on close |
| swim-large-format-dialog-content | close-or-cancel | no | no | dirty boolean |
| swim-drawer | close | no | no | optional detail |
| swim-list | page-change, scroll | no | no | page / scrollTop |
| swim-card | select, outline-click | no | no | selected / — |
| swim-tooltip | show, hide | no | no | true |
| swim-navbar, swim-navbar-item | active-change | no | no | index |
| swim-split-handle | dragstart, drag, dragend, dblclick | no | no | MouseEvent detail |
Slots
Common patterns:
- Default slot: main content (e.g.
swim-card, swim-dialog, swim-drawer, swim-tab body).
- Named slots:
slot="header", slot="footer", slot="hint", slot="prefix", slot="suffix", slot="content" (tooltip), slot="label" (tab), slot="avatar", slot="title", slot="subtitle".
Use the component’s JSDoc @slot in projects/swimlane/swim-ui/src/components/<name>/*.component.ts for the exact list.
Imperative APIs
Drawer
- Declarative:
<swim-drawer open> plus show() / hide() on the element reference.
- Imperative:
openDrawer(options) from @swimlane/swim-ui (or the drawer controller). Options: direction, size, zIndex, closeOnOutsideClick, isRoot, parentContainer, content (HTMLElement | DocumentFragment | string), cssClass. Returns { close(), drawer }. Listen to the drawer’s close event for cleanup.
import { openDrawer } from '@swimlane/swim-ui/drawer';
const { close, drawer } = openDrawer({ direction: 'left', size: 80, content: fragmentOrElement });
When using the CDN bundle, the drawer may be created with document.createElement('swim-drawer'), set properties, append content, append to body, then call drawer.show() and on close remove from DOM. See projects/swimlane/swim-ui/src/components/drawer/drawer-controller.ts.
Component list (quick reference)
| Tag | Purpose |
|---|
| swim-button | Buttons: variant, size, disabled, state (active/in-progress/success/fail), promise |
| swim-button-group | Group of buttons; orientation, variant |
| swim-button-toggle | Single toggle button |
| swim-button-toggle-group | Toggle group; single selection, value-change |
| swim-input | Text/number/textarea; label, hint, validation, appearance, prefix/suffix slots |
| swim-select | Single/multi select; options prop or swim-option children; filter |
| swim-checkbox | Checkbox; indeterminate; change, checked-change |
| swim-radio | Single option |
| swim-radio-group | Radios; change with value |
| swim-toggle | Toggle switch; change |
| swim-slider | Slider; single or range; change { value, percent } |
| swim-tabs | Tab container; vertical; appearance |
| swim-tab | Tab panel; label slot; active |
| swim-section | Collapsible section; section-title, section-collapsed, section-collapsible, header slot |
| swim-card | Card; orientation, status, selectable, selected, outline-text |
| swim-card-header, swim-card-body, swim-card-footer, swim-card-avatar, swim-card-placeholder | Card structure |
| swim-dialog | Modal; dialog-title, format (regular/medium/large), visible, show-backdrop, close-button, close-on-blur, close-on-escape |
| swim-large-format-dialog-content, swim-large-format-dialog-footer | Large/medium dialog layout slots |
| swim-drawer | Slide panel; direction (left/right/bottom), size, open, closeOnOutsideClick, isRoot; show()/hide() |
| swim-tooltip | Tooltip/popover; content, placement, alignment, type, show-event |
| swim-icon | Icons; font-icon, font-set (e.g. "lit"); alt for a11y |
| swim-navbar | Navbar; swim-navbar-item children; active-change |
| swim-list | List/table; columns, headerLabels, dataSource, column-layout, height, default-row-status; page-change, scroll |
| swim-progress-spinner | Spinner; mode, appearance; in-progress-icon, complete-icon, fail-icon slots |
| swim-split | Resizable split; swim-split-area, swim-split-handle children; handle fires drag / dblclick |
| swim-calendar | Calendar; change, day-key-enter |
| swim-date-time | Date/time input + picker; change, value-change, blur, focus |
Design and accessibility
- Use lit-elements as-is: no extra visual styling (colors, borders, shadows, typography) on
swim-*; only layout (flex, grid, spacing).
- Use design tokens where needed (e.g.
--spacing-16, --radius-4 from the demo).
- Preserve semantics and ARIA; ensure labels, focus, and keyboard behavior. See the generate-swimlane-lit-solution skill for full a11y and leak-free rules.
Relationship to generate-swimlane-lit-solution
This skill is the single source for the swim-ui component list, CDN/base usage, design rules, and API (see reference.md). When the task is to generate a full solution file (single .js in projects/swimlane/swim-ui/demo/solutions), apply the generate-swimlane-lit-solution skill for output location, create vs update, WCAG, and no memory leaks; it references use-swim-ui for components and design.
Detailed API reference
For per-component properties, events, slots, and enums, see reference.md and the source under projects/swimlane/swim-ui/src/components/<name>/.