Marker Primitives
Composable glyphs, badges, pills, icons, indicators, and presets for Formation marker systems. Use them to build custom slot-based marker UI or start from a ready-made preset.
Composable building blocks.
These primitives are designed to live inside Formation marker slots. The catalogue below shows the individual parts first; the stories underneath show how the same pieces behave in a full lineup context.
Canonical behaviors.
Formation gives each marker 8 fixed slots around the central glyph. Slot content can be a single primitive or a stacked array; layout and pitch-edge clamping stay with the Formation layer.
top, left, and right stay centered on their anchor.
Corner slots pin the first item to the corner and stack outward from the marker.
bottom sits directly below the glyph and pushes the name pill farther down.
Dual-team horizontal layout using the FotMob preset. The slot system stays the same; the preset decides which primitives go where.
Same lineup context with the SofaScore preset. Presets change the marker composition, not the underlying formation or pitch wiring.
Shared concerns.
Slot Ownership
Marker primitives do not position themselves. Formation owns the 8-slot map, stacking, and pitch-edge clamping. Primitives should stay focused on their own visual footprint.
Themeability
Marker pages inherit the shared pitch-theme controller because presets usually render in formation context. The marker primitives themselves stay independent from pitch theming.
Cell Sizes
The slot layout engine relies on each primitive's nominal cell size. When adding a new custom primitive, register or provide a cell size so stacking and clamping remain stable.
Accessibility
Marker primitives are usually not standalone interactive elements. Accessibility belongs to the chart or formation wrapper that owns names, legends, and reading order.
Best-practice examples.
Custom Slot Composition
Build marker UI by choosing a central glyph and returning slot content. Formation owns placement, stacking, and edge clamping.
import {
CountBadge,
FootballFillIcon,
Formation,
MarkerBadge,
MarkerIcon,
MarkerPill,
RatingPill,
} from "@withqwerty/campos-react";
<Formation
formation="4-3-3"
players={players}
markers={{ glyphKind: "photo" }}
markerLabels={{ nameFormat: (player) => `${player.number} ${player.label}` }}
markerComposition={{
slots: ({ player, r }) => ({
topLeft: player.captain ? (
<MarkerBadge size={r * 0.75}>
<MarkerIcon kind="captain" r={r * 0.68} />
</MarkerBadge>
) : null,
topRight:
player.rating != null ? <RatingPill r={r} rating={player.rating} /> : null,
right:
player.transferValue != null ? <MarkerPill r={r} text={player.transferValue} /> : null,
bottomRight:
player.goals != null ? (
<CountBadge
r={r}
count={player.goals}
icon={<FootballFillIcon size={r * 0.58} color="#1a202c" strokeColor="#1a202c" />}
/>
) : null,
}),
}}
/>
Preset
Use a ready-made preset when you want a coherent marker system without rebuilding the slot map yourself.
import { Formation, formationMarkerPresets } from "@withqwerty/campos-react";
<Formation
formation="4-3-3"
players={players}
{...formationMarkerPresets.sofascore()}
pitchTheme="secondary"
/>
Public surface.
Composable Primitives
Standalone marker building blocks. Use them directly inside marker slots or custom render functions.
| Prop | Type | Description |
|---|---|---|
MarkerCircle / MarkerPhoto / MarkerShirt | glyph primitives | Central marker glyphs. Use them directly or reference them through markers.glyphKind / markerComposition.glyph. |
MarkerIcon | kind + r | Raw icon primitive for captain, cards, substitution, goal, assist, and outline variants. |
MarkerBadge | size + children | Circular badge wrapper for icons and other compact primitives. |
CountBadge | r + icon + count | Badge plus icon with an optional count pip for repeated events. |
MarkerPill / RatingPill | r + text/value | Text and rating pills sized from the marker radius. |
DotIndicator / FlagImage / StarIcon | specialized primitives | Minimal indicators for cards, flags, player awards, and other secondary signals. |
FootballFillIcon / BootFillIcon / ArrowUpIcon / ArrowDownIcon | asset icons | Low-level asset icons for goals, assists, and substitutions. |
Slot System And Presets
Formation owns slot layout. Marker primitives plug into that contract rather than solving placement themselves.
| Prop | Type | Default | Description |
|---|---|---|---|
markers.glyphKind / markerComposition.glyph | "circle" | "photo" | "shirt" | render fn | "circle" | First-class glyph selection lives on markers.glyphKind. Use markerComposition.glyph when you need a custom render function. |
markerComposition.slots | ({ player, r, teamColor }) => slot map | - | Returns content for any of the 8 fixed marker slots. Slots can hold one node or a stacked array. |
MARKER_SLOT_NAMES | readonly slot names | - | Stable slot ordering: top, topRight, right, bottomRight, bottom, bottomLeft, left, topLeft. |
formationMarkerPresets | preset factories | - | Ready-made marker systems for common product styles such as FotMob and SofaScore. |
computeMarkerSlotLayout | layout engine | - | Pure slot layout helper used by Formation. Useful when you need the same 8-slot logic outside the main component. |
markers / markerLabels / markerBadges | first-class style families | - | Bounded styling hooks for marker fill/stroke, name-pill treatment, and prefix badges without replacing the slot system. |
Create a React component using Campos marker primitives. Show a Formation with first-class markers and markerLabels styling, then use markerComposition.slots only for the genuinely custom badge content. Keep provider parsing outside the component, and use formationMarkerPresets only when the request matches a named product style.