Skip to content

UI Components

github-actions[bot] edited this page Oct 18, 2026 · 4 revisions

UI components

@nynxz/zenkit-ui is ZenKit's Vue 3 component library: 48 components styled entirely from --zen-* CSS tokens. It does not touch window.ZenKit, so it works in ZenKit plugins and in plain node packs alike.

Install

pnpm add @nynxz/zenkit-ui      # peer: vue ^3.5.0
import '@nynxz/zenkit-ui/style.css' // component styles
import '@nynxz/zenkit-ui/comfy-bridge.css' // only when the ZenKit runtime may be absent
import { ZenButton, ZenNumber, ZenSelect } from '@nynxz/zenkit-ui'
<script setup lang="ts">
import { ref } from 'vue'
import { ZenField, ZenNumber, ZenRow, ZenSelect, ZenWidget, ZenButton } from '@nynxz/zenkit-ui'

const steps = ref(20)
const sampler = ref('euler')
</script>

<template>
  <ZenWidget>
    <ZenRow>
      <ZenField label="Steps"><ZenNumber v-model="steps" :min="1" :max="150" :step="1" /></ZenField>
      <ZenSelect v-model="sampler" :options="['euler', 'dpmpp_2m']" data-grow />
    </ZenRow>
    <template #footer><ZenButton variant="primary" block>Run</ZenButton></template>
  </ZenWidget>
</template>

How you get the package depends on what you build:

Consumer Resolves @nynxz/zenkit-ui to
In-repo ZenKit plugins Package source (Vite alias), served at runtime from /zenkit/runtime/ui.js (sharedRuntime)
External node packs npm, bundled into the pack's main.js

With sharedRuntime, the runtime's ui.js already includes the styles; the CSS imports above are for bundled consumers.

Theming

Every component reads --zen-* custom properties, with inline fallbacks.

Situation Who sets the tokens
ZenKit runtime installed core sets the full set from the active theme pack (see Themes)
No runtime comfy-bridge.css maps them at :root onto ComfyUI's own variables, so components follow the ComfyUI theme with no JS

Tokens comfy-bridge.css defines:

Token From ComfyUI variable
--zen-bg --comfy-menu-bg
--zen-surface, --zen-surface-2 --comfy-menu-secondary-bg
--zen-input --comfy-input-bg
--zen-border --border-color
--zen-text --input-text, then --fg-color
--zen-muted --descrip-text
--zen-accent, --zen-accent-text --p-primary-color, --p-button-text-primary-color
--zen-radius --border-radius-base (7px)
--zen-danger, --zen-warn, --zen-ok, --zen-info (+ -text) ComfyUI status colours
--zen-mono a monospace stack

Other tokens components read (--zen-chrome-bg, --zen-control-bg, --zen-control-border, --zen-control-hover-*, --zen-field-bg, --zen-surface-border, --zen-radius-surface, --zen-glass, --zen-scrollbar, --zen-switch-radius) are not in the bridge; they fall back inline to the core tokens. Override any token on an ancestor to restyle a subtree.

Floating layers

Overlays (popovers, menus, modals, windows, pickers) are teleported to <body>. Each floating root carries a data-zen-layer attribute:

  • Click-outside handlers ignore clicks inside another [data-zen-layer], so a ZenSelect inside a ZenPopover does not close the popover.
  • Layers render above ComfyUI's own dialogs and the ZenKit taskbar. Escape closes the innermost layer that handles it.
  • [data-zen-layer] re-tints scrollbars (see below).

If you build your own teleported overlay, set data-zen-layer on its root so the components above treat clicks inside it as "inside".

Scrollbars

lib/scrollbar.css styles the .zen-scroll class: a thin scrollbar coloured by --zen-scrollbar (falling back to ComfyUI's --dialog-surface). Inside [data-zen-layer] the thumb is tinted from --zen-text instead. ZenScroll and the overlays apply it; add class="zen-scroll" to your own scroll containers.

Conventions

Convention Detail
v-model Plain modelValue unless noted. Some components use named models (v-model:open, v-model:width, v-model:volume, …).
Icons Material Design Icons classes. Every icon prop accepts either the full class ('mdi mdi-cog') or the bare glyph ('mdi-cog'). The package does not load the MDI font; the page must.
Wrapping rows Use ZenRow in node bodies: children wrap instead of squashing. Mark the child that should stretch with data-grow.
Wheel in node bodies ComfyUI only gives the wheel to a focused data-capture-wheel element. Use useWheelClaim for a body with panels, useFocusSurface for a surface that uses the wheel (Layout and primitives).
Persistence A few components remember UI state in localStorage under zenkit.* keys (noted per component).
Boolean controls Pick by weight: ZenSwitch (a setting), ZenCheckbox (an option in a list), ZenDot (state in a repeated row).

Component index

"Since" is the first @nynxz/zenkit-ui release that exports the component.

Component Purpose Since Page
ZenWidget Shell for a whole node body 0.2.0 Layout and primitives
ZenRow Row whose children wrap 0.2.0 Layout and primitives
ZenField Labelled control 0.2.0 Layout and primitives
ZenSection Collapsible titled block 0.3.0 Layout and primitives
ZenSections Groups ZenSections, optional accordion 0.3.0 Layout and primitives
ZenSplit Resizable panes 0.3.0 Layout and primitives
ZenResizeHandle Shared resize grip and input lifecycle 0.3.0 Layout and primitives
ZenView Standard panel layout 0.2.0 Layout and primitives
ZenToolbar Panel header bar 0.2.0 Layout and primitives
ZenScroll Themed scroll container 0.2.0 Layout and primitives
ZenButton Text button 0.2.0 Layout and primitives
ZenIconButton Icon-only button 0.2.0 Layout and primitives
ZenIcon MDI or image-URL icon 0.2.0 Layout and primitives
ZenEmpty Empty state with the lotus mark 0.3.0 Layout and primitives
ZenLotus ZenKit's lotus mark, one colour 0.3.0 Layout and primitives
ZenInput Text, number, password, textarea 0.2.0 Inputs
ZenMentionInput Textarea with @mentions 0.3.0 Inputs
ZenNumber Numeric field with scrub and steppers 0.2.0 Inputs
ZenResolution Aspect-ratio and megapixel size picker 0.3.0 Inputs
ZenDimensions Inline width × height 0.2.0 Inputs
ZenSelect Dropdown 0.2.0 Inputs
ZenCombo Searchable, virtualised picker 0.2.0 Inputs
ZenSwitch Toggle switch 0.2.0 Inputs
ZenCheckbox Checkbox 0.2.0 Inputs
ZenDot Small on/off dot 0.2.0 Inputs
ZenToggleGroup Segmented single-select 0.2.0 Inputs
ZenSlider Range slider 0.2.0 Inputs
ZenVolume Volume and mute 0.3.0 Inputs
ZenCurveEditor 0–1 curve editor 0.3.0 Inputs
ZenColorPicker Colour picker 0.2.0 Inputs
ZenPopover Anchored floating panel 0.2.0 Overlays
ZenMenuItem Menu row, optional submenu 0.2.0 Overlays
ZenMenuSeparator Menu divider 0.2.0 Overlays
ZenContextMenu Right-click menu 0.3.0 Overlays
ZenModal Centred dialog 0.2.0 Overlays
ZenWindow Draggable, resizable window 0.2.0 Overlays
ZenLightbox Image/video/audio viewer 0.2.0 Media and LoRA
ZenPeek Shift-hover preview window 0.3.0 Media and LoRA
ZenMediaControls Player controls for a media element 0.3.0 Media and LoRA
ZenMediaPicker Media browser modal 0.3.0 Media and LoRA
ZenTimeline Multi-track timeline 0.3.0 Media and LoRA
ZenBoxCanvas Draw, move, resize boxes; paint masks 0.3.3 Media and LoRA
ZenLayerList Layer stack: select, hide, lock, order 0.3.3 Media and LoRA
ZenStepChart Sampler run chart 0.3.0 Media and LoRA
LoraPicker LoRA combo 0.3.0 Media and LoRA
LoraBrowser Full LoRA library modal 0.3.0 Media and LoRA
LoraThumb LoRA preview tile 0.3.0 Media and LoRA
LoraDetail Everything about one LoRA 0.3.0 Media and LoRA
JsonTree Collapsible JSON viewer 0.2.0 Data
ZenFolderTree Folder tree 0.3.0 Data

Non-component exports:

Export Page
useFocusSurface, FocusSurface, FocusSurfaceOptions, useWheelClaim, scrollsUnder, WheelClaim, WheelClaimOptions Layout and primitives
isIconUrl Layout and primitives
Dimension math (aspectRatio, snap, megapixels, …) Inputs
createHistory, placeRects Media and LoRA
setLoraSource, openLoraDetail, setLoraDetailOpener, loraLibrary Media and LoRA
Types: SplitPane, ComboItem, LightboxItem, MentionItem, ResolutionRatio, CurvePoint, CurvePreset, DimensionsValue, ContextMenuAction, ContextMenuItem, MediaPickerItem, MediaPickerKind, MediaPickerLibrary, Timeline*, ZenBox, BoxRect, BoxHandle, BoxTool, History, HistoryOptions, LayerItem, Lora*, FolderTreeEntry, Peek* On each component's page

Clone this wiki locally