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:.

robotpartstablecardschart7 views of one actuators.json

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.