Navigation and Menus

Project Space Command Palette

Complete a command palette for a project space scenario: includes real content, actionable controls, clear status feedback, and responsive layouts.

Navigation and MenusCommand PaletteHTMLCSSJavaScript
With JavaScript enabled, you can edit, run, and save this example. The fixed source is as follows:
<!doctype html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Project Space Command Palette</title>
  <style>
    :root { --ink:#111111; --paper:#f8f8f4; --accent:#111111; --secondary:#8d8d88; --line:color-mix(in srgb, var(--ink) 18%, transparent); --shadow:0 24px 60px color-mix(in srgb, var(--ink) 16%, transparent); color-scheme:light; }
    * { box-sizing:border-box; }
    html { min-width:320px; background:var(--paper); }
    body { min-height:100vh; margin:0; overflow-x:hidden; color:var(--ink); font-family:Helvetica,"PingFang SC",sans-serif; background:repeating-linear-gradient(0deg,transparent 0 31px,color-mix(in srgb,var(--ink) 7%,transparent) 32px),var(--paper); }
    button,input,select,textarea { color:inherit; font:inherit; }
    button,[role="button"],input,select,textarea { accent-color:var(--accent); }
    button { cursor:pointer; }
    button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible { outline:3px solid var(--accent); outline-offset:3px; }
    [hidden] { display:none !important; }
    @media (max-width:700px) { .mast h1 { line-height:1.08 !important; letter-spacing:-.035em !important; overflow-wrap:anywhere; } }
    @media (prefers-reduced-motion:reduce) { *,*::before,*::after { scroll-behavior:auto !important; animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; } }
    .page{width:min(1120px,calc(100% - 30px));margin:auto;padding:48px 0 80px}.mast{display:grid;grid-template-columns:1fr auto;border-top:10px solid var(--ink);padding-top:20px;gap:20px;align-items:end;margin-bottom:26px}.mast h1{font-family:Helvetica,"PingFang SC",sans-serif;font-weight:900;font-size:clamp(44px,10vw,106px);letter-spacing:-.075em;margin:0;line-height:.82}.eyebrow{display:inline-block;margin-bottom:12px;padding:5px 8px;color:var(--paper);background:var(--ink);font:900 10px/1 ui-monospace,monospace;letter-spacing:.14em}.intro{max-width:700px;line-height:1.55}.scenario{padding:9px 12px;border:3px solid var(--ink);font-weight:900}.demo{border:3px solid var(--ink);border-radius:0;box-shadow:12px 12px 0 var(--ink);position:relative;min-height:410px;overflow:hidden;padding:clamp(22px,4vw,46px);background:var(--paper)}@media(max-width:700px){.page{width:calc(100% - 18px);padding:20px 0}.mast{grid-template-columns:1fr}.demo{padding:15px}}
    .panel{padding:24px;border-block:1px solid var(--ink);background:transparent}.stack{display:grid;gap:22px}.row{display:flex;flex-wrap:wrap;gap:16px}.action{padding:8px 0;border:0;border-bottom:1px solid currentColor;background:transparent;letter-spacing:.08em}.action.primary,.action.is-active{color:var(--accent);border-bottom-width:4px}.status{min-height:28px;margin-top:20px;font-style:italic}.metric{font-family:Didot,serif;font-size:clamp(38px,8vw,76px)}.muted{max-width:54ch;line-height:1.8}.meter{position:relative;height:3px;background:var(--line)}.meter>i{position:absolute;inset:0 auto 0 0;background:var(--accent)}.chip{padding-bottom:3px;border-bottom:1px solid var(--ink);font-size:13px}
    .composition-index{position:relative;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:18px}.index-mark{display:grid;align-content:space-between;width:76px;padding:16px 10px;border:1px solid var(--line);color:var(--accent);background:color-mix(in srgb,var(--paper) 82%,transparent);text-align:center}.index-mark strong{font:900 34px/1 ui-monospace,monospace}.index-mark span{writing-mode:vertical-rl;font:800 10px/1.2 ui-monospace,monospace;letter-spacing:.18em}.composition-index .demo{grid-column:1;grid-row:1}.composition-index::before{content:"";position:absolute;left:-12px;top:38px;width:5px;height:45%;background:linear-gradient(var(--accent),var(--secondary))}@media(max-width:700px){.composition-index{grid-template-columns:1fr}.index-mark{grid-row:1;width:auto;grid-template-columns:auto 1fr}.index-mark span{writing-mode:horizontal-tb}.composition-index .demo{grid-row:2}}
    .command{max-width:720px;margin:auto;padding:0;overflow:hidden}.command-input{display:grid;grid-template-columns:auto 1fr auto;gap:12px;align-items:center;padding:18px;border-bottom:1px solid var(--line)}.command-input input{width:100%;border:0;outline:0;background:transparent;font-size:18px}.sr{display:block}.sr>span{position:absolute;clip:rect(0 0 0 0)}kbd{padding:3px 7px;border:1px solid var(--line);border-radius:6px;background:var(--paper);font:700 11px/1.2 ui-monospace,monospace}.command-list{display:grid;max-height:320px;overflow:auto;padding:10px}.command-list button{display:flex;justify-content:space-between;gap:16px;padding:13px;border:0;border-radius:10px;text-align:left;background:transparent}.command-list button:hover,.command-list button:focus{background:color-mix(in srgb,var(--secondary) 35%,transparent)}.command-list span{display:grid;gap:4px}.command-list small{color:color-mix(in srgb,var(--ink) 60%,transparent)}.workflow-compare{display:grid;grid-template-columns:minmax(230px,.55fr) minmax(0,1.45fr);gap:18px}.compare-stage{display:grid;gap:12px;min-width:0}.compare-stage>header{display:flex;justify-content:space-between;gap:16px;align-items:end}.compare-stage h2{margin:.2em 0}.compare-core{--compare-split:50%;min-width:0;padding:14px;clip-path:inset(0 calc(100% - var(--compare-split)) 0 0);outline:1px dashed var(--accent);outline-offset:-8px;transition:clip-path .25s,filter .25s}.compare-core[data-compare-channel="B"]{filter:hue-rotate(32deg) saturate(1.15)}.compare-controls{display:grid;align-content:start;gap:16px;padding:20px;border:1px solid var(--line);border-radius:24px 4px 24px 4px;background:var(--paper)}.compare-controls fieldset,.compare-controls>label{display:grid;gap:8px}.compare-controls input[type="range"]{width:100%}#workflowCompareShelf{display:grid;gap:6px;padding:0;margin:0;list-style:none}#workflowCompareShelf li{display:grid;grid-template-columns:auto 1fr auto;gap:8px;padding:9px;border-top:1px solid var(--line);font-size:12px}@media(max-width:900px){.workflow-compare{grid-template-columns:1fr}.compare-stage{order:-1}.compare-core{clip-path:none;border-left:8px solid var(--accent)}}
  </style>
</head>
<body data-aesthetic="monochrome" data-composition="field-index">
  <main class="page">
    <header class="mast"><div><span class="eyebrow">monochrome / Command Palette / BEGINNER</span><h1>Project Space Command Palette</h1><p class="intro">Complete a command palette for a project space scenario: includes real content, actionable controls, clear status feedback, and responsive layouts.</p></div><span class="scenario">Project Space</span></header>
    <div class="composition-index"><section class="demo" aria-label="Project Space Command Palette Interactive Area"><div class="workflow-compare"><form id="workflowCompareControls" class="compare-controls"><fieldset><legend>Reference Channel</legend><label><input type="radio" name="workflowChannel" value="A" checked>A · To-Do Space</label><label><input type="radio" name="workflowChannel" value="B">B · File Space</label></fieldset><label>Member scope weight<input id="workflowCompareWeight" type="range" min="10" max="90" value="50"><output id="workflowCompareWeightValue">50 Person</output></label><label><input id="workflowCompareFreeze" type="checkbox">Freeze current version</label><button id="workflowCompareCapture" class="action primary" type="button">Sample and switch spaces</button><ol id="workflowCompareShelf" aria-label="Version Sampling Record"></ol></form><section class="compare-stage"><header><span class="eyebrow">Project Space COMPARE</span><h2>Project View Dual-Version Comparison</h2><output id="workflowCompareLive">Version A waiting for sampling</output></header><section id="workflowCore" class="workflow-core compare-core" data-compare-channel="A" style="--compare-split:50%"><!-- 11DZ_CORE_START:navigation-menus-command-palette --><div class="command panel"><div class="command-input"><span aria-hidden="true">⌘</span><label class="sr"><span>Search commands</span><input id="commandQuery" type="search" placeholder="Enter a command or keyword" autocomplete="off" aria-controls="commandList"></label><kbd>Esc</kbd></div><div id="commandList" class="command-list" role="listbox" aria-label="Available Commands"><button type="button" role="option" aria-selected="true" tabindex="0" data-core-bridge="navigation-menus-command-palette"><span><b>Project Space Favorites</b><small>Execute quick actions</small></span><kbd>1</kbd></button><button type="button" role="option" aria-selected="false" tabindex="-1"><span><b>Project Space Overview</b><small>Navigate to Content</small></span><kbd>2</kbd></button><button type="button" role="option" aria-selected="false" tabindex="-1"><span><b>Project space planning</b><small>Execute quick actions</small></span><kbd>3</kbd></button><button type="button" role="option" aria-selected="false" tabindex="-1"><span><b>Project Space Inspiration</b><small>Navigate to Content</small></span><kbd>4</kbd></button><button type="button" role="option" aria-selected="false" tabindex="-1"><span><b>Project Space Notes</b><small>Execute quick actions</small></span><kbd>5</kbd></button><button type="button" role="option" aria-selected="false" tabindex="-1"><span><b>Project Space Collaboration</b><small>Navigate to Content</small></span><kbd>6</kbd></button><button type="button" role="option" aria-selected="false" tabindex="-1"><span><b>Project space progress</b><small>Execute quick actions</small></span><kbd>7</kbd></button></div><div id="commandEmpty" hidden>No matching commands</div></div><!-- 11DZ_CORE_END --></section></section></div><p id="status" class="status" role="status" aria-live="polite"></p></section><aside class="index-mark" aria-hidden="true"><strong>05</strong><span>Project space FIELD INDEX</span></aside></div>
  </main>
  <script>
    'use strict';
    const statusOutput = document.querySelector('#status');
    const announce = message => { statusOutput.textContent = message; };
    /* 11DZ_CORE_SCRIPT_START:navigation-menus-command-palette */
const commandInput = document.querySelector('#commandQuery'); const commands = [...document.querySelectorAll('#commandList button')]; const emptyCommand = document.querySelector('#commandEmpty'); let activeCommand=0;
    function selectCommand(index,focus=false){const visible=commands.filter(command=>!command.hidden);if(!visible.length)return;const command=visible[(index+visible.length)%visible.length];commands.forEach(item=>{const selected=item===command;item.setAttribute('aria-selected',String(selected));item.tabIndex=selected?0:-1;});activeCommand=visible.indexOf(command);if(focus)command.focus();}
    function filterCommands() { const query = commandInput.value.normalize('NFKC').trim().toLowerCase(); let count = 0; commands.forEach(command => { const searchable = command.querySelector('b').textContent.normalize('NFKC').toLowerCase(); command.hidden = Boolean(query && !searchable.includes(query)); if (!command.hidden) count += 1; }); emptyCommand.hidden = count !== 0; activeCommand=0;selectCommand(0);announce('Available Commands ' + count + ' item'); }
    commandInput.addEventListener('input',filterCommands); document.addEventListener('keydown',event => { if (event.key === 'Escape') { commandInput.value = ''; filterCommands(); commandInput.focus(); } });document.querySelector('#commandList').addEventListener('keydown',event=>{if(!['ArrowDown','ArrowUp','Home','End'].includes(event.key))return;event.preventDefault();const visible=commands.filter(command=>!command.hidden);const next=event.key==='Home'?0:event.key==='End'?visible.length-1:activeCommand+(event.key==='ArrowDown'?1:-1);selectCommand(next,true);}); commands.forEach(command => {command.addEventListener('focus',()=>selectCommand(commands.filter(item=>!item.hidden).indexOf(command)));command.addEventListener('click',() => announce('Executed:' + command.querySelector('b').textContent));});
/* 11DZ_CORE_SCRIPT_END */
const workflowBridgeSpec={"name":"navigation-menus-command-palette","selector":"[data-core-bridge=\"navigation-menus-command-palette\"]","mode":"click","key":"Enter"};const workflowBridgeCore=document.querySelector('#workflowCore');const workflowBridgeControl=workflowBridgeCore.querySelector(workflowBridgeSpec.selector);if(!workflowBridgeControl)throw new Error('Missing core bridge: '+workflowBridgeSpec.name);const workflowBridgeControlledId=workflowBridgeControl.getAttribute('aria-controls');const workflowBridgeControlled=workflowBridgeControlledId?document.getElementById(workflowBridgeControlledId):null;workflowBridgeCore.dataset.workflowBridge=workflowBridgeSpec.name;workflowBridgeCore.dataset.workflowVersion='0';function workflowBridgeSerialize(){const visualNode=workflowBridgeCore.firstElementChild||workflowBridgeCore;const visual=getComputedStyle(visualNode);const outputs=[...workflowBridgeCore.querySelectorAll('output,[role="status"],[aria-live],meter,progress')].map(node=>node.textContent.trim()+'|'+node.getAttribute('aria-valuenow')+'|'+node.getAttribute('value'));const canvas=[...workflowBridgeCore.querySelectorAll('canvas')].map(node=>{try{return node.toDataURL().slice(-160);}catch{return 'canvas-unavailable';}});return JSON.stringify({html:workflowBridgeCore.innerHTML,status:statusOutput.textContent,outputs,canvas,visual:[visual.display,visual.visibility,visual.opacity,visual.transform,visual.filter,visual.backgroundColor,visual.width,visual.height],scroll:workflowBridgeSpec.mode==='scroll'?workflowBridgeControl.scrollTop:null});}let workflowBridgeLastEffect=workflowBridgeSerialize();function workflowBridgeSummary(){const label=(workflowBridgeControl.getAttribute('aria-label')||workflowBridgeControl.textContent||workflowBridgeControl.value||workflowBridgeSpec.name).trim().replace(/\s+/g,' ').slice(0,72);return label+' · Core Version '+workflowBridgeCore.dataset.workflowVersion;}function workflowBridgeCommit(){const effect=workflowBridgeSerialize();if(effect===workflowBridgeLastEffect)return {changed:false,summary:workflowBridgeSummary()};workflowBridgeLastEffect=effect;workflowBridgeCore.dataset.workflowVersion=String(Number(workflowBridgeCore.dataset.workflowVersion||0)+1);return {changed:true,summary:workflowBridgeSummary()};}function workflowBridgeScheduleCommit(){queueMicrotask(workflowBridgeCommit);setTimeout(workflowBridgeCommit,0);}workflowBridgeControl.addEventListener("click",workflowBridgeScheduleCommit);const workflowBridgeStateTargets=new Set(workflowBridgeCore.querySelectorAll('dialog'));if(workflowBridgeControlled&&workflowBridgeCore.contains(workflowBridgeControlled))workflowBridgeStateTargets.add(workflowBridgeControlled);workflowBridgeStateTargets.forEach(target=>['close','cancel','toggle'].forEach(eventName=>target.addEventListener(eventName,workflowBridgeScheduleCommit)));function workflowBridgeActivate(){workflowBridgeControl.focus();workflowBridgeControl.click();const result=workflowBridgeCommit();setTimeout(workflowBridgeCommit,0);return result;}function workflowBridgeReset(){workflowBridgeCore.dataset.workflowVersion='0';workflowBridgeLastEffect=workflowBridgeSerialize();}
const workflowCompareCore=document.querySelector('#workflowCore');const workflowCompareWeight=document.querySelector('#workflowCompareWeight');const workflowCompareState={channel:'A',weight:50,frozen:false,snapshots:[]};function workflowCompareFingerprint(){const controls=[...workflowCompareCore.querySelectorAll('input,select,textarea')];const outputs=[...workflowCompareCore.querySelectorAll('output,[role="status"],strong')].map(node=>node.textContent.trim()).filter(Boolean);return {controlValues:controls.map(control=>control.type==='checkbox'||control.type==='radio'?control.checked:control.value),summary:outputs.slice(0,4).join(' / '),nodes:workflowCompareCore.querySelectorAll('*').length};}function workflowCompareDrive(){workflowCompareCore.dataset.compareChannel=workflowCompareState.channel;workflowCompareCore.style.setProperty('--compare-split',workflowCompareState.weight+'%');document.querySelector('#workflowCompareWeightValue').textContent=workflowCompareState.weight+' person';document.querySelector('#workflowCompareLive').textContent=workflowCompareState.channel+' Version · '+workflowCompareState.weight+' person'+(workflowCompareState.frozen?' · Frozen':'');announce('Project view is being viewed '+workflowCompareState.channel+' Version');}function workflowCompareCapture(source){const bridge=workflowBridgeActivate();const snapshot={...workflowCompareFingerprint(),channel:workflowCompareState.channel,weight:workflowCompareState.weight,source,bridge:bridge.summary};workflowCompareState.snapshots.push(snapshot);const item=document.createElement('li');item.innerHTML='<b>'+snapshot.channel+'</b><span>'+(snapshot.summary||snapshot.bridge)+'</span><small>'+snapshot.weight+' person · '+snapshot.bridge+'</small>';document.querySelector('#workflowCompareShelf').prepend(item);announce('sampled '+snapshot.channel+' Version and switch spaces · '+bridge.summary);}document.querySelectorAll('[name="workflowChannel"]').forEach(input=>input.addEventListener('change',()=>{workflowCompareState.channel=input.value;workflowCompareDrive();}));workflowCompareWeight.addEventListener('input',()=>{workflowCompareState.weight=Number(workflowCompareWeight.value);workflowCompareDrive();});document.querySelector('#workflowCompareFreeze').addEventListener('change',event=>{workflowCompareState.frozen=event.currentTarget.checked;workflowCompareDrive();});document.querySelector('#workflowCompareCapture').addEventListener('click',()=>workflowCompareCapture('Button Sampling'));workflowCompareCore.addEventListener('dblclick',()=>workflowCompareCapture('Main view double-click'));workflowCompareDrive();
workflowBridgeReset();
  </script>
</body>
</html>
Page feedbackFound an issue or have suggestions for improvement?
Feedback features need to be used in the online version

Please enable JavaScript in the online version before submitting; local features of the current tool or example are not affected.

Go to the online version for feedback