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

layers-select-control

v0.4.0

Published

Mimics Google layer select layers.

Readme

LayersSelectControl

A high-performance React component for selecting layers, inspired by the Google Maps layer switcher. It provides a sleek, collapsed preview that expands into a scrollable panel with high-definition thumbnails and descriptions.

Features

  • Google Maps UI: Seamlessly transitions between a collapsed thumbnail and an expanded list.
  • Intelligent Image Loading: The ManagedImage system handles HD transitions and fallbacks (thumbnailHd -> thumbnail -> noImageThumb) without UI flickering.
  • Ref/Imperative API: Access internal state and control selection programmatically using useImperativeHandle.
  • Adaptive Positioning: Anchor the control to any corner using xRel and yRel.
  • Dynamic Sizing: Built-in small, medium, and large presets that scale all dimensions via CSS variables.
  • Interactive Scrolling: Automatically detects overflow and provides navigation arrows for horizontal scrolling.
  • Lifecycle Hooks: onExpand and onCollapse callbacks for integration with other UI elements.
  • Touch Optimized: Includes pointer-event handling and touch-start detection for mobile map environments.

Installation

# Using npm
npm install layers-select-control

# Using yarn
yarn add layers-select-control

Props

The component is highly configurable to fit different map layouts and branding requirements.

| Prop | Type | Default | Description | | --- | --- | --- | --- | | items | LayerItem[] | Required | Array of items to display in the main scrollable area. | | onSelect | (item: LayerItem) => void | Required | Callback triggered when a layer is selected. | | onDefault | (item?: LayerItem) => void | Required | Callback for the "Default" tile click. | | value | string | - | Controlled mode: The ID of the currently selected item. | | defaultValue | string | - | Uncontrolled mode: The initial ID to be selected. | | defaultItem | LayerItem | - | A special tile that appears fixed at the start of the list. | | moreItem | LayerItem | - | Custom title/description for the "More" tile. | | size | "small" | "medium" | "large" | | theme | "dark" | "light" | "dark" | | maxVisible | number | 5 | Number of items visible before enabling horizontal scroll. | | x, y | number | 8, 32 | Numerical offset from the anchor point. | | xRel | "left" | "right" | "left" | | yRel | "top" | "bottom" | "bottom" | | onMore | () => void | - | If provided, a "More..." tile is appended to the list. | | onExpand | () => void | - | Fired when the panel opens. | | onCollapse | () => void | - | Fired when the panel closes. | | defaultThumb | string | - | Override the default "reset" icon URL. | | noImageThumb | string | - | Fallback image for items without thumbnails. | | moreThumb | string | - | Icon for the "More" tile. |

Data Interfaces

LayerItem

export interface LayerItem {
    id: string;
    title: string;
    description?: string;
    thumbnail?: string;     // Standard thumbnail
    thumbnailHd?: string;   // HD version loaded only when panel expands
}

Imperative Handle (Ref)

You can control the component externally by passing a ref:

export interface LayersSelectControlRef {
    setSelectedItem: (id: string) => void;
    getSelectedItem: () => LayerItem | undefined;
}

Usage Example

import React, { useRef } from "react";
import { LayersSelectControl, LayerItem, LayersSelectControlRef } from "layers-select-control";

const LAYERS: LayerItem[] = [
  { 
    id: "satellite", 
    title: "Satellite", 
    description: "Global imagery",
    thumbnail: "/thumbs/sat.jpg", 
    thumbnailHd: "/thumbs/sat-hd.jpg" 
  },
  { id: "terrain", title: "Terrain", description: "Topographic maps", thumbnail: "/thumbs/terrain.jpg" },
];

export const App = () => {
  const controlRef = useRef<LayersSelectControlRef>(null);

  return (
    <div style={{ position: "relative", width: "100%", height: "600px" }}>
      <LayersSelectControl
        ref={controlRef}
        items={LAYERS}
        size="medium"
        theme="light"
        defaultItem={{ id: "base", title: "Standard", description: "Default Map" }}
        onSelect={(item) => console.log("Active Layer:", item.id)}
        onDefault={() => console.log("Reset to default")}
        onMore={() => alert("Open full catalog")}
      />
    </div>
  );
};

Styling & Theme

The component uses scoped CSS logic to manage layouts dynamically:

  • Responsive Scaling: Uses internal configurations to calculate exact pixel dimensions for thumbnails and tiles.
  • Auto-Width: Utilizes ResizeObserver on the parent container to ensure the expanded panel never overflows the screen boundaries.
  • Pointer Awareness: Automatically switches between hover and touch events depending on the user's device.

License

MIT © Felipe Carrillo