Spring Menu
A spring navigation panel that folds through a full-width bar into a centered pill.
Install the component, then paste your configured usage. Your settings are included in the code below.
Pro source comes with Arclen UI Pro. See plans
| Property | Type | Default |
|---|---|---|
directionDirection Options: panel (A · Folded panel), editorial (B · Editorial), directory (C · Directory) | select | "panel" |
brandIdentity Up to 40 characters | text | "arclen" |
homeUrlHome destination Up to 300 characters | text | "#home" |
taglineIdentity detail Up to 70 characters | text | "arclen" |
group1TitleGroup 1 heading Up to 40 characters | text | "Product" |
group1LabelsGroup 1 labels Minimum 1 itemsMaximum 8 itemsUp to 60 characters per item | string-list | ["Website builder","Page diagnosis","Ad studio","Analytics"] |
group1AnnotationsGroup 1 annotations Match link order. Leave an entry empty for no annotation; digits appear as a count, words as a badge. Minimum 0 itemsMaximum 8 itemsUp to 20 characters per item | string-list | ["AI","","",""] |
group1UrlsGroup 1 destinations Minimum 1 itemsMaximum 8 itemsUp to 300 characters per item | string-list | ["#website-builder","#page-diagnosis","#ad-studio","#analytics"] |
group2TitleGroup 2 heading Up to 40 characters | text | "Create" |
group2LabelsGroup 2 labels Minimum 1 itemsMaximum 8 itemsUp to 60 characters per item | string-list | ["Components","Templates","Showcase"] |
group2AnnotationsGroup 2 annotations Match link order. Leave an entry empty for no annotation; digits appear as a count, words as a badge. Minimum 0 itemsMaximum 8 itemsUp to 20 characters per item | string-list | ["","New",""] |
group2UrlsGroup 2 destinations Minimum 1 itemsMaximum 8 itemsUp to 300 characters per item | string-list | ["#components","#templates","#showcase"] |
group3TitleGroup 3 heading Up to 40 characters | text | "Resources" |
group3LabelsGroup 3 labels Minimum 1 itemsMaximum 8 itemsUp to 60 characters per item | string-list | ["Documentation","Guides","Changelog","Contact"] |
group3AnnotationsGroup 3 annotations Match link order. Leave an entry empty for no annotation; digits appear as a count, words as a badge. Minimum 0 itemsMaximum 8 itemsUp to 20 characters per item | string-list | ["","","Updated",""] |
group3UrlsGroup 3 destinations Minimum 1 itemsMaximum 8 itemsUp to 300 characters per item | string-list | ["#documentation","#guides","#changelog","#contact"] |
primaryLabelPrimary action Up to 40 characters | text | "Start building" |
primaryUrlPrimary destination Up to 300 characters | text | "#start-building" |
secondaryLabelSecondary action Up to 40 characters | text | "Sign in" |
secondaryUrlSecondary destination Up to 300 characters | text | "#sign-in" |
showActionsShow actions | boolean | true |
showSocialShow social links | boolean | true |
socialLabelsSocial link labels Recognized platform labels show their brand icon. Other labels use generic navigation symbols. Minimum 1 itemsMaximum 5 itemsUp to 40 characters per item | string-list | ["X","Instagram","LinkedIn","GitHub","YouTube"] |
socialUrlsSocial destinations Demo fragments. Replace with your own social profile URLs. Minimum 1 itemsMaximum 5 itemsUp to 300 characters per item | string-list | ["#x","#instagram","#linkedin","#github","#youtube"] |
maxWidthMaximum width 600–1440Step 10 | number | 1100 |
paddingGroup spacing 16–48Step 2 | number | 32 |
surfaceShell | color | "#141414" |
panelGroup surface | color | "#242424" |
textColorText | color | "#f5f5f5" |
mutedGroup headings | color | "#999999" |
accentAccent | color | "#F54E00" |
accentTextBadge and monogram text | color | "#ffffff" |
initialOpenStart expanded | boolean | true |
motionAnimate transitions | boolean | true |
phaseDelayFold pause (ms) 200–800Step 50 | number | 500 |
brandMarkUrlCustom brand mark URL Optional HTTPS or root-relative image URL. Empty uses the built-in mark or monogram. Up to 300 characters | text | "" |
brandWordmarkUrlCustom wordmark URL Optional HTTPS or root-relative image URL. Empty uses the built-in wordmark or brand detail. Up to 300 characters | text | "" |
brandMarkSizeBrand mark size 16–32Step 1 | number | 24 |
wordmarkWidthWordmark width 40–120Step 0.1 | number | 78.4 |
fontFamilyType family Options: geist (Geist), system (System sans), serif (System serif) | select | "geist" |
linkFontSizeLink text size Base size. Editorial headings scale up; directory links scale down by 2px. 14–24Step 1 | number | 18 |
linkSpacingLink row spacing Vertical rhythm for the folded panel direction. 12–28Step 2 | number | 20 |
shellRadiusShell corners Folded panel radius; editorial uses 5/16 and directory uses half this value. 0–40Step 2 | number | 32 |
panelRadiusGroup corners Rounded group panels in the folded panel direction. 0–28Step 2 | number | 16 |
socialIconStyleSocial symbols Options: brand (Platform brands), generic (Generic symbols) | select | "brand" |
socialIconSizeSocial symbol size 16–24Step 1 | number | 20 |
primarySurfacePrimary action background | color | "#f5f5f5" |
primaryTextPrimary action text | color | "#141414" |
menuLabelOpen button label Up to 24 characters | text | "Menu" |
closeLabelClose button label Up to 24 characters | text | "Close" |
navigationLabelNavigation accessible name Up to 80 characters | text | "Main navigation" |
demoDestinationsCreate example anchor sections Disable to preserve fragment URLs exactly and link to sections in your own page. | boolean | true |
closeOnNavigateClose phone sheet on navigation | boolean | true |
Spring Menu
A navigation panel with a two-part desktop fold and a full-height phone sheet. Spring Menu is an Arclen UI Pro component, available through the authenticated installer or Pro download. Keep its stylesheet, assets and licence notices together. React is required only for the React export; the standalone core has no runtime dependencies.
React
Copy the downloaded spring-menu directory beside this example. The React entry imports its stylesheet and assets.
import { SpringMenu } from './spring-menu/src/react';
export default function Navigation() {
return (
<SpringMenu
brand="North Studio"
tagline="Independent design"
homeUrl="/"
group1Title="Work"
group1Labels={['Selected projects', 'Services']}
group1Urls={['/projects', '/services']}
group1Annotations={['', 'New']}
primaryLabel="Start a project"
primaryUrl="/contact"
secondaryLabel="About us"
secondaryUrl="/about"
accent="#7195e0"
primarySurface="#dbe8ff"
primaryText="#14223a"
maxWidth={1040}
padding={28}
linkFontSize={19}
initialOpen={false}
demoDestinations={false}
/>
);
}All manifest settings are React props. className, style and paused apply to the React wrapper. The named SpringMenu, Component alias and default export are available. Keep this interactive component behind a client boundary in frameworks that distinguish server and client components.
HTML download
Serve the complete HTML download over HTTP, including component.css, component.js, poster.webp and the included notices. The downloaded component.html already contains semantic navigation for visitors without JavaScript. Edit the JSON in its data-settings attribute to configure it; retain its existing child markup for the no-JavaScript fallback.
This complete page mounts a configured menu from the downloaded files. Its fallback remains a usable navigation link until JavaScript loads:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>North Studio</title>
<link rel="stylesheet" href="./component.css">
</head>
<body>
<div data-arclen-ui="spring-menu"
data-settings='{"brand":"North Studio","tagline":"Independent design","homeUrl":"/","initialOpen":false,"demoDestinations":false,"maxWidth":1040,"accent":"#7195e0"}'>
<nav aria-label="Main navigation"><a href="/">North Studio home</a></nav>
</div>
<script src="./component.js" defer></script>
</body>
</html>For a bundler-based vanilla application, import mount from ./spring-menu/src/core and ./spring-menu/src/styles.css, then call mount(host, settings). The returned handle exposes update(settings), pause(), resume() and destroy(). render(settings, id) supplies semantic HTML without browser globals. resolveSettings validates inputs; defaults comes from the manifest.
Configuration
The generated settings table contains every default, option and bound from component.json.
- **Content:** three groups each accept one to eight labels and destinations. Each label list must have the same length as its URL list. Annotation lists are optional and follow link order: empty entries omit metadata, digits become counts and words become badges. Social lists accept one to five entries. Actions and socials can be hidden.
- **Destinations:** use fragment identifiers, HTTP(S), mailto or root-relative paths. Set demoDestinations={false} for real in-page anchors: #contact then links directly to your own section. With example sections enabled, fragments are scoped to the instance and local example sections are created. Text is escaped and unsafe URLs are rejected.
- **Brand:** change brand and tagline for a monogram and detail text, or supply brandMarkUrl and brandWordmarkUrl. Image URLs accept HTTPS or root-relative paths; empty strings restore the automatic identity. Host and license your own image files. Mark size and wordmark width are bounded. Custom wordmarks retain a 20px-high box and use object-fit: contain. The default Arclen identity uses the supplied mark and outlined wordmark.
- **Type and layout:** choose bundled Geist, system sans or system serif; set base link size, width and group spacing. Editorial headings scale from the base size; directory links are 2px smaller. Link row spacing and group corners apply to the folded-panel direction. Shell corners also scale for editorial and directory layouts. Keep long translations readable by adjusting spacing and checking your narrowest container.
- **Palette:** surface, group panel, text, muted headings, accent and badge text are independent. Primary action background and text have separate controls. Accent colours affect focus rings, custom monograms and badges; badge fills use a darker tint. Choose contrasting colours for text and focus states.
- **Icons:** platform mode selects local X, Instagram, LinkedIn, GitHub and YouTube icons by label. Other labels use generic symbols. Generic mode uses those symbols for every link. Labels remain accessible names; symbol size is independent.
- **Behavior:** localize menuLabel, closeLabel and navigationLabel. initialOpen sets the starting state. phaseDelay controls the pause between desktop fold stages. motion={false} removes travel and scale. closeOnNavigate controls phone-sheet dismissal after following a link.
Interaction and lifecycle
The menu follows its container width. It uses a phone sheet below a 900px viewport or inside a container narrower than 772px. Phone sheets have Escape dismissal, focus containment and page scroll locking; desktop navigation is nonmodal. Only one phone sheet is active per document. Opening another closes the previous sheet before moving focus and background ownership to the new one, including when both instances start open. Enter or Space activates the toggle. Hover underlines also respond to keyboard focus. The intermediate desktop fold stage ignores repeated clicks until it finishes; a subsequent click can retarget the remaining spring.
Reduced-motion preference changes state immediately. Pause settles active transitions and stops owned animation work. Offscreen menus settle when Intersection Observer is available; without it, explicit pause and document visibility still work. Without Resize Observer, window resizing still updates the layout, but container-only changes require an update. Destroy releases listeners, observers, timers and modal state.
update validates the complete next configuration before replacing the menu. Omitted values return to defaults, and the new menu starts at initialOpen. Invalid input leaves the mounted menu intact. Two instances have separate IDs and settings. Without JavaScript, the generated download keeps its full semantic navigation visible.
Assets and rights
Geist includes Latin glyphs; unsupported scripts use the selected system fallback. Its full OFL notice is in assets/OFL-Geist.txt. Local social silhouettes are Bootstrap Icons 1.13.1, under MIT; retain assets/Bootstrap-Icons-LICENSE.txt. Platform marks belong to their owners and do not imply endorsement. Default social destinations are example fragments, not verified Arclen profiles. Replace them with your own destinations.
The supplied Arclen mark and wordmark are example branding with trademark rights reserved. Replace them for another business. No commercial font software is included in the logos. See NOTICE.md and PROVENANCE.md for the package’s authorship and asset notices.
The preview runs the component’s own JavaScript. It respects reduced motion and pauses when off screen. The HTML bundle includes a poster fallback.
Every setting in this panel comes from the component manifest. Preview size, pause and replay stay in the inspector.