Environment Switcher
motiq/environment-switcherFreeComponent
A presentation + control surface for choosing the environment an app targets (dev / staging / production, regions, preview branches). Current-environment trigger opens a searchable, fully keyboard-navigable listbox with per-environment status/health, region/branch/version/last-deploy, disabled reasons, recents + favorites, and optional groups. Production switches are icon + label marked (never color alone) and can be gated behind a confirmation dialog. Controlled value/onValueChange with app-owned switching + error/retry. It never mutates a backend.
Live preview
live · rendered by the registry
Rendered by motiq on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://www.motiq.dev/r/environment-switcher.jsonSource
1"use client";23import * as React from "react";4import { createPortal } from "react-dom";5import { motion, AnimatePresence } from "motion/react";67import { cn } from "@/lib/utils";8import {9 useControllableState,10 useReducedMotion,11 getStatusMeta,12 statusVars,13 formatTimestamp as defaultFormatTimestamp,14 type StatusTone,15} from "@/lib/motiq";1617/**18 * EnvironmentSwitcher — a presentation + control surface for choosing the19 * environment (dev / staging / production, regions, preview branches) an app is20 * pointed at. It is NOT a deployment tool: it never opens a socket, deploys,21 * promotes, or mutates any backend. The host application owns the actual switch;22 * this component surfaces the choice, the per-environment status/health the host23 * already knows, and — critically — a production safety guard.24 *25 * What makes it worth shipping over a bare <select>: each environment carries a26 * status (available / active / degraded / offline / deploying / locked /27 * restricted), optional region / branch / version / last-deploy / health, and an28 * app-provided disabled reason. Production is treated as a first-class hazard —29 * it is marked with an icon AND a text label (never colour alone) and, when the30 * host opts in via `requireProductionConfirmation`, a switch to it is gated31 * behind an explicit confirmation dialog. A switch in flight and a switch error32 * (with retry) are app-owned states the component renders honestly.33 *34 * Accessibility: the trigger is a real button (aria-haspopup="listbox"); the35 * popup is the ARIA combobox pattern — a search input (role="combobox",36 * aria-activedescendant) controlling a role="listbox" of role="option" rows with37 * full Arrow / Home / End / Enter / Escape keyboard support. Disabled options38 * keep their reason readable. The current value is announced via a polite live39 * region; production and every status use icon + text; focus is restored to the40 * trigger on close; targets are ≥44px; under prefers-reduced-motion everything41 * renders in its final state. Clean-room original.42 */4344/* -------------------------------------------------------------------------- */45/* Types */46/* -------------------------------------------------------------------------- */4748export type EnvironmentType =49 | "local"50 | "development"51 | "preview"52 | "staging"53 | "production"54 | (string & {});5556/** App-owned health/lifecycle of an environment. */57// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from motiq
All 100 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Activity Streamactivity-stream | motiq | Components | Free | 1 dep | |
| Adaptive Safe-Zone Gridadaptive-safe-zone-grid | motiq | Components | Free | no deps | |
| Agent Run Timelineagent-run-timeline | motiq | Components | Free | 1 dep | |
| AI Response Streamai-response-stream | motiq | Components | Free | 1 dep | |
| Animated Accordionanimated-accordion | motiq | Components | Free | 2 deps | |
| Animated Buttonanimated-button | motiq | Components | Free | 1 dep | |
| Animated Dialoganimated-dialog | motiq | Components | Free | 2 deps | |
| Animated Gridanimated-grid | motiq | Components | Free | 2 deps |
