Getting Started with the PlacesBar Constructor

PlacesBar Constructor: API Reference and Examples—

Overview

The PlacesBar Constructor is a UI component factory used to create, configure, and manage a “places bar” — a compact, horizontally oriented control that displays a set of place shortcuts, locations, or contextual actions. This article provides a detailed API reference, usage examples, configuration patterns, accessibility considerations, and troubleshooting tips to help developers integrate the PlacesBar Constructor into web or desktop applications.


Table of contents

  1. Introduction
  2. Key concepts and terms
  3. Constructor signature and options
  4. Methods and events
  5. Configuration examples
  6. Rendering and styling
  7. Accessibility and internationalization
  8. Performance considerations
  9. Testing and debugging
  10. Migration and versioning notes
  11. FAQ and troubleshooting
  12. Complete example: building an interactive places bar

1. Introduction

The PlacesBar Constructor simplifies the creation of compact navigation or action strips that present users with contextually relevant places (such as folders, frequently visited locations, or quick actions). It abstracts layout, keyboard navigation, selection models, and event dispatching so you can focus on integrating the component with application data and behavior.


2. Key concepts and terms

  • Places item: a single entry displayed in the bar (icon, label, optional description).
  • Selection model: how items are selected (single, multiple, none).
  • Overflow handling: strategy used when items exceed available space (scroll, wrap, menu).
  • Placement: where the places bar is attached (top, bottom, left, right, inline).
  • Action: an interactive behavior attached to an item (open, navigate, show menu).

3. Constructor signature and options

Constructor (TypeScript-like):

interface PlacesBarOptions {   container: HTMLElement | string;    // required: DOM container or selector   items?: PlacesBarItem[];            // optional: initial items   selection?: 'single' | 'multiple' | 'none'; // default 'single'   overflow?: 'scroll' | 'wrap' | 'menu';      // default 'menu'   orientation?: 'horizontal' | 'vertical';    // default 'horizontal'   placement?: 'top' | 'bottom' | 'left' | 'right' | 'inline'; // default 'inline'   itemRenderer?: (item: PlacesBarItem) => HTMLElement; // custom renderer   keyboardNavigation?: boolean;       // default true   animations?: boolean | { durationMs: number }; // default true   responsiveBreakpoints?: Record<string, unknown>; // optional   ariaLabel?: string;                 // accessibility label   className?: string;                 // additional class   onSelect?: (item: PlacesBarItem, event: Event) => void; // selection callback   onAction?: (item: PlacesBarItem, action: string, event: Event) => void;   onOverflow?: (overflowedItems: PlacesBarItem[]) => void;   lazyLoadIcons?: boolean;            // default false   maxVisibleItems?: number;           // optional } interface PlacesBarItem {   id: string | number;   title: string;   subtitle?: string;   icon?: string | HTMLElement;   badge?: string | number;   action?: string;                    // action identifier   disabled?: boolean;   selected?: boolean;   metadata?: Record<string, any>; } 

Example constructor call:

const bar = new PlacesBarConstructor({   container: '#places-bar',   items: myItems,   selection: 'single',   overflow: 'menu',   orientation: 'horizontal',   ariaLabel: 'Quick places',   onSelect: (item) => console.log('Selected', item.id) }); 

4. Methods and events

Core methods (instance API):

  • addItem(item: PlacesBarItem, index?: number): void
  • removeItem(id: string | number): boolean
  • updateItem(id: string | number, patch: Partial): boolean
  • getItem(id: string | number): PlacesBarItem | null
  • getItems(): PlacesBarItem[]
  • select(id: string | number): boolean
  • deselect(id: string | number): boolean
  • clearSelection(): void
  • setItems(items: PlacesBarItem[]): void
  • openOverflowMenu(): void
  • closeOverflowMenu(): void
  • destroy(): void

Events (emitted or callback hooks):

  • select — fired when an item is selected (provides item, source event)
  • action — fired when an item’s action is triggered (action id, item)
  • itemAdded / itemRemoved — fired on collection changes
  • overflow — fired when items overflow the available space
  • focus / blur — keyboard focus events

Event subscription examples:

bar.on('select', ({ item, event }) => { /* ... */ }); bar.on('action', ({ item, action, event }) => { /* ... */ }); 

5. Configuration examples

Basic static bar

<div id="places-bar"></div> 
const items = [   { id: 'home', title: 'Home', icon: 'icons/home.svg' },   { id: 'downloads', title: 'Downloads', icon: 'icons/download.svg' },   { id: 'documents', title: 'Documents', icon: 'icons/docs.svg' } ]; const bar = new PlacesBarConstructor({   container: '#places-bar',   items,   overflow: 'menu',   ariaLabel: 'Main places' }); 

Dynamic items with selection and actions

const bar = new PlacesBarConstructor({   container: '#places-bar',   items: [],   selection: 'single',   onSelect: (item) => navigateTo(item.id),   onAction: (item, action) => handleAction(item, action) }); fetch('/api/places').then(res => res.json()).then(data => bar.setItems(data)); 

Custom renderer for rich item content

const cardRenderer = (item) => {   const el = document.createElement('div');   el.className = 'places-item';   el.innerHTML = `<img src="${item.icon}" alt=""><div>${item.title}<small>${item.subtitle || ''}</small></div>`;   return el; }; const bar = new PlacesBarConstructor({   container: '#places-bar',   items,   itemRenderer: cardRenderer }); 

6. Rendering and styling

  • The constructor injects a root element with class .places-bar. Use BEM-style modifiers for states: .places-bar__item–selected, –disabled, –overflowed.
  • Styling tips: use CSS variables to control spacing, color, and icon sizes.
  • Example CSS variables: –placesbar-gap, –placesbar-item-padding, –placesbar-icon-size, –placesbar-font-size.
  • For theming, add a class such as .places-bar–dark and override variables.

7. Accessibility and internationalization

  • Provide ariaLabel or aria-labelledby on the root element. Keyboard navigation must support Arrow keys, Home/End, Enter/Space for activation, and Esc for closing overflow.
  • Use aria-selected, role=“listbox” on the container, role=“option” on items (for single/multiple selection modes).
  • For overflow menus, ensure proper focus trapping and aria-expanded on the overflow button.
  • Support RTL by switching orientation via CSS logical properties or the orientation option.
  • Localize item titles and aria labels; avoid embedding strings directly in code.

8. Performance considerations

  • Use virtualized rendering when items exceed a few dozen entries.
  • Lazy-load icons (SVG or raster) when lazyLoadIcons=true.
  • Debounce resize observers used to compute overflow.
  • Batch DOM updates when adding/removing multiple items.

9. Testing and debugging

  • Unit test item addition/removal, selection state transitions, event emissions.
  • Integration test keyboard navigation and overflow behavior across viewport sizes.
  • Use dev-mode logging for layout calculations; toggle with an option like debug: true.
  • Inspect DOM to verify ARIA attributes and roles are correctly set.

10. Migration and versioning notes

  • If upgrading from v1 to v2, note these breaking changes: selection default switched from ‘multiple’ to ‘single’; item.icon now accepts strings or HTMLElements; overflow behavior API renamed openOverflow -> openOverflowMenu.
  • Maintain a migration utility: migrateItemsV1ToV2(items).

11. FAQ and troubleshooting

Q: Items disappearing when resizing?
A: Check overflow strategy and ensure maxVisibleItems or CSS doesn’t inadvertently hide items. Enable debug layout logs.

Q: Icons not appearing in some browsers?
A: Verify correct MIME types for SVG and that lazy loading isn’t blocking fetch during initial render.

Q: How to add context menus per item?
A: Use onAction and render a contextual menu anchored to the item’s DOM node; ensure menu is accessible.


12. Complete example: building an interactive places bar

HTML:

<div id="places-bar"></div> 

CSS (minimal):

.places-bar { display:flex; gap:var(--placesbar-gap,8px); align-items:center; } .places-bar__item { padding:var(--placesbar-item-padding,6px 10px); cursor:pointer; display:flex; align-items:center; gap:8px; } .places-bar__item--selected { outline:2px solid #0a84ff; border-radius:6px; } .places-bar__icon { width:var(--placesbar-icon-size,20px); height:var(--placesbar-icon-size,20px); } 

JavaScript:

const items = [   { id: 'home', title: 'Home', icon: '/icons/home.svg' },   { id: 'recent', title: 'Recent', icon: '/icons/recent.svg' },   { id: 'favorites', title: 'Favorites', icon: '/icons/star.svg', badge: 3 }, ]; const bar = new PlacesBarConstructor({   container: '#places-bar',   items,   selection: 'single',   overflow: 'menu',   ariaLabel: 'Quick access places',   onSelect: (item) => console.log('Navigate to', item.id),   itemRenderer: (item) => {     const el = document.createElement('div');     el.className = 'places-bar__item';     el.innerHTML = `<img class="places-bar__icon" src="${item.icon}" alt=""><span>${item.title}</span>`;     if (item.badge) el.insertAdjacentHTML('beforeend', `<span class="badge">${item.badge}</span>`);     return el;   } }); 

If you want, I can also:

  • Produce a downloadable code sandbox with this example.
  • Convert examples to React/Vue/Svelte components.
  • Add unit-test examples (Jest/Testing Library) for the component.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *