Painting Borders
The border resolvers read the framework border rails as BorderFill objects. Apply them to custom rails, or convert them for Highcharts axes and grid lines.
Borders and dividers
Every resolver takes an optional { el }: the id
or element whose nearest .screen ancestor
supplies the paint. The probe technique is documented on
Paint API
Paint API
TRMNLPaint: read the live CSS cascade from JavaScript to resolve framework colors and tile patterns
TRMNLPaint is the framework's public JavaScript paint API. It reads the live CSS cascade (bit depth, dark mode, theme, limited palette, and tiles all resolved) and hands back a canonical Fill, so token mappings are never duplicated in JavaScript. Charts are just one consumer; any plugin can resolve framework colors from JS for any purpose.
.
-
border(spec, { dir, el }): a border rail as aBorderFill. Thespecis a shade step from 10 to 75 or the literal'black'/'white'rails;diris'h'(default) or'v'. Framework borders paint as a background on a pseudo-element, so the resolved paint is read there. -
divider({ dir, el }): the level-6.dividerrail as aBorderFill, probed on the element itself.
Dither-mode lines are multi-layer and list-valued, so
BorderFill keeps
size,
position and
repeat as verbatim computed strings. It also
carries the renderer-ready SVG program declared by the same CSS rule; JavaScript never parses gradients or
derives their geometry.
BorderFill = {
color: string | null, // resolved background-color (solid/black-white modes)
image: string | null, // resolved background-image gradient(s); null when "none"
url: string | null, // first url(...) ink tile (black/white rails); null otherwise
size: string | null, // VERBATIM background-size string (dither lines are list-valued)
position: string | null, // VERBATIM background-position string
repeat: string | null, // VERBATIM background-repeat string
render: { // CSS-declared; copied verbatim by renderer adapters
stroke: string | null,
width: string | null,
height: string | null,
viewBox: string | null,
path1: string | null,
color1: string | null,
path2: string | null,
color2: string | null,
} | null,
dir: "h" | "v", // which pseudo/orientation was probed
}
border() is the guaranteed-hairline path: it
probes the fill-backed .border--* utilities,
which carry real ink in every mode and pick up theme tinting for free.
semantic('border-strong') and
semantic('border-muted') describe the semantic
role's token tile, not the directional rail art. Draw rails with
border(); reach for
semantic('border-*') only when you need the
role as a Fill.
// Framework rail utilities, resolved for the current mode/theme.
var gridRail = TRMNLPaint.border(65, { el: "my-chart" }); // -> BorderFill
var axisRail = TRMNLPaint.border("black", { dir: "v", el: "my-chart" });
var step40 = TRMNLPaint.border(40, { el: "my-chart" });
Painting rails
A resolved rail is written back verbatim, so it paints exactly as the CSS
.border--* utilities do. Wrap paints in
watch() so rails re-resolve on mode, dark and
theme changes; see
Paint API
Paint API
TRMNLPaint: read the live CSS cascade from JavaScript to resolve framework colors and tile patterns
TRMNLPaint is the framework's public JavaScript paint API. It reads the live CSS cascade (bit depth, dark mode, theme, limited palette, and tiles all resolved) and hands back a canonical Fill, so token mappings are never duplicated in JavaScript. Charts are just one consumer; any plugin can resolve framework colors from JS for any purpose.
.
-
applyBorder(node, borderFill): writes aBorderFillonto a node as its five background longhands, verbatim, so a solid, a flat gradient and a multi-layer dither line all round-trip unchanged.
Highcharts axes
The axis adapters copy a resolved rail into Highcharts' native options; the fill adapter and the adapter ground rules live on Painting Charts Painting Charts Chart series colors from the framework ramp, with Highcharts adapters The chart resolvers pick evenly spaced series colors from the framework chart ramp, resolved through the live cascade. Adapters convert the resulting Fills into Highcharts color options. .
-
toHighchartsAxis(borderFill): turns aBorderFillinto a{ gridLineColor, gridLineWidth, gridLineDashStyle, lineColor, tickColor }block. -
applyHighchartsAxisPaint(): carries the resolved BorderFill into Highcharts' render cycle and copies its CSS-declared SVG program onto the rendered grid, axis and tick paths. Flat modes declare a stroke; patterned modes declare their complete tile, paths and colors.
// Rails into Highcharts axis/grid options.
var grid = TRMNLPaint.toHighchartsAxis(
TRMNLPaint.border(65, { el: "my-chart" }));
// TRMNLCharts.options() applies the BorderFill pattern to rendered SVG paths.
Live example
The separator under each schedule row is painted with
TRMNLPaint.border() and
TRMNLPaint.applyBorder(), wrapped in
TRMNLPaint.watch(). Each row uses a different
spec (shade steps 65 and 40, the literal black and white rails), labelled on the right. Change the
device mode or Style in the picker and the rails re-resolve, picking up dither art and theme tinting.
<div id="border-strip" class="flex flex--col w--full"></div>
<script type="text/javascript">
// plugins.js bundles TRMNLPaint; wait for it before painting.
function whenReady(cb) {
if (window.TRMNLPaint) return cb();
window.addEventListener("load", function () {
if (window.TRMNLPaint) cb();
}, { once: true });
}
whenReady(function () {
var el = "border-strip";
var SPECS = [65, 40, "black", "white"];
// watch() re-resolves each rail whenever the screen device/scale/mode/dark/theme changes.
TRMNLPaint.watch(el, function () {
var box = document.getElementById(el);
if (!box) return;
box.innerHTML = "";
SPECS.forEach(function (spec) {
var row = document.createElement("div");
row.style.cssText = "padding:12px 0;";
row.textContent = "border(" + JSON.stringify(spec) + ")";
var rail = document.createElement("div");
rail.style.cssText = "height:2px;width:100%;";
// applyBorder writes the five background longhands verbatim, so the
// rail paints exactly as the CSS .border--* utilities do.
TRMNLPaint.applyBorder(rail, TRMNLPaint.border(spec, { el: el }));
box.appendChild(row);
box.appendChild(rail);
});
});
});
</script>