Skip to Content
V0.2Playground

Playground

An earlier release

These pages document @evanion/react-widget 0.2.0. npm install @evanion/react-widget gives you 0.3.3, documented here. Values on this page were produced by running 0.2.0 in CI at d50a1c6 and are not re-executed.

Experiment with the React Widget System. Try the live demos below or copy the examples to learn how the system works.

Interactive Demo

Try these live examples to experiment with different widget configurations:

The interactive example this release showed here runs against the current source, so it is on the same page under /next/ and not on this one.

Basic Widget System

Start with a simple widget system:

import { createWidgets } from '@evanion/react-widget'; // Define your widget components const NewsTeaser = ({ title, publishedAt, body }) => ( <article className="news-teaser"> <h3>{title}</h3> <time>{publishedAt.toLocaleDateString()}</time> <p>{body}</p> </article> ); const UserSidebar = ({ username, avatar, messages }) => ( <div className="user-info"> <img src={avatar} alt={username} /> <span>{username}</span> <span>{messages} messages</span> </div> ); // Create the widget system const { Widgets } = createWidgets({ components: { news: NewsTeaser, userInfo: UserSidebar, }, }); // Define your layout data const items = [ { id: 'userinfo', type: 'userInfo', props: { username: 'Evanion', avatar: 'https://evanion.com/avatar.jpg', messages: 5, }, }, { id: 'news1', type: 'news', props: { title: 'Breaking News', publishedAt: new Date('2024-01-15'), body: 'This is a sample news article...', }, }, ]; // Render your widgets function PlaygroundExample() { return <Widgets items={items} />; }

Custom Chrome Example

Try adding custom wrappers:

const { Widgets } = createWidgets({ components: { news: NewsTeaser, userInfo: UserSidebar, }, chrome: { wrapper: ({ children }) => ( <aside className="blog-sidebar"> <header>Latest Updates</header> <div className="widget-container">{children}</div> </aside> ), item: ({ children }) => <div className="widget-item">{children}</div>, }, });

Nested Widgets

Experiment with nested widgets:

const CardWidget = ({ title, Output }) => ( <div className="card"> <h3>{title}</h3> <div className="card-content"> <Output /> </div> </div> ); const TextWidget = ({ content }) => <p>{content}</p>; const { Widgets } = createWidgets({ components: { card: CardWidget, text: TextWidget, }, }); const nestedItems = [ { id: 'card1', type: 'card', props: { title: 'My Card', }, children: [ { id: 'text1', type: 'text', props: { content: 'Nested text content' }, }, ], }, ];

Dynamic Widgets

Create dynamic widget systems:

import { useState } from 'react'; function DynamicPlayground() { const [widgetType, setWidgetType] = useState('news'); const [widgetData, setWidgetData] = useState({ title: 'Dynamic News', publishedAt: new Date(), body: 'This widget is dynamically configured!', }); const { Widgets } = createWidgets({ components: { news: NewsTeaser, userInfo: UserSidebar, }, }); const dynamicItems = [ { id: 'dynamic1', type: widgetType, props: widgetData, }, ]; return ( <div> <div className="controls"> <select value={widgetType} onChange={(e) => setWidgetType(e.target.value)} > <option value="news">News</option> <option value="userInfo">User Info</option> </select> <input type="text" value={widgetData.title} onChange={(e) => setWidgetData({ ...widgetData, title: e.target.value }) } placeholder="Widget title" /> </div> <Widgets items={dynamicItems} /> </div> ); }

Error Handling

Test error handling:

const { Widgets } = createWidgets({ components: { news: NewsTeaser, // Intentionally missing 'userInfo' component }, }); const errorItems = [ { id: 'valid1', type: 'news', props: { title: 'Valid News', publishedAt: new Date(), body: 'This will render', }, }, { id: 'invalid1', type: 'userInfo', // This type is not defined props: { username: 'Test User', avatar: '/avatar.jpg', messages: 3, }, }, ]; // Only the valid widget will render // The invalid one will be skipped with a console warning function ErrorHandlingExample() { return <Widgets items={errorItems} />; }

Tips for Experimenting

  • Start simple - Begin with basic widget components
  • Add complexity gradually - Add chrome, then nesting, then dynamic features
  • Use TypeScript - Get better IntelliSense and error checking
  • Check the console - Look for warnings about unknown widget types
  • Copy working examples - Use the examples from the documentation as starting points

Common Patterns to Try

Conditional Widgets

const conditionalItems = [ ...(showNews ? [ { id: 'news1', type: 'news', props: { title: 'News', publishedAt: new Date(), body: 'Content' }, }, ] : []), ];

Dynamic Props

const dynamicItems = items.map((item) => ({ ...item, props: { ...item.props, className: isActive ? 'active' : 'inactive', }, }));

Component Overrides

// Use different components for different contexts <Widgets items={items} components={{ news: isHomePage ? FeaturedNews : RegularNews, }} />
Last updated on