soft

App data

Tables, charts and content widgets for real apps: all generated from data attributes, all themed with tokens.

Table

sf-table in sf-table-wrap. Add data-sf-tablesort and data-sf-selectable; sf-table--stack turns rows into cards on phones. Set --sf-table-h on the wrap for a scrolling body with a sticky header.

Recent orders
OrderCustomerStatusTotalDate
#1042Maya OkaforPaid$1,240.00Oct 12, 2026
#1043Daniel WeissPending$318.50Oct 13, 2026
#1044Sofia RicciPaid$89.00Oct 13, 2026
#1045Arjun PatelRefunded$742.25Oct 14, 2026
#1046Lena FischerPaid$2,015.00Oct 15, 2026
#1047Tomas NovakPending$56.40Oct 16, 2026
#1048Grace LiuPaid$460.00Oct 16, 2026
#1049Omar HaddadPaid$129.99Oct 17, 2026

Data grid toolbar

sf-gridbar with data-sf-gridbar and data-sf-for="tableId": live search, filter chips, density toggle and a column menu.

Team members
NameRoleStatusLocationProjects
Maya OkaforDesign leadActiveLagos12
Daniel WeissEngineerAwayBerlin8
Sofia RicciProduct managerActiveMilan15
Arjun PatelEngineerOfflinePune6
Lena FischerResearcherActiveZurich9
Tomas NovakDesignerAwayPrague11
Grace LiuEngineerActiveToronto14
Omar HaddadSupportOfflineAmman4

List and list item

sf-list with sf-list__item (lead, main, trail). The swipe variant adds sf-swipe + data-sf-swipe: drag a row left to reveal actions.

  • Maya OkaforSent the revised brand deck
    9:41
  • Daniel WeissMerged the billing fix
    Yesterday
  • Sofia RicciRoadmap review moved to Friday
  • Arjun PatelJoined the design system channel
    New
  • Lena FischerInterview notes are ready
    2m
  • Tomas NovakInvoice 2041 is overdue
    1h
  • Grace LiuCan we pair on the importer?
    3h

Stat / KPI card

sf-stat with a label, value (add data-sf-statcount to animate it), delta (--up, --down, --flat) and a sparkline.

Monthly revenue $48,260
Up 12.4%
Active users 8,412
Up 3.1%
Churn rate 2.8%
Down 0.6%
Avg. response time 1.4h
No change 0.0%

Sparkline

Inline SVG drawn from data-sf-sparkline and data-sf-values. Options: data-sf-width, data-sf-height, data-sf-area, data-sf-smooth="false", sf-spark--fluid.

Bar chart

data-sf-chart="bar" or "hbar". Data from data-sf-values + data-sf-labels, data-sf-data JSON, or a script type=application/json child. Hover, or focus the chart and use arrow keys.

Line / area chart

data-sf-chart="line" or "area": draw-in animation, crosshair and tooltip on hover or arrow keys, multiple series with a legend.

Donut / pie chart

data-sf-chart="donut" or "pie". Hover a segment or legend row: it pops, the centre label updates.

Progress group, stacked bar, goal meter

sf-meters / sf-dmeter use --sf-value. sf-stack takes flex weights in --v. sf-goal is generated from data-sf-goal with role="meter".

Storage used72%
Sprint scope48%
Onboarding91%
Test coverage63%
  • Design 40%
  • Build 25%
  • Review 20%
  • Admin 15%

Heatmap

Calendar contribution grid from data-sf-heatmap with data-sf-values (oldest to newest) or a date-keyed data-sf-data object. Choose a colour with data-tone.

Calendar

sf-cal from data-sf-calendar: today ring, selected day, event dots, month-switch animation, full keyboard grid (arrows, Home/End, PageUp/PageDown). Add data-sf-agenda for the day list.

Date picker and range picker

sf-datepicker with data-sf-datepicker (add data-sf-range for a range). Type an ISO date, or open the popover. Esc closes.

Format YYYY-MM-DD
Click a start day, then an end day

Kanban board

data-sf-kanban: drag cards between columns (mouse anywhere, touch by the grip). Keyboard: focus a card, Space to pick up, arrows to move, Space to drop, Esc to cancel.

To do

0
Write onboarding emails
ContentMO
Audit colour contrast
DesignLF
Plan the Q4 roadmap review
PlanningSRAP

In progress

0
Ship the billing importer
EngineeringDW
Redesign empty states
DesignTN

Done

0
Set up analytics events
EngineeringGL

Timeline / activity feed

sf-timeline with sf-timeline__group per day, an icon dot per event (tinted with data-tone).

Today

  1. Daniel Weiss merged billing-importer into main

  2. Maya Okafor commented on Empty states

    "Let's try a friendlier illustration for the inbox."

Yesterday

  1. Lena Fischer uploaded research-notes.pdf

  2. Arjun Patel joined the workspace

  3. Sofia Ricci published release v2.4

Avatar group

sf-avgroup stacks sf-avatar. data-sf-max="N" collapses the rest into a +N chip. Hover or focus to spread.

MODWSRAPLFTNGL
ABCDEF
OHPNJRKPNA

Chat

sf-chat with sf-msg bubbles, sf-typing and sf-composer. Enter sends, Shift+Enter adds a line. data-sf-autoreply simulates a reply.

Maya OkaforOnline
Today
Hey! Did you get a chance to look at the new dashboard layout?
Maya · 9:12 AM
Just finished. The tile grid feels so much calmer.
You · 9:14 AM
Great. Shall we ship it this week?
Maya · 9:15 AM

Comment thread

sf-thread of nested sf-comment. sf-reactions toggles with a count; Reply opens an inline composer.

Maya Okafor2 hours ago

The new empty states are lovely. Could we reuse the same illustration style on the 404 page?

Daniel Weiss1 hour ago

Yes, the shapes are CSS only, so it costs nothing to reuse them.

Sofia Ricci45 minutes ago

Adding it to the sprint board.

Arjun PatelYesterday

Nice work everyone. Reduced motion is respected too, which I appreciate.

Chip / tag

sf-chip: static, selectable (button with aria-pressed inside data-sf-chips), removable (sf-chip--removable) and a tag input (sf-chips + sf-chips__input). Colours via data-tone.

DefaultPinkYellowBlueGreen
Urgent Backend Q4
launch pricing

Notification list

sf-notifs grouped by day, unread dot, tap to mark read, or swipe a row right (data-sf-swipe="commit"). Mark all read is data-sf-notif-all.

Notifications 3

Today
  • Mark read
  • Mark read
  • Mark read
Earlier
  • Mark read
  • Mark read

Profile card and user hover card

sf-profile is a full card. sf-hovercard wraps a trigger link and a card that opens on hover or keyboard focus (Esc dismisses).

Maya Okafor

@maya · Lagos

Design lead building calm, springy interfaces. Coffee, type and tiny animations.

248Posts
12.4kFollowers
312Following
Last week @maya Maya Okafor@maya

Design lead building calm, springy interfaces.

12.4k followersLagos
shared the new tile grid with @daniel Daniel Weiss@daniel

Engineer. Ships small, careful pull requests.

3.1k followersBerlin
, and they both loved it.

File list and file tile

sf-file with data-type (pdf, doc, xls, img, zip, code, video, audio) and data-status (uploading, done, error). The icon is pure CSS. Try Retry.

  • Q4-roadmap.pdf2.4 MBEdited today
    Uploaded
  • revenue-forecast.xlsx840 KB
    62%
  • hero-illustration.png12.8 MBToo large to upload
    Failed
  • brand-assets.zip38 MBOct 14
    Uploaded
Brief.docx120 KB
importer.js18 KB
demo-reel.mp4212 MB
podcast-intro.mp34.1 MB

Code block

sf-code with data-sf-code="js|css|py|sh|html|json": light tokenizer, line numbers, tab label, copy button (data-sf-copy), data-sf-highlight="2,5-6".

importer.js
// Import invoices in batches
async function importInvoices(rows, size = 50) {
  const results = [];
  for (let i = 0; i < rows.length; i += size) {
    const batch = rows.slice(i, i + size);
    const res = await fetch("/api/invoices", {
      method: "POST",
      body: JSON.stringify(batch),
    });
    results.push(await res.json());
  }
  /* done */
  return results.flat();
}
button.css
/* springy press */
.btn {
  --spring: cubic-bezier(.3,1.7,.5,1);
  min-height: 48px;
  border-radius: 999px;
  transition: scale .2s var(--spring);
}
.btn:active { scale: 1.12 .84; }
terminal
# install and run
npm install soft-ui
npm run dev -- --port 3000
echo "ready on http://localhost:3000"

Description list / spec table

sf-dl with sf-dl__row (dt + dd). Modifiers: --stack, --spec (framed), --tiles.

Display
6.1-inch OLED, 120 Hz
Battery
3,300 mAh, up to 24 hours
Storage
128 GB / 256 GB / 512 GB
Weight
171 g
Connectivity
5G, Wi-Fi 6E, Bluetooth 5.3
Customer
Maya Okafor
Email
maya@example.com
Plan
Team, billed yearly
Renews
March 3, 2027
Open issues
23
Merged PRs
148
Contributors
12
Latest release
v2.4.1

Rating summary

data-sf-reviewsum with data-sf-counts (five stars first) builds the average and distribution bars. sf-stars shows any fractional --sf-rate on its own.

Leaderboard

data-sf-leaderboard sorts by data-score. Call Soft.leaderboard(el).setScores({id: score}) and rows glide to their new rank. The button here does it with random scores.

  1. Maya Okafor2,840
  2. Daniel Weiss2,410
  3. Sofia Ricci2,175
  4. Arjun Patel1,860
  5. Lena Fischer1,540
  6. Tomas Novak1,120

Metric tile grid / dashboard layout

sf-dash is a responsive grid (1, 2 then 4 columns). sf-tile holds any widget; span with sf-tile--w2, --w3, --w4, --h2.

Revenue$48.3k
Up 12%
Users8,412
Up 3%
Churn2.8%
Down 0.6%
NPS61
Up 4 pts

Visitors

Last 12 weeks

Sources

Goals

New customers74%
Support SLA92%
Docs coverage55%

Recent activity

  • New design reviewMaya Okafor
    9:41
  • Importer mergedDaniel Weiss
    8:15
  • New teammateArjun Patel
    Mon