feat: sync showcase with WRNexusJS 0.8.72 and @wrnexus/ui 0.8.88

- Sync app, public, scripts, test and examples from the framework's
  component-showcase: redesigned component demos, marketing blocks under
  /blocks, template and preview galleries, distinct Timeline/Section
  variants, Chat Bubble receipts, a top-placement Drawer demo, and the
  playground code panel fix (objects in array props no longer blank out).
- Standalone adaptations kept: the generator and tests read
  component-reference.json from the published @wrnexus/ui, and tests use
  the published @wrnexus/compiler and @wrnexus/syntax.
- Dependencies: every @wrnexus/* package to its latest release (ui 0.8.88,
  styles 0.8.26, core 0.8.16, cli 0.8.72, ...), happy-dom for the
  playground tests, Tailwind 4.3; bun.lock and package-lock.json refreshed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClintchizandClaude Opus 5.5 committed 2026-09-30 16:50:22 +05:30
1 parent bec9ef2889
commit c0ac38c572
171 files changed
+21983 -35658

No files matched your search

+97 -12
View File
@@ -253,6 +253,43 @@ const DATATABLE_ROWS =
'[{"id": 1, "name": "Northwind", "plan": "Scale", "owner": "A. Okafor", "seats": 6, "status": "Active", "statusHtml": "<span class=\\"showcase-pill showcase-pill--success\\">Active</span>"}, {"id": 2, "name": "Acme Industrial", "plan": "Team", "owner": "R. Silva", "seats": 13, "status": "Trial", "statusHtml": "<span class=\\"showcase-pill showcase-pill--info\\">Trial</span>"}, {"id": 3, "name": "Globex", "plan": "Enterprise", "owner": "M. Chen", "seats": 20, "status": "Past due", "statusHtml": "<span class=\\"showcase-pill showcase-pill--danger\\">Past due</span>"}, {"id": 4, "name": "Initech", "plan": "Starter", "owner": "J. Dubois", "seats": 27, "status": "Active", "statusHtml": "<span class=\\"showcase-pill showcase-pill--success\\">Active</span>"}, {"id": 5, "name": "Umbrella", "plan": "Scale", "owner": "P. Novak", "seats": 34, "status": "Trial", "statusHtml": "<span class=\\"showcase-pill showcase-pill--info\\">Trial</span>"}, {"id": 6, "name": "Stark Labs", "plan": "Team", "owner": "A. Okafor", "seats": 41, "status": "Past due", "statusHtml": "<span class=\\"showcase-pill showcase-pill--danger\\">Past due</span>"}, {"id": 7, "name": "Wayne Foods", "plan": "Enterprise", "owner": "R. Silva", "seats": 48, "status": "Active", "statusHtml": "<span class=\\"showcase-pill showcase-pill--success\\">Active</span>"}, {"id": 8, "name": "Soylent", "plan": "Starter", "owner": "M. Chen", "seats": 55, "status": "Trial", "statusHtml": "<span class=\\"showcase-pill showcase-pill--info\\">Trial</span>"}, {"id": 9, "name": "Hooli", "plan": "Scale", "owner": "J. Dubois", "seats": 62, "status": "Past due", "statusHtml": "<span class=\\"showcase-pill showcase-pill--danger\\">Past due</span>"}, {"id": 10, "name": "Vehement", "plan": "Team", "owner": "P. Novak", "seats": 69, "status": "Active", "statusHtml": "<span class=\\"showcase-pill showcase-pill--success\\">Active</span>"}, {"id": 11, "name": "Massive Dynamic", "plan": "Enterprise", "owner": "A. Okafor", "seats": 76, "status": "Trial", "statusHtml": "<span class=\\"showcase-pill showcase-pill--info\\">Trial</span>"}, {"id": 12, "name": "Cyberdyne", "plan": "Starter", "owner": "R. Silva", "seats": 83, "status": "Past due", "statusHtml": "<span class=\\"showcase-pill showcase-pill--danger\\">Past due</span>"}, {"id": 13, "name": "Tyrell", "plan": "Scale", "owner": "M. Chen", "seats": 90, "status": "Active", "statusHtml": "<span class=\\"showcase-pill showcase-pill--success\\">Active</span>"}, {"id": 14, "name": "Aperture", "plan": "Team", "owner": "J. Dubois", "seats": 97, "status": "Trial", "statusHtml": "<span class=\\"showcase-pill showcase-pill--info\\">Trial</span>"}, {"id": 15, "name": "Black Mesa", "plan": "Enterprise", "owner": "P. Novak", "seats": 104, "status": "Past due", "statusHtml": "<span class=\\"showcase-pill showcase-pill--danger\\">Past due</span>"}]';
export const componentProfiles = {
Accordion: {
demos: [
standard(
"Plain disclosure rows",
"Unframed questions with trailing chevrons and aligned answers.",
{},
),
compact("Bordered group", "One shared border with leading indicators.", {}),
advanced("Separate panels", "Individually framed rows; multiple answers can stay open.", {}),
],
},
Alert: {
demos: [
standard("Success message", "A concise confirmation that can be dismissed.", {}),
compact("Informational notice", "One useful message without unnecessary actions.", {}),
advanced("Action required", "A warning with one relevant next step.", {}),
],
},
Carousel: {
demos: [
standard(
"Full-width, unframed",
"An edge-to-edge carousel without a card, border, or outer padding.",
{ framed: false },
),
compact(
"Framed gallery",
"Opt into a contained gallery when the surrounding layout needs it.",
{ framed: true },
),
advanced("Draggable slides", "Move between slides with dragging, arrows, or pagination.", {
framed: false,
isDraggable: true,
}),
],
},
Navbar: {
demos: [
standard(
@@ -378,7 +415,7 @@ export const componentProfiles = {
description:
"Scroll the page and the marker moves to whichever section is in view. The sections below are real page content, because the runtime observes against the viewport -- a table of contents inside a small scrolling box would have nothing to react to.",
before:
'<div class="showcase-spy-doc"><section id="overview" class="showcase-spy-section"><h3>Overview</h3><p>Scroll this page and watch the marker in the list move. The runtime observes these sections against the viewport, so the current link follows whatever you are reading.</p></section><section id="installation" class="showcase-spy-section"><h3>Installation</h3><p>Each link points at one of these ids. Nothing is wired up by hand -- the component only renders the links, and the runtime moves aria-current.</p></section><section id="usage" class="showcase-spy-section"><h3>Usage</h3><p>The active link is marked with aria-current="location", which is what a screen reader announces, and styled through data-active.</p></section><section id="api" class="showcase-spy-section"><h3>API</h3><p>Clicking a link jumps to its section and marks it immediately, so the control responds even before the scroll settles.</p></section></div>',
'<div class="showcase-spy-doc"><section id="overview" class="showcase-spy-section"><h3>Overview</h3><p>Scroll this page and watch the marker in the list move. The runtime observes these sections against the viewport, so the current link follows whatever you are reading.</p></section><section id="installation" class="showcase-spy-section"><h3>Installation</h3><p>Each link points at one of these ids. Nothing is connected up by hand -- the component only renders the links, and the runtime moves aria-current.</p></section><section id="usage" class="showcase-spy-section"><h3>Usage</h3><p>The active link is marked with aria-current="location", which is what a screen reader announces, and styled through data-active.</p></section><section id="api" class="showcase-spy-section"><h3>API</h3><p>Clicking a link jumps to its section and marks it immediately, so the control responds even before the scroll settles.</p></section></div>',
props: {
heading: "On this page",
items: [
@@ -1235,7 +1272,7 @@ export const componentProfiles = {
standard(
"Standard content section",
"Create predictable vertical rhythm around a page section.",
{ id: "standard-section", spacing: "lg", maxWidth: "xl" },
{ id: "standard-section", spacing: "lg", maxWidth: "xl", variant: "grid" },
{ default: '<div class="showcase-content-block">Standard section content</div>' },
),
compact(
@@ -1253,7 +1290,7 @@ export const componentProfiles = {
maxWidth: "full",
borderTop: true,
borderBottom: true,
variant: "raised",
variant: "solid",
},
{ default: '<div class="showcase-content-block">Full-width public page section</div>' },
),
@@ -1261,7 +1298,7 @@ export const componentProfiles = {
options: {
spacing: ["none", "sm", "md", "lg", "xl"],
maxWidth: ["compact", "lg", "xl", "wide", "2xl", "full"],
variant: ["default", "soft", "raised", "transparent"],
variant: ["default", "soft", "raised", "tinted", "solid", "panel", "grid"],
},
},
@@ -1941,7 +1978,7 @@ export const componentProfiles = {
},
),
],
playground: { items: menuItems, open: false, defaultOpen: false, trigger: "click" },
playground: { items: menuItems, open: false, defaultOpen: false, trigger: "contextmenu" },
options: {
trigger: ["contextmenu", "click", "both", "manual"],
placement: ["pointer", "top-start", "top-end", "bottom-start", "bottom-end"],
@@ -2056,6 +2093,24 @@ export const componentProfiles = {
'<div class="showcase-overlay-content showcase-overlay-content--tall"><p>Long scrollable content</p><p>Filters, navigation, details, and forms can be composed here.</p></div>',
},
),
compact(
"Top notice drawer",
"Slide a panel down from the top edge for announcements, search, or quick settings.",
{
open: false,
defaultOpen: false,
triggerLabel: "Open top drawer",
triggerIcon: "icon-[lucide--panel-top-open]",
title: "Scheduled maintenance",
description: "The workspace will be read-only on Sunday from 02:00 to 03:00 UTC.",
placement: "top",
size: "sm",
},
{
default:
'<div class="showcase-overlay-content"><p>Save your work before the window starts.</p></div>',
},
),
],
playground: {
open: false,
@@ -2411,13 +2466,13 @@ export const componentProfiles = {
{ default: '<strong class="showcase-card-value">38</strong>' },
),
advanced(
"Raised interactive card",
"Use a stronger visual treatment for featured content.",
"Featured resource",
"Keep the description and next action together in a single surface.",
{
title: "Featured guide",
description: "A complete guide to public safety and emergency readiness.",
size: "spacious",
variant: "raised",
size: "lg",
variant: "default",
},
{ default: '<a href="#guide" class="showcase-action">Read guide</a>' },
),
@@ -2785,7 +2840,7 @@ export const componentProfiles = {
{ title: "Document uploaded", time: "3 days ago" },
],
size: "sm",
variant: "soft",
variant: "compact",
},
),
advanced(
@@ -2814,11 +2869,11 @@ export const componentProfiles = {
},
],
size: "lg",
variant: "raised",
variant: "alternate",
},
),
],
options: { size: ["sm", "default", "lg"], variant: ["default", "soft", "raised", "outline"] },
options: { size: ["sm", "default", "lg"], variant: ["default", "soft", "raised", "outline", "minimal", "compact", "alternate"] },
},
Typography: {
@@ -2903,6 +2958,30 @@ const genericEventDescriptions = {
toggle: "Fires when the component changes between open and closed or on and off states.",
};
componentProfiles.Card.demos.push(
standard("Image with footer", "A cover image, concise body, and separate footer.", {title:"Design your next chapter",description:"A practical guide to building thoughtful products.",imageSrc:"/showcase-images/green-hero.svg",imageAlt:"Green abstract cover",footer:"6 min read",actionLabel:"Read guide",actionHref:"#guide"}),
compact("Without a header", "Body content with an optional footer; no reserved heading space.", {title:"",description:"Your workspace is ready. Invite your teammates to get started.",footer:"Updated just now"}, {default:""}),
advanced("Image-only card", "A simple image surface without header or footer chrome.", {title:"",description:"",imageSrc:"/showcase-images/blue-mountain.svg",imageAlt:"Blue geometric landscape"}, {default:""}),
);
componentProfiles.Map = { demos:[
standard("OpenStreetMap", "A real interactive geographic map. Set latitude, longitude and zoomLevel; no API key is needed.", {title:"Bengaluru",description:"Pan and zoom to explore the city",provider:"openstreetmap",latitude:12.9716,longitude:77.5946,zoomLevel:13,imageSrc:"",items:[]}),
compact("Google Maps", "Pass your restricted Maps Embed API key and a place query to show Google Maps.", {title:"Google Maps",provider:"google",apiKey:"",query:"Bengaluru",imageSrc:"",items:[]}),
], playground:{title:"Bengaluru",description:"Interactive geographic map",provider:"openstreetmap",latitude:12.9716,longitude:77.5946,zoomLevel:13,imageSrc:"",items:[]}, options:{provider:["openstreetmap","google"]} };
componentProfiles.Rating = {demos:[standard("Whole stars", "Choose a rating from zero to five with step 1.",{title:"Rate your experience",value:3,step:1}),compact("Half stars", "Click a half star or use the precise slider and arrow keys.",{title:"Half-star rating",value:3.5,step:0.5}),advanced("Fine increments", "Use increments of 0.2 for a more precise rating.",{title:"Detailed score",value:4.2,step:0.2})]};
componentProfiles.LegendIndicator = {demos:[standard("Chart legend", "Toggle a series and handle @toggle to update your chart.",{title:"Traffic sources",description:"Select a source to toggle its visibility.",items:[{label:"Direct",color:"#8b5cf6",value:"42%"},{label:"Search",color:"#14b8a6",value:"35%"},{label:"Referral",color:"#f59e0b",value:"23%"}]})]};
componentProfiles.Chart = {demos:[standard("Bar chart", "Pass an array of label/value objects through data.",{title:"Weekly signups",type:"bar",data:[{label:"Mon",value:24},{label:"Tue",value:38},{label:"Wed",value:29},{label:"Thu",value:52},{label:"Fri",value:45}],items:[],showLegend:false}),compact("Line chart", "Use type=line to compare a trend over time.",{title:"Monthly revenue",type:"line",data:[{label:"Jan",value:20},{label:"Feb",value:35},{label:"Mar",value:28},{label:"Apr",value:55}],items:[],showLegend:false})],options:{type:["bar","line"]}};
componentProfiles.DatePicker = { demos:[
standard("Date picker", "An anchored calendar that does not move surrounding content.", {label:"Start date",name:"start-date",type:"date"}),
compact("Date and time", "Choose a calendar date and a time in one field.", {label:"Schedule for",name:"schedule",type:"datetime-local",value:"2026-09-20T09:30"}),
advanced("Disabled date", "A read-only scheduled date.", {label:"Scheduled date",readonly:true}),
], options:{type:["date","datetime-local"]} };
componentProfiles.TimePicker = { demos:[standard("Time picker", "Choose an hour and minute in an anchored panel.", {label:"Meeting time",name:"meeting-time",value:"09:30"})] };
componentProfiles.Modal.demos.push(
advanced("Custom header and footer", "Supply your own header, body, and footer actions.", {title:"",description:"",cancelLabel:"",confirmLabel:"",triggerLabel:"Open custom dialog"}, {header:'<h2>Invite a teammate</h2>',default:'<p>Give your teammate access to your workspace.</p>',footer:`<button type="button" class="showcase-action" data-modal-close="true">Done</button>`}),
compact("Centered content", "Omit the standard header and footer for a fully custom composition.", {showHeader:false,showFooter:false,title:"",description:"",icon:"",size:"sm",triggerLabel:"Open centered dialog"}, {default:`<div style="text-align:center;padding:2rem"><h2>You are all set</h2><p>Your preferences have been saved.</p><button type="button" class="showcase-action" data-modal-close="true">Continue</button></div>`}),
);
export function profileFor(name) {
return componentProfiles[name] ?? null;
}
@@ -2912,3 +2991,9 @@ export function eventDescriptionFor(_componentName, eventName) {
genericEventDescriptions[eventName] ?? `Fires when the component emits the ${eventName} event.`
);
}
componentProfiles.Card.demos.push(advanced("Custom slots", "Supply arbitrary header, body, and footer content. Use showHeader and showFooter to hide either region.", {title:"",description:"",showHeader:true,showFooter:true,footer:"",actionLabel:""}, {header:"<strong>Team invitation</strong>",default:'<Input label="Email" placeholder="name@company.com" />',footer:'<Button label="Send invitation" />'}));
componentProfiles.RangeSlider = { demos: [compact("Fractional steps", "Use step=0.2 for precise increments with buttons, dragging, or arrow keys.", {label:"Scale",min:0,max:5,value:2.4,step:0.2})] };
componentProfiles.FileInput = {demos:[standard("Choose a document", "Select a PDF or image. The selected filename replaces the placeholder.", {label:"Attachment",name:"attachment",value:"",accept:".pdf,image/*",helperText:"PDF or image",placeholder:"Choose a file"}),compact("Multiple attachments", "Select several files; each filename is shown in the control.",{label:"Attachments",name:"attachments",value:"",multiple:true,placeholder:"Choose files"}),advanced("Disabled upload", "A disabled control cannot open the file chooser.",{label:"Attachment",name:"disabled-file",value:"",disabled:true,placeholder:"Uploads unavailable"})]};