Skip to main content

Button

The standard clickable button control, with label, optional icon, and hover/pressed/focus states.

The Button control renders a styled, accessible button with a text label and optional icon. Its main product is the onClick signal; it also exposes its interaction state as boolean levels (hoverState, pressedState, focusState) for styling reactions, and an enabled input to disable it. Visual-state variants let hover/pressed/disabled styling be defined per state.

When to use it​

Any tap/click affordance with a caption. For a custom-drawn clickable area, a Group's onClick works; prefer the Button control when you want built-in states, label/icon layout and accessibility. The legacy Button type is superseded by this control.

At a glance​

CategoryVisual
Type namenet.noodl.controls.button
Available inbrowser
SSR compatibilitysafe
Provided bynoodl-viewer-react

Inputs​

Values​

NameTypeDefaultDescription
alignXEnum (left, center, right)—Horizontal alignment of this element within the space its parent gives it
alignYEnum (top, center, bottom)—Vertical alignment of this element within the space its parent gives it
backgroundColorColor#000000Fill colour behind the label and icon
blockTouchBoolean—Stops every pointer event that lands on this control from reaching the nodes it sits inside. Blunt: it takes hover and pointer-down with it, so reach for Click Bubbling first if it is only clicks you want to keep in
borderBottomColorColor—Colour of the bottom edge only, overriding Border Color
borderBottomLeftRadiusNumber—Rounds the bottom-left corner only, overriding Corner Radius
borderBottomRightRadiusNumber—Rounds the bottom-right corner only, overriding Corner Radius
borderBottomStyleEnum (none, solid, dotted, dashed)—Line style for the bottom edge only, overriding Border Style; None hides that edge
borderBottomWidthNumber—Thickness of the bottom edge in pixels, and it adds to the element's size
borderColorColor#000000Colour of the border, which has no effect while Border Style is None
borderLeftColorColor—Colour of the left edge only, overriding Border Color
borderLeftStyleEnum (none, solid, dotted, dashed)—Line style for the left edge only, overriding Border Style; None hides that edge
borderLeftWidthNumber—Thickness of the left edge in pixels, and it adds to the element's size
borderRadiusNumber0Rounds all four corners, except any corner that sets its own radius
borderRightColorColor—Colour of the right edge only, overriding Border Color
borderRightStyleEnum (none, solid, dotted, dashed)—Line style for the right edge only, overriding Border Style; None hides that edge
borderRightWidthNumber—Thickness of the right edge in pixels, and it adds to the element's size
borderStyleEnum (none, solid, dotted, dashed)noneLine style for all four edges; None hides the border and leaves Border Width and Color inactive
borderTopColorColor—Colour of the top edge only, overriding Border Color
borderTopLeftRadiusNumber—Rounds the top-left corner only, overriding Corner Radius
borderTopRightRadiusNumber—Rounds the top-right corner only, overriding Corner Radius
borderTopStyleEnum (none, solid, dotted, dashed)—Line style for the top edge only, overriding Border Style; None hides that edge
borderTopWidthNumber—Thickness of the top edge in pixels, and it adds to the element's size
borderWidthNumber2Thickness of the border in pixels, which adds to the element's size unless Box Sizing accounts for it
boxShadowBlurRadiusNumber5How soft the shadow edge is; 0 gives a hard edge
boxShadowColorColor#00000033Colour of the shadow, including how transparent it is
boxShadowEnabledBooleanfalseTurns the drop shadow on
boxShadowInsetBooleanfalseDraws the shadow inside the element instead of behind it
boxShadowOffsetXNumber0How far to the right the shadow is cast from the element
boxShadowOffsetYNumber0How far down the shadow is cast from the element
boxShadowSpreadRadiusNumber2How much larger than the element the shadow is drawn
boxSizingEnum (border-box, content-box)border-boxWhether Width and Height include this element's padding and border, or only its content
clickBubblingEnum (auto, always, never)autoWhether a click on this control also fires Click on the nodes it sits inside. Automatic keeps it here as soon as this control's own Click is connected, so a Favourite button inside a clickable card runs Favourite and not the card; Always is the older behaviour where both run; Never keeps every click here, wired or not
colorColor—Colour of the text itself, not of the element behind it
cssClassNameString``Extra CSS class names to put on this element, for styling from a stylesheet you supply
enabledBooleantrueLets the user interact with this control; when off it still renders and occupies its space but ignores clicks, touches and typing
fontFamilyFont—Typeface to render the text in, either a web-safe family name or a font file added to the project
fontSizeNumber—Height of the text, in pixels
fontStyleEnum (normal, italic)normalRenders the text upright or italic
fontVariantNumericEnum (normal, tabular-nums)normalTabular draws every digit at the same width so columns of numbers align; Normal follows the font
fontWeightNumberAutoHow heavy the text is drawn, from 100 (thin) to 900 (black); leave as Auto to use the weight the font family sets
heightDimension100Height of the element; how the value is read depends on Size Mode
iconColorColor—Colour of the icon
iconIconSourceIcon—Which glyph to show, picked from an installed icon set
iconImageSourceImage—Image file to show instead of an icon-set glyph
iconPlacementEnum (left, right)leftWhich side of the label the icon sits on, with Icon Spacing as the gap between them
iconSizeNumber16Height of the icon
iconSourceTypeEnum (image, icon)iconWhether the icon comes from an installed icon set or from an image file, which decides the source port below
iconSpacingNumber10Gap between the icon and the text beside it
labelStringLabelText shown on this element
letterSpacingNumberAutoExtra space added between characters; leave as Auto to use the spacing built into the font
lineHeightNumberAutoVertical space each line of text occupies; leave as Auto to follow the font
marginBottomNumber—Space outside the element's bottom edge, between it and its neighbours
marginLeftNumber—Space outside the element's left edge, between it and its neighbours
marginRightNumber—Space outside the element's right edge, between it and its neighbours
marginTopNumber—Space outside the element's top edge, between it and its neighbours
maxHeightNumber—Largest height the element may grow to, taking priority over Height
maxWidthNumber—Largest width the element may grow to, taking priority over Width
minHeightNumber—Smallest height the element may shrink to, taking priority over Height
minWidthNumber—Smallest width the element may shrink to, taking priority over Width
mixBlendModeEnum (normal, multiply, screen, overlay, darken, lighten, color-dodge, color-burn, hard-light, soft-light, difference, exclusion, hue, saturation, color, luminosity)normalHow this element's colours blend with whatever is painted behind it
mountedBooleantrueRemoves the element from the page entirely when false, unlike Visible which leaves its space behind
opacityNumber1How opaque this element is, from 0 for invisible to 1 for solid
paddingBottomNumber0Space inside the element's bottom edge, between it and its content
paddingLeftNumber0Space inside the element's left edge, between it and its content
paddingRightNumber0Space inside the element's right edge, between it and its content
paddingTopNumber0Space inside the element's top edge, between it and its content
positionEnum (relative, absolute, sticky, fixed)relativeHow the element is placed: In Layout follows its siblings, Absolute ignores them, Sticky pins to the parent edge on overflow, Fixed stays put and takes no space
sizeModeEnum (explicit, contentWidth, contentHeight, contentSize)contentSizeWhether Width and Height are used as given, or the element sizes itself to fit its contents
styleCssString/* background-color: red; */Raw CSS declarations applied to this element, overriding the styling ports above
textStyleTextStyleNoneApplies one of the project's saved text styles; the individual font ports below override whatever it sets
textTransformEnum (none, uppercase, lowercase, capitalize)noneForces the text to upper case, lower case or capitalised without changing the underlying value
transformOriginXNumber50Horizontal point the element rotates and scales around, as a fraction of its width
transformOriginYNumber50Vertical point the element rotates and scales around, as a fraction of its height
transformRotationNumber0Rotates the element clockwise in degrees, without affecting the layout
transformScaleNumber1Scales the element about its transform origin; 1 leaves it unscaled
transformXNumber0Moves the element right after layout, without moving its siblings
transformYNumber0Moves the element down after layout, without moving its siblings
useIconBooleanfalseShows an icon on this element
useLabelBooleantrueShows a text label on this element
variantString—Name of a saved variant of this node type to apply, replacing the styling set here
visibleBooleantrueHides the element while keeping the space it occupies in the layout
widthDimension100Width of the element; how the value is read depends on Size Mode
zIndexNumber—Paint order among overlapping siblings; higher numbers paint on top

Outputs​

Values​

NameTypeDefaultDescription
boundingHeightNumber—Height this element actually ended up with after layout, in pixels
boundingWidthNumber—Width this element actually ended up with after layout, in pixels
childIndexNumber—This element's position among its parent's children, counting from 0
childrenCountNumber—How many child elements are currently mounted inside this one
enabledBoolean—Reports back whether this control is currently accepting interaction, following the Enabled input
focusStateBoolean—True while this control holds keyboard focus, so typing and Enter go to it
hoverStateBoolean—True while the pointer is over this control; stays false on touch devices with no pointer
pressedStateBoolean—True while a mouse button or finger is held down on this control, and false again the moment it is released or slides off
screenPositionXNumber—Distance in pixels from the left edge of the window to this element's left edge
screenPositionYNumber—Distance in pixels from the top edge of the window to this element's top edge
thisReference—A reference to this node itself, for ports that take a node rather than a value

Signals​

NameTypeDefaultDescription
didMountSignal—Fires once this element has been added to the page and can be measured
hoverEndSignal—Fires when the pointer leaves this control, including when it leaves while a button is still held
hoverStartSignal—Fires when the pointer moves onto this control
onBlurSignal—Fires when keyboard focus leaves this control, which is the usual place to validate what was entered
onClickSignal—Fires when the button is clicked or tapped, and on Enter or Space while it has keyboard focus
onFocusSignal—Fires the moment this control takes keyboard focus, whether from a click, a tab or a Focus action
pointerDownSignal—Fires as a mouse button or finger goes down on this control, before any click has completed
pointerUpSignal—Fires when the mouse button or finger is lifted, and also when a touch is cancelled by the system
willUnmountSignal—Fires just before this element is removed from the page, while it still exists

Dynamic ports​

This node's port list changes at runtime (declared-port-groups); the tables above may be incomplete for a given instance.

Declares conditional/expandable port groups whose visibility depends on parameter values (see declaredPortGroups).

ConditionInputs shownOutputs shown
sizeMode = explicit OR sizeMode = contentHeightwidth—
sizeMode = explicit OR sizeMode = contentWidthheight—
useLabel = true OR useLabel NOT SETlabel, textStyle, fontFamily, fontSize, fontWeight, fontStyle, color, letterSpacing, lineHeight, textTransform, fontVariantNumeric—
useIcon = trueiconSourceType, iconSize, iconPlacement, iconSpacing—
useIcon = true AND iconSourceType = imageiconImageSource—
useIcon = true AND iconSourceType = iconiconIconSource, iconColor—
borderStyle = solid OR borderStyle = dashed OR borderStyle = dottedborderWidth, borderColor—
borderLeftStyle = solid OR borderLeftStyle = dashed OR borderLeftStyle = dotted OR borderStyle = solid OR borderStyle = dashed OR borderStyle = dottedborderLeftWidth, borderLeftColor—
borderTopStyle = solid OR borderTopStyle = dashed OR borderTopStyle = dotted OR borderStyle = solid OR borderStyle = dashed OR borderStyle = dottedborderTopWidth, borderTopColor—
borderRightStyle = solid OR borderRightStyle = dashed OR borderRightStyle = dotted OR borderStyle = solid OR borderStyle = dashed OR borderStyle = dottedborderRightWidth, borderRightColor—
borderBottomStyle = solid OR borderBottomStyle = dashed OR borderBottomStyle = dotted OR borderStyle = solid OR borderStyle = dashed OR borderStyle = dottedborderBottomWidth, borderBottomColor—
boxShadowEnabled = trueboxShadowOffsetX, boxShadowOffsetY, boxShadowInset, boxShadowBlurRadius, boxShadowSpreadRadius, boxShadowColor—

Ports at runtime​

Declared-port-groups: icon ports appear when an icon source is chosen, and each visual state (hover, pressed, disabled, focused) contributes state-scoped styling ports. The catalog list is the superset; the editor shows the subset matching current parameters.

Patterns​

  • onClick → Condition eval: validate before acting.
  • onClick → RouterNavigate navigate: page navigation.
  • A boolean derived from form state → enabled: prevent invalid submits at the source.

Watch out for​

  • Simulating disabled state by hiding the button; drive enabled instead so layout and accessibility stay intact.

Examples​

Validate an input before acting on a click

The idiomatic gate shape: a Button click does not act directly — it evaluates a Condition. The Condition's boolean comes from an Expression that checks the text input's current value, so the same click either proceeds (ontrue) or reveals an error message (isfalse drives the error Text's visibility as a level, not a pulse). Note the two kinds of flow: text/booleans are values, onClick/eval/ontrue are momentary signals.

Router page navigation from a button

URL-style navigation: a Router hosts the app's pages (each page is a component, configured in the Router's pages parameter), and a Navigate node (RouterNavigate) switches it. The Button's onClick signal triggers navigate; which page to go to, and any path parameters, are set on the Navigate node's parameters — those ports are created from the Router's page configuration at edit time, which is why they are runtime-determined in the catalog.

Split hero: copy column and image, with a display headline that looks set rather than typed

Two columns inside the shell, each width 100% so an UNWRAPPED row shrinks them to half each — this is why a plain row works where a wrapped grid does not. The copy column carries the page's one display headline (--display-lg — a fluid clamp() that is 44px on a phone and 96px on a wide desktop — with --font-bold, --leading-none and --tracking-tighter; tight tracking is what makes a large heading look set), an eyebrow above it, a lead paragraph capped at ~520px, and two buttons whose concrete parameters are copied from the style vocabulary because variant is a connection-only port. The image gets sizeMode "explicit" plus a width, a height and objectFit "cover" — without explicit sizing those three ports are inert and the photo renders at its natural size.

Empty state: what a list shows when it has no rows

A list with nothing in it should say what it is and what to do, not render nothing. The designed version is small and centred inside a dashed card: an icon in a muted disc, one heading, one line of explanation capped at ~380px, and exactly one action. The switch is one wire: the query's isEmpty boolean into the empty state's mounted input. Use mounted, not visible — mounted takes the element out of the layout, while visible only hides it and keeps the space it occupies, which leaves a page-height hole above your empty state. The list needs no gate at all: a For Each over an empty array renders no rows and occupies no height, so nothing has to be inverted and no logic node is involved. Skipping the empty state is the difference between an app that looks unfinished on first run and one that does not, and first run is when it is always seen.

Group, Text Input, Condition, Navigate

Generated

This page is generated from node-catalog-enriched.json. Do not edit it by hand — run npm run docs:nodes to regenerate, and fix the source enrichment instead.