Skip to main content
cngx-src documentation

CngxTimelineConnector

ComponentOnPushNo encapsulationv0.1.0WCAG AA

projects/common/timeline/connector.component.ts

Import#

import { CngxTimelineConnector } from '@cngx/common/timeline'

Description#

The rail segment between two markers.

Decorative and aria-hidden: it repeats a sequence the DOM order already carries, so announcing it would only add noise. It is status-capable all the same, because the visual run of a history is where a rejected step or a not-yet-reached tail reads fastest - a dashed segment for upcoming and a danger-toned one for rejected, so the distinction survives without colour.

Drawn with border-inline-start and clipped with block-direction margins - logical properties throughout, so the rail lands on the correct side under dir="rtl" with no override.

Between two items

<cngx-timeline-connector status="done" />

Last item in the run

<cngx-timeline-connector position="last" />

Metadata#

Host#

Relationships

Index#

Inputs#

input()

Position in the run. 'first' clips the head back to the marker centre, 'last' clips the tail, 'only' hides the segment entirely. Defaults to 'middle' - a full-height segment.

default 'middle'
input()

Status of the segment. upcoming renders dashed, rejected in the danger tone, done and active solid in their own tones. Left unset the rail paints in the neutral border colour.

HostBindings#

BindingExpression
[attr.data-status]status()
[attr.data-position]position()

The --cngx-timeline-* custom-property family, shared by every artifact in @cngx/common/timeline and re-used by the <cngx-timeline> organism in @cngx/ui/timeline. A pure token surface - registrations plus :root chains, no structural rules and no @scope.

It lives with the atoms rather than with the organism on purpose: a <cngx-timeline-item> dropped into a hand-rolled layout has to render complete and density-correct on its own. A token family that only resolved under a Level-4 host would make the molecule a fragment instead of a terminal unit.

Where the spacing tokens are, and why not here

This file carries no -gap / -padding registration. A spacing token is registered in the same stylesheet that SETs it from --cngx-space-*, at that component's own host:

  • --cngx-timeline-gap, --cngx-timeline-row-gap, --cngx-timeline-content-padding - timeline-item.component.css
  • --cngx-timeline-group-gap - the organism's stylesheet

Registering them here and SETting them there would put a registration one file away from its derivation, where the two can drift silently: a registered initial-value defeats every use-site var(token, fallback), so a token that loses its SET rule freezes at the literal and a nested [data-density] never reaches it. Keeping the pair together makes that failure impossible to introduce by accident, and is what the repo's density guard checks per file.

The sizes that remain here are affordances, not compactness, and are deliberately outside the density scale. --cngx-timeline-rail-inset in particular derives from --cngx-timeline-marker-size: the rail has to meet the marker's centre, and a density swap that moved one without the other would detach the rail from the dot. That derivation is applied at the row host (timeline-item.component.css), the nearest common ancestor of the marker and the connector - custom properties inherit downwards only, so deriving it on either sibling would never reach the other.

Colour and dark mode

Every colour chains to a --cngx-color-* foundation token, which already carries its own light and dark values. Dark mode therefore needs no per-token redefinition here - overriding --cngx-color-primary or the active colour scheme re-themes the timeline for free. The literal in each chain's tail is the leaf default for consumers running without the foundation stylesheet.

  • --cngx-timeline-connector-color -> --cngx-color-border
  • --cngx-timeline-surface -> --cngx-color-surface
  • --cngx-timeline-text-color -> --cngx-color-text
  • --cngx-timeline-muted-color -> --cngx-color-text-muted
  • --cngx-timeline-done-color -> --cngx-color-success
  • --cngx-timeline-active-color -> --cngx-color-primary
  • --cngx-timeline-rejected-color -> --cngx-color-danger
  • --cngx-timeline-upcoming-color -> --cngx-color-text-muted

Default visuals for CngxTimelineConnector - the vertical rail between two markers.

Geometry

The rail is the element's own border-inline-start, which puts it on the left in LTR and on the right in RTL with no override and no physical property anywhere in this file. justify-self: center inside the item's marker column lines it up with the dot above it.

Position modifiers

[data-position] clips the segment back to the adjacent marker's centre using --cngx-timeline-rail-inset:

  • middle (default) - full height
  • first - head clipped, so the rail starts at the first marker
  • last - tail clipped, so the rail stops at the last marker
  • only - not rendered; a single-item timeline has no rail

Status modifiers

[data-status] recolours the border, and upcoming also switches it to dashed so the state does not rest on colour alone.

Orientation

[data-orientation='horizontal'] on any ancestor swaps the rail onto the other axis: the border moves from border-inline-start to border-block-start, the position clips move from margin-block-* to margin-inline-*, and the status recolours follow. Still no physical property anywhere - in horizontal the run's main axis is the inline axis, so RTL reverses the whole timeline for free, exactly as the block axis carries it in vertical.

Index#

Layout

--cngx-timeline-rail-inset#<length>
Default value 6px

Distance the rail is pulled back from the edge of the marker cell so it meets the marker's centre. Affordance geometry, deliberately outside the density scale - it tracks --cngx-timeline-marker-size instead, and a density swap that moved it would detach the rail from the dot.

--cngx-timeline-marker-size#<length>
Default value 12px

Diameter of the marker dot.

--cngx-timeline-marker-glyph-size#<percentage>
Default value 60%

Size of a bare svg glyph projected into the marker, as a share of the marker box. A percentage rather than a length so it tracks --cngx-timeline-marker-size on its own: em would resolve against the marker's pinned font-size, which is not the dot's size.

Photos are not covered by this - an img or picture fills the dot edge to edge, because a cropped portrait wants no inset and a glyph does.

--cngx-timeline-item-inline-size#<length>
Default value 192px

Width of one row on the horizontal axis. Ignored in the vertical default, where a row takes the container's width.

An affordance, not compactness, so it is deliberately outside the density scale. It exists because a horizontal run has no sensible content-derived width: flex would size every card to its longest word and the axis would read as a ragged queue. Override per instance for denser or wider cards.

--cngx-timeline-connector-width#<length>
Default value 2px

Thickness of the connector rail.

--cngx-timeline-marker-ring-width#<length>
Default value 3px

Width of the halo ring drawn around a marker in the active status.

Surface

--cngx-timeline-connector-color#<color>
Default value oklch(0.88 0.005 250)

Colour of the connector rail in its default (unstated) status.

See: [[--cngx-color-border]]

--cngx-timeline-surface#<color>
Default value oklch(1 0 0)

Background the marker is punched out of, so a coloured rail passing behind the dot does not show through it.

See: [[--cngx-color-surface]]

Typography

--cngx-timeline-marker-fg#<color>
Default value oklch(1 0 0)

Foreground colour of a glyph projected into the marker.

--cngx-timeline-meta-size#*
Default value 0.8125rem

Font size for secondary text across the family - timestamps, inline errors, date headers, the refreshing tail. Registered here rather than with either consumer, because the row and the organism both read it and a registration in one is out of scope for the other.

--cngx-timeline-text-color#<color>
Default value oklch(0.2 0.01 250)

Primary text colour inside an item.

See: [[--cngx-color-text]]

--cngx-timeline-muted-color#<color>
Default value oklch(0.5 0.01 250)

Secondary text colour - timestamps, group headers, the refreshing tail.

See: [[--cngx-color-text-muted]]

Variant / Done

--cngx-timeline-done-color#<color>
Default value oklch(0.6 0.15 145)

Marker and rail colour for the done status.

See: [[--cngx-color-success]]

Variant / Active

--cngx-timeline-active-color#<color>
Default value oklch(0.66 0.19 50)

Marker and rail colour for the active status.

See: [[--cngx-color-primary]]

Variant / Upcoming

--cngx-timeline-upcoming-color#<color>
Default value oklch(0.5 0.01 250)

Marker and rail colour for the upcoming status. Pairs with a dashed rail, so the state survives a colour-blind reader.

See: [[--cngx-color-text-muted]]

Variant / Rejected

--cngx-timeline-rejected-color#<color>
Default value oklch(0.6 0.18 25)

Marker and rail colour for the rejected status, and for an item whose own [state] failed.

See: [[--cngx-color-danger]]

Motion

--cngx-timeline-pulse-duration#<time>
Default value 1.6s

Period of the busy pulse on a marker. Set to 0s to stop it without touching the rest of the family.