Examples › robotparts › The bar: data-ui's toolbar
The bar: data-ui's toolbar
robotparts' 1,149 actuators under toolbar="bar": one row with the view chip (or tabs), the table's own query bar,
the filter control and Display, then the filter pills or the bulk bar. Every variant is an attribute of the element
(docs/CONTRACT.md §15).
The .base file and its data
Every tab above is one entry of this file; the views read these rows. ⋯ in the toolbar copies the current view as YAML.
# The bar (docs/CONTRACT.md §15) over robotparts' 1,149 actuators: the same file as robotparts-actuators plus a
# gallery and a chart, so the view menu has every layout to show. Was: Actuators: one .base file, many views. The five table views are the table lane's
# presets (robotparts lane/tables @ ab5ba92, presets/actuators.base); the pivots are data-ui's. Obsidian Bases
# grammar plus data-ui's keys (docs/CONTRACT.md §5). Check it: node bin/data-ui.mjs check <this file>
data: ../robotparts-actuators/actuators.json
facets:
- brand
- form
- drivetrain
- buses
- level
- { property: peak_torque, as: range }
- { property: mass, as: range }
- { property: price, as: range }
- { property: torque_density, as: has }
properties:
model: { displayName: Model }
brand: { displayName: Brand }
form: { displayName: Form }
drivetrain: { displayName: Drivetrain }
peak_torque: { displayName: Peak torque }
rated_torque: { displayName: Rated torque }
max_speed: { displayName: Max speed }
mass: { displayName: Mass }
gear_ratio: { displayName: Ratio }
voltage: { displayName: Voltage }
od: { displayName: OD }
length: { displayName: Length }
buses: { displayName: Bus }
torque_density: { displayName: Peak N·m/kg }
price: { displayName: Price from }
sellers: { displayName: Sellers }
level: { displayName: Level }
views:
- type: table
name: Rows
order: [model, brand, form, drivetrain, peak_torque, rated_torque, mass, price, buses]
sort:
- { property: peak_torque, direction: DESC }
- type: cards
name: Gallery
order: [model, brand, peak_torque, mass, price]
image: photo
imageFit: contain
imageAspectRatio: 0.8
cardSize: 190
- type: chart
name: Torque vs mass
chart:
mark: point
encoding:
x: { field: mass, type: quantitative }
y: { field: peak_torque, type: quantitative }
color: { field: brand, type: nominal }
- type: table
name: By brand
order: [model, form, peak_torque, rated_torque, max_speed, mass, gear_ratio, voltage, od, length, buses, price]
groupBy: { property: brand, direction: ASC }
sort:
- { property: peak_torque, direction: DESC }
summaries: { peak_torque: Max, mass: Min, price: Min }
- type: table
name: Brand › form
order: [model, peak_torque, mass, gear_ratio, voltage, price]
groupBy: { property: brand, direction: ASC }
subGroupBy: { property: form, direction: ASC }
sort:
- { property: peak_torque, direction: DESC }
summaries: { peak_torque: Max, price: Min }
fold: closed
- type: table
name: Torque density
filters: '!torque_density.isEmpty()'
order: [model, brand, torque_density, peak_torque, mass, price]
sort:
- { property: torque_density, direction: DESC }
display: { torque_density: bar }
- type: table
name: Geared CAN under $150
filters:
and:
- 'drivetrain == "geared"'
- 'buses.contains("can")'
- 'price < 150'
order: [model, brand, price, peak_torque, mass, gear_ratio, voltage]
sort:
- { property: price, direction: ASC }
display: { price: bar }
- type: table
name: All, flat
order: [model, brand, form, drivetrain, peak_torque, rated_torque, max_speed, mass, gear_ratio, voltage, od, length, buses, torque_density, price, sellers, level]
sort:
- { property: brand, direction: ASC }
- { property: model, direction: ASC }
- type: pivot
name: Brand × form
order: [brand]
splitBy: [form]
value: { property: null, summary: Count }
sort:
- { property: brand, direction: ASC }
- type: pivot
name: Torque by drivetrain × form
order: [drivetrain]
splitBy: [form]
value: { property: peak_torque, summary: Median, display: dist }
// ../robotparts-actuators/actuators.json: 1,149 rows, 608 KB; the first 3
{
"id": "actuators",
"title": "Actuators",
"titleProperty": "name",
"linkProperty": "url",
"source": "robotparts dist/site/v2/catalog.json, release 2026.10.25 (lane/tables @ ab5ba92); mass from each spec's own unit; photo: robotparts media/photos.jsonl, 150 of 1725 copied at 240 px",
"properties": {
"name": {
"type": "text",
"hidden": true
},
"model": {
"type": "text",
"width": 190
},
"brand": {
"type": "text",
"width": 120
},
"form": {
"type": "text",
"width": 140,
"display": "badge"
},
"drivetrain": {
"type": "text",
"width": 104
},
"buses": {
"type": "list",
"width": 120
},
"level": {
"type": "number",
"width": 58
},
"url": {
"type": "text",
"hidden": true
},
"torque_density": {
"type": "number",
"unitText": "N·m/kg",
"width": 130,
"derived": "peak torque / mass, by robotparts"
},
"price": {
"type": "number",
"unitText": "USD",
"decimals": 0,
"width": 120
},
"sellers": {
"type": "number",
"width": 70
},
"peak_torque": {
"type": "number",
"unitText": "N·m",
"width": 126
},
"rated_torque": {
"type": "number",
"unitText": "N·m",
"width": 126
},
"max_speed": {
"type": "number",
"unitText": "rpm",
"width": 126
},
"mass": {
"type": "number",
"unitText": "g",
"width": 126
},
"gear_ratio": {
"type": "number",
"unitText": ":1",
"width": 126
},
"voltage": {
"type": "number",
"unitText": "V",
"width": 126
},
"od": {
"type": "number",
"unitText": "mm",
"width": 126
},
"length": {
"type": "number",
"unitText": "mm",
"width": 126
},
"photo": {
"type": "text",
"hidden": true,
"display": "image",
"note": "robotparts' primary photo, resized; only the parts this case copied have one"
},
"step_up": {
"type": "text",
"hidden": true,
"derived": "the next photographed part of the same brand up in peak torque (build_examples.py)",
"note": "an edge for the graph view: among the parts with a photo here, the brand's next one up in peak torque"
}
},
"rows": [
{
"id": "aifitlab-8541438771336",
"name": "Steadywin GIM4305-10",
"brand": "Steadywin",
"model": "GIM4305-10",
"form": "integrated actuator",
"drivetrain": "geared",
"buses": [
"can",
"rs485"
],
"level": 4,
"url": "https://robotparts.dev/actuator/aifitlab-8541438771336/",
"peak_torque": {
"value": 3.82,
"basis": "seller",
"source": "aifitlab.com"
},
"rated_torque": 1.05,
"max_speed": 402,
"mass": {
"value": 150,
"basis": "seller",
"source": "aifitlab.com"
},
"gear_ratio": 10,
"voltage": 24,
"od": 53,
"length": 26,
"torque_density": 25.467,
"price": 70,
"sellers": 1,
"photo": "photos/aifitlab-8541438771336.webp",
"step_up": "aifitlab-8542347853960"
},
{
"id": "aifitlab-8542347853960",
"name": "Steadywin GIM6010-8",
"brand": "Steadywin",
"model": "GIM6010-8",
"form": "integrated actuator",
"drivetrain": "geared",
"buses": [
"can",
"rs485"
],
"level": 1,
"url": "https://robotparts.dev/actuator/aifitlab-8542347853960/",
"peak_torque": {
"value": 11,
"basis": "seller",
"source": "aifitlab.com"
},
"rated_torque": 5,
"max_speed": 420,
"mass": {
"value": 388,
"basis": "seller",
"source": "aifitlab.com"
},
"gear_ratio": 8,
"voltage": 24,
"od": 80,
"length": 40,
"torque_density": 28.351,
"price": 70,
"sellers": 1,
"photo": "photos/aifitlab-8542347853960.webp",
"step_up": "aifitlab-8542620287112"
},
{
"id": "aifitlab-8542620287112",
"name": "Steadywin GIM8108-8",
"brand": "Steadywin",
"model": "GIM8108-8",
"form": "integrated actuator",
"drivetrain": "geared",
"buses": [
"can",
"rs485"
],
"level": 1,
"url": "https://robotparts.dev/actuator/aifitlab-8542620287112/",
"peak_torque": {
"value": 22,
"basis": "seller",
"source": "aifitlab.com"
},
"rated_torque": 7.5,
"max_speed": 320,
"mass": {
"value": 396,
"basis": "seller",
"source": "aifitlab.com"
},
"gear_ratio": 8,
"voltage": 48,
"od": 92,
"length": 55,
"torque_density": 55.556,
"price": 85,
"sellers": 1,
"photo": "photos/aifitlab-8542620287112.webp",
"step_up": null
}
],
"imageProperty": "photo"
}README.md
# The bar: data-ui's toolbar
robotparts' 1,149 actuators under `toolbar="bar"`: one row with the view chip (or tabs), the table's own query bar,
the filter control and Display, then the filter pills or the bulk bar. Every variant is an attribute of the element
(docs/CONTRACT.md §15).
- **App:** robotparts
- **Replaces:** the full toolbar's row of words (Layout, Group, Sort, Filter, Properties, Units, ⋯) and the toolbar
proposals' six mocks (lane/toolbar-proposals @ 4481dfe).
- **Shows:** `views="auto"`, `filters="pills rail"`, `display="panel"`, `selectable`: Bases' view menu in the chip,
Shopify's query builder with autocomplete, pills that mirror the rail, Notion's resizable View settings panel,
shift / ctrl-click selection with a bulk bar.
- **Data:** `../robotparts-actuators/actuators.json` (the robotparts-actuators case's file).
The original UI it replaces
the full toolbar's row of words (Layout, Group, Sort, Filter, Properties, Units, ⋯) and the toolbar proposals' six mocks (lane/toolbar-proposals @ 4481dfe).
What it shows
views="auto", filters="pills rail", display="panel", selectable: Bases' view menu in the chip, Shopify's query builder with autocomplete, pills that mirror the rail, Notion's resizable View settings panel, shift / ctrl-click selection with a bulk bar.
Data
../robotparts-actuators/actuators.json (the robotparts-actuators case's file).