npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@meetelise/studio-components

v0.1.53

Published

Elise Studio component library — renderer, layout primitives, and data-fetching components for property websites

Readme

elise-studio-components

Curated floor plan catalogs

FloorplanCatalog is a grouped, selector-and-accordion presentation of live Elise floor plans. Each authored plan is a reference to an Elise floor plan id; references missing from the authenticated property API are not rendered. Authored JSON controls group order, marketing copy, actions, optional image fallbacks, and an optional square-footage marketing label. API records remain the source of identity, bed/bath values, availability, rent, and preferred media. The component follows all cursor pages so a curated id is not lost beyond the first response page, and stops safely if the API repeats a cursor.

The catalog uses Studio's keyed sm through 2xl responsive contract and a semantic collapseAt breakpoint. Actions reuse the canonical Button contract, navigation stays router-aware, analytics emit canonical API floor plan ids, and images use the shared accessible Lightbox. FloorplanExplorer remains unchanged for uncurated listing grids and lists. A validated compactPresentation object controls accordion typography, rhythm, panel insets, and action alignment below the collapse breakpoint without relying on arbitrary classes or site templates.

The opt-in desktopPresentation: "workspace" mode integrates a bounded, scrollable grouped selector with a stable summary-and-drawing canvas for larger catalogs. Selector headings, counts, and API-backed plan details are separately configurable. Below collapseAt, compactDisclosure: "single" turns the same catalog into a globally single-open inline accordion; responsive detail columns and connected panel styling remain authored presentation choices. The default split/perGroup behavior and API contract are unchanged.

Motion and background media

BackgroundMedia is a generic frame for decorative image or muted video backgrounds. It accepts normal Studio children, so headings, buttons, and data components remain independently editable. The optional parallax motion moves only the media layer; overlay content and document layout stay fixed. Video is paused outside the viewport and replaced by its poster or image when the visitor requests reduced motion. If no still is authored, a paused first video frame is used instead.

{
  "type": "BackgroundMedia",
  "props": {
    "video": { "$content": "hero.video" },
    "poster": { "$content": "hero.poster" },
    "minHeight": "90vh",
    "contentPosition": "bottom-left",
    "motion": "parallax"
  },
  "children": [
    {
      "type": "Text",
      "props": { "content": { "$content": "hero.headline" }, "variant": "display" }
    }
  ]
}

Parallax applies the same bounded, request-animation-frame scroll transform to any child subtree. StickyFrame pins a subtree within its parent scroll range and defaults to normal flow on mobile. Together with Grid, Container, and ScrollReveal, these frames support sticky storytelling, independently moving media, and layered editorial sections without site-specific JavaScript or CSS. All motion is progressive enhancement: server output remains visible, unsupported browsers retain a static layout, and operating-system reduced-motion preferences disable continuous translation.

Atlas authoring contract

The exported component schema includes optional authoring metadata for Atlas and semantic validators. It describes component roles, breakpoint-aware props, composition constraints, required context, relative performance cost, stable repair hints, and recommended recipe IDs. Runtime rendering ignores this metadata.

The generated dist/componentSchema.json versions the component schema, authoring contract, and diagnostic envelope independently. Diagnostics use a shared shape and may include existing Studio design operations for Atlas to apply:

{
  "code": "STICKY_MEDIA_OVERLAP",
  "severity": "error",
  "nodeId": "hero-media",
  "breakpoint": "sm",
  "message": "The transformed media can leave its sticky boundary.",
  "suggestedOperations": [
    {
      "type": "set_node_prop",
      "node_id": "hero-media",
      "prop_path": ["motion"],
      "value": "none"
    }
  ]
}

validateAuthoringTree is the shared, side-effect-free semantic validator used by Atlas, preview, and compiler consumers. It checks required props, component nesting, authoring contexts, incompatibilities, deprecations, and an optional normalized performance budget without resolving or rendering the tree:

const { diagnostics, performanceCost } = validateAuthoringTree(page.tree, {
  availableContexts: ["property"],
  performanceBudget: 24,
  path: "pages[0].tree",
});

Errors represent invalid authoring decisions; warnings cover deprecations, unknown props, and budget pressure. When a safe default exists, a diagnostic may include a typed Studio design operation that Atlas can apply as a repair.

Atlas composition recipes

The @meetelise/studio-components/recipes export and generated dist/authoringRecipes.json provide versioned, validated section blueprints. Each recipe declares its content fields, required site contexts, normalized performance budget, and a normal Studio component tree using $content bindings. The initial catalog includes editorial hero, split-media story, sticky-media story, and availability/conversion compositions.

Recipes are build-validated against the canonical component schema and semantic validator. A build fails if a recipe references an unknown component, an undeclared content key, or a missing recipe ID. Atlas can therefore select a recipe, create its declared content fields, and insert the tree through ordinary typed Studio operations.

Amenity presentations

AmenityList keeps layout and ordering independent. Existing sites continue to use the alphabetized icon-grid default, while order="source" preserves the first occurrence of each amenity from either authored content or the Elise property API. The opt-in bulleted layout emits semantic ul/li markup and uses theme body typography. Its indentation, item spacing, and typography can be adjusted through the validated bulletPresentation object without baking a property's measurements into the shared component.

Navigation presentations

Nav keeps the inline, solid header and dropdown menu as its default. Sites may opt into stacked or overlay layouts, compact links or equal-width tabs, separate primary and utility actions, per-link desktop/mobile visibility, a scrolled logo, an optional compact scroll effect, and a modal drawer. The existing sticky flag controls viewport following while overlay controls whether the initial header occupies document flow. collapseAt uses the shared sm/md/lg/xl/2xl breakpoints. Optional validated lengths control logo bounds, link rhythm, content width, section padding, tab borders, and drawer width without embedding a site template in the component. For sticky compact navigation, optional topStyle and scrolledStyle objects can independently control validated logo height, frame padding and gap, background color/opacity, divider, shadow, backdrop blur, and foreground scheme. A bounded pixel threshold and whitelisted transition timing provide a two-state CSS transition with an optional logo crossfade; reduced-motion preferences disable that motion. Button-style links consume the canonical Button presentation contract. Omitting the presentation fields preserves the existing inline/dropdown behavior.

Footer presentations

Footer keeps its columns-and-copyright output as the default. The optional property presentation composes structured brand, address, contact, action, badge, and legal content inside one semantic footer. Sections and responsive grids follow the content that is present; actions reuse Button's canonical presentation and routing behavior. propertyLayout and keyed responsivePropertyLayout overrides use Studio's shared breakpoints and validated CSS lengths, while colors come from the active theme.

Responsive layout overrides

Container and Stack keep their token spacing as the default design language. For layouts that need exact authored geometry, Container also accepts optional base edge padding values and keyed responsivePadding overrides. Studio uses the same mobile-first scale as Tailwind: sm (40rem), md (48rem), lg (64rem), xl (80rem), and 2xl (96rem). Stack and Grid use the same duplicate-free keyed contract for authored gaps. Values are limited to simple CSS lengths with finite, unit-specific bounds; malformed and extreme declarations are ignored. Container bottom margin is signed so layout composition can intentionally overlap sections.

Button supports the same opt-in pattern for base/responsive font size, weight, line-height, tracking, horizontal/vertical padding, border width, inset outline, and bounded shadow presets. responsiveTypography can override font size, line height, or signed letter spacing at the shared breakpoints. Focus presentation is site-wide rather than per button: token themes may define focus.ring.width, focus.ring.offset, and focus.ring.color. Unsafe values are ignored, and the native focus indicator remains the fallback. Omitting presentation fields preserves the existing variant/size output.

Background-image sections can opt into bgAttachment and responsiveBgAttachment (scroll or fixed). Omitting both preserves the browser default while allowing authored fixed-background behavior at any shared breakpoint without runtime-authored CSS classes. Background position supports edges and all four corners. bgOverlayOpacity controls the overlay layer independently from its color and is bounded to the CSS opacity range.

Coordinate-aware property maps

PropertyMap renders a property coordinate on the same map runtime used by Studio's unit marketplace. Its default MapLibre style is served by Elise; an installation may instead configure Mapbox or an alternate style through the existing Studio runtime configuration. Provider credentials are platform configuration and are never authored into site JSON.

Authors control center, zoom, responsive height, the property marker, and an optional list of nearby-place markers. Every marker can use an image or safe custom/category color, a structured information card, and a generated or custom Google Maps view/directions action. When nearby places are present the map fits the property and visible places by default; authors may opt back into manual center and zoom. Only one card opens at a time and it remains attached to its coordinate while the visitor pans or zooms, flips and clamps inside the map viewport, supports phone, email, and Google Maps actions, and can be dismissed and reopened. Responsive values use Studio's keyed sm through 2xl contract. MapEmbed remains the lightweight iframe option and retains its existing output and TypeScript markers input.

Contact form presentations

ContactForm keeps its existing comfortable, stacked lead form as the default and continues to submit through Elise's authenticated /v1/prospect endpoint. Opt-in grid layout, one-to-three columns, compact density, grouped names, configurable fields, labels, and requiredness are independent authoring choices. The native date input remains the default; usText accepts editable numeric or punctuated input, formats it on blur, validates the calendar date, and sends the existing ISO move_in_date payload.

Base and keyed responsive values can control row, column, and label-to-control gaps. A bounded control-presentation object covers minimum heights, padding, border, radius, and label typography without embedding a site template. Submit buttons consume the canonical Button presentation contract and add independent base/responsive alignment. Invalid authored CSS values are ignored, fields keep theme colors and visible focus, and validation errors identify and focus the affected control.

Property SEO template tokens

A building_template: true page may use the following compile-time tokens in plain string fields. Resolution is recursive, so the same tokens work in the page path, search/social metadata, and nested seo.structuredData strings.

| Token | Merged content source | | --- | --- | | {{property.name}} | building.name | | {{property.slug}} | vars.slug | | {{property.city}} | building.city | | {{property.state}} | building.state | | {{property.neighborhood}} | building.neighborhood | | {{property.address}} | building.address | | {{property.shortDescription}} | building.short_description, then building.tagline | | {{property.amenitySummary}} | building.amenity_summary | | {{property.bedroomRange}} | building.bedroom_range | | {{site.name}} | site.name, then merged meta.name / meta.title, then raw site name metadata |

The existing {{slug}} syntax remains an alias for vars.slug. A token whose source is missing stays visibly unresolved so publish-time SEO checks can report the missing data. Runtime {$data: "..."} bindings are never interpolated.

Property hero images are intentionally not string tokens. Author an image or social-image field with the building-scoped object binding {$content: "building.image"}; the resolver converts its AssetValue to that building's CDN URL.

Typography theme tokens

Typography is configured by role so a bounded token set can cover every Text variant. All tokens are optional. Without an authored role override, each variant retains its built-in responsive size, weight, line-height, and tracking.

| Role | Family | Scale | Weight | Line height | Tracking | | --- | --- | --- | --- | --- | --- | | Heading (display, h1h3) | font.heading | font.heading.scale | font.heading.weight | font.heading.line-height | font.heading.tracking | | Body (subtitle, body, body-lg, caption, overline) | font.body | font.body.scale | font.body.weight | font.body.line-height | font.body.tracking |

Scale is a unitless multiplier such as "1.1". Weight and line-height accept CSS values such as "600" and "1.4"; tracking accepts a CSS letter-spacing value such as "-0.02em". All values may use the existing {$token} alias shape, and building-mode overrides inherit through ThemeScope.

Individual Text nodes can override base font size, weight, line height, letter spacing, transform, and alignment. The keyed responsiveTypography object uses the same sm through 2xl contract as layout and Button, with optional font-size, line-height, and signed letter-spacing values at each minimum viewport. Values are validated and bounded before rendering; invalid authored values are ignored without removing the variant defaults.

Body Google fonts include the regular italic face in addition to the upright weight range, allowing semantic emphasis to use the selected family without requesting every italic weight. Duplicate stylesheet requests are suppressed.