Gallery › robotparts › Filters
Filters
Every standard rail filter kind in one rail, on robotparts' 1,149 actuators: search, popular filters, a form ›
brand tree, McMaster's picture gallery and picture list with line drawings, logo swatches, a values list with
exclude, a toggle, a select, has-a-value, Amazon's price buckets and "& up" rating, a histogram slider and a plain
log slider, ranges with dimension diagrams, a date with "last 7 days" and "older than", tag chips, a compact grid, a
Digi-Key listbox and the current-filters bar. Each one edits the same filter, so the table, the cards and the chart
move together. The McMaster, Amazon, Digi-Key and Obsidian tabs are recipes: a view with its own facets:.
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.
# Filters: every standard rail filter kind (docs/CONTRACT.md §7) on robotparts' 1,149 actuators, one .base file.
# The top-level `facets:` is the full rail, one entry per kind; the four recipe views carry their own `facets:`
# (McMaster, Amazon, Digi-Key, Obsidian), so switching tab switches the rail. Every kind edits the ONE all-views
# filter, so a tick shows in the table, the cards and the chart alike. kinds.html lists each kind with its snippet.
# Check it: node bin/data-ui.mjs check <this file>
data: actuators.json
facets:
- { as: current, label: Current filters }
- { property: model, as: search, properties: [model, name], label: Search, placeholder: "Model or name, e.g. AK80" }
- property: price
as: popular
label: Popular filters
options:
- { label: In stock, filter: 'in_stock == "yes"' }
- { label: CAN bus, filter: 'buses.contains("can")' }
- { label: Under $100, filter: 'price < 100' }
- { label: Has a photo, filter: '!photo.isEmpty()' }
- { property: form, as: tree, levels: [form, brand], label: Form › brand }
- property: form
as: gallery
label: Form
columns: 2
info: "How the actuator is built: a hobby servo's case and horn, an integrated joint with its driver inside, a frameless direct-drive ring, a motor with a separate gearbox, or a motor inside a wheel."
images:
hobby servo: icons/form-hobby_servo.svg
integrated actuator: icons/form-integrated_actuator.svg
direct drive: icons/form-direct_drive.svg
bare gearmotor: icons/form-bare_gearmotor.svg
wheel hub: icons/form-wheel_hub.svg
- property: drivetrain
as: picture-list
label: Drivetrain
images:
geared: icons/drivetrain-geared.svg
direct_drive: icons/drivetrain-direct_drive.svg
motor: icons/drivetrain-motor.svg
- property: brand
as: swatch
label: Brand (logos)
limit: 12
images:
Steadywin: logos/steadywin.webp
Damiao: logos/damiao.webp
JMC: logos/jmc.webp
- { property: brand, as: values, exclude: true, label: Brand, searchable: true }
- { property: in_stock, as: toggle, value: "yes", text: In stock only }
- { property: in_stock, as: select, label: Stock }
- { property: checks, as: toggle, value: cad, text: Has CAD, label: CAD }
- { property: photo, as: has, properties: [photo, torque_density, price], label: Has data, match: all }
- { property: price, as: buckets, buckets: [50, 100, 250, 500], unit: USD, label: Price }
- { property: price, as: range, choices: [25, 50, 100, 250, 500, 1000, 2500], label: Price (min / max) }
- { property: peak_torque, as: slider-histogram, log: true, label: Peak torque }
- { property: mass, as: slider, log: true, label: Mass }
- { property: od, as: range, diagram: diagrams/od.svg, label: Outer diameter, info: "Across the actuator's face, housing to housing; not the output flange." }
- { property: length, as: range, diagram: diagrams/length.svg, label: Axial length, collapsed: true }
- { property: torque_density, as: buckets, label: Peak N·m/kg }
- { property: level, as: rating, max: 5, label: robotparts level }
- { property: level, as: min-level, max: 5, label: Level }
- { property: listed, as: date, presets: [7d, 30d, year], older: [14d, 90d], label: First listed }
- { property: buses, as: chips, label: Bus }
- { property: gear_ratio, as: grid, columns: 3, sort: value, limit: 15, label: Gear ratio, info: "Output turns per motor turn; 1 is direct drive." }
- { property: voltage, as: listbox, sort: value, label: Voltage }
properties:
name: { displayName: Name }
model: { displayName: Model }
brand: { displayName: Brand }
form: { displayName: Form }
drivetrain: { displayName: Drivetrain }
peak_torque: { displayName: Peak torque }
rated_torque: { displayName: Rated torque }
mass: { displayName: Mass }
gear_ratio: { displayName: Ratio }
voltage: { displayName: Voltage }
od: { displayName: OD, description: "Outer diameter of the housing" }
length: { displayName: Length, description: "Axial length, mounting face to back face" }
buses: { displayName: Bus }
torque_density: { displayName: Peak N·m/kg }
price: { displayName: Price from }
level: { displayName: Level }
in_stock: { displayName: In stock }
checks: { displayName: Checks }
listed: { displayName: First listed }
photo: { displayName: Photo }
views:
- type: table
name: Every kind
order: [model, brand, form, drivetrain, peak_torque, mass, od, price, in_stock, listed, level]
sort:
- { property: peak_torque, direction: DESC }
- type: cards
name: Cards
order: [model, brand, peak_torque, price]
image: photo
imageFit: contain
imageAspectRatio: 0.8
cardSize: 170
sort:
- { property: photo, direction: DESC }
- { property: peak_torque, direction: DESC }
- type: chart
name: Chart
chart:
mark: { type: point, filled: true }
encoding:
x: { field: mass, scale: { type: log } }
y: { field: peak_torque, scale: { type: log } }
color: { field: form }
hover: { image: photo, title: name, fields: [peak_torque, mass, price, form] }
- type: table
name: McMaster-style
order: [model, brand, form, od, length, gear_ratio, peak_torque, price]
facets:
- property: form
as: gallery
label: Form
columns: 2
images:
hobby servo: icons/form-hobby_servo.svg
integrated actuator: icons/form-integrated_actuator.svg
direct drive: icons/form-direct_drive.svg
bare gearmotor: icons/form-bare_gearmotor.svg
wheel hub: icons/form-wheel_hub.svg
- property: drivetrain
as: picture-list
label: Drivetrain
images:
geared: icons/drivetrain-geared.svg
direct_drive: icons/drivetrain-direct_drive.svg
motor: icons/drivetrain-motor.svg
- { property: brand, as: values, searchable: true, limit: 10, label: Brand }
- { property: od, as: grid, columns: 3, sort: value, limit: 18, diagram: diagrams/od.svg, label: Outer diameter, info: "Across the actuator's face, housing to housing." }
- { property: length, as: range, diagram: diagrams/length.svg, label: Axial length }
- { property: gear_ratio, as: grid, columns: 3, sort: value, limit: 18, label: Gear ratio }
- { property: peak_torque, as: range, label: Peak torque }
- type: table
name: Amazon-style
order: [model, brand, price, level, in_stock, peak_torque]
sort:
- { property: price, direction: ASC }
facets:
- { as: current, label: Your filters }
- { property: in_stock, as: toggle, value: "yes", text: In stock only, label: Availability }
- { property: level, as: rating, max: 5, label: robotparts level }
- { property: price, as: buckets, buckets: [25, 50, 100, 250], unit: USD, label: Price }
- { property: brand, as: values, limit: 6, label: Brand }
- type: table
name: Digi-Key-style
order: [model, brand, form, drivetrain, voltage, gear_ratio, buses, in_stock, price]
facets:
- { property: in_stock, as: toggle, value: "yes", text: In stock, label: Stocking options }
- { property: brand, as: listbox, sort: alpha, label: Manufacturer }
- { property: form, as: listbox, label: Form }
- { property: drivetrain, as: listbox, label: Drivetrain }
- { property: voltage, as: listbox, sort: value, label: Voltage - rated }
- { property: gear_ratio, as: listbox, sort: value, label: Gear ratio }
- { property: buses, as: listbox, label: Interface }
- type: table
name: Obsidian-style
order: [model, brand, peak_torque, mass, price]
filters:
and:
- 'peak_torque > 10 || mass < 100'
- 'brand != "KST"'
facets: []
// actuators.json: 1,149 rows, 679 KB; the first 3
{
"id": "actuators-filters",
"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; in_stock and checks: robotparts /search/views/actuator.json; listed: catalog listings[].observed_at",
"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"
},
"in_stock": {
"type": "text",
"width": 90,
"note": "robotparts' own reading of its sellers' stock (yes, no, unknown)"
},
"checks": {
"type": "list",
"width": 160,
"note": "the checks a part has passed on robotparts: listed, cited, CAD, sim, measured"
},
"listed": {
"type": "date",
"width": 100,
"note": "the day robotparts first saw the part listed for sale (its earliest listing)"
}
},
"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": "../robotparts-actuators/photos/aifitlab-8541438771336.webp",
"step_up": "aifitlab-8542347853960",
"in_stock": "yes",
"checks": [
"listed",
"cited",
"cad",
"sim"
],
"listed": "2026-10-22"
},
{
"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": "../robotparts-actuators/photos/aifitlab-8542347853960.webp",
"step_up": "aifitlab-8542620287112",
"in_stock": "yes",
"checks": [
"listed"
],
"listed": "2026-10-22"
},
{
"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": "../robotparts-actuators/photos/aifitlab-8542620287112.webp",
"step_up": null,
"in_stock": "yes",
"checks": [
"listed"
],
"listed": "2026-10-22"
}
],
"imageProperty": "photo"
}README.md
# Filters
Every standard rail filter kind in one rail, on robotparts' 1,149 actuators: search, popular filters, a form ›
brand tree, McMaster's picture gallery and picture list with line drawings, logo swatches, a values list with
exclude, a toggle, a select, has-a-value, Amazon's price buckets and "& up" rating, a histogram slider and a plain
log slider, ranges with dimension diagrams, a date with "last 7 days" and "older than", tag chips, a compact grid, a
Digi-Key listbox and the current-filters bar. Each one edits the same filter, so the table, the cards and the chart
move together. The McMaster, Amazon, Digi-Key and Obsidian tabs are recipes: a view with its own `facets:`.
- **App:** robotparts
- **Replaces:** the three-kind rail (values, range, has) robotparts.dev's category pages use today
(`robotparts/site/views/actuator.base`), and each site's own hand-built filter widgets that the kinds copy:
McMaster-Carr's pictorial facets, Algolia InstantSearch's widgets, Airbnb's price histogram, Amazon's rating and
price bands, Digi-Key's parametric columns, Booking.com's popular filters.
- **Shows:** [every kind, the site it copies and its .base snippet](kinds.html): 21 facet kinds (`as:` values, select, toggle, has, range, slider, slider-histogram, buckets, rating,
min-level, date, chips, swatch, gallery, picture-list, grid, listbox, tree, search, popular, current), the facet
options (`label`, `info` ⓘ, `diagram`, `collapsed`, `limit`, `sort`, `unit`, `log`, `buckets`, `presets`,
`older`, `images`, `columns`, `exclude`, `choices`, `levels`, `properties`, `value`), a view's own rail (`facets:` on
a view), the readable URL (`?brand=A&peak_torque=10..<100&brand!=KST`), disjunctive counts, light and dark.
- **Data:** `actuators.json` is the robotparts-actuators case's rows (its photos stay in that folder) plus
`in_stock`, `checks` and `listed`, written by `source/build.py` from robotparts' live rows and catalog. `logos/`
holds the three actuator brands robotparts has a logo for (Steadywin, Damiao, JMC; hosted on the owner's basis);
every other brand's swatch is a monogram. `icons/` and `diagrams/` are line drawings made by `source/icons.py`.
The original UI it replaces
the three-kind rail (values, range, has) robotparts.dev's category pages use today (robotparts/site/views/actuator.base), and each site's own hand-built filter widgets that the kinds copy: McMaster-Carr's pictorial facets, Algolia InstantSearch's widgets, Airbnb's price histogram, Amazon's rating and price bands, Digi-Key's parametric columns, Booking.com's popular filters.
What it shows
every kind, the site it copies and its .base snippet: 21 facet kinds (as: values, select, toggle, has, range, slider, slider-histogram, buckets, rating, min-level, date, chips, swatch, gallery, picture-list, grid, listbox, tree, search, popular, current), the facet options (label, info ⓘ, diagram, collapsed, limit, sort, unit, log, buckets, presets, older, images, columns, exclude, choices, levels, properties, value), a view's own rail (facets: on a view), the readable URL (?brand=A&peak_torque=10..<100&brand!=KST), disjunctive counts, light and dark.
Data
actuators.json is the robotparts-actuators case's rows (its photos stay in that folder) plus in_stock, checks and listed, written by source/build.py from robotparts' live rows and catalog. logos/ holds the three actuator brands robotparts has a logo for (Steadywin, Damiao, JMC; hosted on the owner's basis); every other brand's swatch is a monogram. icons/ and diagrams/ are line drawings made by source/icons.py.