@owodesign/owoui 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -5
- package/dist/index.d.ts +73 -21
- package/dist/index.min.js +1 -1
- package/dist/storybook/catalog.js +32 -8
- package/dist/storybook/catalog.json +32 -8
- package/dist/storybook/index.d.ts +1 -0
- package/dist/storybook/index.min.js +9 -8
- package/dist/storybook-static/app.css +4171 -0
- package/dist/storybook-static/assets/main.css +2 -0
- package/dist/storybook-static/assets/main.js +235 -0
- package/dist/storybook-static/index.html +24 -0
- package/dist/tokens.d.ts +4 -2
- package/dist/tokens.min.js +1 -1
- package/package.json +32 -15
- package/src/preset-default.css +27 -0
- package/src/preset-elevated.css +27 -0
- package/src/preset-flat.css +27 -0
- package/src/preset-glass.css +27 -0
- package/src/style.css +3 -1
- package/src/styles/tokens.css +131 -83
- package/src/styles/ui/collapsible.css +13 -0
- package/src/styles/ui/input.css +2 -2
- package/src/styles/ui/select.css +4 -4
- package/src/styles/ui/status-notice.css +8 -0
- package/src/styles/ui/tabs.css +33 -0
- package/src/styles/ui/textarea.css +8 -0
- package/src/styles/ui/tooltip.css +7 -2
- package/src/theme-dark.css +87 -0
- package/src/theme-light.css +102 -0
- package/src/dark.css +0 -70
- package/src/elevated.css +0 -20
- package/src/flat.css +0 -1
- package/src/glass.css +0 -17
- package/src/styles/ui/empty-state.css +0 -34
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import{Plus as
|
|
1
|
+
import{Plus as Xt,ArrowRight as Zt}from"lucide-react";import{clsx as go}from"clsx";import{clsx as no}from"clsx";import{jsx as D,jsxs as He}from"react/jsx-runtime";var oo={xs:12,sm:14,md:16,lg:24};function ao({px:e}){let n=Math.PI*2*9;return He("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",children:[D("circle",{cx:"12",cy:"12",r:9,stroke:"currentColor",strokeWidth:"3",opacity:"0.2"}),D("circle",{cx:"12",cy:"12",r:9,stroke:"currentColor",strokeWidth:"3",strokeLinecap:"round",strokeDasharray:`${n*.28} ${n*.72}`})]})}function ro({px:e}){return He("svg",{width:e,height:e,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",children:[D("path",{d:"M12 2a10 10 0 0 1 10 10",opacity:"0.9"}),D("path",{d:"M12 2a10 10 0 0 0-7.07 2.93",opacity:"0.2"}),D("path",{d:"M4.93 4.93A10 10 0 0 0 2 12",opacity:"0.2"}),D("path",{d:"M2 12a10 10 0 0 0 2.93 7.07",opacity:"0.2"}),D("path",{d:"M4.93 19.07A10 10 0 0 0 12 22",opacity:"0.2"}),D("path",{d:"M12 22a10 10 0 0 0 7.07-2.93",opacity:"0.2"}),D("path",{d:"M19.07 19.07A10 10 0 0 0 22 12",opacity:"0.2"})]})}function io({px:e}){return D("svg",{width:e,height:e,viewBox:"0 0 24 24",children:[0,1,2,3,4,5,6,7].map(n=>{let o=n/8*360,a=.15+n/8*.85;return D("circle",{cx:"12",cy:"3.5",r:"1.8",fill:"currentColor",opacity:a,transform:`rotate(${o} 12 12)`},n)})})}function so({px:e}){return D("svg",{width:e,height:e,viewBox:"0 0 24 24",children:[0,1,2,3].map(t=>He("rect",{x:3+t*5.5,y:"4",width:"3",height:"16",rx:"1.5",fill:"currentColor",opacity:"0.3",children:[D("animate",{attributeName:"opacity",values:"0.3;1;0.3",dur:"1s",begin:`${t*.15}s`,repeatCount:"indefinite"}),D("animate",{attributeName:"height",values:"16;8;16",dur:"1s",begin:`${t*.15}s`,repeatCount:"indefinite"}),D("animate",{attributeName:"y",values:"4;8;4",dur:"1s",begin:`${t*.15}s`,repeatCount:"indefinite"})]},t))})}function lo({px:e}){let t=e*.14,n=e*.33,o=e/2-n,a=e/2,r=e/2+n,i=e/2;return D("svg",{width:e,height:e,viewBox:`0 0 ${e} ${e}`,children:[o,a,r].map((l,d)=>He("circle",{cx:l,cy:i,r:t,fill:"currentColor",opacity:"0.4",children:[D("animate",{attributeName:"cy",values:`${i};${i-e*.25};${i}`,dur:"0.6s",begin:`${d*.12}s`,repeatCount:"indefinite",calcMode:"spline",keySplines:"0.4 0 0.2 1;0.4 0 0.2 1"}),D("animate",{attributeName:"opacity",values:"0.4;1;0.4",dur:"0.6s",begin:`${d*.12}s`,repeatCount:"indefinite"})]},d))})}function co({px:e}){return He("svg",{width:e,height:e,viewBox:"0 0 24 24",children:[He("circle",{cx:"12",cy:"12",r:"0",fill:"currentColor",opacity:"0",children:[D("animate",{attributeName:"r",values:"4;10;4",dur:"1.2s",repeatCount:"indefinite"}),D("animate",{attributeName:"opacity",values:"0.8;0.1;0.8",dur:"1.2s",repeatCount:"indefinite"})]}),D("circle",{cx:"12",cy:"12",r:"3.5",fill:"currentColor",opacity:"0.7"})]})}function uo({px:e}){return He("svg",{width:e,height:e,viewBox:"0 0 24 24",children:[D("circle",{cx:"12",cy:"12",r:"8",stroke:"currentColor",strokeWidth:"1.5",fill:"none",opacity:"0.15"}),D("circle",{cx:"12",cy:"4",r:"2.2",fill:"currentColor",children:D("animateTransform",{attributeName:"transform",type:"rotate",from:"0 12 12",to:"360 12 12",dur:"0.9s",repeatCount:"indefinite"})}),D("circle",{cx:"12",cy:"20",r:"1.5",fill:"currentColor",opacity:"0.5",children:D("animateTransform",{attributeName:"transform",type:"rotate",from:"0 12 12",to:"-360 12 12",dur:"0.9s",repeatCount:"indefinite"})})]})}function po({px:e}){let t=e*.14,n=e*.33,o=e/2-n,a=e/2,r=e/2+n,i=e/2;return D("svg",{width:e,height:e,viewBox:`0 0 ${e} ${e}`,children:[o,a,r].map((l,d)=>D("circle",{cx:l,cy:i,r:t,fill:"currentColor",opacity:"0.25",children:D("animate",{attributeName:"opacity",values:"0.25;1;0.25",dur:"0.9s",begin:`${d*.2}s`,repeatCount:"indefinite"})},d))})}var mo={ring:ao,arc:ro,dots:io,bars:so,bounce:lo,pulse:co,orbit:uo,flow:po},fo=new Set(["ring","arc","dots"]);function se({variant:e="ring",size:t="md",className:n,label:o}){let a=typeof t=="number"?t:oo[t],r=mo[e];return D("span",{"aria-hidden":!o,"aria-label":o,role:o?"img":void 0,className:no("ui-spinner inline-flex",fo.has(e)&&"animate-spin",n),children:D(r,{px:a})})}import{Fragment as vo,jsx as Oe,jsxs as ho}from"react/jsx-runtime";function bo({variant:e="secondary",size:t="md",loading:n=!1,className:o}){return go("ui-button","inline-flex items-center justify-center gap-2 rounded-md border font-medium transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-inset disabled:cursor-not-allowed disabled:opacity-[var(--button-disabled-opacity)]",t==="sm"?"min-h-8 px-3 text-xs":"min-h-9 px-4 text-sm",n&&"pointer-events-none cursor-wait",o)}function u(e){let{variant:t="secondary",size:n="md",loading:o=!1,leadingIcon:a,trailingIcon:r,className:i,children:l,...d}=e,s=ho(vo,{children:[o?Oe("span",{className:"shrink-0",children:Oe(se,{size:n==="sm"?"sm":"md"})}):a?Oe("span",{className:"shrink-0",children:a}):null,Oe("span",{children:l}),!o&&r?Oe("span",{className:"shrink-0",children:r}):null]}),p=bo({variant:t,size:n,loading:o,className:i});if("href"in e&&e.href){let{href:b,...m}=d;return Oe("a",{href:b,"data-variant":t,"data-size":n,"data-loading":o?"true":void 0,"aria-disabled":o||void 0,tabIndex:o?-1:void 0,className:p,onClick:o?f=>f.preventDefault():void 0,...m,children:s})}let c=d;return Oe("button",{type:c.type??"button","data-variant":t,"data-size":n,"data-loading":o?"true":void 0,disabled:c.disabled||o,className:p,...c,children:s})}var Mt=[],yo=[{group:"actions",componentId:"button"},{group:"actions",componentId:"dropdown-menu"},{group:"actions",componentId:"icon-button"},{group:"forms",componentId:"input"},{group:"forms",componentId:"field"},{group:"forms",componentId:"select"},{group:"forms",componentId:"segmented-control"},{group:"forms",componentId:"switch"},{group:"forms",componentId:"textarea"},{group:"forms",componentId:"collapsible"},{group:"forms",componentId:"tabs"},{group:"feedback",componentId:"badge"},{group:"feedback",componentId:"status-notice"},{group:"feedback",componentId:"empty-state"},{group:"feedback",componentId:"spinner"},{group:"feedback",componentId:"skeleton"},{group:"feedback",componentId:"dialog"},{group:"feedback",componentId:"toast"},{group:"feedback",componentId:"avatar"},{group:"feedback",componentId:"tooltip"},{group:"layout",componentId:"drawer"},{group:"layout",componentId:"panel"}];function h(e){Mt.push(e)}function xo(e,t){return Mt.find(n=>n.group===e&&n.componentId===t)}function wo(){let e={actions:[],forms:[],feedback:[],layout:[]};for(let t of Mt)e[t.group].push(t);return e}var No={actions:"Actions",forms:"Forms",feedback:"Feedback",layout:"Layout"},To=["actions","forms","feedback","layout"];import{jsx as F,jsxs as Xe}from"react/jsx-runtime";h({group:"actions",componentId:"button",componentName:"Button",description:"Primary action trigger. Supports variants, sizes, icons, loading, and disabled states.",defaultScale:1.5,props:[{name:"variant",type:"'primary' | 'secondary' | 'ghost' | 'danger'",default:"'primary'",description:"Visual style variant."},{name:"size",type:"'sm' | 'md'",default:"'md'",description:"Button size."},{name:"loading",type:"boolean",default:"false",description:"Shows loading state and sets cursor-wait."},{name:"disabled",type:"boolean",default:"false",description:"Disables the button."},{name:"children",type:"string",default:"'Get Started'",description:"Button label text."},{name:"leadingIcon",type:"ReactNode",description:"Icon rendered before children."},{name:"trailingIcon",type:"ReactNode",description:"Icon rendered after children."},{name:"href",type:"string",description:"When set, renders as a Next.js Link."}],renderPlayground:e=>F(u,{variant:e.variant,size:e.size,loading:!!e.loading,disabled:!!e.disabled,children:e.children||"Get Started"}),stories:[{id:"variants",title:"Variants",description:"primary / secondary / ghost / danger",source:`<Button variant="primary">Primary</Button>
|
|
2
2
|
<Button variant="secondary">Secondary</Button>
|
|
3
3
|
<Button variant="ghost">Ghost</Button>
|
|
4
|
-
<Button variant="danger">Danger</Button>`,render:()=>We("div",{className:"flex flex-wrap items-center gap-3",children:[_(d,{variant:"primary",children:"Primary"}),_(d,{variant:"secondary",children:"Secondary"}),_(d,{variant:"ghost",children:"Ghost"}),_(d,{variant:"danger",children:"Danger"})]})},{id:"sizes",title:"Sizes",description:"sm / md",render:()=>We("div",{className:"flex flex-wrap items-center gap-3",children:[_(d,{size:"sm",children:"Small"}),_(d,{size:"md",children:"Medium"})]})},{id:"with-icons",title:"With Icons",description:"leadingIcon / trailingIcon",render:()=>We("div",{className:"flex flex-wrap items-center gap-3",children:[_(d,{variant:"primary",leadingIcon:_(Ot,{size:16}),children:"Create"}),_(d,{variant:"secondary",trailingIcon:_(_t,{size:16}),children:"Next"}),_(d,{variant:"ghost",leadingIcon:_(Ot,{size:16}),trailingIcon:_(_t,{size:16}),children:"Both"})]})},{id:"loading-disabled",title:"Loading & Disabled",render:()=>We("div",{className:"flex flex-wrap items-center gap-3",children:[_(d,{variant:"primary",loading:!0,children:"Saving\u2026"}),_(d,{variant:"secondary",loading:!0,children:"Loading"}),_(d,{variant:"secondary",disabled:!0,children:"Disabled"}),_(d,{variant:"danger",disabled:!0,children:"Disabled Danger"})]})},{id:"all-variants-sm",title:"All Variants (sm)",render:()=>We("div",{className:"flex flex-wrap items-center gap-3",children:[_(d,{variant:"primary",size:"sm",children:"Primary"}),_(d,{variant:"secondary",size:"sm",children:"Secondary"}),_(d,{variant:"ghost",size:"sm",children:"Ghost"}),_(d,{variant:"danger",size:"sm",children:"Danger"})]})}]});import{X as Ge,Settings as et,Trash2 as oo,ChevronRight as ao}from"lucide-react";import{clsx as no}from"clsx";import{jsx as Ft}from"react/jsx-runtime";function Y({variant:e="ghost",size:t="md",label:n,icon:o,className:a,...i}){let r=no("ui-icon-button","inline-flex items-center justify-center rounded-md transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-inset disabled:cursor-not-allowed disabled:opacity-50",t==="sm"?"h-7 w-7":"h-8 w-8",a);if("href"in i&&i.href){let{href:c,...s}=i;return Ft("a",{href:c,"aria-label":n,title:s.title??n,"data-variant":e,"data-size":t,className:r,...s,children:o})}let p=i;return Ft("button",{type:p.type??"button","aria-label":n,title:p.title??n,"data-variant":e,"data-size":t,className:r,...p,children:o})}import{jsx as F,jsxs as tt}from"react/jsx-runtime";y({group:"actions",componentId:"icon-button",componentName:"IconButton",description:"Icon-only action button. Supports ghost/subtle variants, sm/md sizes.",props:[{name:"variant",type:"'ghost' | 'subtle'",default:"'ghost'",description:"Visual style variant."},{name:"size",type:"'sm' | 'md'",default:"'md'",description:"Button size."},{name:"label",type:"string",description:"Accessible label used for aria-label and title fallback."},{name:"icon",type:"ReactNode",description:"Icon content rendered inside the button."},{name:"href",type:"string",description:"When set, renders as a Next.js Link instead of a button."},{name:"disabled",type:"boolean",default:"false",description:"Disables button interaction when rendered as a button."}],renderPlayground:e=>F(Y,{variant:e.variant,size:e.size,disabled:!!e.disabled,label:"Settings",icon:F(et,{size:e.size==="sm"?14:16})}),stories:[{id:"variants",title:"Variants",description:"ghost / subtle",render:()=>tt("div",{className:"flex items-center gap-3",children:[F(Y,{variant:"ghost",label:"Close",icon:F(Ge,{size:16})}),F(Y,{variant:"subtle",label:"Settings",icon:F(et,{size:16})})]})},{id:"sizes",title:"Sizes",description:"sm / md",render:()=>tt("div",{className:"flex items-center gap-3",children:[F(Y,{size:"sm",label:"Small",icon:F(Ge,{size:14})}),F(Y,{size:"md",label:"Medium",icon:F(Ge,{size:16})})]})},{id:"use-cases",title:"Use Cases",render:()=>tt("div",{className:"flex items-center gap-3",children:[F(Y,{label:"Close",icon:F(Ge,{size:16})}),F(Y,{label:"Settings",icon:F(et,{size:16})}),F(Y,{label:"Delete",icon:F(oo,{size:16})}),F(Y,{label:"Navigate",icon:F(ao,{size:16})})]})},{id:"disabled",title:"Disabled",render:()=>tt("div",{className:"flex items-center gap-3",children:[F(Y,{label:"Disabled ghost",icon:F(Ge,{size:16}),disabled:!0}),F(Y,{variant:"subtle",label:"Disabled subtle",icon:F(et,{size:16}),disabled:!0})]})}]});import{clsx as io}from"clsx";import{jsx as Wt}from"react/jsx-runtime";function Vt(e){return io("ui-input w-full rounded-lg px-3 py-2 text-sm placeholder:text-[var(--field-placeholder)] focus:outline-none focus:ring-1",e)}function de(e){let{className:t,tone:n="default",...o}=e;return e.as==="textarea"?Wt("textarea",{"data-tone":n,className:Vt(t),...o}):Wt("input",{"data-tone":n,className:Vt(t),...o})}import{jsx as Se,jsxs as Gt}from"react/jsx-runtime";y({group:"forms",componentId:"input",componentName:"Input",description:"Unified input element. Renders as input or textarea via the `as` prop. For dropdown selection, use the Select component.",props:[{name:"as",type:"'input' | 'textarea'",default:"'input'",description:"Chooses which native form element to render."},{name:"tone",type:"'default' | 'warning'",default:"'default'",description:"Visual tone for neutral or warning emphasis."},{name:"className",type:"string",description:"Additional CSS classes for the rendered element."},{name:"placeholder",type:"string",description:"Placeholder text for input or textarea variants."},{name:"rows",type:"number",description:'Textarea row count when `as="textarea"`.'}],renderPlayground:e=>Se("div",{className:"max-w-xs",children:Se(de,{as:e.as,tone:e.tone,placeholder:"Type something\u2026"})}),stories:[{id:"text-input",title:"Text Input",render:()=>Gt("div",{className:"max-w-xs space-y-3",children:[Se(de,{"aria-label":"Default input",name:"demo-default",autoComplete:"off",placeholder:"e.g., hello world\u2026"}),Se(de,{"aria-label":"With value",name:"demo-value",autoComplete:"off",placeholder:"e.g., hello world\u2026",defaultValue:"Hello world"})]})},{id:"textarea",title:"Textarea",render:()=>Se("div",{className:"max-w-sm",children:Se(de,{as:"textarea","aria-label":"Textarea",placeholder:"Write something\u2026",rows:3})})},{id:"tones",title:"Tones",description:"default / warning",render:()=>Gt("div",{className:"max-w-xs space-y-3",children:[Se(de,{tone:"default","aria-label":"Default tone",name:"demo-tone-default",autoComplete:"off",placeholder:"Default tone\u2026"}),Se(de,{tone:"warning","aria-label":"Warning tone",name:"demo-tone-warning",autoComplete:"off",placeholder:"Warning tone\u2026"})]})}]});import{useState as uo}from"react";import{clsx as ro}from"clsx";import{jsx as $t,jsxs as so}from"react/jsx-runtime";function Ee({label:e,help:t,htmlFor:n,children:o,className:a,...i}){return so("div",{className:ro("ui-field block",a),...i,children:[$t("label",{htmlFor:n,className:"ui-field__label mb-1 block text-xs",children:e}),o,t?$t("span",{className:"ui-field__help mt-1 block text-xs",children:t}):null]})}import{clsx as Ae}from"clsx";import{useCallback as vt,useEffect as Ut,useId as lo,useMemo as co,useRef as Kt,useState as qt}from"react";import{jsx as $e,jsxs as Xt}from"react/jsx-runtime";function ce({value:e,onChange:t,options:n,placeholder:o="Select\u2026",size:a="md",tone:i="default",disabled:r=!1,className:p,ariaLabel:c,renderValue:s,renderOption:u}){let[l,m]=qt(!1),[g,w]=qt(-1),M=Kt(null),v=Kt(null),h=lo(),D=n.find(f=>f.value===e),N=co(()=>n.reduce((f,k,Z)=>(k.disabled||f.push(Z),f),[]),[n]),z=vt(()=>{if(r||n.length===0)return;m(!0);let f=n.findIndex(k=>k.value===e);w(f>=0?f:N[0]??-1)},[r,n,e,N]),S=vt(()=>{m(!1),w(-1)},[]),W=vt(f=>{f.disabled||(t(f.value),S())},[t,S]);Ut(()=>{if(!l)return;function f(k){M.current&&!M.current.contains(k.target)&&S()}return document.addEventListener("mousedown",f),()=>document.removeEventListener("mousedown",f)},[l,S]),Ut(()=>{if(!l||g<0)return;v.current?.children[g]?.scrollIntoView({block:"nearest"})},[l,g]);function G(f){if(!r)switch(f.key){case"Enter":case" ":{f.preventDefault(),l?g>=0&&n[g]&&!n[g].disabled&&W(n[g]):z();break}case"ArrowDown":{if(f.preventDefault(),!l)z();else{let k=N.indexOf(g),Z=N[k+1];Z!==void 0&&w(Z)}break}case"ArrowUp":{if(f.preventDefault(),!l)z();else{let k=N.indexOf(g),Z=N[k-1];Z!==void 0&&w(Z)}break}case"Escape":{l&&(f.preventDefault(),S());break}case"Tab":{l&&S();break}}}let q=e!==""&&D,I=s?s({open:l,placeholder:o,selectedOption:D}):$e("span",{className:Ae("truncate",!q&&"ui-select__placeholder"),children:q?D.label:o});return Xt("div",{ref:M,"data-state":l?"open":"closed","data-disabled":r||void 0,"data-size":a,"data-tone":i,className:Ae("ui-select relative inline-block",p),children:[Xt("button",{type:"button",role:"combobox","aria-expanded":l,"aria-haspopup":"listbox","aria-controls":h,"aria-label":c,"aria-activedescendant":l&&g>=0?`${h}-opt-${g}`:void 0,"data-state":l?"open":"closed","data-disabled":r||void 0,"data-tone":i,"data-size":a,"data-open":l||void 0,"data-has-value":q||void 0,disabled:r,className:Ae("ui-select__trigger flex w-full items-center justify-between gap-2 rounded-lg text-left transition-colors focus:outline-none focus:ring-1",a==="sm"?"min-h-7 px-2 py-1 text-xs":"min-h-9 px-3 py-2 text-sm"),onClick:()=>l?S():z(),onKeyDown:G,children:[I,$e("svg",{"aria-hidden":"true",className:Ae("ui-select__chevron h-3.5 w-3.5 shrink-0 transition-transform",l&&"rotate-180"),viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:$e("path",{d:"M4 6l4 4 4-4"})})]}),l&&$e("ul",{ref:v,id:h,role:"listbox","aria-label":c,"data-state":"open",className:Ae("ui-select__dropdown absolute z-50 mt-1 max-h-60 w-full overflow-auto rounded-lg py-1 ring-1",a==="sm"?"text-xs":"text-sm"),children:n.map((f,k)=>$e("li",{id:`${h}-opt-${k}`,role:"option","aria-selected":f.value===e,"aria-disabled":f.disabled||void 0,"data-state":f.value===e?"selected":k===g?"highlighted":"idle","data-focused":k===g||void 0,"data-selected":f.value===e||void 0,"data-disabled":f.disabled||void 0,"data-highlighted":k===g||void 0,className:Ae("ui-select__option cursor-default select-none px-3 py-1.5 transition-colors",f.disabled&&"cursor-not-allowed opacity-50"),onClick:()=>W(f),onMouseEnter:()=>!f.disabled&&w(k),children:u?u({option:f,index:k,selected:f.value===e,highlighted:k===g}):f.label},f.value))})]})}import{jsx as re}from"react/jsx-runtime";function po(){let[e,t]=uo("");return re("div",{className:"max-w-xs pb-36",children:re(Ee,{label:"Category",htmlFor:"sb-category",children:re(ce,{value:e,onChange:t,options:[{value:"tech",label:"Technology"},{value:"design",label:"Design"},{value:"other",label:"Other"}],placeholder:"Select a category",ariaLabel:"Category"})})})}y({group:"forms",componentId:"field",componentName:"Field",description:"Form field wrapper with label and optional help text.",props:[{name:"label",type:"ReactNode",description:"Visible field label rendered above the control."},{name:"help",type:"ReactNode",description:"Optional helper text rendered below the control."},{name:"htmlFor",type:"string",description:"Associates the label with the inner form control id."},{name:"children",type:"ReactNode",description:"Form control content, such as Input or Select."}],stories:[{id:"basic",title:"Basic Field",render:()=>re("div",{className:"max-w-xs",children:re(Ee,{label:"Username",htmlFor:"sb-username",children:re(de,{id:"sb-username",name:"username",autoComplete:"username",placeholder:"Enter username"})})})},{id:"with-help",title:"With Help Text",render:()=>re("div",{className:"max-w-xs",children:re(Ee,{label:"Email",htmlFor:"sb-email",help:"We'll never share your email.",children:re(de,{id:"sb-email",type:"email",name:"email",autoComplete:"email",spellCheck:!1,placeholder:"you@example.com"})})})},{id:"with-textarea",title:"With Textarea",render:()=>re("div",{className:"max-w-sm",children:re(Ee,{label:"Bio",htmlFor:"sb-bio",help:"Brief description about yourself.",children:re(de,{as:"textarea",id:"sb-bio",name:"bio",autoComplete:"off",placeholder:"Tell us about yourself\u2026",rows:3})})})},{id:"with-select",title:"With Select",render:()=>re(po,{})}]});import{useState as Ue}from"react";import{jsx as J,jsxs as ht}from"react/jsx-runtime";function mo(){let[e,t]=Ue("");return J("div",{className:"max-w-xs pb-44",children:J(ce,{value:e,onChange:t,options:[{value:"apple",label:"Apple"},{value:"banana",label:"Banana"},{value:"cherry",label:"Cherry"},{value:"dragonfruit",label:"Dragonfruit"}],placeholder:"Choose a fruit\u2026",ariaLabel:"Fruit select"})})}function fo(){let[e,t]=Ue("apple"),[n,o]=Ue("apple"),a=[{value:"apple",label:"Apple"},{value:"banana",label:"Banana"},{value:"cherry",label:"Cherry"}];return ht("div",{className:"flex max-w-xs flex-col gap-3 pb-36",children:[J(ce,{value:e,onChange:t,options:[...a],size:"sm",ariaLabel:"Small select"}),J(ce,{value:n,onChange:o,options:[...a],size:"md",ariaLabel:"Medium select"})]})}function go(){let[e,t]=Ue("a"),[n,o]=Ue("a"),a=[{value:"a",label:"Option A"},{value:"b",label:"Option B"}];return ht("div",{className:"flex max-w-xs flex-col gap-3 pb-28",children:[J(ce,{value:e,onChange:t,options:[...a],tone:"default",ariaLabel:"Default tone"}),J(ce,{value:n,onChange:o,options:[...a],tone:"warning",ariaLabel:"Warning tone"})]})}function bo(){return ht("div",{className:"flex max-w-xs flex-col gap-3 pb-28",children:[J(ce,{value:"",onChange:()=>{},options:[{value:"a",label:"Option A"}],disabled:!0,placeholder:"Disabled",ariaLabel:"Disabled select"}),J(ce,{value:"",onChange:()=>{},options:[{value:"a",label:"Enabled"},{value:"b",label:"Disabled option",disabled:!0},{value:"c",label:"Also enabled"}],placeholder:"Has disabled option",ariaLabel:"Disabled option select"})]})}y({group:"forms",componentId:"select",componentName:"Select",description:"Custom dropdown select with keyboard navigation and design-system styling.",props:[{name:"value",type:"string",description:"Currently selected value."},{name:"onChange",type:"(value: T) => void",description:"Callback when selection changes."},{name:"options",type:"SelectOption<T>[]",description:"Array of { value, label, disabled? }."},{name:"placeholder",type:"string",default:"'Select\u2026'",description:"Placeholder text when no value is selected."},{name:"size",type:"'sm' | 'md'",default:"'md'",description:"Trigger size."},{name:"tone",type:"'default' | 'warning'",default:"'default'",description:"Visual tone."},{name:"disabled",type:"boolean",default:"false",description:"Disables the entire select."},{name:"ariaLabel",type:"string",description:"Accessible label for the trigger button."}],renderPlayground:(e,t)=>J("div",{className:"max-w-xs pb-36",children:J(ce,{value:String(e.value??""),onChange:n=>t("value",n),options:[{value:"apple",label:"Apple"},{value:"banana",label:"Banana"},{value:"cherry",label:"Cherry"}],size:e.size,tone:e.tone,disabled:!!e.disabled,ariaLabel:"Playground select"})}),stories:[{id:"default",title:"Default",render:()=>J(mo,{})},{id:"sizes",title:"Sizes",description:"sm / md",render:()=>J(fo,{})},{id:"tones",title:"Tones",description:"default / warning",render:()=>J(go,{})},{id:"disabled",title:"Disabled",description:"Whole component disabled & individual option disabled.",render:()=>J(bo,{})}]});import{useState as Jt}from"react";import{clsx as Yt}from"clsx";import{jsx as Qt}from"react/jsx-runtime";function nt({value:e,onChange:t,options:n,size:o="sm",className:a,ariaLabel:i}){return Qt("div",{role:"tablist","aria-label":i,className:Yt("ui-segmented-control inline-flex rounded-md p-0.5 ring-1",o==="sm"?"text-xs":"text-sm",a),children:n.map(r=>{let p=r.value===e;return Qt("button",{type:"button",role:"tab","aria-selected":p,disabled:r.disabled,"data-active":p?"true":void 0,className:Yt("ui-segmented-control__item rounded font-medium transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-inset disabled:cursor-not-allowed disabled:opacity-50",o==="sm"?"px-2.5 py-1":"px-3 py-1.5"),onClick:()=>t(r.value),children:r.label},r.value)})})}import{jsx as Ke,jsxs as ho}from"react/jsx-runtime";function Zt({size:e,label:t}){let[n,o]=Jt("a");return Ke(nt,{value:n,onChange:o,options:[{value:"a",label:"Alpha"},{value:"b",label:"Beta"},{value:"c",label:"Gamma"}],size:e,ariaLabel:t})}function vo(){let[e,t]=Jt("on");return Ke(nt,{value:e,onChange:t,options:[{value:"on",label:"On"},{value:"off",label:"Off"},{value:"auto",label:"Auto",disabled:!0}],ariaLabel:"Mode with disabled"})}y({group:"forms",componentId:"segmented-control",componentName:"SegmentedControl",description:"Tab-like toggle for mutually exclusive options.",props:[{name:"value",type:"T extends string",description:"Currently selected option value."},{name:"onChange",type:"(value: T) => void",description:"Called when a new option is selected."},{name:"options",type:"Array<{ value: T; label: string; disabled?: boolean }>",description:"Selectable option list."},{name:"size",type:"'sm' | 'md'",default:"'sm'",description:"Control size."},{name:"ariaLabel",type:"string",description:"Accessible label for the tablist."}],stories:[{id:"sizes",title:"Sizes",description:"sm / md",render:()=>ho("div",{className:"flex flex-wrap items-center gap-4",children:[Ke(Zt,{size:"sm",label:"Small"}),Ke(Zt,{size:"md",label:"Medium"})]})},{id:"with-disabled",title:"With Disabled Option",render:()=>Ke(vo,{})}]});import{useState as ot}from"react";import{clsx as jt}from"clsx";import{jsx as en}from"react/jsx-runtime";var yo={sm:"h-5 w-9",md:"h-6 w-11"},wo={sm:"h-3.5 w-3.5",md:"h-4.5 w-4.5"},xo={sm:"translate-x-4",md:"translate-x-5"};function xe({checked:e,onChange:t,size:n="md",disabled:o=!1,className:a,ariaLabel:i}){return en("button",{type:"button",role:"switch","aria-checked":e,"aria-label":i,disabled:o,"data-size":n,className:jt("ui-switch relative inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",yo[n],o&&"cursor-not-allowed opacity-50",a),onClick:()=>t(!e),children:en("span",{"aria-hidden":"true",className:jt("ui-switch__thumb pointer-events-none inline-block rounded-full bg-white shadow transition-transform",wo[n],e?xo[n]:"translate-x-0.5")})})}import{jsx as be,jsxs as yt}from"react/jsx-runtime";function No(){let[e,t]=ot(!1);return be(xe,{checked:e,onChange:t,ariaLabel:"Demo toggle"})}function So(){let[e,t]=ot(!0),[n,o]=ot(!0);return yt("div",{className:"flex items-center gap-4",children:[be(xe,{checked:e,onChange:t,size:"sm",ariaLabel:"Small switch"}),be(xe,{checked:n,onChange:o,size:"md",ariaLabel:"Medium switch"})]})}function To(){let[e,t]=ot(!1);return yt("label",{className:"inline-flex items-center gap-2 text-sm text-[var(--color-n800)]",children:[be(xe,{checked:e,onChange:t,ariaLabel:"Notifications"}),"Enable notifications"]})}y({group:"forms",componentId:"switch",componentName:"Switch",description:"Toggle switch for boolean settings.",props:[{name:"checked",type:"boolean",description:"Controlled checked state."},{name:"onChange",type:"(checked: boolean) => void",description:"Callback when toggled."},{name:"size",type:"'sm' | 'md'",default:"'md'",description:"Switch size."},{name:"disabled",type:"boolean",default:"false",description:"Disables the switch."},{name:"ariaLabel",type:"string",description:"Accessible label."}],renderPlayground:(e,t)=>be(xe,{checked:!!e.checked,onChange:n=>t("checked",n),size:e.size,disabled:!!e.disabled,ariaLabel:"Playground switch"}),stories:[{id:"default",title:"Default",render:()=>be(No,{})},{id:"sizes",title:"Sizes",description:"sm / md",render:()=>be(So,{})},{id:"with-label",title:"With Label",render:()=>be(To,{})},{id:"disabled",title:"Disabled",render:()=>yt("div",{className:"flex items-center gap-4",children:[be(xe,{checked:!1,onChange:()=>{},disabled:!0,ariaLabel:"Disabled off"}),be(xe,{checked:!0,onChange:()=>{},disabled:!0,ariaLabel:"Disabled on"})]})}]});import{clsx as Co}from"clsx";import{jsx as Do}from"react/jsx-runtime";function K({tone:e="neutral",variant:t="soft",size:n="xs",className:o,children:a,...i}){return Do("span",{"data-tone":e,"data-variant":t,"data-size":n,className:Co("ui-badge inline-flex items-center rounded-full border text-[var(--badge-text)]",n==="xs"?"px-2.5 py-1 text-[11px]":"px-3 py-1 text-xs font-medium",o),...i,children:a})}import{jsx as j,jsxs as He}from"react/jsx-runtime";y({group:"feedback",componentId:"badge",componentName:"Badge",description:"Inline label for status, categories, or counts. Token-driven: --badge-bg, --badge-text, --badge-border.",props:[{name:"tone",type:"'neutral' | 'info' | 'success' | 'warning' | 'danger'",default:"'neutral'",description:"Semantic color tone."},{name:"variant",type:"'soft' | 'outline'",default:"'soft'",description:"Fill style. Soft uses tinted background; outline uses transparent bg with visible border."},{name:"size",type:"'xs' | 'sm'",default:"'xs'",description:"Compact or slightly larger badge size."},{name:"children",type:"ReactNode",description:"Badge content."}],renderPlayground:e=>j(K,{tone:e.tone,variant:e.variant,size:e.size,children:"Badge"}),stories:[{id:"tones-soft",title:"Tones (Soft)",description:"neutral / info / success / warning / danger \u2014 soft variant",render:()=>He("div",{className:"flex flex-wrap items-center gap-3",children:[j(K,{tone:"neutral",children:"Neutral"}),j(K,{tone:"info",children:"Info"}),j(K,{tone:"success",children:"Success"}),j(K,{tone:"warning",children:"Warning"}),j(K,{tone:"danger",children:"Danger"})]})},{id:"tones-outline",title:"Tones (Outline)",description:"Same tones with outline variant \u2014 transparent bg, colored border.",render:()=>He("div",{className:"flex flex-wrap items-center gap-3",children:[j(K,{tone:"neutral",variant:"outline",children:"Neutral"}),j(K,{tone:"info",variant:"outline",children:"Info"}),j(K,{tone:"success",variant:"outline",children:"Success"}),j(K,{tone:"warning",variant:"outline",children:"Warning"}),j(K,{tone:"danger",variant:"outline",children:"Danger"})]})},{id:"sizes",title:"Sizes",description:"xs / sm",render:()=>He("div",{className:"flex flex-wrap items-center gap-3",children:[j(K,{size:"xs",tone:"info",children:"XS Badge"}),j(K,{size:"sm",tone:"info",children:"SM Badge"})]})},{id:"variant-comparison",title:"Variant Comparison",description:"Soft vs outline side by side for each tone.",render:()=>j("div",{className:"space-y-3",children:["neutral","info","success","warning","danger"].map(e=>He("div",{className:"flex items-center gap-3",children:[He(K,{size:"sm",tone:e,variant:"soft",children:[e," soft"]}),He(K,{size:"sm",tone:e,variant:"outline",children:[e," outline"]})]},e))})}]});import{Info as Io,CheckCircle2 as Bo,TriangleAlert as Ro,CircleAlert as Lo}from"lucide-react";import{clsx as ko}from"clsx";import{Fragment as Po,jsx as wt,jsxs as Mo}from"react/jsx-runtime";function ue({tone:e="neutral",icon:t,className:n,children:o,...a}){return wt("div",{"data-tone":e,className:ko("ui-status-notice rounded-md border px-4 py-3 text-sm",t&&"ui-status-notice--with-icon grid grid-cols-[auto_minmax(0,1fr)] gap-3",n),...a,children:t?Mo(Po,{children:[wt("span",{className:"ui-status-notice__icon mt-0.5 shrink-0","aria-hidden":"true",children:t}),wt("div",{className:"min-w-0",children:o})]}):o})}import{jsx as ee,jsxs as tn}from"react/jsx-runtime";y({group:"feedback",componentId:"status-notice",componentName:"StatusNotice",description:"Block-level feedback banner. Supports neutral plus semantic tones, with optional icon slot.",props:[{name:"tone",type:"'neutral' | 'info' | 'success' | 'warning' | 'danger'",default:"'neutral'",description:"Semantic message tone."},{name:"icon",type:"ReactNode",description:"Optional leading icon slot."},{name:"children",type:"ReactNode",description:"Notice content."},{name:"className",type:"string",description:"Additional classes for layout or spacing."}],renderPlayground:e=>ee(ue,{tone:e.tone,children:"This is a status notice."}),stories:[{id:"tones",title:"Tones",description:"info / success / warning / danger",render:()=>tn("div",{className:"space-y-3",children:[ee(ue,{tone:"neutral",children:"General system guidance without a semantic alert state."}),ee(ue,{tone:"info",children:"This is an informational notice."}),ee(ue,{tone:"success",children:"Operation completed successfully."}),ee(ue,{tone:"warning",children:"Please review before continuing."}),ee(ue,{tone:"danger",children:"Something went wrong. Please try again."})]})},{id:"with-icons",title:"With Icons",render:()=>tn("div",{className:"space-y-3",children:[ee(ue,{tone:"info",icon:ee(Io,{size:16}),children:"Background indexing is still in progress."}),ee(ue,{tone:"success",icon:ee(Bo,{size:16}),children:"Draft and main are fully aligned."}),ee(ue,{tone:"warning",icon:ee(Ro,{size:16}),children:"One route conflict still needs manual review."}),ee(ue,{tone:"danger",icon:ee(Lo,{size:16}),children:"Publishing failed. Retry after refreshing the snapshot."})]})}]});import{clsx as zo}from"clsx";import{jsx as qe,jsxs as Eo}from"react/jsx-runtime";function Te({tone:e="neutral",icon:t,title:n,description:o,action:a,className:i,children:r,...p}){let c=t||n||o||a;return qe("div",{"data-tone":e,className:zo("ui-empty-state rounded-lg border px-4 py-3 text-sm",i),...p,children:c?Eo("div",{className:"flex flex-col items-center gap-2 py-4 text-center",children:[t&&qe("div",{className:"ui-empty-state__icon text-lg",children:t}),n&&qe("div",{className:"ui-empty-state__title font-medium",children:n}),o&&qe("div",{className:"ui-empty-state__description",children:o}),a&&qe("div",{className:"mt-2",children:a})]}):r})}import{jsx as Ce,jsxs as Ao}from"react/jsx-runtime";y({group:"feedback",componentId:"empty-state",componentName:"EmptyState",description:"Placeholder for empty lists or missing content. Token-driven: --empty-state-bg, --empty-state-border, --empty-state-title, --empty-state-text, --empty-state-icon.",props:[{name:"tone",type:"'neutral' | 'notice' | 'warning'",default:"'neutral'",description:"Semantic tone for contextual emphasis."},{name:"icon",type:"ReactNode",description:"Optional icon displayed above title."},{name:"title",type:"ReactNode",description:"Optional title text."},{name:"description",type:"ReactNode",description:"Optional description text."},{name:"action",type:"ReactNode",description:"Optional action slot (e.g. a button)."},{name:"children",type:"ReactNode",description:"Fallback content when structured slots are not used."}],stories:[{id:"basic",title:"Basic (children)",render:()=>Ce(Te,{children:"No items found."})},{id:"structured",title:"Structured Slots",description:"Using title, description, and action slots.",render:()=>Ce(Te,{title:"No posts yet",description:"Create your first post to get started.",action:Ce(d,{variant:"primary",size:"sm",children:"Create Post"})})},{id:"tones",title:"Tones",description:"neutral / notice / warning",render:()=>Ao("div",{className:"space-y-4",children:[Ce(Te,{tone:"neutral",title:"Neutral",description:"Default empty state."}),Ce(Te,{tone:"notice",title:"Notice",description:"Informational empty state."}),Ce(Te,{tone:"warning",title:"Warning",description:"Attention-drawing empty state."})]})},{id:"with-icon",title:"With Icon",render:()=>Ce(Te,{icon:Ce("span",{className:"text-2xl",children:"\u{1F4ED}"}),title:"Inbox empty",description:"You have no new messages."})}]});import{jsx as te,jsxs as Oe}from"react/jsx-runtime";y({group:"feedback",componentId:"spinner",componentName:"Spinner",description:"Animated loading indicator with multiple icon styles. Used standalone or composed into other components (e.g. Button loading state).",props:[{name:"variant",type:"'ring' | 'arc' | 'dots' | 'bars' | 'bounce' | 'pulse' | 'orbit' | 'flow'",default:"'ring'",description:"Spinner icon style."},{name:"size",type:"'xs' | 'sm' | 'md' | 'lg'",default:"'md'",description:"Preset size, or pass a number for custom pixel size."},{name:"label",type:"string",description:"Accessible label. When set, spinner is announced to screen readers."},{name:"className",type:"string",description:"Additional CSS classes."}],renderPlayground:e=>te(ie,{variant:e.variant,size:e.size}),stories:[{id:"variants",title:"Variants",description:"ring / arc / dots / bars / bounce / pulse / orbit / flow",render:()=>te("div",{className:"flex flex-wrap items-center gap-8",children:["ring","arc","dots","bars","bounce","pulse","orbit","flow"].map(e=>Oe("div",{className:"flex flex-col items-center gap-2",children:[te(ie,{variant:e,size:"lg"}),te("span",{className:"text-[11px] text-[var(--color-n500)]",children:e})]},e))})},{id:"sizes",title:"Sizes",description:"xs / sm / md / lg",render:()=>Oe("div",{className:"flex items-center gap-4",children:[te(ie,{size:"xs"}),te(ie,{size:"sm"}),te(ie,{size:"md"}),te(ie,{size:"lg"})]})},{id:"with-text",title:"Inline with Text",render:()=>Oe("div",{className:"space-y-3",children:[Oe("div",{className:"flex items-center gap-2 text-sm text-[var(--color-n600)]",children:[te(ie,{variant:"ring",size:"sm"}),te("span",{children:"Loading data\u2026"})]}),Oe("div",{className:"flex items-center gap-2 text-sm text-[var(--color-n600)]",children:[te(ie,{variant:"flow",size:"sm"}),te("span",{children:"Processing\u2026"})]}),Oe("div",{className:"flex items-center gap-2 text-sm text-[var(--color-n600)]",children:[te(ie,{variant:"bounce",size:"sm"}),te("span",{children:"Waiting for response\u2026"})]})]})}]});import{clsx as Ho}from"clsx";import{jsx as _o}from"react/jsx-runtime";var Oo={slow:"4s",default:"3s",fast:"2s"};function H({className:e,animation:t="scan",tone:n="default",speed:o="default",style:a,...i}){let r=n==="warm"?"emphasis":n,p={...a,"--ui-skeleton-scan-duration":Oo[o]};return _o("div",{className:Ho("ui-skeleton rounded",e),"data-animation":t,"data-tone":r,"aria-hidden":"true",style:p,...i})}import{jsx as B,jsxs as se}from"react/jsx-runtime";y({group:"feedback",componentId:"skeleton",componentName:"Skeleton",description:"Loading placeholder with `scan` or `pulse` animation and configurable speed.",props:[{name:"animation",type:"'pulse' | 'scan'",default:"'scan'",description:"Chooses the loading motion style."},{name:"tone",type:"'default' | 'emphasis'",default:"'default'",description:"Semantic emphasis level of the placeholder."},{name:"speed",type:"'slow' | 'default' | 'fast'",default:"'default'",description:"Scan animation speed: slow (4s), default (3s), fast (2s)."},{name:"className",type:"string",description:"Controls skeleton shape and dimensions."}],renderPlayground:e=>se("div",{className:"space-y-3",children:[B(H,{animation:e.animation,tone:e.tone,speed:e.speed,className:"h-4 w-48"}),B(H,{animation:e.animation,tone:e.tone,speed:e.speed,className:"h-4 w-64"})]}),stories:[{id:"scan",title:"Scan",render:()=>se("div",{className:"space-y-4",children:[B(H,{className:"h-4 w-48"}),B(H,{className:"h-4 w-64"}),B(H,{className:"h-4 w-32"})]})},{id:"scan-speed",title:"Scan Speed",render:()=>se("div",{className:"space-y-4",children:[se("div",{className:"space-y-2",children:[B("div",{className:"text-xs font-medium text-[var(--color-n500)]",children:"Slow \xB7 4s"}),B(H,{speed:"slow",className:"h-4 w-64"})]}),se("div",{className:"space-y-2",children:[B("div",{className:"text-xs font-medium text-[var(--color-n500)]",children:"Default \xB7 3s"}),B(H,{className:"h-4 w-64"})]}),se("div",{className:"space-y-2",children:[B("div",{className:"text-xs font-medium text-[var(--color-n500)]",children:"Fast \xB7 2s"}),B(H,{speed:"fast",className:"h-4 w-64"})]})]})},{id:"pulse",title:"Pulse",render:()=>se("div",{className:"space-y-4",children:[B(H,{animation:"pulse",className:"h-4 w-48"}),B(H,{animation:"pulse",className:"h-4 w-64"}),B(H,{animation:"pulse",className:"h-4 w-32"})]})},{id:"on-surfaces",title:"On Different Surfaces",description:"Verifies shimmer visibility against various backgrounds.",render:()=>B("div",{className:"grid gap-4 sm:grid-cols-3",children:[{label:"Canvas",bg:"var(--color-surface-canvas)"},{label:"Base",bg:"var(--color-surface-base)"},{label:"Inset",bg:"var(--color-surface-inset)"}].map(({label:e,bg:t})=>se("div",{className:"rounded-lg p-4",style:{backgroundColor:t},children:[B("p",{className:"mb-2 text-[11px] font-medium text-[var(--color-n500)]",children:e}),se("div",{className:"space-y-2",children:[B(H,{className:"h-4 w-full"}),B(H,{className:"h-4 w-3/4"})]})]},e))})},{id:"card-placeholder",title:"Card Placeholder",render:()=>se("div",{className:"max-w-sm space-y-3 rounded-lg border border-[var(--color-surface-border)] p-4",children:[B(H,{className:"h-5 w-3/4"}),B(H,{className:"h-4 w-full"}),B(H,{className:"h-4 w-5/6"}),se("div",{className:"flex gap-2 pt-2",children:[B(H,{animation:"pulse",className:"h-8 w-20 rounded-md"}),B(H,{animation:"pulse",className:"h-8 w-20 rounded-md"})]})]})},{id:"avatar-line",title:"Avatar + Lines",render:()=>se("div",{className:"flex items-start gap-3",children:[B(H,{className:"h-10 w-10 shrink-0 rounded-full"}),se("div",{className:"flex-1 space-y-2",children:[B(H,{animation:"pulse",className:"h-4 w-32"}),B(H,{className:"h-3 w-48"})]})]})}]});import{useState as at}from"react";import{clsx as Xe}from"clsx";import{useEffect as Fo,useRef as nn,useCallback as Vo}from"react";import{jsx as Ye,jsxs as Uo}from"react/jsx-runtime";function Wo({className:e,children:t,...n}){return Ye("div",{className:Xe("ui-dialog__header px-5 pt-5 pb-1 text-base font-semibold",e),...n,children:t})}function Go({className:e,children:t,...n}){return Ye("div",{className:Xe("ui-dialog__body px-5 py-3 text-sm",e),...n,children:t})}function $o({className:e,children:t,...n}){return Ye("div",{className:Xe("ui-dialog__footer flex items-center justify-end gap-2 px-5 pt-3 pb-5",e),...n,children:t})}function R({open:e,onClose:t,size:n="sm",children:o,className:a,overlayClassName:i,panelClassName:r,...p}){let c=nn(null),s=nn(null),u=Vo(l=>{l.key==="Escape"&&(l.stopPropagation(),t())},[t]);return Fo(()=>(e?(s.current=document.activeElement,document.body.style.overflow="hidden",requestAnimationFrame(()=>{let l=c.current;if(!l)return;let m=l.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');m?m.focus():l.focus()}),document.addEventListener("keydown",u)):(document.body.style.overflow="",s.current?.focus()),()=>{document.removeEventListener("keydown",u),document.body.style.overflow=""}),[e,u]),e?Uo("div",{"data-state":"open",className:"ui-dialog-overlay fixed inset-0 z-50 flex items-center justify-center",children:[Ye("button",{type:"button","aria-label":"Close dialog","data-state":"open",className:Xe("ui-dialog-backdrop absolute inset-0 bg-black/30",i),onClick:t}),Ye("div",{ref:c,role:"dialog","aria-modal":"true",tabIndex:-1,"data-state":"open","data-size":n,className:Xe("ui-dialog relative z-10 w-full rounded-xl shadow-xl","animate-[dialog-in_0.2s_var(--ease-standard)]",n==="sm"?"max-w-[26rem]":"max-w-[32rem]",r,a),...p,children:o})]}):null}R.Header=Wo;R.Body=Go;R.Footer=$o;import{createContext as Ko,useCallback as on,useContext as qo,useRef as Xo,useState as Yo}from"react";import{Fragment as Qo,jsx as _e,jsxs as xt}from"react/jsx-runtime";var an=Ko(null);function rn(){let e=qo(an);if(!e)throw new Error("useConfirm must be used within <ConfirmProvider>");return e}function sn({children:e}){let[t,n]=Yo(null),o=Xo(null),a=on(r=>(o.current&&o.current.resolve(!1),new Promise(p=>{let c={options:r,resolve:p};o.current=c,n(c)})),[]),i=on(r=>{o.current&&(o.current.resolve(r),o.current=null),n(null)},[]);return xt(an.Provider,{value:a,children:[e,_e(R,{open:t!==null,onClose:()=>i(!1),children:t&&xt(Qo,{children:[_e(R.Header,{children:t.options.title}),_e(R.Body,{children:typeof t.options.description=="string"?_e("p",{className:"whitespace-pre-wrap",children:t.options.description}):t.options.description}),xt(R.Footer,{children:[_e(d,{variant:"ghost",size:"sm",onClick:()=>i(!1),children:t.options.cancelLabel??"\u53D6\u6D88"}),_e(d,{variant:t.options.variant??"primary",size:"sm",onClick:()=>i(!0),children:t.options.confirmLabel??"\u786E\u8BA4"})]})]})})]})}import{Fragment as Nt,jsx as b,jsxs as L}from"react/jsx-runtime";function Zo(){let[e,t]=at(!1);return L(Nt,{children:[b(d,{variant:"primary",size:"sm",onClick:()=>t(!0),children:"Open Dialog"}),L(R,{open:e,onClose:()=>t(!1),children:[b(R.Header,{children:"Basic Dialog"}),b(R.Body,{children:b("p",{children:"This is a basic dialog with header, body, and footer sections."})}),L(R.Footer,{children:[b(d,{variant:"ghost",size:"sm",onClick:()=>t(!1),children:"Cancel"}),b(d,{variant:"primary",size:"sm",onClick:()=>t(!1),children:"Confirm"})]})]})]})}function Jo(){let[e,t]=at(!1);return L(Nt,{children:[b(d,{variant:"danger",size:"sm",onClick:()=>t(!0),children:"Delete Item"}),L(R,{open:e,onClose:()=>t(!1),children:[b(R.Header,{children:"Delete Draft"}),L(R.Body,{children:[b("p",{children:"Are you sure you want to delete the ZH locale draft?"}),L("p",{className:"mt-2",children:["Article ID: post-20260320-example",b("br",{}),"Category: post"]}),b("p",{className:"mt-2",children:"This action cannot be undone."})]}),L(R.Footer,{children:[b(d,{variant:"ghost",size:"sm",onClick:()=>t(!1),children:"Cancel"}),b(d,{variant:"danger",size:"sm",onClick:()=>t(!1),children:"Delete"})]})]})]})}function jo(){let[e,t]=at(!1);return L(Nt,{children:[b(d,{variant:"secondary",size:"sm",onClick:()=>t(!0),children:"Open Medium Dialog"}),L(R,{open:e,onClose:()=>t(!1),size:"md",children:[b(R.Header,{children:"Publish Confirmation"}),L(R.Body,{children:[b("p",{children:"You are about to publish the current draft branch."}),L("div",{className:"mt-3 rounded-lg border border-[var(--color-surface-border)] bg-[var(--color-surface-base)] p-3 text-sm",children:[L("div",{className:"flex justify-between",children:[b("span",{children:"Articles:"}),b("span",{children:"3"})]}),L("div",{className:"flex justify-between",children:[b("span",{children:"Languages:"}),b("span",{children:"ZH, EN"})]}),L("div",{className:"flex justify-between",children:[b("span",{children:"Branch:"}),b("span",{children:"draft"})]})]}),b("p",{className:"mt-3",children:"This will trigger a Cloudflare deployment."})]}),L(R.Footer,{children:[b(d,{variant:"ghost",size:"sm",onClick:()=>t(!1),children:"Cancel"}),b(d,{variant:"primary",size:"sm",onClick:()=>t(!1),children:"Publish"})]})]})]})}function ea(){let e=rn(),[t,n]=at("");return L("div",{className:"flex flex-col gap-3",children:[L("div",{className:"flex gap-2",children:[b(d,{variant:"primary",size:"sm",onClick:async()=>{let i=await e({title:"Confirm Action",description:"This demonstrates the useConfirm() hook. Click confirm or cancel.",confirmLabel:"Do it",cancelLabel:"Nope"});n(i?"Confirmed!":"Cancelled.")},children:"useConfirm()"}),b(d,{variant:"danger",size:"sm",onClick:async()=>{let i=await e({title:"Delete Everything",description:"This is a danger variant confirm dialog.",confirmLabel:"Delete",variant:"danger"});n(i?"Deleted!":"Cancelled.")},children:"Danger Confirm"})]}),t&&L("p",{className:"text-sm text-[var(--color-n600)]",children:["Result: ",t]})]})}function ta(){return b(sn,{children:b(ea,{})})}y({group:"feedback",componentId:"dialog",componentName:"Dialog",description:"Modal dialog for confirmations and focused tasks. Supports declarative usage via <Dialog> and imperative usage via `useConfirm()` hook. The imperative API requires `<ConfirmProvider>` in an ancestor (mounted in admin layout).",props:[{name:"open",type:"boolean",default:"false",description:"Controls dialog visibility."},{name:"size",type:"'sm' | 'md'",default:"'sm'",description:"Dialog width."},{name:"onClose",type:"() => void",description:"Called on backdrop click or Escape key."}],renderPlayground:(e,t)=>{let n=e.size||"sm",o=!!e.open;return L("div",{className:"flex flex-col items-center gap-4",children:[L(d,{variant:"primary",size:"sm",onClick:()=>t("open",!0),children:["Open Dialog (",n,")"]}),L(R,{open:o,onClose:()=>t("open",!1),size:n,children:[b(R.Header,{children:"Playground Dialog"}),b(R.Body,{children:L("p",{children:["Toggle the ",b("code",{className:"rounded bg-[var(--color-surface-subtle)] px-1 py-0.5 text-xs",children:"open"})," and ",b("code",{className:"rounded bg-[var(--color-surface-subtle)] px-1 py-0.5 text-xs",children:"size"})," controls below."]})}),L(R.Footer,{children:[b(d,{variant:"ghost",size:"sm",onClick:()=>t("open",!1),children:"Cancel"}),b(d,{variant:"primary",size:"sm",onClick:()=>t("open",!1),children:"Confirm"})]})]})]})},stories:[{id:"provider-setup",title:"Provider Setup",description:"useConfirm() requires <ConfirmProvider> in an ancestor. Mount it once in your layout \u2014 all descendant components can then call useConfirm().",source:`// src/app/qadmin/layout.tsx
|
|
4
|
+
<Button variant="danger">Danger</Button>`,render:()=>Xe("div",{className:"flex flex-wrap items-center gap-3",children:[F(u,{variant:"primary",children:"Primary"}),F(u,{variant:"secondary",children:"Secondary"}),F(u,{variant:"ghost",children:"Ghost"}),F(u,{variant:"danger",children:"Danger"})]})},{id:"sizes",title:"Sizes",description:"sm / md",render:()=>Xe("div",{className:"flex flex-wrap items-center gap-3",children:[F(u,{size:"sm",children:"Small"}),F(u,{size:"md",children:"Medium"})]})},{id:"with-icons",title:"With Icons",description:"leadingIcon / trailingIcon",render:()=>Xe("div",{className:"flex flex-wrap items-center gap-3",children:[F(u,{variant:"primary",leadingIcon:F(Xt,{size:16}),children:"Create"}),F(u,{variant:"secondary",trailingIcon:F(Zt,{size:16}),children:"Next"}),F(u,{variant:"ghost",leadingIcon:F(Xt,{size:16}),trailingIcon:F(Zt,{size:16}),children:"Both"})]})},{id:"loading-disabled",title:"Loading & Disabled",render:()=>Xe("div",{className:"flex flex-wrap items-center gap-3",children:[F(u,{variant:"primary",loading:!0,children:"Saving\u2026"}),F(u,{variant:"secondary",loading:!0,children:"Loading"}),F(u,{variant:"secondary",disabled:!0,children:"Disabled"}),F(u,{variant:"danger",disabled:!0,children:"Disabled Danger"})]})},{id:"all-variants-sm",title:"All Variants (sm)",render:()=>Xe("div",{className:"flex flex-wrap items-center gap-3",children:[F(u,{variant:"primary",size:"sm",children:"Primary"}),F(u,{variant:"secondary",size:"sm",children:"Secondary"}),F(u,{variant:"ghost",size:"sm",children:"Ghost"}),F(u,{variant:"danger",size:"sm",children:"Danger"})]})}]});import{X as Ze,Settings as ct,Trash2 as So,ChevronRight as Do}from"lucide-react";import{clsx as Co}from"clsx";import{jsx as Qt}from"react/jsx-runtime";function J({variant:e="ghost",size:t="md",label:n,icon:o,className:a,...r}){let i=Co("ui-icon-button","inline-flex items-center justify-center rounded-md transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-inset disabled:cursor-not-allowed disabled:opacity-50",t==="sm"?"h-7 w-7":"h-8 w-8",a);if("href"in r&&r.href){let{href:d,...s}=r;return Qt("a",{href:d,"aria-label":n,title:s.title??n,"data-variant":e,"data-size":t,className:i,...s,children:o})}let l=r;return Qt("button",{type:l.type??"button","aria-label":n,title:l.title??n,"data-variant":e,"data-size":t,className:i,...l,children:o})}import{jsx as V,jsxs as ut}from"react/jsx-runtime";h({group:"actions",componentId:"icon-button",componentName:"IconButton",description:"Icon-only action button. Supports ghost/subtle variants, sm/md sizes.",props:[{name:"variant",type:"'ghost' | 'subtle'",default:"'ghost'",description:"Visual style variant."},{name:"size",type:"'sm' | 'md'",default:"'md'",description:"Button size."},{name:"label",type:"string",description:"Accessible label used for aria-label and title fallback."},{name:"icon",type:"ReactNode",description:"Icon content rendered inside the button."},{name:"href",type:"string",description:"When set, renders as a Next.js Link instead of a button."},{name:"disabled",type:"boolean",default:"false",description:"Disables button interaction when rendered as a button."}],renderPlayground:e=>V(J,{variant:e.variant,size:e.size,disabled:!!e.disabled,label:"Settings",icon:V(ct,{size:e.size==="sm"?14:16})}),stories:[{id:"variants",title:"Variants",description:"ghost / subtle",render:()=>ut("div",{className:"flex items-center gap-3",children:[V(J,{variant:"ghost",label:"Close",icon:V(Ze,{size:16})}),V(J,{variant:"subtle",label:"Settings",icon:V(ct,{size:16})})]})},{id:"sizes",title:"Sizes",description:"sm / md",render:()=>ut("div",{className:"flex items-center gap-3",children:[V(J,{size:"sm",label:"Small",icon:V(Ze,{size:14})}),V(J,{size:"md",label:"Medium",icon:V(Ze,{size:16})})]})},{id:"use-cases",title:"Use Cases",render:()=>ut("div",{className:"flex items-center gap-3",children:[V(J,{label:"Close",icon:V(Ze,{size:16})}),V(J,{label:"Settings",icon:V(ct,{size:16})}),V(J,{label:"Delete",icon:V(So,{size:16})}),V(J,{label:"Navigate",icon:V(Do,{size:16})})]})},{id:"disabled",title:"Disabled",render:()=>ut("div",{className:"flex items-center gap-3",children:[V(J,{label:"Disabled ghost",icon:V(Ze,{size:16}),disabled:!0}),V(J,{variant:"subtle",label:"Disabled subtle",icon:V(ct,{size:16}),disabled:!0})]})}]});import{clsx as Po}from"clsx";import{jsx as Jt}from"react/jsx-runtime";function pt(e){return Po("ui-input w-full rounded-lg px-3 py-2 text-sm placeholder:text-[var(--field-placeholder)] focus:outline-none focus:ring-1",e)}function fe(e){let{className:t,tone:n="default",...o}=e;return e.as==="textarea"?Jt("textarea",{"data-tone":n,className:pt(t),...o}):Jt("input",{"data-tone":n,className:pt(t),...o})}import{jsx as Le,jsxs as jt}from"react/jsx-runtime";h({group:"forms",componentId:"input",componentName:"Input",description:'Single-line text input. Legacy `as="textarea"` support remains available, but new multiline usage should prefer the dedicated Textarea primitive.',props:[{name:"as",type:"'input' | 'textarea'",default:"'input'",description:"Chooses which native form element to render."},{name:"tone",type:"'default' | 'warning'",default:"'default'",description:"Visual tone for neutral or warning emphasis."},{name:"className",type:"string",description:"Additional CSS classes for the rendered element."},{name:"placeholder",type:"string",description:"Placeholder text for input or textarea variants."},{name:"rows",type:"number",description:'Textarea row count when `as="textarea"`.'}],renderPlayground:e=>Le("div",{className:"max-w-xs",children:Le(fe,{as:e.as,tone:e.tone,placeholder:"Type something\u2026"})}),stories:[{id:"text-input",title:"Text Input",render:()=>jt("div",{className:"max-w-xs space-y-3",children:[Le(fe,{"aria-label":"Default input",name:"demo-default",autoComplete:"off",placeholder:"e.g., hello world\u2026"}),Le(fe,{"aria-label":"With value",name:"demo-value",autoComplete:"off",placeholder:"e.g., hello world\u2026",defaultValue:"Hello world"})]})},{id:"textarea",title:"Textarea",render:()=>Le("div",{className:"max-w-sm",children:Le(fe,{as:"textarea","aria-label":"Textarea",placeholder:"Write something\u2026",rows:3})})},{id:"tones",title:"Tones",description:"default / warning",render:()=>jt("div",{className:"max-w-xs space-y-3",children:[Le(fe,{tone:"default","aria-label":"Default tone",name:"demo-tone-default",autoComplete:"off",placeholder:"Default tone\u2026"}),Le(fe,{tone:"warning","aria-label":"Warning tone",name:"demo-tone-warning",autoComplete:"off",placeholder:"Warning tone\u2026"})]})}]});import{useState as Lo}from"react";import{clsx as ko}from"clsx";import{jsx as en,jsxs as Io}from"react/jsx-runtime";function Re({label:e,help:t,htmlFor:n,children:o,className:a,...r}){return Io("div",{className:ko("ui-field block",a),...r,children:[en("label",{htmlFor:n,className:"ui-field__label mb-1 block text-xs",children:e}),o,t?en("span",{className:"ui-field__help mt-1 block text-xs",children:t}):null]})}import{clsx as We}from"clsx";import{useCallback as Bt,useEffect as tn,useId as Mo,useMemo as Bo,useRef as nn,useState as on}from"react";import{jsx as Qe,jsxs as an}from"react/jsx-runtime";function ge({value:e,onChange:t,options:n,placeholder:o="Select\u2026",size:a="md",tone:r="default",disabled:i=!1,className:l,ariaLabel:d,renderValue:s,renderOption:p}){let[c,b]=on(!1),[m,f]=on(-1),C=nn(null),w=nn(null),v=Mo(),I=n.find(g=>g.value===e),N=Bo(()=>n.reduce((g,P,ce)=>(P.disabled||g.push(ce),g),[]),[n]),$=Bt(()=>{if(i||n.length===0)return;b(!0);let g=n.findIndex(P=>P.value===e);f(g>=0?g:N[0]??-1)},[i,n,e,N]),T=Bt(()=>{b(!1),f(-1)},[]),G=Bt(g=>{g.disabled||(t(g.value),T())},[t,T]);tn(()=>{if(!c)return;function g(P){C.current&&!C.current.contains(P.target)&&T()}return document.addEventListener("mousedown",g),()=>document.removeEventListener("mousedown",g)},[c,T]),tn(()=>{if(!c||m<0)return;w.current?.children[m]?.scrollIntoView({block:"nearest"})},[c,m]);function E(g){if(!i)switch(g.key){case"Enter":case" ":{g.preventDefault(),c?m>=0&&n[m]&&!n[m].disabled&&G(n[m]):$();break}case"ArrowDown":{if(g.preventDefault(),!c)$();else{let P=N.indexOf(m),ce=N[P+1];ce!==void 0&&f(ce)}break}case"ArrowUp":{if(g.preventDefault(),!c)$();else{let P=N.indexOf(m),ce=N[P-1];ce!==void 0&&f(ce)}break}case"Escape":{c&&(g.preventDefault(),T());break}case"Tab":{c&&T();break}}}let K=e!==""&&I,Q=s?s({open:c,placeholder:o,selectedOption:I}):Qe("span",{className:We("truncate",!K&&"ui-select__placeholder"),children:K?I.label:o});return an("div",{ref:C,"data-state":c?"open":"closed","data-disabled":i||void 0,"data-size":a,"data-tone":r,className:We("ui-select relative inline-block",l),children:[an("button",{type:"button",role:"combobox","aria-expanded":c,"aria-haspopup":"listbox","aria-controls":v,"aria-label":d,"aria-activedescendant":c&&m>=0?`${v}-opt-${m}`:void 0,"data-state":c?"open":"closed","data-disabled":i||void 0,"data-tone":r,"data-size":a,"data-open":c||void 0,"data-has-value":K||void 0,disabled:i,className:We("ui-select__trigger flex w-full items-center justify-between gap-2 rounded-lg text-left transition-colors focus:outline-none",a==="sm"?"min-h-7 px-2 py-1 text-xs":"min-h-9 px-3 py-2 text-sm"),onClick:()=>c?T():$(),onKeyDown:E,children:[Q,Qe("svg",{"aria-hidden":"true",className:We("ui-select__chevron h-3.5 w-3.5 shrink-0 transition-transform",c&&"rotate-180"),viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:Qe("path",{d:"M4 6l4 4 4-4"})})]}),c&&Qe("ul",{ref:w,id:v,role:"listbox","aria-label":d,"data-state":"open",className:We("ui-select__dropdown absolute z-50 mt-1 max-h-60 w-full overflow-auto rounded-lg py-1 ring-1",a==="sm"?"text-xs":"text-sm"),children:n.map((g,P)=>Qe("li",{id:`${v}-opt-${P}`,role:"option","aria-selected":g.value===e,"aria-disabled":g.disabled||void 0,"data-state":g.value===e?"selected":P===m?"highlighted":"idle","data-focused":P===m||void 0,"data-selected":g.value===e||void 0,"data-disabled":g.disabled||void 0,"data-highlighted":P===m||void 0,className:We("ui-select__option cursor-default select-none px-3 py-1.5 transition-colors",g.disabled&&"cursor-not-allowed opacity-50"),onClick:()=>G(g),onMouseEnter:()=>!g.disabled&&f(P),children:p?p({option:g,index:P,selected:g.value===e,highlighted:P===m}):g.label},g.value))})]})}import{jsx as le}from"react/jsx-runtime";function Ro(){let[e,t]=Lo("");return le("div",{className:"max-w-xs pb-36",children:le(Re,{label:"Category",htmlFor:"sb-category",children:le(ge,{value:e,onChange:t,options:[{value:"tech",label:"Technology"},{value:"design",label:"Design"},{value:"other",label:"Other"}],placeholder:"Select a category",ariaLabel:"Category"})})})}h({group:"forms",componentId:"field",componentName:"Field",description:"Form field wrapper with label and optional help text.",props:[{name:"label",type:"ReactNode",description:"Visible field label rendered above the control."},{name:"help",type:"ReactNode",description:"Optional helper text rendered below the control."},{name:"htmlFor",type:"string",description:"Associates the label with the inner form control id."},{name:"children",type:"ReactNode",description:"Form control content, such as Input or Select."}],stories:[{id:"basic",title:"Basic Field",render:()=>le("div",{className:"max-w-xs",children:le(Re,{label:"Username",htmlFor:"sb-username",children:le(fe,{id:"sb-username",name:"username",autoComplete:"username",placeholder:"Enter username"})})})},{id:"with-help",title:"With Help Text",render:()=>le("div",{className:"max-w-xs",children:le(Re,{label:"Email",htmlFor:"sb-email",help:"We'll never share your email.",children:le(fe,{id:"sb-email",type:"email",name:"email",autoComplete:"email",spellCheck:!1,placeholder:"you@example.com"})})})},{id:"with-textarea",title:"With Textarea",render:()=>le("div",{className:"max-w-sm",children:le(Re,{label:"Bio",htmlFor:"sb-bio",help:"Brief description about yourself.",children:le(fe,{as:"textarea",id:"sb-bio",name:"bio",autoComplete:"off",placeholder:"Tell us about yourself\u2026",rows:3})})})},{id:"with-select",title:"With Select",render:()=>le(Ro,{})}]});import{useState as Je}from"react";import{jsx as ee,jsxs as Lt}from"react/jsx-runtime";function zo(){let[e,t]=Je("");return ee("div",{className:"max-w-xs pb-44",children:ee(ge,{value:e,onChange:t,options:[{value:"apple",label:"Apple"},{value:"banana",label:"Banana"},{value:"cherry",label:"Cherry"},{value:"dragonfruit",label:"Dragonfruit"}],placeholder:"Choose a fruit\u2026",ariaLabel:"Fruit select"})})}function Ao(){let[e,t]=Je("apple"),[n,o]=Je("apple"),a=[{value:"apple",label:"Apple"},{value:"banana",label:"Banana"},{value:"cherry",label:"Cherry"}];return Lt("div",{className:"flex max-w-xs flex-col gap-3 pb-36",children:[ee(ge,{value:e,onChange:t,options:[...a],size:"sm",ariaLabel:"Small select"}),ee(ge,{value:n,onChange:o,options:[...a],size:"md",ariaLabel:"Medium select"})]})}function Eo(){let[e,t]=Je("a"),[n,o]=Je("a"),a=[{value:"a",label:"Option A"},{value:"b",label:"Option B"}];return Lt("div",{className:"flex max-w-xs flex-col gap-3 pb-28",children:[ee(ge,{value:e,onChange:t,options:[...a],tone:"default",ariaLabel:"Default tone"}),ee(ge,{value:n,onChange:o,options:[...a],tone:"warning",ariaLabel:"Warning tone"})]})}function Ho(){return Lt("div",{className:"flex max-w-xs flex-col gap-3 pb-28",children:[ee(ge,{value:"",onChange:()=>{},options:[{value:"a",label:"Option A"}],disabled:!0,placeholder:"Disabled",ariaLabel:"Disabled select"}),ee(ge,{value:"",onChange:()=>{},options:[{value:"a",label:"Enabled"},{value:"b",label:"Disabled option",disabled:!0},{value:"c",label:"Also enabled"}],placeholder:"Has disabled option",ariaLabel:"Disabled option select"})]})}h({group:"forms",componentId:"select",componentName:"Select",description:"Custom dropdown select with keyboard navigation and design-system styling.",props:[{name:"value",type:"string",description:"Currently selected value."},{name:"onChange",type:"(value: T) => void",description:"Callback when selection changes."},{name:"options",type:"SelectOption<T>[]",description:"Array of { value, label, disabled? }."},{name:"placeholder",type:"string",default:"'Select\u2026'",description:"Placeholder text when no value is selected."},{name:"size",type:"'sm' | 'md'",default:"'md'",description:"Trigger size."},{name:"tone",type:"'default' | 'warning'",default:"'default'",description:"Visual tone."},{name:"disabled",type:"boolean",default:"false",description:"Disables the entire select."},{name:"ariaLabel",type:"string",description:"Accessible label for the trigger button."}],renderPlayground:(e,t)=>ee("div",{className:"max-w-xs pb-36",children:ee(ge,{value:String(e.value??""),onChange:n=>t("value",n),options:[{value:"apple",label:"Apple"},{value:"banana",label:"Banana"},{value:"cherry",label:"Cherry"}],size:e.size,tone:e.tone,disabled:!!e.disabled,ariaLabel:"Playground select"})}),stories:[{id:"default",title:"Default",render:()=>ee(zo,{})},{id:"sizes",title:"Sizes",description:"sm / md",render:()=>ee(Ao,{})},{id:"tones",title:"Tones",description:"default / warning",render:()=>ee(Eo,{})},{id:"disabled",title:"Disabled",description:"Whole component disabled & individual option disabled.",render:()=>ee(Ho,{})}]});import{useState as dn}from"react";import{clsx as rn}from"clsx";import{jsx as sn}from"react/jsx-runtime";function mt({value:e,onChange:t,options:n,size:o="sm",className:a,ariaLabel:r}){return sn("div",{role:"tablist","aria-label":r,className:rn("ui-segmented-control inline-flex rounded-md p-0.5 ring-1",o==="sm"?"text-xs":"text-sm",a),children:n.map(i=>{let l=i.value===e;return sn("button",{type:"button",role:"tab","aria-selected":l,disabled:i.disabled,"data-active":l?"true":void 0,className:rn("ui-segmented-control__item rounded font-medium transition-colors focus:outline-none focus-visible:ring-1 focus-visible:ring-inset disabled:cursor-not-allowed disabled:opacity-50",o==="sm"?"px-2.5 py-1":"px-3 py-1.5"),onClick:()=>t(i.value),children:i.label},i.value)})})}import{jsx as je,jsxs as _o}from"react/jsx-runtime";function ln({size:e,label:t}){let[n,o]=dn("a");return je(mt,{value:n,onChange:o,options:[{value:"a",label:"Alpha"},{value:"b",label:"Beta"},{value:"c",label:"Gamma"}],size:e,ariaLabel:t})}function Oo(){let[e,t]=dn("on");return je(mt,{value:e,onChange:t,options:[{value:"on",label:"On"},{value:"off",label:"Off"},{value:"auto",label:"Auto",disabled:!0}],ariaLabel:"Mode with disabled"})}h({group:"forms",componentId:"segmented-control",componentName:"SegmentedControl",description:"Tab-like toggle for mutually exclusive options.",props:[{name:"value",type:"T extends string",description:"Currently selected option value."},{name:"onChange",type:"(value: T) => void",description:"Called when a new option is selected."},{name:"options",type:"Array<{ value: T; label: string; disabled?: boolean }>",description:"Selectable option list."},{name:"size",type:"'sm' | 'md'",default:"'sm'",description:"Control size."},{name:"ariaLabel",type:"string",description:"Accessible label for the tablist."}],stories:[{id:"sizes",title:"Sizes",description:"sm / md",render:()=>_o("div",{className:"flex flex-wrap items-center gap-4",children:[je(ln,{size:"sm",label:"Small"}),je(ln,{size:"md",label:"Medium"})]})},{id:"with-disabled",title:"With Disabled Option",render:()=>je(Oo,{})}]});import{useState as ft}from"react";import{clsx as cn}from"clsx";import{jsx as un}from"react/jsx-runtime";var Fo={sm:"h-5 w-9",md:"h-6 w-11"},Vo={sm:"h-3.5 w-3.5",md:"h-4.5 w-4.5"},Wo={sm:"translate-x-4",md:"translate-x-5"};function Ce({checked:e,onChange:t,size:n="md",disabled:o=!1,className:a,ariaLabel:r}){return un("button",{type:"button",role:"switch","aria-checked":e,"aria-label":r,disabled:o,"data-size":n,className:cn("ui-switch relative inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",Fo[n],o&&"cursor-not-allowed opacity-50",a),onClick:()=>t(!e),children:un("span",{"aria-hidden":"true",className:cn("ui-switch__thumb pointer-events-none inline-block rounded-full bg-white shadow transition-transform",Vo[n],e?Wo[n]:"translate-x-0.5")})})}import{jsx as xe,jsxs as Rt}from"react/jsx-runtime";function $o(){let[e,t]=ft(!1);return xe(Ce,{checked:e,onChange:t,ariaLabel:"Demo toggle"})}function Go(){let[e,t]=ft(!0),[n,o]=ft(!0);return Rt("div",{className:"flex items-center gap-4",children:[xe(Ce,{checked:e,onChange:t,size:"sm",ariaLabel:"Small switch"}),xe(Ce,{checked:n,onChange:o,size:"md",ariaLabel:"Medium switch"})]})}function Uo(){let[e,t]=ft(!1);return Rt("label",{className:"inline-flex items-center gap-2 text-sm text-[var(--color-n800)]",children:[xe(Ce,{checked:e,onChange:t,ariaLabel:"Notifications"}),"Enable notifications"]})}h({group:"forms",componentId:"switch",componentName:"Switch",description:"Toggle switch for boolean settings.",props:[{name:"checked",type:"boolean",description:"Controlled checked state."},{name:"onChange",type:"(checked: boolean) => void",description:"Callback when toggled."},{name:"size",type:"'sm' | 'md'",default:"'md'",description:"Switch size."},{name:"disabled",type:"boolean",default:"false",description:"Disables the switch."},{name:"ariaLabel",type:"string",description:"Accessible label."}],renderPlayground:(e,t)=>xe(Ce,{checked:!!e.checked,onChange:n=>t("checked",n),size:e.size,disabled:!!e.disabled,ariaLabel:"Playground switch"}),stories:[{id:"default",title:"Default",render:()=>xe($o,{})},{id:"sizes",title:"Sizes",description:"sm / md",render:()=>xe(Go,{})},{id:"with-label",title:"With Label",render:()=>xe(Uo,{})},{id:"disabled",title:"Disabled",render:()=>Rt("div",{className:"flex items-center gap-4",children:[xe(Ce,{checked:!1,onChange:()=>{},disabled:!0,ariaLabel:"Disabled off"}),xe(Ce,{checked:!0,onChange:()=>{},disabled:!0,ariaLabel:"Disabled on"})]})}]});import{useCallback as Ko,useEffect as qo,useRef as Yo}from"react";import{jsx as Xo}from"react/jsx-runtime";function _e({className:e,tone:t="default",resize:n="vertical",autoResize:o=!1,style:a,onInput:r,rows:i=3,...l}){let d=Yo(null),s=r,p=Ko(()=>{if(!o||!d.current)return;let m=d.current;m.style.height="auto",m.style.height=`${m.scrollHeight}px`},[o]);qo(()=>{p()},[p,l.value,l.defaultValue,i]);function c(m){p(),s?.(m)}let b={...a,resize:o?"none":n};return Xo("textarea",{...l,ref:d,rows:i,"data-tone":t,"data-auto-resize":o||void 0,className:pt(`ui-textarea ${e??""}`),style:b,onInput:c})}import{jsx as Se,jsxs as Zo}from"react/jsx-runtime";h({group:"forms",componentId:"textarea",componentName:"Textarea",description:"Dedicated multiline text input that matches the Input token contract while supporting resize and auto-resize behavior.",props:[{name:"tone",type:"'default' | 'warning'",default:"'default'",description:"Visual tone for neutral or warning emphasis."},{name:"rows",type:"number",default:"3",description:"Initial row count before any auto-resize behavior."},{name:"resize",type:"'none' | 'vertical' | 'both'",default:"'vertical'",description:"Controls native resize affordance."},{name:"autoResize",type:"boolean",default:"false",description:"Automatically grows height to fit content."}],renderPlayground:e=>Se("div",{className:"max-w-sm",children:Se(_e,{tone:e.tone,rows:Number(e.rows??3),resize:e.resize??"vertical",autoResize:!!e.autoResize,placeholder:"Write something longer\u2026"})}),stories:[{id:"default",title:"Default",render:()=>Se("div",{className:"max-w-sm",children:Se(_e,{"aria-label":"Default textarea",placeholder:"Write something longer\u2026",rows:4})})},{id:"tones-and-resize",title:"Tones And Resize",render:()=>Zo("div",{className:"max-w-sm space-y-3",children:[Se(_e,{"aria-label":"Default tone textarea",rows:3,placeholder:"Default tone\u2026",resize:"vertical"}),Se(_e,{"aria-label":"Warning tone textarea",rows:3,placeholder:"Warning tone\u2026",tone:"warning",resize:"both"})]})},{id:"with-field",title:"With Field",render:()=>Se("div",{className:"max-w-sm",children:Se(Re,{label:"System Prompt",help:"Supports the same visual contract as Input.",children:Se(_e,{"aria-label":"System prompt",rows:5,autoResize:!0,defaultValue:`You are a concise assistant.
|
|
5
|
+
Keep responses short.`})})})}]});import{ChevronDown as ia}from"lucide-react";import{clsx as zt}from"clsx";import{createContext as Qo,useContext as Jo,useEffect as jo,useId as ea,useMemo as ta,useRef as pn,useState as fn}from"react";import{jsx as et}from"react/jsx-runtime";var gn=Qo(null);function bn(e){let t=Jo(gn);if(!t)throw new Error(`${e} must be used within Collapsible.Root`);return t}function na({open:e,defaultOpen:t,onOpenChange:n}){let[o,a]=fn(t??!1),r=e!==void 0,i=r?e:o;function l(d){r||a(d),n?.(d)}return[i,l]}function mn({children:e,open:t,defaultOpen:n,onOpenChange:o,className:a,...r}){let[i,l]=na({open:t,defaultOpen:n,onOpenChange:o}),d=ea(),s=ta(()=>({open:i,setOpen:l,contentId:d}),[d,i,l]);return et(gn.Provider,{value:s,children:et("div",{"data-state":i?"open":"closed",className:zt("ui-collapsible",a),...r,children:e})})}function oa({children:e,className:t,onClick:n,...o}){let{open:a,setOpen:r,contentId:i}=bn("Collapsible.Trigger");return et("button",{type:"button","aria-expanded":a,"aria-controls":i,"data-state":a?"open":"closed",className:zt("ui-collapsible__trigger",t),onClick:l=>{n?.(l),l.defaultPrevented||r(!a)},...o,children:e})}function aa({children:e,className:t,...n}){let{open:o,contentId:a}=bn("Collapsible.Content"),[r,i]=fn(o),l=pn(null),d=pn(null);return jo(()=>{let s=l.current,p=d.current;if(!s||!p)return;let c=0,b=0,m=()=>{s.style.height="auto",s.style.overflow="visible"};if(o&&i(!0),!r&&!o)return;let f=w=>{w.target!==s||w.propertyName!=="height"||(s.removeEventListener("transitionend",f),o?m():i(!1))};return(()=>{let w=p.scrollHeight;if(s.style.overflow="hidden",o){s.style.height="0px",c=window.requestAnimationFrame(()=>{s.addEventListener("transitionend",f),s.style.height=`${w}px`}),b=window.setTimeout(m,240);return}s.style.height=`${w}px`,c=window.requestAnimationFrame(()=>{s.addEventListener("transitionend",f),s.style.height="0px"}),b=window.setTimeout(()=>i(!1),240)})(),()=>{window.cancelAnimationFrame(c),window.clearTimeout(b),s.removeEventListener("transitionend",f)}},[o,r]),!r&&!o?null:et("div",{id:a,ref:l,"data-state":o?"open":"closed","aria-hidden":!o,className:zt("ui-collapsible__content",t),...n,children:et("div",{ref:d,className:"ui-collapsible__content-inner",children:e})})}var ra=Object.assign(mn,{Root:mn,Trigger:oa,Content:aa}),gt=ra;import{jsx as bt,jsxs as vn}from"react/jsx-runtime";h({group:"forms",componentId:"collapsible",componentName:"Collapsible",description:"Composable primitive for disclosure sections, reasoning panels, and settings details blocks.",props:[{name:"open",type:"boolean",description:"Controlled open state."},{name:"defaultOpen",type:"boolean",default:"false",description:"Initial open state for uncontrolled usage."},{name:"onOpenChange",type:"(open: boolean) => void",description:"Change callback for controlled or uncontrolled state updates."}],stories:[{id:"default",title:"Default",render:()=>bt("div",{className:"max-w-lg rounded-xl border border-[var(--ui-surface-border)] bg-[var(--ui-surface-bg)] p-3",children:vn(gt,{defaultOpen:!0,children:[vn(gt.Trigger,{className:"flex w-full items-center justify-between gap-3 rounded-lg px-2 py-2 text-left text-sm font-medium",children:[bt("span",{children:"Reasoning"}),bt(ia,{className:"h-4 w-4"})]}),bt(gt.Content,{className:"px-2 pb-2 pt-1 text-sm text-[var(--ui-text-secondary)]",children:"This area can hold AI reasoning, debug detail, or an advanced configuration section."})]})})}]});import{clsx as ht}from"clsx";import{createContext as sa,useContext as la,useId as da,useMemo as ca,useState as ua}from"react";import{jsx as tt}from"react/jsx-runtime";var yn=sa(null);function xn(e){let t=la(yn);if(!t)throw new Error(`${e} must be used within Tabs.Root`);return t}function vt(e){return e.replace(/[^a-zA-Z0-9_-]+/g,"-")}function pa({value:e,defaultValue:t,onValueChange:n}){let[o,a]=ua(t??""),r=e!==void 0,i=r?e:o;function l(d){r||a(d),n?.(d)}return[i,l]}function hn({children:e,value:t,defaultValue:n,onValueChange:o,className:a,...r}){let[i,l]=pa({value:t,defaultValue:n,onValueChange:o}),d=da(),s=ca(()=>({value:i,setValue:l,baseId:d}),[d,i,l]);return tt(yn.Provider,{value:s,children:tt("div",{className:ht("ui-tabs",a),...r,children:e})})}function ma({children:e,className:t,ariaLabel:n,...o}){return tt("div",{role:"tablist","aria-label":n,className:ht("ui-tabs__list flex items-end gap-1 border-b",t),...o,children:e})}function fa({children:e,className:t,value:n,disabled:o,onClick:a,onKeyDown:r,...i}){let{value:l,setValue:d,baseId:s}=xn("Tabs.Trigger"),p=l===n,c=`${s}-trigger-${vt(n)}`,b=`${s}-panel-${vt(n)}`;function m(f,C){let w=f.closest('[role="tablist"]');if(!w)return;let v=Array.from(w.querySelectorAll('[role="tab"]:not([disabled])')),I=v.indexOf(f);if(I<0)return;let N;C==="first"&&(N=v[0]),C==="last"&&(N=v[v.length-1]),C==="next"&&(N=v[(I+1)%v.length]),C==="prev"&&(N=v[(I-1+v.length)%v.length]),N&&(N.focus(),N.click())}return tt("button",{type:"button",id:c,role:"tab","aria-selected":p,"aria-controls":b,tabIndex:p?0:-1,"data-state":p?"active":"inactive",disabled:o,className:ht("ui-tabs__trigger relative -mb-px inline-flex min-h-9 items-center justify-center rounded-t-md border-b-2 px-3 py-2 text-sm font-medium transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-inset disabled:cursor-not-allowed disabled:opacity-50",t),onClick:f=>{a?.(f),!f.defaultPrevented&&!o&&d(n)},onKeyDown:f=>{if(r?.(f),f.defaultPrevented||o)return;let C=f.currentTarget;switch(f.key){case"ArrowRight":f.preventDefault(),m(C,"next");break;case"ArrowLeft":f.preventDefault(),m(C,"prev");break;case"Home":f.preventDefault(),m(C,"first");break;case"End":f.preventDefault(),m(C,"last");break}},...i,children:e})}function ga({children:e,className:t,value:n,...o}){let{value:a,baseId:r}=xn("Tabs.Content"),i=a===n,l=`${r}-trigger-${vt(n)}`,d=`${r}-panel-${vt(n)}`;return i?tt("div",{id:d,role:"tabpanel","aria-labelledby":l,"data-state":"active",className:ht("ui-tabs__content pt-4",t),...o,children:e}):null}var ba=Object.assign(hn,{Root:hn,List:ma,Trigger:fa,Content:ga}),De=ba;import{jsx as we,jsxs as wn}from"react/jsx-runtime";h({group:"forms",componentId:"tabs",componentName:"Tabs",description:"Navigation-grade tab primitive with keyboard support and linked tab panels.",props:[{name:"value",type:"string",description:"Controlled active tab value."},{name:"defaultValue",type:"string",description:"Initial tab value for uncontrolled usage."},{name:"onValueChange",type:"(value: string) => void",description:"Change callback when the active tab changes."}],stories:[{id:"settings-tabs",title:"Settings Tabs",render:()=>we("div",{className:"max-w-2xl",children:wn(De,{defaultValue:"settings",children:[wn(De.List,{ariaLabel:"Settings sections",children:[we(De.Trigger,{value:"settings",children:"Settings"}),we(De.Trigger,{value:"account",children:"Account"}),we(De.Trigger,{value:"admin",disabled:!0,children:"Admin"})]}),we(De.Content,{value:"settings",children:we("div",{className:"rounded-xl border border-[var(--ui-surface-border)] bg-[var(--ui-surface-bg)] p-4 text-sm text-[var(--ui-text-secondary)]",children:"Settings panel content."})}),we(De.Content,{value:"account",children:we("div",{className:"rounded-xl border border-[var(--ui-surface-border)] bg-[var(--ui-surface-bg)] p-4 text-sm text-[var(--ui-text-secondary)]",children:"Account panel content."})}),we(De.Content,{value:"admin",children:we("div",{className:"rounded-xl border border-[var(--ui-surface-border)] bg-[var(--ui-surface-bg)] p-4 text-sm text-[var(--ui-text-secondary)]",children:"Admin panel content."})})]})})}]});import{clsx as va}from"clsx";import{jsx as ha}from"react/jsx-runtime";function H({tone:e="neutral",variant:t="soft",size:n="xs",className:o,children:a,...r}){return ha("span",{"data-tone":e,"data-variant":t,"data-size":n,className:va("ui-badge inline-flex items-center rounded-full border text-[var(--badge-text)]",n==="xs"?"px-2.5 py-1 text-[11px]":"px-3 py-1 text-xs font-medium",o),...r,children:a})}import{jsx as te,jsxs as $e}from"react/jsx-runtime";h({group:"feedback",componentId:"badge",componentName:"Badge",description:"Inline label for status, categories, or counts. Token-driven: --badge-bg, --badge-text, --badge-border.",props:[{name:"tone",type:"'neutral' | 'info' | 'success' | 'warning' | 'danger'",default:"'neutral'",description:"Semantic color tone."},{name:"variant",type:"'soft' | 'outline'",default:"'soft'",description:"Fill style. Soft uses tinted background; outline uses transparent bg with visible border."},{name:"size",type:"'xs' | 'sm'",default:"'xs'",description:"Compact or slightly larger badge size."},{name:"children",type:"ReactNode",description:"Badge content."}],renderPlayground:e=>te(H,{tone:e.tone,variant:e.variant,size:e.size,children:"Badge"}),stories:[{id:"tones-soft",title:"Tones (Soft)",description:"neutral / info / success / warning / danger \u2014 soft variant",render:()=>$e("div",{className:"flex flex-wrap items-center gap-3",children:[te(H,{tone:"neutral",children:"Neutral"}),te(H,{tone:"info",children:"Info"}),te(H,{tone:"success",children:"Success"}),te(H,{tone:"warning",children:"Warning"}),te(H,{tone:"danger",children:"Danger"})]})},{id:"tones-outline",title:"Tones (Outline)",description:"Same tones with outline variant \u2014 transparent bg, colored border.",render:()=>$e("div",{className:"flex flex-wrap items-center gap-3",children:[te(H,{tone:"neutral",variant:"outline",children:"Neutral"}),te(H,{tone:"info",variant:"outline",children:"Info"}),te(H,{tone:"success",variant:"outline",children:"Success"}),te(H,{tone:"warning",variant:"outline",children:"Warning"}),te(H,{tone:"danger",variant:"outline",children:"Danger"})]})},{id:"sizes",title:"Sizes",description:"xs / sm",render:()=>$e("div",{className:"flex flex-wrap items-center gap-3",children:[te(H,{size:"xs",tone:"info",children:"XS Badge"}),te(H,{size:"sm",tone:"info",children:"SM Badge"})]})},{id:"variant-comparison",title:"Variant Comparison",description:"Soft vs outline side by side for each tone.",render:()=>te("div",{className:"space-y-3",children:["neutral","info","success","warning","danger"].map(e=>$e("div",{className:"flex items-center gap-3",children:[$e(H,{size:"sm",tone:e,variant:"soft",children:[e," soft"]}),$e(H,{size:"sm",tone:e,variant:"outline",children:[e," outline"]})]},e))})}]});import{Info as Cn,CheckCircle2 as ya,TriangleAlert as Sn,CircleAlert as xa}from"lucide-react";import{clsx as Nn}from"clsx";import{Fragment as Tn,jsx as Pe,jsxs as yt}from"react/jsx-runtime";function U({tone:e="neutral",layout:t="horizontal",icon:n,title:o,description:a,action:r,className:i,children:l,...d}){if(t==="vertical"){let s=n||o||a||r;return Pe("div",{"data-tone":e,"data-layout":"vertical",className:Nn("ui-status-notice rounded-lg border px-4 py-3 text-sm",i),...d,children:s?yt("div",{className:"flex flex-col items-center gap-2 py-4 text-center",children:[n&&Pe("div",{className:"ui-status-notice__icon text-lg",children:n}),o&&Pe("div",{className:"ui-status-notice__title font-medium",children:o}),a&&Pe("div",{className:"ui-status-notice__description",children:a}),r&&Pe("div",{className:"mt-2",children:r})]}):l})}return Pe("div",{"data-tone":e,className:Nn("ui-status-notice rounded-md border px-4 py-3 text-sm",n&&"ui-status-notice--with-icon grid grid-cols-[auto_minmax(0,1fr)] gap-3",i),...d,children:n?yt(Tn,{children:[Pe("span",{className:"ui-status-notice__icon mt-0.5 shrink-0","aria-hidden":"true",children:n}),yt("div",{className:"min-w-0",children:[o&&Pe("div",{className:"ui-status-notice__title font-medium",children:o}),l]})]}):yt(Tn,{children:[o&&Pe("div",{className:"ui-status-notice__title font-medium",children:o}),l]})})}import{jsx as M,jsxs as nt}from"react/jsx-runtime";h({group:"feedback",componentId:"status-notice",componentName:"StatusNotice",description:"Block-level feedback banner. Supports horizontal (default) and vertical layouts, with optional icon, title, description, and action slots.",props:[{name:"tone",type:"'neutral' | 'info' | 'success' | 'warning' | 'danger'",default:"'success'",description:"Semantic message tone."},{name:"layout",type:"'horizontal' | 'vertical'",default:"'horizontal'",description:"Layout direction. Vertical centers content for empty states."},{name:"children",type:"string",default:"'Operation completed successfully.'",description:"Notice content."},{name:"icon",type:"ReactNode",description:"Optional icon slot."},{name:"title",type:"ReactNode",description:"Optional bold title above content."},{name:"description",type:"ReactNode",description:"Description text (vertical layout)."},{name:"action",type:"ReactNode",description:"Action slot, e.g. a button (vertical layout)."},{name:"className",type:"string",description:"Additional classes for layout or spacing."}],renderPlayground:e=>M(U,{tone:e.tone,layout:e.layout,children:e.children||"Operation completed successfully."}),stories:[{id:"tones",title:"Tones",description:"info / success / warning / danger",render:()=>nt("div",{className:"space-y-3",children:[M(U,{tone:"neutral",children:"General system guidance without a semantic alert state."}),M(U,{tone:"info",children:"This is an informational notice."}),M(U,{tone:"success",children:"Operation completed successfully."}),M(U,{tone:"warning",children:"Please review before continuing."}),M(U,{tone:"danger",children:"Something went wrong. Please try again."})]})},{id:"with-icons",title:"With Icons",render:()=>nt("div",{className:"space-y-3",children:[M(U,{tone:"info",icon:M(Cn,{size:16}),children:"Background indexing is still in progress."}),M(U,{tone:"success",icon:M(ya,{size:16}),children:"Draft and main are fully aligned."}),M(U,{tone:"warning",icon:M(Sn,{size:16}),children:"One route conflict still needs manual review."}),M(U,{tone:"danger",icon:M(xa,{size:16}),children:"Publishing failed. Retry after refreshing the snapshot."})]})},{id:"with-title",title:"With Title",description:"Horizontal layout with bold title above children.",render:()=>nt("div",{className:"space-y-3",children:[M(U,{tone:"info",icon:M(Cn,{size:16}),title:"New feature available",children:"Workspace analytics are now in beta. Enable them in your project settings."}),M(U,{tone:"warning",icon:M(Sn,{size:16}),title:"Action required",children:"Your API key expires in 3 days. Regenerate it from Settings."})]})},{id:"vertical-empty",title:"Vertical Layout (Empty State)",description:"Centered layout for empty lists or missing content.",render:()=>nt("div",{className:"space-y-4",children:[M(U,{layout:"vertical",children:"No items found."}),M(U,{layout:"vertical",title:"No posts yet",description:"Create your first post to get started.",action:M(u,{variant:"primary",size:"sm",children:"Create Post"})}),M(U,{layout:"vertical",icon:M("span",{className:"text-2xl",children:"\u{1F4ED}"}),title:"Inbox empty",description:"You have no new messages."})]})},{id:"vertical-tones",title:"Vertical Tones",description:"Vertical layout with semantic tones.",render:()=>nt("div",{className:"space-y-4",children:[M(U,{layout:"vertical",tone:"neutral",title:"Neutral",description:"Default empty state."}),M(U,{layout:"vertical",tone:"info",title:"Info",description:"Informational empty state."}),M(U,{layout:"vertical",tone:"warning",title:"Warning",description:"Attention-drawing empty state."})]})}]});import{jsx as ne,jsxs as Ge}from"react/jsx-runtime";h({group:"feedback",componentId:"spinner",componentName:"Spinner",description:"Animated loading indicator with multiple icon styles. Used standalone or composed into other components (e.g. Button loading state).",defaultScale:5,props:[{name:"variant",type:"'ring' | 'arc' | 'dots' | 'bars' | 'bounce' | 'pulse' | 'orbit' | 'flow'",default:"'ring'",description:"Spinner icon style."},{name:"size",type:"'xs' | 'sm' | 'md' | 'lg'",default:"'md'",description:"Preset size, or pass a number for custom pixel size."},{name:"label",type:"string",description:"Accessible label. When set, spinner is announced to screen readers."},{name:"className",type:"string",description:"Additional CSS classes."}],renderPlayground:e=>ne(se,{variant:e.variant,size:e.size}),stories:[{id:"variants",title:"Variants",description:"ring / arc / dots / bars / bounce / pulse / orbit / flow",render:()=>ne("div",{className:"flex flex-wrap items-center gap-8",children:["ring","arc","dots","bars","bounce","pulse","orbit","flow"].map(e=>Ge("div",{className:"flex flex-col items-center gap-2",children:[ne(se,{variant:e,size:"lg"}),ne("span",{className:"text-[11px] text-[var(--color-n500)]",children:e})]},e))})},{id:"sizes",title:"Sizes",description:"xs / sm / md / lg",render:()=>Ge("div",{className:"flex items-center gap-4",children:[ne(se,{size:"xs"}),ne(se,{size:"sm"}),ne(se,{size:"md"}),ne(se,{size:"lg"})]})},{id:"with-text",title:"Inline with Text",render:()=>Ge("div",{className:"space-y-3",children:[Ge("div",{className:"flex items-center gap-2 text-sm text-[var(--color-n600)]",children:[ne(se,{variant:"ring",size:"sm"}),ne("span",{children:"Loading data\u2026"})]}),Ge("div",{className:"flex items-center gap-2 text-sm text-[var(--color-n600)]",children:[ne(se,{variant:"flow",size:"sm"}),ne("span",{children:"Processing\u2026"})]}),Ge("div",{className:"flex items-center gap-2 text-sm text-[var(--color-n600)]",children:[ne(se,{variant:"bounce",size:"sm"}),ne("span",{children:"Waiting for response\u2026"})]})]})}]});import{clsx as wa}from"clsx";import{jsx as Ta}from"react/jsx-runtime";var Na={slow:"4s",default:"3s",fast:"2s"};function O({className:e,animation:t="scan",tone:n="default",speed:o="default",style:a,...r}){let i=n==="warm"?"emphasis":n,l={...a,"--ui-skeleton-scan-duration":Na[o]};return Ta("div",{className:wa("ui-skeleton rounded",e),"data-animation":t,"data-tone":i,"aria-hidden":"true",style:l,...r})}import{jsx as B,jsxs as de}from"react/jsx-runtime";h({group:"feedback",componentId:"skeleton",componentName:"Skeleton",description:"Loading placeholder with `scan` or `pulse` animation and configurable speed.",props:[{name:"animation",type:"'pulse' | 'scan'",default:"'scan'",description:"Chooses the loading motion style."},{name:"tone",type:"'default' | 'emphasis'",default:"'default'",description:"Semantic emphasis level of the placeholder."},{name:"speed",type:"'slow' | 'default' | 'fast'",default:"'default'",description:"Scan animation speed: slow (4s), default (3s), fast (2s)."},{name:"className",type:"string",description:"Controls skeleton shape and dimensions."}],renderPlayground:e=>de("div",{className:"space-y-3",children:[B(O,{animation:e.animation,tone:e.tone,speed:e.speed,className:"h-4 w-48"}),B(O,{animation:e.animation,tone:e.tone,speed:e.speed,className:"h-4 w-64"})]}),stories:[{id:"scan",title:"Scan",render:()=>de("div",{className:"space-y-4",children:[B(O,{className:"h-4 w-48"}),B(O,{className:"h-4 w-64"}),B(O,{className:"h-4 w-32"})]})},{id:"scan-speed",title:"Scan Speed",render:()=>de("div",{className:"space-y-4",children:[de("div",{className:"space-y-2",children:[B("div",{className:"text-xs font-medium text-[var(--color-n500)]",children:"Slow \xB7 4s"}),B(O,{speed:"slow",className:"h-4 w-64"})]}),de("div",{className:"space-y-2",children:[B("div",{className:"text-xs font-medium text-[var(--color-n500)]",children:"Default \xB7 3s"}),B(O,{className:"h-4 w-64"})]}),de("div",{className:"space-y-2",children:[B("div",{className:"text-xs font-medium text-[var(--color-n500)]",children:"Fast \xB7 2s"}),B(O,{speed:"fast",className:"h-4 w-64"})]})]})},{id:"pulse",title:"Pulse",render:()=>de("div",{className:"space-y-4",children:[B(O,{animation:"pulse",className:"h-4 w-48"}),B(O,{animation:"pulse",className:"h-4 w-64"}),B(O,{animation:"pulse",className:"h-4 w-32"})]})},{id:"on-surfaces",title:"On Different Surfaces",description:"Verifies shimmer visibility against various backgrounds.",render:()=>B("div",{className:"grid gap-4 sm:grid-cols-3",children:[{label:"Canvas",bg:"var(--color-surface-canvas)"},{label:"Base",bg:"var(--color-surface-base)"},{label:"Inset",bg:"var(--color-surface-inset)"}].map(({label:e,bg:t})=>de("div",{className:"rounded-lg p-4",style:{backgroundColor:t},children:[B("p",{className:"mb-2 text-[11px] font-medium text-[var(--color-n500)]",children:e}),de("div",{className:"space-y-2",children:[B(O,{className:"h-4 w-full"}),B(O,{className:"h-4 w-3/4"})]})]},e))})},{id:"card-placeholder",title:"Card Placeholder",render:()=>de("div",{className:"max-w-sm space-y-3 rounded-lg border border-[var(--color-surface-border)] p-4",children:[B(O,{className:"h-5 w-3/4"}),B(O,{className:"h-4 w-full"}),B(O,{className:"h-4 w-5/6"}),de("div",{className:"flex gap-2 pt-2",children:[B(O,{animation:"pulse",className:"h-8 w-20 rounded-md"}),B(O,{animation:"pulse",className:"h-8 w-20 rounded-md"})]})]})},{id:"avatar-line",title:"Avatar + Lines",render:()=>de("div",{className:"flex items-start gap-3",children:[B(O,{className:"h-10 w-10 shrink-0 rounded-full"}),de("div",{className:"flex-1 space-y-2",children:[B(O,{animation:"pulse",className:"h-4 w-32"}),B(O,{className:"h-3 w-48"})]})]})}]});import{useState as xt}from"react";import{clsx as ot}from"clsx";import{useEffect as Ca,useRef as Dn,useCallback as Sa}from"react";import{jsx as at,jsxs as Ia}from"react/jsx-runtime";function Da({className:e,children:t,...n}){return at("div",{className:ot("ui-dialog__header px-5 pt-5 pb-1 text-base font-semibold",e),...n,children:t})}function Pa({className:e,children:t,...n}){return at("div",{className:ot("ui-dialog__body px-5 py-3 text-sm",e),...n,children:t})}function ka({className:e,children:t,...n}){return at("div",{className:ot("ui-dialog__footer flex items-center justify-end gap-2 px-5 pt-3 pb-5",e),...n,children:t})}function L({open:e,onClose:t,size:n="sm",children:o,className:a,overlayClassName:r,panelClassName:i,...l}){let d=Dn(null),s=Dn(null),p=Sa(c=>{c.key==="Escape"&&(c.stopPropagation(),t())},[t]);return Ca(()=>(e?(s.current=document.activeElement,document.body.style.overflow="hidden",requestAnimationFrame(()=>{let c=d.current;if(!c)return;let b=c.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');b?b.focus():c.focus()}),document.addEventListener("keydown",p)):(document.body.style.overflow="",s.current?.focus()),()=>{document.removeEventListener("keydown",p),document.body.style.overflow=""}),[e,p]),e?Ia("div",{"data-state":"open",className:"ui-dialog-overlay fixed inset-0 z-50 flex items-center justify-center",children:[at("button",{type:"button","aria-label":"Close dialog","data-state":"open",className:ot("ui-dialog-backdrop absolute inset-0 bg-black/30",r),onClick:t}),at("div",{ref:d,role:"dialog","aria-modal":"true",tabIndex:-1,"data-state":"open","data-size":n,className:ot("ui-dialog relative z-10 w-full rounded-xl shadow-xl","animate-[dialog-in_0.2s_var(--ease-standard)]",n==="sm"?"max-w-[26rem]":"max-w-[32rem]",i,a),...l,children:o})]}):null}L.Header=Da;L.Body=Pa;L.Footer=ka;import{createContext as Ma,useCallback as Pn,useContext as Ba,useRef as La,useState as Ra}from"react";import{Fragment as za,jsx as Ue,jsxs as At}from"react/jsx-runtime";var kn=Ma(null);function In(){let e=Ba(kn);if(!e)throw new Error("useConfirm must be used within <ConfirmProvider>");return e}function Mn({children:e}){let[t,n]=Ra(null),o=La(null),a=Pn(i=>(o.current&&o.current.resolve(!1),new Promise(l=>{let d={options:i,resolve:l};o.current=d,n(d)})),[]),r=Pn(i=>{o.current&&(o.current.resolve(i),o.current=null),n(null)},[]);return At(kn.Provider,{value:a,children:[e,Ue(L,{open:t!==null,onClose:()=>r(!1),children:t&&At(za,{children:[Ue(L.Header,{children:t.options.title}),Ue(L.Body,{children:typeof t.options.description=="string"?Ue("p",{className:"whitespace-pre-wrap",children:t.options.description}):t.options.description}),At(L.Footer,{children:[Ue(u,{variant:"ghost",size:"sm",onClick:()=>r(!1),children:t.options.cancelLabel??"\u53D6\u6D88"}),Ue(u,{variant:t.options.variant??"primary",size:"sm",onClick:()=>r(!0),children:t.options.confirmLabel??"\u786E\u8BA4"})]})]})})]})}import{Fragment as Et,jsx as y,jsxs as R}from"react/jsx-runtime";function Aa(){let[e,t]=xt(!1);return R(Et,{children:[y(u,{variant:"primary",size:"sm",onClick:()=>t(!0),children:"Open Dialog"}),R(L,{open:e,onClose:()=>t(!1),children:[y(L.Header,{children:"Basic Dialog"}),y(L.Body,{children:y("p",{children:"This is a basic dialog with header, body, and footer sections."})}),R(L.Footer,{children:[y(u,{variant:"ghost",size:"sm",onClick:()=>t(!1),children:"Cancel"}),y(u,{variant:"primary",size:"sm",onClick:()=>t(!1),children:"Confirm"})]})]})]})}function Ea(){let[e,t]=xt(!1);return R(Et,{children:[y(u,{variant:"danger",size:"sm",onClick:()=>t(!0),children:"Delete Item"}),R(L,{open:e,onClose:()=>t(!1),children:[y(L.Header,{children:"Delete Draft"}),R(L.Body,{children:[y("p",{children:"Are you sure you want to delete the ZH locale draft?"}),R("p",{className:"mt-2",children:["Article ID: post-20260320-example",y("br",{}),"Category: post"]}),y("p",{className:"mt-2",children:"This action cannot be undone."})]}),R(L.Footer,{children:[y(u,{variant:"ghost",size:"sm",onClick:()=>t(!1),children:"Cancel"}),y(u,{variant:"danger",size:"sm",onClick:()=>t(!1),children:"Delete"})]})]})]})}function Ha(){let[e,t]=xt(!1);return R(Et,{children:[y(u,{variant:"secondary",size:"sm",onClick:()=>t(!0),children:"Open Medium Dialog"}),R(L,{open:e,onClose:()=>t(!1),size:"md",children:[y(L.Header,{children:"Publish Confirmation"}),R(L.Body,{children:[y("p",{children:"You are about to publish the current draft branch."}),R("div",{className:"mt-3 rounded-lg border border-[var(--color-surface-border)] bg-[var(--color-surface-base)] p-3 text-sm",children:[R("div",{className:"flex justify-between",children:[y("span",{children:"Articles:"}),y("span",{children:"3"})]}),R("div",{className:"flex justify-between",children:[y("span",{children:"Languages:"}),y("span",{children:"ZH, EN"})]}),R("div",{className:"flex justify-between",children:[y("span",{children:"Branch:"}),y("span",{children:"draft"})]})]}),y("p",{className:"mt-3",children:"This will trigger a Cloudflare deployment."})]}),R(L.Footer,{children:[y(u,{variant:"ghost",size:"sm",onClick:()=>t(!1),children:"Cancel"}),y(u,{variant:"primary",size:"sm",onClick:()=>t(!1),children:"Publish"})]})]})]})}function Oa(){let e=In(),[t,n]=xt("");return R("div",{className:"flex flex-col gap-3",children:[R("div",{className:"flex gap-2",children:[y(u,{variant:"primary",size:"sm",onClick:async()=>{let r=await e({title:"Confirm Action",description:"This demonstrates the useConfirm() hook. Click confirm or cancel.",confirmLabel:"Do it",cancelLabel:"Nope"});n(r?"Confirmed!":"Cancelled.")},children:"useConfirm()"}),y(u,{variant:"danger",size:"sm",onClick:async()=>{let r=await e({title:"Delete Everything",description:"This is a danger variant confirm dialog.",confirmLabel:"Delete",variant:"danger"});n(r?"Deleted!":"Cancelled.")},children:"Danger Confirm"})]}),t&&R("p",{className:"text-sm text-[var(--color-n600)]",children:["Result: ",t]})]})}function _a(){return y(Mn,{children:y(Oa,{})})}h({group:"feedback",componentId:"dialog",componentName:"Dialog",description:"Modal dialog for confirmations and focused tasks. Supports declarative usage via <Dialog> and imperative usage via `useConfirm()` hook. The imperative API requires `<ConfirmProvider>` in an ancestor (mounted in admin layout).",props:[{name:"open",type:"boolean",default:"false",description:"Controls dialog visibility."},{name:"size",type:"'sm' | 'md'",default:"'sm'",description:"Dialog width."},{name:"onClose",type:"() => void",description:"Called on backdrop click or Escape key."}],renderPlayground:(e,t)=>{let n=e.size||"sm",o=!!e.open;return R("div",{className:"flex flex-col items-center gap-4",children:[R(u,{variant:"primary",size:"sm",onClick:()=>t("open",!0),children:["Open Dialog (",n,")"]}),R(L,{open:o,onClose:()=>t("open",!1),size:n,children:[y(L.Header,{children:"Playground Dialog"}),y(L.Body,{children:R("p",{children:["Toggle the ",y("code",{className:"rounded bg-[var(--color-surface-subtle)] px-1 py-0.5 text-xs",children:"open"})," and ",y("code",{className:"rounded bg-[var(--color-surface-subtle)] px-1 py-0.5 text-xs",children:"size"})," controls below."]})}),R(L.Footer,{children:[y(u,{variant:"ghost",size:"sm",onClick:()=>t("open",!1),children:"Cancel"}),y(u,{variant:"primary",size:"sm",onClick:()=>t("open",!1),children:"Confirm"})]})]})]})},stories:[{id:"provider-setup",title:"Provider Setup",description:"useConfirm() requires <ConfirmProvider> in an ancestor. Mount it once in your layout \u2014 all descendant components can then call useConfirm().",source:`// src/app/qadmin/layout.tsx
|
|
5
6
|
import { ConfirmProvider } from '../../components/ConfirmDialog';
|
|
6
7
|
|
|
7
8
|
export default function AdminLayout({ children }) {
|
|
@@ -30,19 +31,19 @@ function MyComponent() {
|
|
|
30
31
|
if (!ok) return;
|
|
31
32
|
// proceed with deletion
|
|
32
33
|
};
|
|
33
|
-
}`,render:()=>
|
|
34
|
+
}`,render:()=>R("div",{className:"rounded-lg border border-[var(--color-surface-border)] bg-[var(--color-surface-subtle)] px-4 py-3 text-sm text-[var(--color-n600)]",children:[y("p",{className:"font-medium text-[var(--color-n800)]",children:"Provider is already mounted in admin layout."}),R("p",{className:"mt-1",children:["Click the ",y("strong",{children:"Code"})," button below to see the setup example."]})]})},{id:"basic",title:"Basic Dialog",description:"Standard confirmation dialog with header, body, and footer.",source:`<Dialog open={open} onClose={() => setOpen(false)}>
|
|
34
35
|
<Dialog.Header>Title</Dialog.Header>
|
|
35
36
|
<Dialog.Body>Content here.</Dialog.Body>
|
|
36
37
|
<Dialog.Footer>
|
|
37
38
|
<Button variant="ghost" onClick={close}>Cancel</Button>
|
|
38
39
|
<Button variant="primary" onClick={close}>Confirm</Button>
|
|
39
40
|
</Dialog.Footer>
|
|
40
|
-
</Dialog>`,render:()=>
|
|
41
|
+
</Dialog>`,render:()=>y(Aa,{})},{id:"danger",title:"Danger Dialog",description:"Destructive action confirmation with danger-styled button.",render:()=>y(Ea,{})},{id:"medium",title:"Medium Size",description:"Wider dialog for content-heavy confirmations.",render:()=>y(Ha,{})},{id:"use-confirm",title:"useConfirm() Hook",description:"Imperative confirm API that returns a Promise<boolean>. Replaces window.confirm.",source:`const confirm = useConfirm();
|
|
41
42
|
const ok = await confirm({
|
|
42
43
|
title: 'Confirm',
|
|
43
44
|
description: 'Are you sure?',
|
|
44
45
|
variant: 'danger',
|
|
45
|
-
});`,render:()=>
|
|
46
|
+
});`,render:()=>y(_a,{})}]});import{clsx as Bn}from"clsx";import{createContext as Fa,useCallback as Ln,useContext as Va,useMemo as Wa,useRef as Rn,useState as $a}from"react";import{jsx as Y,jsxs as rt}from"react/jsx-runtime";var An=Fa(null),Ht=5,zn=4e3;function En(){let e=Va(An);if(!e)throw new Error("useToast must be used within <ToastProvider>");return e}function Ga({tone:e}){let t={width:16,height:16,viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};switch(e){case"success":return Y("svg",{...t,children:Y("path",{d:"M3.5 8.5l3 3 6-7"})});case"warning":return rt("svg",{...t,children:[Y("path",{d:"M8 5v4"}),Y("circle",{cx:"8",cy:"11.5",r:"0.5",fill:"currentColor",stroke:"none"})]});case"danger":return Y("svg",{...t,children:Y("path",{d:"M4.5 4.5l7 7M11.5 4.5l-7 7"})});case"info":return rt("svg",{...t,children:[Y("circle",{cx:"8",cy:"3.5",r:"1.2",fill:"currentColor",stroke:"none"}),Y("path",{d:"M8 7v5.5"})]})}}function Ua(e,t){return typeof e=="string"?{message:e,duration:t??zn}:{title:e.title,message:e.message,duration:e.duration??t??zn}}function Ka({item:e,onDismiss:t,renderToast:n}){let o=()=>t(e.id),a=Y(Ga,{tone:e.tone});return n?Y("div",{role:"status","aria-live":"polite","data-state":"open","data-tone":e.tone,className:Bn("ui-toast pointer-events-auto rounded-lg border text-sm backdrop-blur-sm","animate-[toast-in_0.25s_var(--ease-standard)]"),children:n({item:e,dismiss:o,icon:a})}):rt("div",{role:"status","aria-live":"polite","data-state":"open","data-tone":e.tone,className:Bn("ui-toast pointer-events-auto flex items-start gap-2 rounded-lg border px-4 py-3 text-sm backdrop-blur-sm","animate-[toast-in_0.25s_var(--ease-standard)]"),children:[Y("span",{className:"ui-toast__icon mt-0.5 shrink-0","aria-hidden":"true",children:a}),rt("span",{className:"min-w-0 flex-1",children:[e.title?Y("span",{className:"ui-toast__title block font-medium",children:e.title}):null,Y("span",{className:"block",children:e.message})]}),Y("button",{type:"button",onClick:o,className:"ui-toast__close -mr-1 -mt-0.5 shrink-0 rounded p-0.5 text-current opacity-50 transition-opacity hover:opacity-100","aria-label":"Dismiss",children:Y("svg",{width:"14",height:"14",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",children:Y("path",{d:"M4 4l8 8M12 4l-8 8"})})})]})}function Hn({children:e,renderToast:t}){let[n,o]=$a([]),a=Rn(0),r=Rn(new Map),i=Ln(s=>{let p=r.current.get(s);p&&clearTimeout(p),r.current.delete(s),o(c=>c.filter(b=>b.id!==s))},[]),l=Ln((s,p,c)=>{let b=a.current++,m=Ua(p,c),f={id:b,tone:s,...m};o(C=>{let w=[...C,f];if(w.length>Ht){let v=w.slice(0,w.length-Ht);for(let I of v){let N=r.current.get(I.id);N&&clearTimeout(N),r.current.delete(I.id)}return w.slice(-Ht)}return w}),f.duration>0&&r.current.set(b,setTimeout(()=>i(b),f.duration))},[i]),d=Wa(()=>({success:(s,p)=>l("success",s,p),warning:(s,p)=>l("warning",s,p),danger:(s,p)=>l("danger",s,p),info:(s,p)=>l("info",s,p)}),[l]);return rt(An.Provider,{value:d,children:[e,Y("div",{"aria-label":"Notifications","data-state":n.length>0?"open":"closed",className:"pointer-events-none fixed bottom-4 right-4 z-[9999] flex flex-col-reverse gap-2",children:n.map(s=>Y(Ka,{item:s,onDismiss:i,renderToast:t},s.id))})]})}import{jsx as j,jsxs as Ot}from"react/jsx-runtime";function qa(){let e=En();return Ot("div",{className:"flex flex-wrap gap-2",children:[j(u,{size:"sm",variant:"secondary",onClick:()=>e.success("Changes saved successfully."),leadingIcon:j(H,{tone:"success",children:"\u25CF"}),children:"Success"}),j(u,{size:"sm",variant:"secondary",onClick:()=>e.warning("Draft has unsaved changes."),leadingIcon:j(H,{tone:"warning",children:"\u25CF"}),children:"Warning"}),j(u,{size:"sm",variant:"secondary",onClick:()=>e.danger("Failed to publish post."),leadingIcon:j(H,{tone:"danger",children:"\u25CF"}),children:"Danger"}),j(u,{size:"sm",variant:"secondary",onClick:()=>e.info("New version available."),leadingIcon:j(H,{tone:"info",children:"\u25CF"}),children:"Info"}),j(u,{size:"sm",variant:"secondary",onClick:()=>e.success({title:"Draft Saved",message:"All local changes are now synced to the draft branch."}),leadingIcon:j(H,{tone:"success",children:"\u25CF"}),children:"With Title"})]})}function Ya(){return j(Hn,{children:j(qa,{})})}h({group:"feedback",componentId:"toast",componentName:"Toast",description:"Transient notification messages triggered via `useToast()` hook. Requires `<ToastProvider>` wrapper.",props:[{name:"toast.success({ title, message, duration? })",type:"function",description:"Show a success toast with optional title."},{name:"toast.success(msg, duration?)",type:"function",description:"Show a success toast."},{name:"toast.warning(msg, duration?)",type:"function",description:"Show a warning toast."},{name:"toast.danger(msg, duration?)",type:"function",description:"Show a danger toast."},{name:"toast.info(msg, duration?)",type:"function",description:"Show an info toast."}],stories:[{id:"provider-setup",title:"Provider Setup",description:"useToast() requires <ToastProvider> in an ancestor. Mount it once in your layout \u2014 all descendant components can then call useToast().",source:`// src/app/qadmin/layout.tsx
|
|
46
47
|
import { ToastProvider } from '../../components/Toast';
|
|
47
48
|
|
|
48
49
|
export default function AdminLayout({ children }) {
|
|
@@ -69,7 +70,7 @@ function MyComponent() {
|
|
|
69
70
|
toast.danger('Failed to save draft.');
|
|
70
71
|
}
|
|
71
72
|
};
|
|
72
|
-
}`,render:()=>Tt("div",{className:"rounded-lg border border-[var(--color-surface-border)] bg-[var(--color-surface-subtle)] px-4 py-3 text-sm text-[var(--color-n600)]",children:[ve("p",{className:"font-medium text-[var(--color-n800)]",children:"ToastProvider is not yet mounted in admin layout."}),Tt("p",{className:"mt-1",children:["Add it to the layout before using useToast(). Click the ",ve("strong",{children:"Code"})," button below to see the setup example."]})]})},{id:"all-tones",title:"All Tones",description:"Click buttons to trigger toasts, including the optional title layout.",render:()=>ve(ca,{})}]});import{clsx as ua}from"clsx";import{useState as pa}from"react";import{jsx as Ct}from"react/jsx-runtime";var ma={xs:"h-6 w-6 text-[10px]",sm:"h-8 w-8 text-xs",md:"h-10 w-10 text-sm",lg:"h-14 w-14 text-lg"};function fa(e){let t=e.trim().split(/\s+/);return t.length>=2?(t[0][0]+t[t.length-1][0]).toUpperCase():e.slice(0,2).toUpperCase()}function ne({src:e,alt:t,name:n,size:o="md",tone:a="neutral",className:i}){let[r,p]=pa(!1),c=e&&!r,s=n?fa(n):"?";return Ct("span",{"data-tone":a,className:ua("ui-avatar inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full font-medium select-none",ma[o],i),children:c?Ct("img",{src:e,alt:t??n??"",className:"h-full w-full object-cover",onError:()=>p(!0)}):Ct("span",{"aria-label":t??n,children:s})})}import{jsx as oe,jsxs as Fe}from"react/jsx-runtime";y({group:"feedback",componentId:"avatar",componentName:"Avatar",description:"User avatar with image or initials fallback. Token-driven: --avatar-bg, --avatar-text, --avatar-border.",props:[{name:"src",type:"string",description:"Image URL."},{name:"alt",type:"string",description:"Alt text for the image."},{name:"name",type:"string",description:"User name, used to derive initials fallback."},{name:"size",type:"'xs' | 'sm' | 'md' | 'lg'",default:"'md'",description:"Avatar size."},{name:"tone",type:"'neutral' | 'subtle'",default:"'neutral'",description:"Fallback background tone."}],renderPlayground:e=>oe(ne,{name:"Alice Bob",size:e.size,tone:e.tone}),stories:[{id:"sizes",title:"Sizes",description:"xs / sm / md / lg",render:()=>Fe("div",{className:"flex items-end gap-3",children:[oe(ne,{name:"Alice",size:"xs"}),oe(ne,{name:"Bob Chen",size:"sm"}),oe(ne,{name:"Carol Davis",size:"md"}),oe(ne,{name:"David",size:"lg"})]})},{id:"tones",title:"Tones",description:"neutral (default) vs subtle \u2014 applies to initials fallback.",render:()=>Fe("div",{className:"flex items-center gap-4",children:[Fe("div",{className:"text-center",children:[oe(ne,{name:"Neutral",size:"lg",tone:"neutral"}),oe("p",{className:"mt-1 text-xs text-[var(--color-n500)]",children:"neutral"})]}),Fe("div",{className:"text-center",children:[oe(ne,{name:"Subtle",size:"lg",tone:"subtle"}),oe("p",{className:"mt-1 text-xs text-[var(--color-n500)]",children:"subtle"})]})]})},{id:"with-image",title:"With Image",render:()=>Fe("div",{className:"flex items-center gap-3",children:[oe(ne,{src:"https://api.dicebear.com/9.x/initials/svg?seed=QQ",name:"Q",size:"md"}),oe(ne,{src:"https://api.dicebear.com/9.x/initials/svg?seed=AB",name:"Alice Bob",size:"lg"})]})},{id:"fallback",title:"Fallback",description:"When image fails to load, initials are shown.",render:()=>Fe("div",{className:"flex items-center gap-3",children:[oe(ne,{src:"/broken-url.jpg",name:"Fallback User",size:"md"}),oe(ne,{name:"No Image",size:"md"}),oe(ne,{size:"md"})]})}]});import{clsx as ga}from"clsx";import{cloneElement as ba,isValidElement as va,useCallback as it,useEffect as gn,useId as ha,useLayoutEffect as ya,useRef as rt,useState as Dt}from"react";import{createPortal as wa}from"react-dom";import{Fragment as Da,jsx as kt,jsxs as yn}from"react/jsx-runtime";var Ze=6,bn=8,st=4,xa={top:"bottom",bottom:"top",left:"right",right:"left"},Na={top:{left:"50%",top:"100%",transform:"translateX(-50%)"},bottom:{left:"50%",top:-Ze,transform:"translateX(-50%) rotate(180deg)"},left:{top:"50%",left:"100%",transform:"translateY(-50%) rotate(-90deg)"},right:{top:"50%",left:-Ze,transform:"translateY(-50%) rotate(90deg)"}};function vn(e,t,n,o){switch(e){case"top":return{top:t.top-n.height-o,left:t.left+t.width/2-n.width/2};case"bottom":return{top:t.bottom+o,left:t.left+t.width/2-n.width/2};case"left":return{top:t.top+t.height/2-n.height/2,left:t.left-n.width-o};case"right":return{top:t.top+t.height/2-n.height/2,left:t.right+o}}}function hn(e,t){let n=window.innerWidth,o=window.innerHeight;return e.top>=0&&e.left>=0&&e.top+t.height<=o&&e.left+t.width<=n}function Sa(e,t,n,o){let a=o?bn+Ze:bn,i=vn(n,e,t,a),r=n,p=i;if(!hn(i,t)){let m=xa[n],g=vn(m,e,t,a);hn(g,t)&&(r=m,p=g)}let c=window.innerWidth,s=window.innerHeight,u=Math.max(st,Math.min(p.left,c-t.width-st)),l=Math.max(st,Math.min(p.top,s-t.height-st));return{placement:r,top:l,left:u}}function Ta(e,t){return n=>{e.current=n;let o=t.props.ref;typeof o=="function"?o(n):o&&typeof o=="object"&&"current"in o&&(o.current=n)}}var Ca={compact:"px-2 py-1 text-[11px] max-w-[200px]",default:"px-3 py-2 text-xs max-w-xs"};function fe({content:e,placement:t="top",density:n="default",showDelay:o=300,hideDelay:a=150,arrow:i=!0,renderArrow:r,className:p,children:c}){let[s,u]=Dt(!1),[l,m]=Dt(null),[g,w]=Dt(t),M=rt(null),v=rt(null),h=rt(void 0),D=rt(void 0),N=ha(),z=it(()=>{clearTimeout(h.current),clearTimeout(D.current)},[]),S=it(()=>{z(),h.current=setTimeout(()=>u(!0),o)},[z,o]),W=it(()=>{z(),D.current=setTimeout(()=>u(!1),a)},[z,a]),G=it(I=>{I.key==="Escape"&&s&&u(!1)},[s]);if(ya(()=>{if(!s||!M.current||!v.current)return;function I(){if(!M.current||!v.current)return;let f=M.current.getBoundingClientRect(),k=v.current.getBoundingClientRect(),Z=Sa(f,k,t,i),Me=document.body.getBoundingClientRect();m({top:Z.top+window.scrollY-Me.top,left:Z.left+window.scrollX-Me.left}),w(Z.placement)}return I(),window.addEventListener("scroll",I,!0),window.addEventListener("resize",I),()=>{window.removeEventListener("scroll",I,!0),window.removeEventListener("resize",I)}},[s,t,i]),gn(()=>{if(s)return document.addEventListener("keydown",G),()=>document.removeEventListener("keydown",G)},[s,G]),gn(()=>z,[z]),!va(c))return c;let q=ba(c,{ref:Ta(M,c),"data-state":s?"open":"closed",onMouseEnter:I=>{S();let f=c.props.onMouseEnter;f?.(I)},onMouseLeave:I=>{W();let f=c.props.onMouseLeave;f?.(I)},onFocus:I=>{S();let f=c.props.onFocus;f?.(I)},onBlur:I=>{W();let f=c.props.onBlur;f?.(I)},"aria-describedby":s?N:void 0});return yn(Da,{children:[q,s&&wa(yn("div",{ref:v,id:N,role:"tooltip","data-state":s?"open":"closed","data-placement":g,"data-density":n,className:ga("ui-tooltip absolute z-[9999] rounded-lg leading-relaxed",Ca[n],"animate-[tooltip-in_0.15s_var(--ease-standard)]",p),style:l?{top:l.top,left:l.left}:{position:"fixed",visibility:"hidden"},onMouseEnter:S,onMouseLeave:W,children:[e,i&&kt("span",{className:"ui-tooltip__arrow absolute",style:Na[g],children:r?r({placement:g}):kt("svg",{width:Ze*2,height:Ze,viewBox:"0 0 12 6",children:kt("path",{d:"M0 0l6 6 6-6z",fill:"currentColor"})})})]}),document.body)]})}import{Settings as ka}from"lucide-react";import{jsx as A,jsxs as Pt}from"react/jsx-runtime";y({group:"feedback",componentId:"tooltip",componentName:"Tooltip",description:"Hover/focus-triggered floating label. Token-driven: --tooltip-bg, --tooltip-border, --tooltip-text, --tooltip-shadow, --tooltip-arrow-color.",props:[{name:"content",type:"ReactNode",description:"Tooltip content shown on hover/focus."},{name:"placement",type:"'top' | 'bottom' | 'left' | 'right'",default:"'top'",description:"Preferred placement. Auto-flips if clipped by viewport."},{name:"density",type:"'compact' | 'default'",default:"'default'",description:"Controls padding and max-width. Compact is tighter for icon labels."},{name:"showDelay",type:"number",default:"300",description:"Delay in ms before showing."},{name:"hideDelay",type:"number",default:"150",description:"Delay in ms before hiding."},{name:"arrow",type:"boolean",default:"true",description:"Whether to show the directional arrow."},{name:"children",type:"ReactElement",description:"Trigger element."}],stories:[{id:"placements",title:"Placements",description:"top / bottom / left / right \u2014 hover each button.",render:()=>Pt("div",{className:"flex flex-wrap items-center justify-center gap-4 py-12",children:[A(fe,{content:"Placed on top",placement:"top",children:A(d,{variant:"secondary",size:"sm",children:"Top"})}),A(fe,{content:"Placed on bottom",placement:"bottom",children:A(d,{variant:"secondary",size:"sm",children:"Bottom"})}),A(fe,{content:"Placed on left",placement:"left",children:A(d,{variant:"secondary",size:"sm",children:"Left"})}),A(fe,{content:"Placed on right",placement:"right",children:A(d,{variant:"secondary",size:"sm",children:"Right"})})]})},{id:"density",title:"Density",description:"compact vs default \u2014 compact is tighter for icon labels.",render:()=>Pt("div",{className:"flex flex-wrap items-center justify-center gap-6 py-12",children:[A(fe,{content:"Compact tooltip",density:"compact",children:A(d,{variant:"secondary",size:"sm",children:"Compact"})}),A(fe,{content:"Default density tooltip with more room for content",density:"default",children:A(d,{variant:"secondary",size:"sm",children:"Default"})})]})},{id:"rich-content",title:"Rich Content",description:"Tooltip supports ReactNode content.",render:()=>A("div",{className:"flex justify-center py-8",children:A(fe,{content:Pt("div",{children:[A("p",{className:"font-medium",children:"Keyboard shortcut"}),A("p",{className:"mt-1 opacity-80",children:"Press Ctrl+S to save your work."})]}),children:A(d,{variant:"secondary",size:"sm",children:"Hover for shortcut"})})})},{id:"on-icon-button",title:"On IconButton",description:"Common pattern: tooltip on icon-only buttons.",render:()=>A("div",{className:"flex justify-center py-8",children:A(fe,{content:"Settings",density:"compact",children:A(Y,{label:"Settings",icon:A(ka,{size:16})})})})},{id:"no-arrow",title:"Without Arrow",render:()=>A("div",{className:"flex justify-center py-8",children:A(fe,{content:"No arrow variant",arrow:!1,children:A(d,{variant:"secondary",size:"sm",children:"Hover me"})})})}]});import{useState as $a}from"react";import{clsx as ke}from"clsx";import{Children as Pa,cloneElement as Ma,createContext as wn,isValidElement as Ia,useCallback as Q,useContext as Mt,useEffect as Re,useId as lt,useLayoutEffect as Ba,useMemo as ct,useRef as De,useState as Je}from"react";import{createPortal as Ra}from"react-dom";import{jsx as ae,jsxs as Cn}from"react/jsx-runtime";var xn=wn(null),It=wn(null);function Bt(e){let t=Mt(xn);if(!t)throw new Error(`${e} must be used within DropdownMenu.`);return t}function Nn(e){let t=Mt(It);if(!t)throw new Error(`${e} must be used within DropdownMenu.Content.`);return t}function Ve(e,t){return n=>{e?.(n),t(n)}}function Sn(...e){return t=>{for(let n of e)n&&(typeof n=="function"?n(t):n.current=t)}}function dt(e){return typeof e=="string"||typeof e=="number"?String(e):Array.isArray(e)?e.map(dt).join(" "):!e||typeof e=="boolean"?"":Ia(e)?dt(e.props.children):""}function La(e){return[...e].sort((t,n)=>{let o=t.ref.current,a=n.ref.current;if(!o||!a)return 0;let i=o.compareDocumentPosition(a);return i&Node.DOCUMENT_POSITION_FOLLOWING?-1:i&Node.DOCUMENT_POSITION_PRECEDING?1:0})}function za(e){let{anchorRect:t,contentRect:n,sideOffset:o,alignOffset:a,collisionPadding:i}=e,r=window.innerWidth,p=window.innerHeight;function c(v,h){let D=0,N=0;return v==="bottom"?(D=t.bottom+o,h==="start"?N=t.left+a:h==="end"?N=t.right-n.width+a:N=t.left+(t.width-n.width)/2+a):v==="top"?(D=t.top-n.height-o,h==="start"?N=t.left+a:h==="end"?N=t.right-n.width+a:N=t.left+(t.width-n.width)/2+a):v==="right"?(N=t.right+o,h==="start"?D=t.top+a:h==="end"?D=t.bottom-n.height+a:D=t.top+(t.height-n.height)/2+a):(N=t.left-n.width-o,h==="start"?D=t.top+a:h==="end"?D=t.bottom-n.height+a:D=t.top+(t.height-n.height)/2+a),{top:D,left:N}}let s={top:"bottom",bottom:"top",left:"right",right:"left"},u=e.side,l=e.align,m=c(u,l);if(m.left<i||m.top<i||m.left+n.width>r-i||m.top+n.height>p-i){let v=c(s[u],l);v.left>=i&&v.top>=i&&v.left+n.width<=r-i&&v.top+n.height<=p-i&&(u=s[u],m=v)}let w=r-n.width-i,M=p-n.height-i;return m.left=Math.max(i,Math.min(m.left,w)),m.top=Math.max(i,Math.min(m.top,M)),{top:m.top,left:m.left,side:u,align:l}}function Tn({open:e,defaultOpen:t=!1,onOpenChange:n,side:o="bottom",align:a="start",sideOffset:i=8,alignOffset:r=0,collisionPadding:p=8,portal:c=!0,contentRole:s="menu",children:u}){let l=Mt(It),[m,g]=Je(t),w=e!==void 0,M=w?e:m,v=De(null),h=De(null),D=De("selected"),N=lt(),z=lt(),S=Q(k=>{w||g(k),n?.(k)},[w,n]),W=Q(()=>{S(!1)},[S]),G=Q(()=>{S(!1),l?.closeTree()},[l,S]),q=Q(()=>{S(!M)},[M,S]),I=Q(()=>{v.current?.focus()},[]),f=ct(()=>({open:M,setOpen:S,toggleOpen:q,triggerRef:v,contentRef:h,side:o,align:a,sideOffset:i,alignOffset:r,collisionPadding:p,portal:c,contentRole:s,triggerId:N,contentId:z,focusIntentRef:D,parentList:l,isSubmenu:!!l,closeSelf:W,closeTree:G,focusTrigger:I}),[M,a,r,W,G,p,s,l,c,S,o,i,q,N,z,I]);return ae(xn.Provider,{value:f,children:u})}function Ea({asChild:e=!1,disabled:t=!1,className:n,children:o}){let{open:a,setOpen:i,toggleOpen:r,triggerRef:p,contentRole:c,triggerId:s,contentId:u,focusIntentRef:l,isSubmenu:m}=Bt("DropdownMenu.Trigger"),g=Pa.only(o),w=g.props??{},M=typeof w.className=="string"?w.className:void 0,v={id:s,"data-state":a?"open":"closed","aria-expanded":a,"aria-haspopup":c,"aria-controls":a?u:void 0,onClick:Ve(w.onClick,h=>{if(t){h.preventDefault();return}l.current="selected",r()}),onKeyDown:Ve(w.onKeyDown,h=>{t||(h.key==="ArrowDown"?(h.preventDefault(),l.current="first",i(!0)):h.key==="ArrowUp"?(h.preventDefault(),l.current="last",i(!0)):!m&&(h.key==="Enter"||h.key===" ")&&(h.preventDefault(),l.current="selected",r()))})};return e?Ma(g,{...v,ref:Sn(p,w.ref),className:ke(n,M),type:g.type==="button"?w.type??"button":w.type}):ae("button",{ref:p,disabled:t,type:"button",className:ke("ui-dropdown-menu__trigger",n),...v,children:g})}function Aa({className:e,children:t,style:n,matchTriggerWidth:o=!1,maxHeight:a=320,...i}){let{open:r,setOpen:p,triggerRef:c,contentRef:s,side:u,align:l,sideOffset:m,alignOffset:g,collisionPadding:w,portal:M,contentRole:v,triggerId:h,contentId:D,focusIntentRef:N,parentList:z,isSubmenu:S,closeSelf:W,closeTree:G,focusTrigger:q}=Bt("DropdownMenu.Content"),I=De([]),[f,k]=Je(null),[Z,Me]=Je(null),[je,Bn]=Je(null),[mt,Rn]=Je(!1),ft=De(""),Le=De(null),zt=Q(x=>(I.current=[...I.current.filter(O=>O.id!==x.id),x],()=>{I.current=I.current.filter(O=>O.id!==x.id)}),[]),le=Q(()=>La(I.current),[]),Et=Q(x=>{N.current=x},[N]);Re(()=>{Rn(!0)},[]);let Ln=ct(()=>({role:v,highlightedId:f,setHighlightedId:k,registerItem:zt,getItems:le,requestFocusIntent:Et,closeTree:G,closeSelf:W,focusTrigger:q,activeSubmenuId:Z,setActiveSubmenuId:Me,contentRef:s}),[Z,W,G,s,v,q,le,f,zt,Et]),ze=Q(()=>{if(!c.current||!s.current)return;let x=c.current.getBoundingClientRect(),O=s.current.getBoundingClientRect();Bn(za({anchorRect:x,contentRect:O,side:u,align:l,sideOffset:m,alignOffset:g,collisionPadding:w}))},[l,g,w,s,u,m,c]);Ba(()=>{if(!(!r||!mt))return ze(),window.addEventListener("resize",ze),window.addEventListener("scroll",ze,!0),()=>{window.removeEventListener("resize",ze),window.removeEventListener("scroll",ze,!0)}},[mt,r,ze]),Re(()=>{if(!r){k(null),Me(null);return}let x=le().filter(C=>!C.disabled);if(x.length===0)return;let O=x[0];N.current==="last"?O=x[x.length-1]:N.current==="selected"&&(O=x.find(C=>C.selected)??x[0]),k(O.id),requestAnimationFrame(()=>{s.current?.focus(),O.ref.current?.scrollIntoView({block:"nearest"})})},[s,N,le,r]),Re(()=>{if(!r)return;function x(O){let C=O.target,X=c.current?.contains(C),ye=s.current?.contains(C);if(!X&&!ye){let ge=z?.contentRef.current?.contains(C);if(S&&ge){W(),z?.setActiveSubmenuId(null);return}G()}}return document.addEventListener("mousedown",x),()=>document.removeEventListener("mousedown",x)},[W,G,s,S,r,z,c]),Re(()=>{if(r)return()=>{Le.current&&clearTimeout(Le.current)}},[r]);let Ne=Q(x=>{if(k(x),!x){Me(null);return}le().find(C=>C.id===x)?.submenu||Me(null)},[le]),gt=Q((x,O="first")=>{let C=le().filter(we=>!we.disabled);if(C.length===0)return;let X=C.findIndex(we=>we.id===f);if(X===-1){Ne(O==="last"?C[C.length-1].id:C[0].id);return}let ye=(X+x+C.length)%C.length,ge=C[ye];Ne(ge.id),ge.ref.current?.scrollIntoView({block:"nearest"})},[le,f,Ne]),At=Q(x=>{let O=x.length===1?x.toLowerCase():"";if(!O)return;Le.current&&clearTimeout(Le.current),ft.current+=O,Le.current=setTimeout(()=>{ft.current="",Le.current=null},350);let C=le().filter(we=>!we.disabled);if(C.length===0)return;let X=C.findIndex(we=>we.id===f),ge=(X>=0?[...C.slice(X+1),...C.slice(0,X+1)]:C).find(we=>we.textValue.toLowerCase().startsWith(ft.current));ge&&(Ne(ge.id),ge.ref.current?.scrollIntoView({block:"nearest"}))},[le,f,Ne]),zn=Q(x=>{let O=le(),C=O.find(X=>X.id===f)??null;switch(x.key){case"ArrowDown":x.preventDefault(),gt(1);break;case"ArrowUp":x.preventDefault(),gt(-1,"last");break;case"Home":x.preventDefault();{let X=O.find(ye=>!ye.disabled);X&&Ne(X.id)}break;case"End":x.preventDefault();{let X=O.filter(ge=>!ge.disabled),ye=X[X.length-1];ye&&Ne(ye.id)}break;case"Enter":case" ":C&&!C.disabled&&(x.preventDefault(),C.click());break;case"ArrowRight":C?.submenu&&(x.preventDefault(),C.openSubmenu?.());break;case"ArrowLeft":S&&(x.preventDefault(),W(),q(),z?.setActiveSubmenuId(null));break;case"Tab":G();break;case"Escape":x.preventDefault(),W(),q(),S&&z?.setActiveSubmenuId(null);break;default:At(x.key)}},[W,G,q,le,At,f,Ne,S,gt,z]);if(!r||!mt)return null;let Ht=ae(It.Provider,{value:Ln,children:ae("div",{ref:s,id:D,role:v,tabIndex:-1,"aria-labelledby":v==="menu"?h:void 0,"data-state":"open","data-side":je?.side??u,"data-align":je?.align??l,className:ke("ui-dropdown-menu__content",S&&"ui-dropdown-menu__content--submenu",e),style:{...n,position:"fixed",top:je?.top??0,left:je?.left??0,maxHeight:a,minWidth:o?c.current?.getBoundingClientRect().width:void 0},onKeyDown:zn,...i,children:t})});return M?Ra(Ht,document.body):Ht}function Ha({className:e,children:t,...n}){return ae("div",{className:ke("ui-dropdown-menu__group",e),...n,children:t})}function Oa({className:e,children:t,...n}){return ae("div",{className:ke("ui-dropdown-menu__label",e),...n,children:t})}function _a({className:e,...t}){return ae("div",{role:"separator",className:ke("ui-dropdown-menu__separator",e),...t})}function Fa({className:e,children:t,inset:n=!1,disabled:o=!1,selected:a=!1,destructive:i=!1,closeOnSelect:r=!0,shortcut:p,indicator:c,onSelect:s,onMouseEnter:u,onClick:l,...m}){let g=lt(),w=De(null),{role:M,highlightedId:v,setHighlightedId:h,registerItem:D,closeTree:N,setActiveSubmenuId:z}=Nn("DropdownMenu.Item"),S=ct(()=>dt(t),[t]),W=v===g,G=Q(()=>{o||(s?.(),r&&N())},[r,N,o,s]);return Re(()=>D({id:g,ref:w,disabled:o,submenu:!1,selected:a,textValue:S,closeOnSelect:r,click:G}),[r,o,G,g,D,a,S]),Cn("button",{ref:w,id:g,type:"button",role:M==="listbox"?"option":"menuitem",tabIndex:-1,disabled:o,"aria-selected":M==="listbox"?a:void 0,"data-highlighted":W||void 0,"data-selected":a||void 0,"data-disabled":o||void 0,"data-destructive":i||void 0,className:ke("ui-dropdown-menu__item",n&&"ui-dropdown-menu__item--inset",e),onMouseEnter:Ve(u,()=>{o||(h(g),z(null))}),onClick:Ve(l,q=>{q.preventDefault(),G()}),...m,children:[ae("span",{className:"ui-dropdown-menu__item-main",children:t}),p?ae("span",{className:"ui-dropdown-menu__shortcut",children:p}):null,a?ae("span",{className:"ui-dropdown-menu__indicator",children:c??"\u2713"}):null]})}function Va(e){return ae(Tn,{side:"right",align:"start",sideOffset:6,...e,contentRole:"menu"})}function Wa({className:e,children:t,inset:n=!1,disabled:o=!1,destructive:a=!1,shortcut:i,onSelect:r,onMouseEnter:p,onClick:c,...s}){let u=lt(),l=De(null),m=Bt("DropdownMenu.SubTrigger"),{highlightedId:g,setHighlightedId:w,registerItem:M,setActiveSubmenuId:v,activeSubmenuId:h}=Nn("DropdownMenu.SubTrigger"),D=ct(()=>dt(t),[t]),N=g===u,z=m.open&&h===u,S=Q(()=>{o||(m.focusIntentRef.current="first",w(u),v(u),m.setOpen(!0))},[o,u,v,w,m]);return Re(()=>M({id:u,ref:l,disabled:o,submenu:!0,selected:!1,textValue:D,closeOnSelect:!1,click:S,openSubmenu:S}),[o,u,S,M,D]),Re(()=>{h!==u&&m.open&&m.setOpen(!1)},[h,u,m]),Cn("button",{ref:Sn(l,m.triggerRef),id:m.triggerId,type:"button",role:"menuitem",tabIndex:-1,"aria-haspopup":"menu","aria-expanded":m.open,"aria-controls":m.open?m.contentId:void 0,"data-highlighted":N||void 0,"data-state":z?"open":"closed","data-disabled":o||void 0,"data-destructive":a||void 0,className:ke("ui-dropdown-menu__item ui-dropdown-menu__sub-trigger",n&&"ui-dropdown-menu__item--inset",e),onMouseEnter:Ve(p,()=>{S()}),onClick:Ve(c,W=>{W.preventDefault(),S(),r?.()}),...s,children:[ae("span",{className:"ui-dropdown-menu__item-main",children:t}),i?ae("span",{className:"ui-dropdown-menu__shortcut",children:i}):null,ae("span",{className:"ui-dropdown-menu__submenu-indicator","aria-hidden":"true",children:"\u203A"})]})}var Ga=Object.assign(Tn,{Trigger:Ea,Content:Aa,Group:Ha,Label:Oa,Item:Fa,Separator:_a,Submenu:Va,SubTrigger:Wa}),E=Ga;import{jsx as V,jsxs as he}from"react/jsx-runtime";function Ua(){return V("div",{className:"flex min-h-52 items-start justify-start pb-48",children:he(E,{align:"start",children:[V(E.Trigger,{asChild:!0,children:V("button",{className:"rounded-lg border border-[var(--ui-surface-border)] bg-[var(--ui-surface-bg)] px-3 py-2 text-sm font-medium text-[var(--ui-text-primary)]",children:"Workspace"})}),he(E.Content,{children:[he(E.Group,{children:[V(E.Item,{children:"Open settings"}),V(E.Item,{children:"Duplicate workspace"})]}),V(E.Separator,{}),he(E.Submenu,{children:[V(E.SubTrigger,{children:"Theme"}),he(E.Content,{children:[V(E.Item,{children:"Light"}),V(E.Item,{selected:!0,children:"Elevated"}),V(E.Item,{children:"Glass"})]})]}),V(E.Separator,{}),V(E.Item,{destructive:!0,children:"Delete workspace"})]})]})})}function Ka(){let[e,t]=$a("gpt-4.1-mini");return V("div",{className:"flex min-h-64 items-end pb-44",children:he(E,{contentRole:"listbox",side:"top",align:"end",children:[V(E.Trigger,{asChild:!0,children:he("button",{className:"inline-flex items-center gap-2 rounded-lg border border-[var(--ui-surface-border)] bg-[var(--ui-surface-bg)] px-3 py-2 text-sm text-[var(--ui-text-primary)]",children:[V("span",{children:e}),V("span",{className:"text-xs text-[var(--ui-text-muted)]",children:"\u25BC"})]})}),he(E.Content,{className:"w-64",children:[he(E.Group,{children:[V(E.Label,{children:"OpenAI"}),["gpt-4.1-mini","gpt-4.1","o4-mini"].map(n=>V(E.Item,{selected:n===e,onSelect:()=>t(n),children:n},n))]}),he(E.Group,{children:[V(E.Label,{children:"Custom"}),["claude-sonnet-4","gemini-2.5-pro"].map(n=>V(E.Item,{selected:n===e,onSelect:()=>t(n),children:n},n))]})]})]})})}y({group:"actions",componentId:"dropdown-menu",componentName:"DropdownMenu",description:"Industrial dropdown primitive for action menus, grouped pickers, and nested submenus.",props:[{name:"open",type:"boolean",description:"Controlled open state."},{name:"defaultOpen",type:"boolean",description:"Initial open state for uncontrolled usage."},{name:"onOpenChange",type:"(open: boolean) => void",description:"Open-state change callback."},{name:"side",type:"'top' | 'bottom' | 'left' | 'right'",default:"'bottom'",description:"Preferred content side."},{name:"align",type:"'start' | 'center' | 'end'",default:"'start'",description:"Alignment relative to trigger."},{name:"contentRole",type:"'menu' | 'listbox'",default:"'menu'",description:"Semantic role for action menus vs pickers."}],stories:[{id:"actions",title:"Action Menu",description:"Standard action menu with submenu and destructive item.",render:()=>V(Ua,{})},{id:"picker",title:"Grouped Picker",description:"Model-picker style listbox with selected state.",render:()=>V(Ka,{})}]});import{useState as Ya}from"react";import{clsx as Dn}from"clsx";import{Fragment as qa,jsx as kn,jsxs as Xa}from"react/jsx-runtime";function Rt({as:e="aside",open:t,children:n,side:o="right",position:a="fixed",showBackdrop:i=!0,onClose:r,closeLabel:p="\u5173\u95ED\u62BD\u5C49",backdropClassName:c,className:s,...u}){let l=o==="left"?"-translate-x-full":"translate-x-full",m=o==="left"?"left-0 top-0":"right-0 top-0",g=a==="fixed"?"fixed":"absolute";return Xa(qa,{children:[i&&t&&r&&kn("button",{type:"button","aria-label":p,"data-state":"open",className:Dn("ui-drawer-backdrop inset-0 z-10",g,c),onClick:r}),kn(e,{"aria-hidden":!t,"data-state":t?"open":"closed","data-side":o,className:Dn("ui-drawer",g,m,"z-20 flex max-w-full transform flex-col transition-transform duration-200 ease-in-out",t?"pointer-events-auto visible translate-x-0":`pointer-events-none invisible ${l}`,s),...u,children:n})]})}import{jsx as U,jsxs as Pe}from"react/jsx-runtime";function Lt({side:e="right",showBackdrop:t=!0}){let[n,o]=Ya(!1);return Pe("div",{className:"relative h-[26rem] overflow-hidden rounded-xl border border-[var(--color-surface-border)] bg-[var(--color-surface-canvas)]",children:[U("div",{className:"flex h-full items-center justify-center",children:U(d,{variant:"primary",size:"sm",onClick:()=>o(!0),children:"Open Drawer"})}),U(Rt,{open:n,onClose:()=>o(!1),side:e,position:"absolute",showBackdrop:t,"aria-label":"Post settings",className:"h-full w-80 max-w-full border-l",children:Pe("div",{className:"flex h-full flex-col",children:[Pe("div",{className:"flex items-center justify-between border-b border-[var(--panel-section-border,var(--color-surface-border))] px-4 py-3",children:[U("span",{className:"text-sm font-semibold text-n800",children:"Post Settings"}),U(d,{variant:"ghost",size:"sm",onClick:()=>o(!1),children:"Close"})]}),Pe("div",{className:"flex-1 space-y-3 overflow-y-auto p-4",children:[U("p",{className:"text-sm text-n600",children:"Drawer now uses --drawer-surface, --drawer-border, and --drawer-shadow tokens from CSS."}),U("div",{className:"rounded-lg border border-[var(--color-surface-border)] bg-[var(--color-surface-base)] p-3 text-sm text-n700",children:"Forms, filters, or settings can go here."})]}),Pe("div",{className:"flex justify-end gap-2 border-t border-[var(--panel-section-border,var(--color-surface-border))] px-4 py-3",children:[U(d,{variant:"ghost",size:"sm",onClick:()=>o(!1),children:"Cancel"}),U(d,{variant:"primary",size:"sm",onClick:()=>o(!1),children:"Save"})]})]})})]})}y({group:"layout",componentId:"drawer",componentName:"Drawer",description:"Sliding overlay container for left/right drawers with optional backdrop. Token-driven: --drawer-surface, --drawer-border, --drawer-shadow, --drawer-backdrop.",props:[{name:"open",type:"boolean",default:"false",description:"Controls whether the drawer is visible."},{name:"side",type:"'left' | 'right'",default:"'right'",description:"Slide-in edge."},{name:"position",type:"'fixed' | 'absolute'",default:"'fixed'",description:"Positioning mode for app shell or local preview containers."},{name:"showBackdrop",type:"boolean",default:"true",description:"Whether to render a clickable backdrop when open."},{name:"onClose",type:"() => void",description:"Called when the backdrop is clicked."}],stories:[{id:"right",title:"Right Drawer",description:"Standard right-side drawer with backdrop.",source:`<Drawer
|
|
73
|
+
}`,render:()=>Ot("div",{className:"rounded-lg border border-[var(--color-surface-border)] bg-[var(--color-surface-subtle)] px-4 py-3 text-sm text-[var(--color-n600)]",children:[j("p",{className:"font-medium text-[var(--color-n800)]",children:"ToastProvider is not yet mounted in admin layout."}),Ot("p",{className:"mt-1",children:["Add it to the layout before using useToast(). Click the ",j("strong",{children:"Code"})," button below to see the setup example."]})]})},{id:"all-tones",title:"All Tones",description:"Click buttons to trigger toasts, including the optional title layout.",render:()=>j(Ya,{})}]});import{clsx as Xa}from"clsx";import{useState as Za}from"react";import{jsx as _t}from"react/jsx-runtime";var Qa={xs:"h-6 w-6 text-[10px]",sm:"h-8 w-8 text-xs",md:"h-10 w-10 text-sm",lg:"h-14 w-14 text-lg"};function Ja(e){let t=e.trim().split(/\s+/);return t.length>=2?(t[0][0]+t[t.length-1][0]).toUpperCase():e.slice(0,2).toUpperCase()}function oe({src:e,alt:t,name:n,size:o="md",tone:a="neutral",className:r}){let[i,l]=Za(!1),d=e&&!i,s=n?Ja(n):"?";return _t("span",{"data-tone":a,className:Xa("ui-avatar inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full font-medium select-none",Qa[o],r),children:d?_t("img",{src:e,alt:t??n??"",className:"h-full w-full object-cover",onError:()=>l(!0)}):_t("span",{"aria-label":t??n,children:s})})}import{jsx as ae,jsxs as Ke}from"react/jsx-runtime";h({group:"feedback",componentId:"avatar",componentName:"Avatar",description:"User avatar with image or initials fallback. Token-driven: --avatar-bg, --avatar-text, --avatar-border.",props:[{name:"src",type:"string",description:"Image URL."},{name:"alt",type:"string",description:"Alt text for the image."},{name:"name",type:"string",description:"User name, used to derive initials fallback."},{name:"size",type:"'xs' | 'sm' | 'md' | 'lg'",default:"'md'",description:"Avatar size."},{name:"tone",type:"'neutral' | 'subtle'",default:"'neutral'",description:"Fallback background tone."}],renderPlayground:e=>ae(oe,{name:"Alice Bob",size:e.size,tone:e.tone}),stories:[{id:"sizes",title:"Sizes",description:"xs / sm / md / lg",render:()=>Ke("div",{className:"flex items-end gap-3",children:[ae(oe,{name:"Alice",size:"xs"}),ae(oe,{name:"Bob Chen",size:"sm"}),ae(oe,{name:"Carol Davis",size:"md"}),ae(oe,{name:"David",size:"lg"})]})},{id:"tones",title:"Tones",description:"neutral (default) vs subtle \u2014 applies to initials fallback.",render:()=>Ke("div",{className:"flex items-center gap-4",children:[Ke("div",{className:"text-center",children:[ae(oe,{name:"Neutral",size:"lg",tone:"neutral"}),ae("p",{className:"mt-1 text-xs text-[var(--color-n500)]",children:"neutral"})]}),Ke("div",{className:"text-center",children:[ae(oe,{name:"Subtle",size:"lg",tone:"subtle"}),ae("p",{className:"mt-1 text-xs text-[var(--color-n500)]",children:"subtle"})]})]})},{id:"with-image",title:"With Image",render:()=>Ke("div",{className:"flex items-center gap-3",children:[ae(oe,{src:"https://api.dicebear.com/9.x/initials/svg?seed=QQ",name:"Q",size:"md"}),ae(oe,{src:"https://api.dicebear.com/9.x/initials/svg?seed=AB",name:"Alice Bob",size:"lg"})]})},{id:"fallback",title:"Fallback",description:"When image fails to load, initials are shown.",render:()=>Ke("div",{className:"flex items-center gap-3",children:[ae(oe,{src:"/broken-url.jpg",name:"Fallback User",size:"md"}),ae(oe,{name:"No Image",size:"md"}),ae(oe,{size:"md"})]})}]});import{clsx as ja}from"clsx";import{autoUpdate as er,computePosition as tr,flip as nr,offset as or,shift as ar,arrow as rr}from"@floating-ui/dom";import{useCallback as Fe,useEffect as On,useId as ir,useLayoutEffect as sr,useRef as it,useState as wt}from"react";import{createPortal as lr}from"react-dom";import{Fragment as ur,jsx as Nt,jsxs as Wn}from"react/jsx-runtime";var st=6,_n=8,Fn=4,dr={compact:"px-2 py-1 text-[11px] max-w-[200px]",default:"px-3 py-2 text-xs max-w-xs"};function cr(e){return e.split("-")[0]}var Vn={top:"",bottom:"rotate(180deg)",left:"rotate(-90deg)",right:"rotate(90deg)"};function he({content:e,placement:t="top",density:n="default",showDelay:o=300,hideDelay:a=150,arrow:r=!0,renderArrow:i,className:l,children:d}){let[s,p]=wt(!1),[c,b]=wt(null),[m,f]=wt(t),[C,w]=wt({}),v=it(null),I=it(null),N=it(null),$=it(void 0),T=it(void 0),G=ir(),E=Fe(()=>{clearTimeout($.current),clearTimeout(T.current)},[]),K=Fe(()=>{E(),$.current=setTimeout(()=>p(!0),o)},[E,o]),Q=Fe(()=>{E(),p(!0)},[E]),g=Fe(()=>{E(),T.current=setTimeout(()=>p(!1),a)},[E,a]),P=Fe(pe=>{if(pe.target===v.current){K();return}Q()},[K,Q]),ce=Fe(pe=>{pe.pointerType!=="mouse"&&Q()},[Q]),ke=Fe(pe=>{pe.key==="Escape"&&s&&p(!1)},[s]);sr(()=>{if(!s||!v.current||!I.current)return;let pe=[or(r?_n+st:_n),nr({padding:Fn}),ar({padding:Fn})];return r&&N.current&&pe.push(rr({element:N.current})),er(v.current,I.current,()=>{!v.current||!I.current||tr(v.current,I.current,{placement:t,strategy:"fixed",middleware:pe}).then(({x:Ye,y:Me,placement:dt,middlewareData:Z})=>{b({top:Me,left:Ye}),f(cr(dt)),Z.arrow&&w({x:Z.arrow.x,y:Z.arrow.y})})})},[s,t,r]),On(()=>{if(s)return document.addEventListener("keydown",ke),()=>document.removeEventListener("keydown",ke)},[s,ke]),On(()=>E,[E]);let ue={position:"absolute"},Ie=m;return Ie==="top"||Ie==="bottom"?(ue.left=C.x??0,ue[Ie==="top"?"bottom":"top"]=-st,ue.transform=Vn[Ie]||void 0):(ue.top=C.y??0,ue[Ie==="left"?"right":"left"]=-st,ue.transform=Vn[Ie]),Wn(ur,{children:[Nt("span",{ref:v,"data-state":s?"open":"closed",className:"ui-tooltip-trigger inline-flex",onMouseEnter:K,onMouseLeave:g,onFocus:P,onBlur:g,onPointerDown:ce,"aria-describedby":s?G:void 0,children:d}),s&&lr(Wn("div",{ref:I,id:G,role:"tooltip","data-state":s?"open":"closed","data-placement":m,"data-density":n,className:ja("ui-tooltip fixed z-[9999] rounded-lg leading-relaxed",dr[n],"animate-[tooltip-in_0.15s_var(--ease-standard)]",l),style:c?{top:c.top,left:c.left}:{visibility:"hidden"},onMouseEnter:K,onMouseLeave:g,children:[e,r&&Nt("span",{ref:N,className:"ui-tooltip__arrow absolute",style:ue,children:i?i({placement:m}):Nt("svg",{width:st*2,height:st,viewBox:"0 0 12 6",children:Nt("path",{d:"M0 0l6 6 6-6z",fill:"currentColor"})})})]}),document.body)]})}import{Settings as pr}from"lucide-react";import{jsx as z,jsxs as Tt}from"react/jsx-runtime";h({group:"feedback",componentId:"tooltip",componentName:"Tooltip",description:"Hover/focus-triggered floating label. Token-driven: --tooltip-bg, --tooltip-border, --tooltip-text, --tooltip-shadow, --tooltip-arrow-color.",props:[{name:"content",type:"ReactNode",description:"Tooltip content shown on hover/focus."},{name:"placement",type:"'top' | 'bottom' | 'left' | 'right'",default:"'top'",description:"Preferred placement. Auto-flips if clipped by viewport."},{name:"density",type:"'compact' | 'default'",default:"'default'",description:"Controls padding and max-width. Compact is tighter for icon labels."},{name:"showDelay",type:"number",default:"300",description:"Delay in ms before showing."},{name:"hideDelay",type:"number",default:"150",description:"Delay in ms before hiding."},{name:"arrow",type:"boolean",default:"true",description:"Whether to show the directional arrow."},{name:"children",type:"ReactElement",description:"Trigger element."}],stories:[{id:"placements",title:"Placements",description:"top / bottom / left / right \u2014 hover each button.",render:()=>Tt("div",{className:"flex flex-col items-center gap-2 py-12",children:[z(he,{content:"Placed on top",placement:"top",children:z(u,{variant:"secondary",size:"sm",children:"Top"})}),Tt("div",{className:"flex items-center gap-2",children:[z(he,{content:"Placed on left",placement:"left",children:z(u,{variant:"secondary",size:"sm",children:"Left"})}),z("div",{className:"w-6"}),z(he,{content:"Placed on right",placement:"right",children:z(u,{variant:"secondary",size:"sm",children:"Right"})})]}),z(he,{content:"Placed on bottom",placement:"bottom",children:z(u,{variant:"secondary",size:"sm",children:"Bottom"})})]})},{id:"density",title:"Density",description:"compact vs default \u2014 compact is tighter for icon labels.",render:()=>Tt("div",{className:"flex flex-wrap items-center justify-center gap-6 py-12",children:[z(he,{content:"Compact tooltip",density:"compact",children:z(u,{variant:"secondary",size:"sm",children:"Compact"})}),z(he,{content:"Default density tooltip with more room for content",density:"default",children:z(u,{variant:"secondary",size:"sm",children:"Default"})})]})},{id:"rich-content",title:"Rich Content",description:"Tooltip supports ReactNode content.",render:()=>z("div",{className:"flex justify-center py-8",children:z(he,{content:Tt("div",{children:[z("p",{className:"font-medium",children:"Keyboard shortcut"}),z("p",{className:"mt-1 opacity-80",children:"Press Ctrl+S to save your work."})]}),children:z(u,{variant:"secondary",size:"sm",children:"Hover for shortcut"})})})},{id:"on-icon-button",title:"On IconButton",description:"Common pattern: tooltip on icon-only buttons.",render:()=>z("div",{className:"flex justify-center py-8",children:z(he,{content:"Settings",density:"compact",children:z(J,{label:"Settings",icon:z(pr,{size:16})})})})},{id:"no-arrow",title:"Without Arrow",render:()=>z("div",{className:"flex justify-center py-8",children:z(he,{content:"No arrow variant",arrow:!1,children:z(u,{variant:"secondary",size:"sm",children:"Hover me"})})})}]});import{useState as Ar}from"react";import{clsx as Ae}from"clsx";import{autoUpdate as mr,computePosition as fr,flip as gr,offset as br,shift as vr}from"@floating-ui/dom";import{Children as hr,cloneElement as yr,createContext as $n,isValidElement as xr,useCallback as re,useContext as Ft,useEffect as Ve,useId as Ct,useLayoutEffect as wr,useMemo as Dt,useRef as ze,useState as lt}from"react";import{createPortal as Nr}from"react-dom";import{jsx as ie,jsxs as Yn}from"react/jsx-runtime";var Gn=$n(null),Vt=$n(null);function Wt(e){let t=Ft(Gn);if(!t)throw new Error(`${e} must be used within DropdownMenu.`);return t}function Un(e){let t=Ft(Vt);if(!t)throw new Error(`${e} must be used within DropdownMenu.Content.`);return t}function qe(e,t){return n=>{e?.(n),t(n)}}function Kn(...e){return t=>{for(let n of e)n&&(typeof n=="function"?n(t):n.current=t)}}function St(e){return typeof e=="string"||typeof e=="number"?String(e):Array.isArray(e)?e.map(St).join(" "):!e||typeof e=="boolean"?"":xr(e)?St(e.props.children):""}function Tr(e){return[...e].sort((t,n)=>{let o=t.ref.current,a=n.ref.current;if(!o||!a)return 0;let r=o.compareDocumentPosition(a);return r&Node.DOCUMENT_POSITION_FOLLOWING?-1:r&Node.DOCUMENT_POSITION_PRECEDING?1:0})}function Cr(e,t){return t==="center"?e:`${e}-${t}`}function Sr(e){let t=e.split("-");return{side:t[0],align:t[1]??"center"}}function qn({open:e,defaultOpen:t=!1,onOpenChange:n,side:o="bottom",align:a="start",sideOffset:r=8,alignOffset:i=0,collisionPadding:l=8,portal:d=!0,contentRole:s="menu",children:p}){let c=Ft(Vt),[b,m]=lt(t),f=e!==void 0,C=f?e:b,w=ze(null),v=ze(null),I=ze("selected"),N=Ct(),$=Ct(),T=re(P=>{f||m(P),n?.(P)},[f,n]),G=re(()=>{T(!1)},[T]),E=re(()=>{T(!1),c?.closeTree()},[c,T]),K=re(()=>{T(!C)},[C,T]),Q=re(()=>{w.current?.focus()},[]),g=Dt(()=>({open:C,setOpen:T,toggleOpen:K,triggerRef:w,contentRef:v,side:o,align:a,sideOffset:r,alignOffset:i,collisionPadding:l,portal:d,contentRole:s,triggerId:N,contentId:$,focusIntentRef:I,parentList:c,isSubmenu:!!c,closeSelf:G,closeTree:E,focusTrigger:Q}),[C,a,i,G,E,l,s,c,d,T,o,r,K,N,$,Q]);return ie(Gn.Provider,{value:g,children:p})}function Dr({asChild:e=!1,disabled:t=!1,className:n,children:o}){let{open:a,setOpen:r,toggleOpen:i,triggerRef:l,contentRole:d,triggerId:s,contentId:p,focusIntentRef:c,isSubmenu:b}=Wt("DropdownMenu.Trigger"),m=hr.only(o),f=m.props??{},C=typeof f.className=="string"?f.className:void 0,w={id:s,"data-state":a?"open":"closed","aria-expanded":a,"aria-haspopup":d,"aria-controls":a?p:void 0,onClick:qe(f.onClick,v=>{if(t){v.preventDefault();return}c.current="selected",i()}),onKeyDown:qe(f.onKeyDown,v=>{t||(v.key==="ArrowDown"?(v.preventDefault(),c.current="first",r(!0)):v.key==="ArrowUp"?(v.preventDefault(),c.current="last",r(!0)):!b&&(v.key==="Enter"||v.key===" ")&&(v.preventDefault(),c.current="selected",i()))})};return e?yr(m,{...w,ref:Kn(l,f.ref),className:Ae(n,C),type:m.type==="button"?f.type??"button":f.type}):ie("button",{ref:l,disabled:t,type:"button",className:Ae("ui-dropdown-menu__trigger",n),...w,children:m})}function Pr({className:e,children:t,style:n,matchTriggerWidth:o=!1,maxHeight:a=320,...r}){let{open:i,setOpen:l,triggerRef:d,contentRef:s,side:p,align:c,sideOffset:b,alignOffset:m,collisionPadding:f,portal:C,contentRole:w,triggerId:v,contentId:I,focusIntentRef:N,parentList:$,isSubmenu:T,closeSelf:G,closeTree:E,focusTrigger:K}=Wt("DropdownMenu.Content"),Q=ze([]),[g,P]=lt(null),[ce,ke]=lt(null),[ue,Ie]=lt(null),[pe,Ut]=lt(!1),Ye=ze(""),Me=ze(null),dt=re(x=>(Q.current=[...Q.current.filter(_=>_.id!==x.id),x],()=>{Q.current=Q.current.filter(_=>_.id!==x.id)}),[]),Z=re(()=>Tr(Q.current),[]),Kt=re(x=>{N.current=x},[N]);Ve(()=>{Ut(!0)},[]);let eo=Dt(()=>({role:w,highlightedId:g,setHighlightedId:P,registerItem:dt,getItems:Z,requestFocusIntent:Kt,closeTree:E,closeSelf:G,focusTrigger:K,activeSubmenuId:ce,setActiveSubmenuId:ke,contentRef:s}),[ce,G,E,s,w,K,Z,g,dt,Kt]);wr(()=>!i||!pe||!d.current||!s.current?void 0:mr(d.current,s.current,()=>{!d.current||!s.current||fr(d.current,s.current,{placement:Cr(p,c),strategy:"fixed",middleware:[br({mainAxis:b,crossAxis:m}),gr({padding:f}),vr({padding:f})]}).then(({x:_,y:S,placement:q})=>{let me=Sr(q);Ie({top:S,left:_,side:me.side,align:me.align})})}),[c,m,f,s,pe,i,p,b,d]),Ve(()=>{if(!i){P(null),ke(null);return}let x=Z().filter(S=>!S.disabled);if(x.length===0)return;let _=x[0];N.current==="last"?_=x[x.length-1]:N.current==="selected"&&(_=x.find(S=>S.selected)??x[0]),P(_.id),requestAnimationFrame(()=>{s.current?.focus(),_.ref.current?.scrollIntoView({block:"nearest"})})},[s,N,Z,i]),Ve(()=>{if(!i)return;function x(_){let S=_.target,q=d.current?.contains(S),me=s.current?.contains(S);if(!q&&!me){let ye=$?.contentRef.current?.contains(S);if(T&&ye){G(),$?.setActiveSubmenuId(null);return}E()}}return document.addEventListener("mousedown",x),()=>document.removeEventListener("mousedown",x)},[G,E,s,T,i,$,d]),Ve(()=>{if(i)return()=>{Me.current&&clearTimeout(Me.current)}},[i]);let Be=re(x=>{if(P(x),!x){ke(null);return}Z().find(S=>S.id===x)?.submenu||ke(null)},[Z]),It=re((x,_="first")=>{let S=Z().filter(Te=>!Te.disabled);if(S.length===0)return;let q=S.findIndex(Te=>Te.id===g);if(q===-1){Be(_==="last"?S[S.length-1].id:S[0].id);return}let me=(q+x+S.length)%S.length,ye=S[me];Be(ye.id),ye.ref.current?.scrollIntoView({block:"nearest"})},[Z,g,Be]),qt=re(x=>{let _=x.length===1?x.toLowerCase():"";if(!_)return;Me.current&&clearTimeout(Me.current),Ye.current+=_,Me.current=setTimeout(()=>{Ye.current="",Me.current=null},350);let S=Z().filter(Te=>!Te.disabled);if(S.length===0)return;let q=S.findIndex(Te=>Te.id===g),ye=(q>=0?[...S.slice(q+1),...S.slice(0,q+1)]:S).find(Te=>Te.textValue.toLowerCase().startsWith(Ye.current));ye&&(Be(ye.id),ye.ref.current?.scrollIntoView({block:"nearest"}))},[Z,g,Be]),to=re(x=>{let _=Z(),S=_.find(q=>q.id===g)??null;switch(x.key){case"ArrowDown":x.preventDefault(),It(1);break;case"ArrowUp":x.preventDefault(),It(-1,"last");break;case"Home":x.preventDefault();{let q=_.find(me=>!me.disabled);q&&Be(q.id)}break;case"End":x.preventDefault();{let q=_.filter(ye=>!ye.disabled),me=q[q.length-1];me&&Be(me.id)}break;case"Enter":case" ":S&&!S.disabled&&(x.preventDefault(),S.click());break;case"ArrowRight":S?.submenu&&(x.preventDefault(),S.openSubmenu?.());break;case"ArrowLeft":T&&(x.preventDefault(),G(),K(),$?.setActiveSubmenuId(null));break;case"Tab":E();break;case"Escape":x.preventDefault(),G(),K(),T&&$?.setActiveSubmenuId(null);break;default:qt(x.key)}},[G,E,K,Z,qt,g,Be,T,It,$]);if(!i||!pe)return null;let Yt=ie(Vt.Provider,{value:eo,children:ie("div",{ref:s,id:I,role:w,tabIndex:-1,"aria-labelledby":w==="menu"?v:void 0,"data-state":"open","data-side":ue?.side??p,"data-align":ue?.align??c,className:Ae("ui-dropdown-menu__content",T&&"ui-dropdown-menu__content--submenu",e),style:{...n,position:"fixed",top:ue?.top??0,left:ue?.left??0,maxHeight:a,minWidth:o?d.current?.getBoundingClientRect().width:void 0},onKeyDown:to,...r,children:t})});return C?Nr(Yt,document.body):Yt}function kr({className:e,children:t,...n}){return ie("div",{className:Ae("ui-dropdown-menu__group",e),...n,children:t})}function Ir({className:e,children:t,...n}){return ie("div",{className:Ae("ui-dropdown-menu__label",e),...n,children:t})}function Mr({className:e,...t}){return ie("div",{role:"separator",className:Ae("ui-dropdown-menu__separator",e),...t})}function Br({className:e,children:t,inset:n=!1,disabled:o=!1,selected:a=!1,destructive:r=!1,closeOnSelect:i=!0,shortcut:l,indicator:d,onSelect:s,onMouseEnter:p,onClick:c,...b}){let m=Ct(),f=ze(null),{role:C,highlightedId:w,setHighlightedId:v,registerItem:I,closeTree:N,setActiveSubmenuId:$}=Un("DropdownMenu.Item"),T=Dt(()=>St(t),[t]),G=w===m,E=re(()=>{o||(s?.(),i&&N())},[i,N,o,s]);return Ve(()=>I({id:m,ref:f,disabled:o,submenu:!1,selected:a,textValue:T,closeOnSelect:i,click:E}),[i,o,E,m,I,a,T]),Yn("button",{ref:f,id:m,type:"button",role:C==="listbox"?"option":"menuitem",tabIndex:-1,disabled:o,"aria-selected":C==="listbox"?a:void 0,"data-highlighted":G||void 0,"data-selected":a||void 0,"data-disabled":o||void 0,"data-destructive":r||void 0,className:Ae("ui-dropdown-menu__item",n&&"ui-dropdown-menu__item--inset",e),onMouseEnter:qe(p,()=>{o||(v(m),$(null))}),onClick:qe(c,K=>{K.preventDefault(),E()}),...b,children:[ie("span",{className:"ui-dropdown-menu__item-main",children:t}),l?ie("span",{className:"ui-dropdown-menu__shortcut",children:l}):null,a?ie("span",{className:"ui-dropdown-menu__indicator",children:d??"\u2713"}):null]})}function Lr(e){return ie(qn,{side:"right",align:"start",sideOffset:6,...e,contentRole:"menu"})}function Rr({className:e,children:t,inset:n=!1,disabled:o=!1,destructive:a=!1,shortcut:r,onSelect:i,onMouseEnter:l,onClick:d,...s}){let p=Ct(),c=ze(null),b=Wt("DropdownMenu.SubTrigger"),{highlightedId:m,setHighlightedId:f,registerItem:C,setActiveSubmenuId:w,activeSubmenuId:v}=Un("DropdownMenu.SubTrigger"),I=Dt(()=>St(t),[t]),N=m===p,$=b.open&&v===p,T=re(()=>{o||(b.focusIntentRef.current="first",f(p),w(p),b.setOpen(!0))},[o,p,w,f,b]);return Ve(()=>C({id:p,ref:c,disabled:o,submenu:!0,selected:!1,textValue:I,closeOnSelect:!1,click:T,openSubmenu:T}),[o,p,T,C,I]),Ve(()=>{v!==p&&b.open&&b.setOpen(!1)},[v,p,b]),Yn("button",{ref:Kn(c,b.triggerRef),id:b.triggerId,type:"button",role:"menuitem",tabIndex:-1,"aria-haspopup":"menu","aria-expanded":b.open,"aria-controls":b.open?b.contentId:void 0,"data-highlighted":N||void 0,"data-state":$?"open":"closed","data-disabled":o||void 0,"data-destructive":a||void 0,className:Ae("ui-dropdown-menu__item ui-dropdown-menu__sub-trigger",n&&"ui-dropdown-menu__item--inset",e),onMouseEnter:qe(l,()=>{T()}),onClick:qe(d,G=>{G.preventDefault(),T(),i?.()}),...s,children:[ie("span",{className:"ui-dropdown-menu__item-main",children:t}),r?ie("span",{className:"ui-dropdown-menu__shortcut",children:r}):null,ie("span",{className:"ui-dropdown-menu__submenu-indicator","aria-hidden":"true",children:"\u203A"})]})}var zr=Object.assign(qn,{Trigger:Dr,Content:Pr,Group:kr,Label:Ir,Item:Br,Separator:Mr,Submenu:Lr,SubTrigger:Rr}),A=zr;import{jsx as W,jsxs as Ne}from"react/jsx-runtime";function Er(){return W("div",{className:"flex min-h-52 items-start justify-start pb-48",children:Ne(A,{align:"start",children:[W(A.Trigger,{asChild:!0,children:W("button",{className:"rounded-lg border border-[var(--ui-surface-border)] bg-[var(--ui-surface-bg)] px-3 py-2 text-sm font-medium text-[var(--ui-text-primary)]",children:"Workspace"})}),Ne(A.Content,{children:[Ne(A.Group,{children:[W(A.Item,{children:"Open settings"}),W(A.Item,{children:"Duplicate workspace"})]}),W(A.Separator,{}),Ne(A.Submenu,{children:[W(A.SubTrigger,{children:"Theme"}),Ne(A.Content,{children:[W(A.Item,{children:"Light"}),W(A.Item,{selected:!0,children:"Elevated"}),W(A.Item,{children:"Glass"})]})]}),W(A.Separator,{}),W(A.Item,{destructive:!0,children:"Delete workspace"})]})]})})}function Hr(){let[e,t]=Ar("gpt-4.1-mini");return W("div",{className:"flex min-h-64 items-end pb-44",children:Ne(A,{contentRole:"listbox",side:"top",align:"end",children:[W(A.Trigger,{asChild:!0,children:Ne("button",{className:"inline-flex items-center gap-2 rounded-lg border border-[var(--ui-surface-border)] bg-[var(--ui-surface-bg)] px-3 py-2 text-sm text-[var(--ui-text-primary)]",children:[W("span",{children:e}),W("span",{className:"text-xs text-[var(--ui-text-muted)]",children:"\u25BC"})]})}),Ne(A.Content,{className:"w-64",children:[Ne(A.Group,{children:[W(A.Label,{children:"OpenAI"}),["gpt-4.1-mini","gpt-4.1","o4-mini"].map(n=>W(A.Item,{selected:n===e,onSelect:()=>t(n),children:n},n))]}),Ne(A.Group,{children:[W(A.Label,{children:"Custom"}),["claude-sonnet-4","gemini-2.5-pro"].map(n=>W(A.Item,{selected:n===e,onSelect:()=>t(n),children:n},n))]})]})]})})}h({group:"actions",componentId:"dropdown-menu",componentName:"DropdownMenu",description:"Industrial dropdown primitive for action menus, grouped pickers, and nested submenus.",props:[{name:"open",type:"boolean",description:"Controlled open state."},{name:"defaultOpen",type:"boolean",description:"Initial open state for uncontrolled usage."},{name:"onOpenChange",type:"(open: boolean) => void",description:"Open-state change callback."},{name:"side",type:"'top' | 'bottom' | 'left' | 'right'",default:"'bottom'",description:"Preferred content side."},{name:"align",type:"'start' | 'center' | 'end'",default:"'start'",description:"Alignment relative to trigger."},{name:"contentRole",type:"'menu' | 'listbox'",default:"'menu'",description:"Semantic role for action menus vs pickers."}],stories:[{id:"actions",title:"Action Menu",description:"Standard action menu with submenu and destructive item.",render:()=>W(Er,{})},{id:"picker",title:"Grouped Picker",description:"Model-picker style listbox with selected state.",render:()=>W(Hr,{})}]});import{useState as Fr}from"react";import{clsx as Xn}from"clsx";import{Fragment as Or,jsx as Zn,jsxs as _r}from"react/jsx-runtime";function $t({as:e="aside",open:t,children:n,side:o="right",position:a="fixed",showBackdrop:r=!0,onClose:i,closeLabel:l="\u5173\u95ED\u62BD\u5C49",backdropClassName:d,className:s,...p}){let c=o==="left"?"-translate-x-full":"translate-x-full",b=o==="left"?"left-0 top-0":"right-0 top-0",m=a==="fixed"?"fixed":"absolute";return _r(Or,{children:[r&&t&&i&&Zn("button",{type:"button","aria-label":l,"data-state":"open",className:Xn("ui-drawer-backdrop inset-0 z-10",m,d),onClick:i}),Zn(e,{"aria-hidden":!t,"data-state":t?"open":"closed","data-side":o,className:Xn("ui-drawer",m,b,"z-20 flex max-w-full transform flex-col transition-transform duration-200 ease-in-out",t?"pointer-events-auto visible translate-x-0":`pointer-events-none invisible ${c}`,s),...p,children:n})]})}import{jsx as X,jsxs as Ee}from"react/jsx-runtime";function Gt({side:e="right",showBackdrop:t=!0}){let[n,o]=Fr(!1);return Ee("div",{className:"relative h-[26rem] overflow-hidden rounded-xl border border-[var(--color-surface-border)] bg-[var(--color-surface-canvas)]",children:[X("div",{className:"flex h-full items-center justify-center",children:X(u,{variant:"primary",size:"sm",onClick:()=>o(!0),children:"Open Drawer"})}),X($t,{open:n,onClose:()=>o(!1),side:e,position:"absolute",showBackdrop:t,"aria-label":"Post settings",className:"h-full w-80 max-w-full border-l",children:Ee("div",{className:"flex h-full flex-col",children:[Ee("div",{className:"flex items-center justify-between border-b border-[var(--panel-section-border,var(--color-surface-border))] px-4 py-3",children:[X("span",{className:"text-sm font-semibold text-n800",children:"Post Settings"}),X(u,{variant:"ghost",size:"sm",onClick:()=>o(!1),children:"Close"})]}),Ee("div",{className:"flex-1 space-y-3 overflow-y-auto p-4",children:[X("p",{className:"text-sm text-n600",children:"Drawer now uses --drawer-surface, --drawer-border, and --drawer-shadow tokens from CSS."}),X("div",{className:"rounded-lg border border-[var(--color-surface-border)] bg-[var(--color-surface-base)] p-3 text-sm text-n700",children:"Forms, filters, or settings can go here."})]}),Ee("div",{className:"flex justify-end gap-2 border-t border-[var(--panel-section-border,var(--color-surface-border))] px-4 py-3",children:[X(u,{variant:"ghost",size:"sm",onClick:()=>o(!1),children:"Cancel"}),X(u,{variant:"primary",size:"sm",onClick:()=>o(!1),children:"Save"})]})]})})]})}h({group:"layout",componentId:"drawer",componentName:"Drawer",description:"Sliding overlay container for left/right drawers with optional backdrop. Token-driven: --drawer-surface, --drawer-border, --drawer-shadow, --drawer-backdrop.",props:[{name:"open",type:"boolean",default:"false",description:"Controls whether the drawer is visible."},{name:"side",type:"'left' | 'right'",default:"'right'",description:"Slide-in edge."},{name:"position",type:"'fixed' | 'absolute'",default:"'fixed'",description:"Positioning mode for app shell or local preview containers."},{name:"showBackdrop",type:"boolean",default:"true",description:"Whether to render a clickable backdrop when open."},{name:"onClose",type:"() => void",description:"Called when the backdrop is clicked."}],stories:[{id:"right",title:"Right Drawer",description:"Standard right-side drawer with backdrop.",source:`<Drawer
|
|
73
74
|
open={open}
|
|
74
75
|
onClose={() => setOpen(false)}
|
|
75
76
|
side="right"
|
|
@@ -82,7 +83,7 @@ function MyComponent() {
|
|
|
82
83
|
<div className="flex-1 overflow-y-auto p-4">Body</div>
|
|
83
84
|
<div className="border-t px-4 py-3">Footer</div>
|
|
84
85
|
</div>
|
|
85
|
-
</Drawer>`,render:()=>
|
|
86
|
+
</Drawer>`,render:()=>X(Gt,{side:"right"})},{id:"left",title:"Left Drawer",description:"Left-side variant for navigation or contextual tools.",render:()=>X(Gt,{side:"left"})},{id:"without-backdrop",title:"Without Backdrop",description:"Useful inside bounded shells where overlay dimming is not desired.",render:()=>X(Gt,{side:"right",showBackdrop:!1})},{id:"floating-hierarchy",title:"Floating Hierarchy",description:"Drawers belong to the floating layer: backdrop separates context, surface defines body, shadow lifts the panel above the page.",render:()=>X("div",{className:"rounded-xl bg-[var(--color-surface-subtle)] p-5",children:Ee("div",{className:"relative h-[20rem] overflow-hidden rounded-xl border border-[var(--color-surface-border)] bg-[var(--color-surface-canvas)]",children:[X("div",{className:"absolute inset-0 bg-[var(--color-overlay-strong)]"}),Ee("div",{className:"ui-drawer absolute inset-y-0 right-0 flex w-80 max-w-full flex-col border-l",children:[X("div",{className:"border-b border-[var(--drawer-border)] px-4 py-3 text-sm font-semibold text-[var(--color-n800)]",children:"Drawer Surface"}),Ee("div",{className:"flex-1 space-y-3 p-4 text-sm text-[var(--color-n600)]",children:[X("p",{children:"Backdrop handles separation from the page."}),X("p",{children:"Surface defines the drawer body."}),X("p",{children:"Shadow confirms it is a floating layer, not a static card."})]})]})]})})}]});import{clsx as Pt}from"clsx";import{jsx as kt}from"react/jsx-runtime";function Vr(e){switch(e){case"none":return"";case"sm":return"p-4";case"lg":return"p-6";default:return"p-5"}}function be({as:e="section",variant:t="default",padding:n="none",className:o,children:a,...r}){return kt(e,{"data-variant":t,className:Pt("ui-panel rounded-lg border",Vr(n),o),...r,children:a})}function Qn({className:e,children:t,...n}){return kt("div",{className:Pt("ui-panel-header border-b px-6 py-5",e),...n,children:t})}function Jn({className:e,children:t,...n}){return kt("div",{className:Pt("px-6 py-5",e),...n,children:t})}function jn({className:e,children:t,...n}){return kt("div",{className:Pt("ui-panel-footer border-t px-6 py-4",e),...n,children:t})}import{jsx as k,jsxs as ve}from"react/jsx-runtime";h({group:"layout",componentId:"panel",componentName:"Panel",description:"Container card driven by surface hierarchy and structured sections (header/body/footer), not by blanket shadow elevation.",props:[{name:"as",type:"ElementType",default:"'section'",description:"Root element tag."},{name:"variant",type:"'default' | 'subtle' | 'raised'",default:"'default'",description:"Surface hierarchy variant. `raised` includes shadow."},{name:"padding",type:"'none' | 'sm' | 'md' | 'lg'",default:"'none'",description:"Inner padding size."}],renderPlayground:e=>k(be,{variant:e.variant,padding:e.padding,children:k("p",{className:"text-sm",children:"Panel content"})}),stories:[{id:"variants",title:"Variants",description:"default / subtle / raised \u2014 semantic feedback should use StatusNotice instead of overloading panel surface variants.",render:()=>ve("div",{className:"grid gap-4 sm:grid-cols-3",children:[ve(be,{variant:"default",padding:"md",children:[k("p",{className:"text-sm font-medium",children:"Default"}),k("p",{className:"mt-1 text-xs text-[var(--color-n500)]",children:"Standard container."})]}),ve(be,{variant:"subtle",padding:"md",children:[k("p",{className:"text-sm font-medium",children:"Subtle"}),k("p",{className:"mt-1 text-xs text-[var(--color-n500)]",children:"Reduced emphasis."})]}),ve(be,{variant:"raised",padding:"md",children:[k("p",{className:"text-sm font-medium",children:"Raised"}),k("p",{className:"mt-1 text-xs text-[var(--color-n500)]",children:"Elevated surface with shadow."})]})]})},{id:"with-sections",title:"With Sections",description:"PanelHeader + PanelBody + PanelFooter",source:`<Panel variant="default">
|
|
86
87
|
<PanelHeader>
|
|
87
88
|
<h3>Panel Title</h3>
|
|
88
89
|
</PanelHeader>
|
|
@@ -93,4 +94,4 @@ function MyComponent() {
|
|
|
93
94
|
<Button variant="ghost" size="sm">Cancel</Button>
|
|
94
95
|
<Button variant="primary" size="sm">Confirm</Button>
|
|
95
96
|
</PanelFooter>
|
|
96
|
-
</Panel>`,render:()=>
|
|
97
|
+
</Panel>`,render:()=>ve(be,{variant:"default",className:"max-w-md",children:[k(Qn,{children:k("h3",{className:"text-sm font-semibold",children:"Panel Title"})}),k(Jn,{children:k("p",{className:"text-sm text-[var(--color-n600)]",children:"This is the body content of the panel. It can contain any elements."})}),k(jn,{children:ve("div",{className:"flex justify-end gap-2",children:[k(u,{variant:"ghost",size:"sm",children:"Cancel"}),k(u,{variant:"primary",size:"sm",children:"Confirm"})]})})]})},{id:"on-surfaces",title:"On Different Surfaces",description:"Verifies panel contrast against canvas, subtle, and inset backgrounds.",render:()=>k("div",{className:"grid gap-4 sm:grid-cols-3",children:[{label:"Canvas",bg:"var(--color-surface-canvas)"},{label:"Subtle",bg:"var(--color-surface-subtle)"},{label:"Inset",bg:"var(--color-surface-inset)"}].map(({label:e,bg:t})=>ve("div",{className:"rounded-lg p-4",style:{backgroundColor:t},children:[k("p",{className:"mb-2 text-[11px] font-medium text-[var(--color-n500)]",children:e}),k(be,{variant:"default",padding:"md",children:k("p",{className:"text-sm",children:"Default panel"})})]},e))})},{id:"surface-not-shadow",title:"Surface, Not Shadow",description:"Dashboard-style panels should build depth with surface tokens first. The panel itself stays border-led instead of floating like a popover.",render:()=>k("div",{className:"rounded-xl bg-[var(--color-surface-subtle)] p-5",children:ve("div",{className:"grid gap-4 lg:grid-cols-3",children:[ve(be,{variant:"default",padding:"md",children:[k("p",{className:"text-sm font-medium",children:"Default"}),k("p",{className:"mt-1 text-xs text-[var(--color-n500)]",children:"Primary reading card."})]}),ve(be,{variant:"subtle",padding:"md",children:[k("p",{className:"text-sm font-medium",children:"Subtle"}),k("p",{className:"mt-1 text-xs text-[var(--color-n500)]",children:"Secondary summary area."})]}),ve(be,{variant:"raised",padding:"md",children:[k("p",{className:"text-sm font-medium",children:"Raised"}),k("p",{className:"mt-1 text-xs text-[var(--color-n500)]",children:"A slightly lifted surface with --panel-shadow."})]})]})})},{id:"padding",title:"Padding Sizes",description:"none / sm / md / lg",render:()=>k("div",{className:"space-y-3",children:["none","sm","md","lg"].map(e=>k(be,{variant:"default",padding:e,children:ve("span",{className:"text-xs",children:["padding=","\u201C",e,"\u201D"]})},e))})}]});export{wo as getGroupedStories,xo as getStoriesByGroupAndComponent,No as groupLabels,To as groupOrder,h as registerStories,yo as storybookStoryPaths};
|