component 15 / 28WORKING
SC Simple Data Display (Pattern)
- type
- Code Component
- platform
- Framer
- last update
- read time
- 8–11 min
- license
- SecretoCho Design
demo · runs with JavaScript
CMS-friendly label:value list with a leading pattern column, responsive desktop/stacked layouts, and per-column variable-font axis tuning.
CMS-friendly label/value list with an optional pattern column for visual rhythm. Supports variable-font axes per column, responsive switch to a stacked layout, and a friendly placeholder when no data is provided.
- Data
- Typography
- Layout
Main
Overview
- Built With
- React, CSS, Framer Code Component API
- Layout Support
- Fully Responsive (switches to stacked view under breakpoint)
- Orientation
- Pattern column → label → value (desktop); stacked rows (mobile)
- Ideal Use Case
- Pricing/spec blocks, feature matrices, project metadata, compact CMS hand-offs
Tags
Code comment
/** * Simple Data Display (Pattern) * © SecretoCho Design 2025 (https://secretocho.design) * CMS-friendly label/value list with optional pattern column. * Variable-font axis control per column; responsive layout via ResizeObserver. * @framerDisableUnlink * @framerSupportedLayoutWidth any * @framerSupportedLayoutHeight any */Dependencies
- Technologies
- None (pure React + CSS)
- Notes
- No runtime libraries required; works with Framer’s runtime. Variable font axes require a VF family in your project.
Complexity
- Logic Level
- Low–Medium (string parsing + responsive observer)
- Runtime Cost
- Very Low (text rendering)
- Component Size
- ~3–4 KB (raw TSX)
- Notes
- Axes apply via font-variation-settings; provide a VF stack or disable Variable Font.
Guide
Instructions
- Content: In Content, enter one row per line as Label::Value (or change Delimiter).
- Pattern: Choose Pattern, Pattern Color, Pattern Width, and Pattern Align.
- Typography: Pick Font, Label Color, Value Color.
- Variable Fonts: Toggle Variable Font; tune Label Axes and Value Axes (MONO, CASL, CRSV, slnt, wght).
- Layout: Set Label Width, Column Gap, Row Gap, enable Responsive and set Breakpoint.
- Empty State: If no content, a helper placeholder appears automatically.
Examples / Presets
Preset: Spec Sheet Minimal
CPU::Apple M3RAM::16 GBStorage::512 GB SSDDisplay::14" 3024×1964Preset: Project Meta
Client::SecretoCho DesignScope::UI EngineeringStack::Framer, TypeScript, Three.jsStatus::In Production
- Pattern //, Pattern Align right, CASL slight 0.2 on labels.
Mechanics
How it Works
- Parsing: Splits content by newline → each line split by delimiter → {label, value}.
- Pattern Column: Renders pattern as text with reduced opacity; width fixed by Pattern Width.
- Variable Fonts: If Variable Font is on, converts the first family in the stack to its " Variable" form and applies font-variation-settings per column; falls back to cssFontWeight when wght isn’t applied.
- Responsive: A ResizeObserver checks container width and flips to a stacked layout at Breakpoint.
Performance & Tuning
- Prefer concise patterns (e.g. #, //, ·) to avoid visual noise.
- Long values: rely on built-in word-break: break-word.
- Large lists: rendering is light; main cost is text layout—keep Row Gap modest.
Compatibility & Limits
- Modern evergreen browsers.
- Variable font axes require VF support; if unavailable, component falls back to font-weight.
- No server/client fetches; purely presentational.
Quality
Accessibility
- Treat the list as terms + descriptions. For maximum semantics, consider placing the component inside a region with an accessible name, or replicate with <dl>/<dt>/<dd> when exporting to code.
- Pattern column is decorative; if it confuses SRs, wrap it with aria-hidden="true".
- Placeholder uses aria-live="polite" to hint updates when content becomes available.
Security & Privacy
- No network calls; no storage; no device permissions.
- Inputs are rendered as text (not HTML) — no dangerouslySetInnerHTML, no eval.
- Main foot-gun is very large content leading to long pages; paginate or limit rows in CMS.
Reference
Props
| name | type | default | description |
|---|---|---|---|
content | string | "Label::Value\n..." | Multi-line source (one row per line). |
delimiter | string | "::" | Separator between label and value. |
pattern | string | "#" | Characters painted in the pattern column. |
patternColor | color | rgba(0,0,0,0.64) | Pattern text color. |
patternWidth | number(px) | 30 | Fixed width of the pattern column. |
patternAlign | enum | center | Pattern text alignment (left|center|right). |
font | FontValue | Recursive, ... | Shared base font for both columns. |
labelColor | color | #666 | Label text color. |
valueColor | color | #111 | Value text color. |
variableAxes | boolean | true | Enable variable-font axes. |
labelAxes | Axes | { MONO:1, CASL:0, CRSV:0, slnt:0, wght:400, cssFontWeight:400 } | – |
valueAxes | Axes | { MONO:1, CASL:0, CRSV:0, slnt:0, wght:600, cssFontWeight:600 } | – |
labelWidth | number(px) | 180 | Fixed label column width (desktop). |
gap | number(px) | 20 | Gap between columns. |
rowGap | number(px) | 8 | Gap between rows (desktop). |
mobileRowGap | number(px) | 24 | Gap between groups on mobile. |
responsive | boolean | true | Enable layout switch based on width. |
breakpoint | number(px) | 600 | Width to switch to stacked layout. |
placeholderMinHeight | number(px) | 120 | Minimum height of the empty-state box. |
Notes & Tips
- Use monospace flavor (MONO: 1) for technical feel in values.
- Keep Label Width tight to encourage values to wrap, not labels.
- Patterns read best at 24–36px width; align left for subtlety, center/right for ornament.
Troubleshooting / FAQ
My rows don’t split.
Ensure your delimiter matches Delimiter (default ::).
Text wraps oddly.
Increase Label Width or adjust gap.
Variable axes not applying.
Confirm your chosen font is a Variable Font; otherwise disable Variable Font or rely on cssFontWeight.
Source
Header comment
/** * Simple Data Display (Pattern) * © SecretoCho Design 2025 (https://secretocho.design) * CMS-friendly label/value list with optional pattern column. * Variable-font axis control per column; responsive layout via ResizeObserver. */Key excerpt
Rows split on the delimiter (a value may contain it), and a ResizeObserver switches to the stacked layout at the breakpoint.
const dataRows = useMemo(() => { if (!content || content.trim() === "") return [] return content .split("\n") .filter((line) => line.trim()) .map((line) => { const parts = line.split(delimiter) const label = parts[0]?.trim() || "" const value = parts.slice(1).join(delimiter).trim() || "" return { label, value } }) }, [content, delimiter]) const hasValidData = dataRows.length > 0 // Determine display mode const [isMobile, setIsMobile] = React.useState(false) React.useEffect(() => { if (!responsive) { setIsMobile(false) return } const checkWidth = () => { if (containerRef.current) { setIsMobile(containerRef.current.offsetWidth <= breakpoint) } } checkWidth() const resizeObserver = new ResizeObserver(checkWidth) if (containerRef.current) { resizeObserver.observe(containerRef.current) } return () => resizeObserver.disconnect() }, [responsive, breakpoint])Credits
Credits
Variable-font axis controls inspired by modern VF practices (e.g., Recursive).
Development, Implementation and Framer adaptation by SecretoCho Design.
- license
- SecretoCho Design
SecretoCho Design 2025
Disclaimer
Provided “as is” for visual/UX purposes. You are responsible for verifying performance, accessibility, and any font licensing in your project.
Proves
Hiring a design engineer?
I’m open to senior design engineer roles: remote from Belgrade, or relocation with visa sponsorship. Write to me, or read the CV first. Client work stays selective, one project at a time.
sc@secretocho.design