---
title: SC Props Generator
description: Delimiter-separated lines become a props table, desktop or mobile.
url: https://secretocho.design/lab/sc-props-generator/
type: SoftwareSourceCode
status: working
published: 2026-10-05
---

# SC Props Generator

> Delimiter-separated lines become a props table, desktop or mobile.

component 18 / 28 · WORKING

- **type**: Code Component
- **platform**: Framer
- **license**: SecretoCho Design

![A still of the SC Props Generator demo, as its module draws it with reduced motion.](https://secretocho.design/_astro/still.U9aa5ELk_1YUnmz.webp)

*fig 00 · live demo, ported from **SC\_PropsTable.tsx***

Text-to-table props documentation: delimiter-separated lines become a desktop table or a collapsible mobile list, with variable-font axes per column.

Props Generator renders a component’s property table from plain text. One line per prop, four columns separated by a delimiter (name :: type :: default :: description), and the component draws either a four-column desktop table or a collapsible mobile list with name and type chips. Variable-font axes for labels and values are separate, so a mono value column can sit next to a casual label.

It is the component behind the props rows of the old site’s component pages: the CMS Props field uses the same name::type::default::description lines.

- Utilities
- Data
- Design System
- Typography

## Main

### Overview

- **Built With**: React (hooks), CSS (inline), Framer Code Component API
- **Layout Support**: Fills the frame width; the desktop / mobile variant is a prop, not a media query
- **Orientation**: Rows: 25 / 15 / 20 % + flexible description column (desktop); name + type chips with an expandable default / desc panel (mobile)
- **Ideal Use Case**: Component documentation pages, API tables inside Framer, design-system reference

### Tags

- props
- table
- documentation
- api
- delimiter
- variable font
- recursive
- design system

### Code comment

SC\_PropsTable.tsx has no doc comment.

### Dependencies

- **Technologies**: None (pure React + inline CSS)
- **Notes**: No external libraries; the variable-font axes assume a Recursive-style family (MONO, CASL, CRSV, slnt, wght).

### Complexity

- **Logic Level**: Low–Medium (line and delimiter parsing, two row renderers, axis strings)
- **Runtime Cost**: Very Low (plain DOM, hover state per row)
- **Component Size**: ~24 KB TSX (23,726 bytes, 734 lines)
- **Notes**: DesktopRow and MobileRow are declared inside the component, so React remounts them on every parent render (their hover / expanded state resets).

## Guide

### Instructions

1. Drop **Props Generator** into a frame.
2. Fill **Props Data**: one prop per line, columns separated by the **Delimiter** (default ::): name::type::default::description.
3. Pick the **Variant**: Desktop (XL -- Main), Mobile Collapsed (S -- Main) or Mobile Expanded (S -- Extended). Use Framer breakpoints to switch variants.
4. Set the **Font**; turn on **Variable Font** to expose **Label Axes** and **Value Axes**.
5. Adjust the border, background, card and hover colours.

### Examples / Presets

- Desktop
  
  - **variant**: XL -- Main (the default four-column table)
  
- Mobile Collapsed
  
  - **variant**: S -- Main (name and type chips; tap a row for default and desc)
  
- Mobile Expanded
  
  - **variant**: S -- Extended (every row starts open)
  
- Site style
  
  - **variableAxes**: true
  - **labelAxes.MONO**: 1
  - **labelAxes.wght**: 500
  - **valueAxes.MONO**: 1
  - **valueAxes.wght**: 400 (the old site’s component-page settings; its font and colours come from the demo module)
  

The default Props Data (four pattern props) is the text the component ships with; the demo’s “Site style” rows are the CMS Props of an existing lab entry.

## Mechanics

### How it Works

- **Parse**: Props Data is split on newlines, blank lines dropped, each line split on the delimiter and trimmed; a missing column falls back to the placeholder word (name, type, default, description).
- **Desktop row**: four cells at 25 / 15 / 20 % and flex 1, separated by 1 px lines; name and default sit in bordered chips, type and description are plain text; hover swaps the row background and text colour.
- **Mobile row**: a top row with name: and type: chips and a chevron; default: and desc: live in a panel that toggles on click. S -- Extended sets every row open on mount.
- **Fonts**: toVariableStack rewrites the first family to “\<Family\> Variable”; two axis strings are built (labels and values) and font-weight is unset when a wght axis is present.
- **Empty state**: with no rows the component shows the expected format and an example line.

### Performance & Tuning

- Plain DOM; cost is one row per line. Dozens of props are fine.
- Hover and expanded state live inside row components declared in the render function, so each parent render recreates them; keep the parent’s props stable.

### Compatibility & Limits

- Evergreen browsers; no APIs beyond React.
- The variant does not respond to width by itself: switch it per Framer breakpoint.
- Delimiter characters that appear inside a description will split the line; choose a delimiter the text never uses. An empty Delimiter splits each line into characters.
- With Variable Font on, the family stack quotes “sans-serif”, so the generic fallback is lost.

## Quality

### Accessibility

- Rows are \<div\>s, not a \<table\>: screen readers get text in order but no column headers.
- The mobile toggle is a clickable \<div\> without a button role or keyboard handler.
- Default label colour #666 on rgba(0,0,0,0.02): check contrast on dark pages.

### Security & Privacy

- No network calls, no storage, no permissions, no third-party libraries.
- Text is rendered as React text nodes; no dangerouslySetInnerHTML or eval.

## Reference

### Props

| name | type | default | description |
| --- | --- | --- | --- |
| propsData | string | four pattern props (patternType, size, strokeWidth, angle), one per line | Props Data. Enter props data (one per line). |
| delimiter | string | :: | Delimiter. Characters that separate values. |
| variant | enum | XL -- Main | Variant. XL -- Main (Desktop) \| S -- Main (Mobile Collapsed) \| S -- Extended (Mobile Expanded). |
| font | FontStyle | Inter, system-ui, sans-serif · 14 · 400 · 1.5 | Font. Family, size, weight, letter spacing and line height for every cell. |
| variableAxes | boolean | false | Variable Font. Enable variable font axes. |
| labelAxes | object | MONO=0, CASL=0, CRSV=0, slnt=0, wght=500, cssFontWeight=500 | Label Axes. MONO 0–1, CASL 0–1, CRSV 0–1, slnt −15–0, wght 300–1000, cssFontWeight 100–1000 (fallback when the wght axis is not applied); applied to the mobile labels (name:, type:, default:, desc:). |
| valueAxes | object | MONO=0, CASL=0, CRSV=0, slnt=0, wght=400, cssFontWeight=400 | Value Axes. MONO 0–1, CASL 0–1, CRSV 0–1, slnt −15–0, wght 300–1000, cssFontWeight 100–1000 (fallback when the wght axis is not applied); applied to the values and the desktop cells. |
| borderColor | color | rgba(0, 0, 0, 0.04) | Border Color. Row borders and the vertical separators. |
| backgroundColor | color | rgba(0, 0, 0, 0.02) | Background. Row background. |
| hoverBackgroundColor | color | rgba(0, 0, 0, 0.04) | Hover Background. Desktop row background on hover. |
| cardBackgroundColor | color | rgba(0, 0, 0, 0.03) | Card Background. The desktop name and default chips, and all four chips on mobile. |
| labelColor | color | #666 | Label Color. Color for mobile labels (name:, type:, etc.). |
| valueColor | color | #111 | Value Color. Color for actual content values. |
| hoverColor | color | rgba(0, 0, 0, 0.9) | Hover Color. Color applied to both labels and values on hover. |

### Notes & Tips

- Write the four columns in order; a missing fourth column shows the word “description”, which is a useful reminder while drafting.
- Keep defaults short on desktop: the default chip does not wrap (white-space: nowrap).
- For a mono value column with proportional labels set valueAxes.MONO = 1 and labelAxes.MONO = 0.

### Troubleshooting / FAQ

Columns are shifted

A line contains the delimiter inside its text, or uses a different delimiter; check the Delimiter control.

Each row reads the whole line / type / default / description

The lines have no delimiter, so each whole line became the name and the rest fell back to placeholders.

Mobile rows collapse again after an edit

The row components are recreated on each parent render; this resets their open state. Use S -- Extended when rows should stay open.

Table shows “Add Props Data”

Props Data is empty or only blank lines.

## Source

### Header comment

SC\_PropsTable.tsx has no doc comment.

[props \[REF\]](#reference)

### Key excerpt

One text area is the whole API: each line splits on the delimiter into name, type, default and description, with a placeholder word wherever a column is missing.

*SC\_PropsTable.tsx · lines 108–124 · tsx*

```tsx
    // Parse the text data
    const parsedRows = useMemo(() => {
        if (!propsData || propsData.trim() === "") return []

        return propsData
            .split("\n")
            .filter((line) => line.trim())
            .map((line) => {
                const parts = line.split(delimiter).map((p) => p.trim())
                return {
                    name: parts[0] || "name",
                    type: parts[1] || "type",
                    default: parts[2] || "default",
                    description: parts[3] || "description",
                }
            })
    }, [propsData, delimiter])
```

## Credits

### Credits

© SecretoCho Design

- **license**: SecretoCho Design

SecretoCho Design

### Disclaimer

Provided “as is” for visual/UX purposes. Validate performance, accessibility, and licensing within your project.

## Proves

- [Creative coding](https://secretocho.design/about/#capabilities)

## 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](mailto:sc@secretocho.design)

[read the CV](https://secretocho.design/cv/) · [LinkedIn](https://www.linkedin.com/in/secretocho/)
