@owodesign/owoui 0.1.1 → 0.1.2
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 +24 -5
- package/dist/index.d.ts +61 -3
- package/dist/index.min.js +1 -1
- package/dist/storybook/catalog.js +31 -1
- package/dist/storybook/catalog.json +31 -1
- package/dist/storybook/index.min.js +9 -8
- package/dist/storybook-static/app.css +4100 -0
- package/dist/storybook-static/assets/main.js +97 -0
- package/dist/storybook-static/index.html +14 -0
- package/dist/tokens.d.ts +4 -2
- package/dist/tokens.min.js +1 -1
- package/package.json +24 -14
- 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 -0
- package/src/styles/tokens.css +132 -73
- package/src/styles/ui/collapsible.css +13 -0
- package/src/styles/ui/tabs.css +33 -0
- package/src/styles/ui/textarea.css +8 -0
- package/src/theme-dark.css +87 -0
- package/src/theme-light.css +41 -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
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import{Plus as
|
|
1
|
+
import{Plus as Zt,ArrowRight as Qt}from"lucide-react";import{clsx as go}from"clsx";import{clsx as no}from"clsx";import{jsx as D,jsxs as ze}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 ze("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 ze("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=>ze("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((d,l)=>ze("circle",{cx:d,cy:i,r:t,fill:"currentColor",opacity:"0.4",children:[D("animate",{attributeName:"cy",values:`${i};${i-e*.25};${i}`,dur:"0.6s",begin:`${l*.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:`${l*.12}s`,repeatCount:"indefinite"})]},l))})}function co({px:e}){return ze("svg",{width:e,height:e,viewBox:"0 0 24 24",children:[ze("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 ze("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((d,l)=>D("circle",{cx:d,cy:i,r:t,fill:"currentColor",opacity:"0.25",children:D("animate",{attributeName:"opacity",values:"0.25;1;0.25",dur:"0.9s",begin:`${l*.2}s`,repeatCount:"indefinite"})},l))})}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 re({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)&&"motion-safe:animate-spin",n),children:D(r,{px:a})})}import{Fragment as vo,jsx as Ee,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 p(e){let{variant:t="secondary",size:n="md",loading:o=!1,leadingIcon:a,trailingIcon:r,className:i,children:d,...l}=e,s=ho(vo,{children:[o?Ee("span",{className:"shrink-0",children:Ee(re,{size:n==="sm"?"sm":"md"})}):a?Ee("span",{className:"shrink-0",children:a}):null,Ee("span",{children:d}),!o&&r?Ee("span",{className:"shrink-0",children:r}):null]}),u=bo({variant:t,size:n,loading:o,className:i});if("href"in e&&e.href){let{href:m,...f}=l;return Ee("a",{href:m,"data-variant":t,"data-size":n,"data-loading":o?"true":void 0,"aria-disabled":o||void 0,tabIndex:o?-1:void 0,className:u,onClick:o?g=>g.preventDefault():void 0,...f,children:s})}let c=l;return Ee("button",{type:c.type??"button","data-variant":t,"data-size":n,"data-loading":o?"true":void 0,disabled:c.disabled||o,className:u,...c,children:s})}var kt=[],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 y(e){kt.push(e)}function xo(e,t){return kt.find(n=>n.group===e&&n.componentId===t)}function wo(){let e={actions:[],forms:[],feedback:[],layout:[]};for(let t of kt)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 _,jsxs as Ke}from"react/jsx-runtime";y({group:"actions",componentId:"button",componentName:"Button",description:"Primary action trigger. Supports variants, sizes, icons, loading, and disabled states.",props:[{name:"variant",type:"'primary' | 'secondary' | 'ghost' | 'danger'",default:"'secondary'",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:"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."},{name:"disabled",type:"boolean",default:"false",description:"Disables the button."}],renderPlayground:e=>_(p,{variant:e.variant,size:e.size,loading:!!e.loading,disabled:!!e.disabled,children:"Button"}),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:()=>Ke("div",{className:"flex flex-wrap items-center gap-3",children:[_(p,{variant:"primary",children:"Primary"}),_(p,{variant:"secondary",children:"Secondary"}),_(p,{variant:"ghost",children:"Ghost"}),_(p,{variant:"danger",children:"Danger"})]})},{id:"sizes",title:"Sizes",description:"sm / md",render:()=>Ke("div",{className:"flex flex-wrap items-center gap-3",children:[_(p,{size:"sm",children:"Small"}),_(p,{size:"md",children:"Medium"})]})},{id:"with-icons",title:"With Icons",description:"leadingIcon / trailingIcon",render:()=>Ke("div",{className:"flex flex-wrap items-center gap-3",children:[_(p,{variant:"primary",leadingIcon:_(Zt,{size:16}),children:"Create"}),_(p,{variant:"secondary",trailingIcon:_(Qt,{size:16}),children:"Next"}),_(p,{variant:"ghost",leadingIcon:_(Zt,{size:16}),trailingIcon:_(Qt,{size:16}),children:"Both"})]})},{id:"loading-disabled",title:"Loading & Disabled",render:()=>Ke("div",{className:"flex flex-wrap items-center gap-3",children:[_(p,{variant:"primary",loading:!0,children:"Saving\u2026"}),_(p,{variant:"secondary",loading:!0,children:"Loading"}),_(p,{variant:"secondary",disabled:!0,children:"Disabled"}),_(p,{variant:"danger",disabled:!0,children:"Disabled Danger"})]})},{id:"all-variants-sm",title:"All Variants (sm)",render:()=>Ke("div",{className:"flex flex-wrap items-center gap-3",children:[_(p,{variant:"primary",size:"sm",children:"Primary"}),_(p,{variant:"secondary",size:"sm",children:"Secondary"}),_(p,{variant:"ghost",size:"sm",children:"Ghost"}),_(p,{variant:"danger",size:"sm",children:"Danger"})]})}]});import{X as qe,Settings as it,Trash2 as So,ChevronRight as Do}from"lucide-react";import{clsx as Co}from"clsx";import{jsx as Jt}from"react/jsx-runtime";function X({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:l,...s}=r;return Jt("a",{href:l,"aria-label":n,title:s.title??n,"data-variant":e,"data-size":t,className:i,...s,children:o})}let d=r;return Jt("button",{type:d.type??"button","aria-label":n,title:d.title??n,"data-variant":e,"data-size":t,className:i,...d,children:o})}import{jsx as F,jsxs as st}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(X,{variant:e.variant,size:e.size,disabled:!!e.disabled,label:"Settings",icon:F(it,{size:e.size==="sm"?14:16})}),stories:[{id:"variants",title:"Variants",description:"ghost / subtle",render:()=>st("div",{className:"flex items-center gap-3",children:[F(X,{variant:"ghost",label:"Close",icon:F(qe,{size:16})}),F(X,{variant:"subtle",label:"Settings",icon:F(it,{size:16})})]})},{id:"sizes",title:"Sizes",description:"sm / md",render:()=>st("div",{className:"flex items-center gap-3",children:[F(X,{size:"sm",label:"Small",icon:F(qe,{size:14})}),F(X,{size:"md",label:"Medium",icon:F(qe,{size:16})})]})},{id:"use-cases",title:"Use Cases",render:()=>st("div",{className:"flex items-center gap-3",children:[F(X,{label:"Close",icon:F(qe,{size:16})}),F(X,{label:"Settings",icon:F(it,{size:16})}),F(X,{label:"Delete",icon:F(So,{size:16})}),F(X,{label:"Navigate",icon:F(Do,{size:16})})]})},{id:"disabled",title:"Disabled",render:()=>st("div",{className:"flex items-center gap-3",children:[F(X,{label:"Disabled ghost",icon:F(qe,{size:16}),disabled:!0}),F(X,{variant:"subtle",label:"Disabled subtle",icon:F(it,{size:16}),disabled:!0})]})}]});import{clsx as ko}from"clsx";import{jsx as jt}from"react/jsx-runtime";function lt(e){return ko("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"?jt("textarea",{"data-tone":n,className:lt(t),...o}):jt("input",{"data-tone":n,className:lt(t),...o})}import{jsx as De,jsxs as en}from"react/jsx-runtime";y({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=>De("div",{className:"max-w-xs",children:De(de,{as:e.as,tone:e.tone,placeholder:"Type something\u2026"})}),stories:[{id:"text-input",title:"Text Input",render:()=>en("div",{className:"max-w-xs space-y-3",children:[De(de,{"aria-label":"Default input",name:"demo-default",autoComplete:"off",placeholder:"e.g., hello world\u2026"}),De(de,{"aria-label":"With value",name:"demo-value",autoComplete:"off",placeholder:"e.g., hello world\u2026",defaultValue:"Hello world"})]})},{id:"textarea",title:"Textarea",render:()=>De("div",{className:"max-w-sm",children:De(de,{as:"textarea","aria-label":"Textarea",placeholder:"Write something\u2026",rows:3})})},{id:"tones",title:"Tones",description:"default / warning",render:()=>en("div",{className:"max-w-xs space-y-3",children:[De(de,{tone:"default","aria-label":"Default tone",name:"demo-tone-default",autoComplete:"off",placeholder:"Default tone\u2026"}),De(de,{tone:"warning","aria-label":"Warning tone",name:"demo-tone-warning",autoComplete:"off",placeholder:"Warning tone\u2026"})]})}]});import{useState as Bo}from"react";import{clsx as Po}from"clsx";import{jsx as tn,jsxs as Mo}from"react/jsx-runtime";function ke({label:e,help:t,htmlFor:n,children:o,className:a,...r}){return Mo("div",{className:Po("ui-field block",a),...r,children:[tn("label",{htmlFor:n,className:"ui-field__label mb-1 block text-xs",children:e}),o,t?tn("span",{className:"ui-field__help mt-1 block text-xs",children:t}):null]})}import{clsx as Fe}from"clsx";import{useCallback as Pt,useEffect as nn,useId as Io,useMemo as Ro,useRef as on,useState as an}from"react";import{jsx as Ye,jsxs as rn}from"react/jsx-runtime";function ce({value:e,onChange:t,options:n,placeholder:o="Select\u2026",size:a="md",tone:r="default",disabled:i=!1,className:d,ariaLabel:l,renderValue:s,renderOption:u}){let[c,m]=an(!1),[f,g]=an(-1),N=on(null),h=on(null),v=Io(),S=n.find(b=>b.value===e),x=Ro(()=>n.reduce((b,P,Q)=>(P.disabled||b.push(Q),b),[]),[n]),z=Pt(()=>{if(i||n.length===0)return;m(!0);let b=n.findIndex(P=>P.value===e);g(b>=0?b:x[0]??-1)},[i,n,e,x]),C=Pt(()=>{m(!1),g(-1)},[]),W=Pt(b=>{b.disabled||(t(b.value),C())},[t,C]);nn(()=>{if(!c)return;function b(P){N.current&&!N.current.contains(P.target)&&C()}return document.addEventListener("mousedown",b),()=>document.removeEventListener("mousedown",b)},[c,C]),nn(()=>{if(!c||f<0)return;h.current?.children[f]?.scrollIntoView({block:"nearest"})},[c,f]);function $(b){if(!i)switch(b.key){case"Enter":case" ":{b.preventDefault(),c?f>=0&&n[f]&&!n[f].disabled&&W(n[f]):z();break}case"ArrowDown":{if(b.preventDefault(),!c)z();else{let P=x.indexOf(f),Q=x[P+1];Q!==void 0&&g(Q)}break}case"ArrowUp":{if(b.preventDefault(),!c)z();else{let P=x.indexOf(f),Q=x[P-1];Q!==void 0&&g(Q)}break}case"Escape":{c&&(b.preventDefault(),C());break}case"Tab":{c&&C();break}}}let q=e!==""&&S,I=s?s({open:c,placeholder:o,selectedOption:S}):Ye("span",{className:Fe("truncate",!q&&"ui-select__placeholder"),children:q?S.label:o});return rn("div",{ref:N,"data-state":c?"open":"closed","data-disabled":i||void 0,"data-size":a,"data-tone":r,className:Fe("ui-select relative inline-block",d),children:[rn("button",{type:"button",role:"combobox","aria-expanded":c,"aria-haspopup":"listbox","aria-controls":v,"aria-label":l,"aria-activedescendant":c&&f>=0?`${v}-opt-${f}`: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":q||void 0,disabled:i,className:Fe("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:()=>c?C():z(),onKeyDown:$,children:[I,Ye("svg",{"aria-hidden":"true",className:Fe("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:Ye("path",{d:"M4 6l4 4 4-4"})})]}),c&&Ye("ul",{ref:h,id:v,role:"listbox","aria-label":l,"data-state":"open",className:Fe("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((b,P)=>Ye("li",{id:`${v}-opt-${P}`,role:"option","aria-selected":b.value===e,"aria-disabled":b.disabled||void 0,"data-state":b.value===e?"selected":P===f?"highlighted":"idle","data-focused":P===f||void 0,"data-selected":b.value===e||void 0,"data-disabled":b.disabled||void 0,"data-highlighted":P===f||void 0,className:Fe("ui-select__option cursor-default select-none px-3 py-1.5 transition-colors",b.disabled&&"cursor-not-allowed opacity-50"),onClick:()=>W(b),onMouseEnter:()=>!b.disabled&&g(P),children:u?u({option:b,index:P,selected:b.value===e,highlighted:P===f}):b.label},b.value))})]})}import{jsx as ie}from"react/jsx-runtime";function Lo(){let[e,t]=Bo("");return ie("div",{className:"max-w-xs pb-36",children:ie(ke,{label:"Category",htmlFor:"sb-category",children:ie(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:()=>ie("div",{className:"max-w-xs",children:ie(ke,{label:"Username",htmlFor:"sb-username",children:ie(de,{id:"sb-username",name:"username",autoComplete:"username",placeholder:"Enter username"})})})},{id:"with-help",title:"With Help Text",render:()=>ie("div",{className:"max-w-xs",children:ie(ke,{label:"Email",htmlFor:"sb-email",help:"We'll never share your email.",children:ie(de,{id:"sb-email",type:"email",name:"email",autoComplete:"email",spellCheck:!1,placeholder:"you@example.com"})})})},{id:"with-textarea",title:"With Textarea",render:()=>ie("div",{className:"max-w-sm",children:ie(ke,{label:"Bio",htmlFor:"sb-bio",help:"Brief description about yourself.",children:ie(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:()=>ie(Lo,{})}]});import{useState as Xe}from"react";import{jsx as J,jsxs as Mt}from"react/jsx-runtime";function zo(){let[e,t]=Xe("");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 Eo(){let[e,t]=Xe("apple"),[n,o]=Xe("apple"),a=[{value:"apple",label:"Apple"},{value:"banana",label:"Banana"},{value:"cherry",label:"Cherry"}];return Mt("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 Ao(){let[e,t]=Xe("a"),[n,o]=Xe("a"),a=[{value:"a",label:"Option A"},{value:"b",label:"Option B"}];return Mt("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 Ho(){return Mt("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(zo,{})},{id:"sizes",title:"Sizes",description:"sm / md",render:()=>J(Eo,{})},{id:"tones",title:"Tones",description:"default / warning",render:()=>J(Ao,{})},{id:"disabled",title:"Disabled",description:"Whole component disabled & individual option disabled.",render:()=>J(Ho,{})}]});import{useState as cn}from"react";import{clsx as sn}from"clsx";import{jsx as ln}from"react/jsx-runtime";function dt({value:e,onChange:t,options:n,size:o="sm",className:a,ariaLabel:r}){return ln("div",{role:"tablist","aria-label":r,className:sn("ui-segmented-control inline-flex rounded-md p-0.5 ring-1",o==="sm"?"text-xs":"text-sm",a),children:n.map(i=>{let d=i.value===e;return ln("button",{type:"button",role:"tab","aria-selected":d,disabled:i.disabled,"data-active":d?"true":void 0,className:sn("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 Ze,jsxs as _o}from"react/jsx-runtime";function dn({size:e,label:t}){let[n,o]=cn("a");return Ze(dt,{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]=cn("on");return Ze(dt,{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:()=>_o("div",{className:"flex flex-wrap items-center gap-4",children:[Ze(dn,{size:"sm",label:"Small"}),Ze(dn,{size:"md",label:"Medium"})]})},{id:"with-disabled",title:"With Disabled Option",render:()=>Ze(Oo,{})}]});import{useState as ct}from"react";import{clsx as un}from"clsx";import{jsx as pn}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 Ne({checked:e,onChange:t,size:n="md",disabled:o=!1,className:a,ariaLabel:r}){return pn("button",{type:"button",role:"switch","aria-checked":e,"aria-label":r,disabled:o,"data-size":n,className:un("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:pn("span",{"aria-hidden":"true",className:un("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 be,jsxs as It}from"react/jsx-runtime";function $o(){let[e,t]=ct(!1);return be(Ne,{checked:e,onChange:t,ariaLabel:"Demo toggle"})}function Go(){let[e,t]=ct(!0),[n,o]=ct(!0);return It("div",{className:"flex items-center gap-4",children:[be(Ne,{checked:e,onChange:t,size:"sm",ariaLabel:"Small switch"}),be(Ne,{checked:n,onChange:o,size:"md",ariaLabel:"Medium switch"})]})}function Uo(){let[e,t]=ct(!1);return It("label",{className:"inline-flex items-center gap-2 text-sm text-[var(--color-n800)]",children:[be(Ne,{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(Ne,{checked:!!e.checked,onChange:n=>t("checked",n),size:e.size,disabled:!!e.disabled,ariaLabel:"Playground switch"}),stories:[{id:"default",title:"Default",render:()=>be($o,{})},{id:"sizes",title:"Sizes",description:"sm / md",render:()=>be(Go,{})},{id:"with-label",title:"With Label",render:()=>be(Uo,{})},{id:"disabled",title:"Disabled",render:()=>It("div",{className:"flex items-center gap-4",children:[be(Ne,{checked:!1,onChange:()=>{},disabled:!0,ariaLabel:"Disabled off"}),be(Ne,{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 Ae({className:e,tone:t="default",resize:n="vertical",autoResize:o=!1,style:a,onInput:r,rows:i=3,...d}){let l=Yo(null),s=r,u=Ko(()=>{if(!o||!l.current)return;let f=l.current;f.style.height="auto",f.style.height=`${f.scrollHeight}px`},[o]);qo(()=>{u()},[u,d.value,d.defaultValue,i]);function c(f){u(),s?.(f)}let m={...a,resize:o?"none":n};return Xo("textarea",{...d,ref:l,rows:i,"data-tone":t,"data-auto-resize":o||void 0,className:lt(`ui-textarea ${e??""}`),style:m,onInput:c})}import{jsx as Te,jsxs as Zo}from"react/jsx-runtime";y({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=>Te("div",{className:"max-w-sm",children:Te(Ae,{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:()=>Te("div",{className:"max-w-sm",children:Te(Ae,{"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:[Te(Ae,{"aria-label":"Default tone textarea",rows:3,placeholder:"Default tone\u2026",resize:"vertical"}),Te(Ae,{"aria-label":"Warning tone textarea",rows:3,placeholder:"Warning tone\u2026",tone:"warning",resize:"both"})]})},{id:"with-field",title:"With Field",render:()=>Te("div",{className:"max-w-sm",children:Te(ke,{label:"System Prompt",help:"Supports the same visual contract as Input.",children:Te(Ae,{"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 Rt}from"clsx";import{createContext as Qo,useContext as Jo,useEffect as jo,useId as ea,useMemo as ta,useRef as mn,useState as gn}from"react";import{jsx as Qe}from"react/jsx-runtime";var bn=Qo(null);function vn(e){let t=Jo(bn);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]=gn(t??!1),r=e!==void 0,i=r?e:o;function d(l){r||a(l),n?.(l)}return[i,d]}function fn({children:e,open:t,defaultOpen:n,onOpenChange:o,className:a,...r}){let[i,d]=na({open:t,defaultOpen:n,onOpenChange:o}),l=ea(),s=ta(()=>({open:i,setOpen:d,contentId:l}),[l,i,d]);return Qe(bn.Provider,{value:s,children:Qe("div",{"data-state":i?"open":"closed",className:Rt("ui-collapsible",a),...r,children:e})})}function oa({children:e,className:t,onClick:n,...o}){let{open:a,setOpen:r,contentId:i}=vn("Collapsible.Trigger");return Qe("button",{type:"button","aria-expanded":a,"aria-controls":i,"data-state":a?"open":"closed",className:Rt("ui-collapsible__trigger",t),onClick:d=>{n?.(d),d.defaultPrevented||r(!a)},...o,children:e})}function aa({children:e,className:t,...n}){let{open:o,contentId:a}=vn("Collapsible.Content"),[r,i]=gn(o),d=mn(null),l=mn(null);return jo(()=>{let s=d.current,u=l.current;if(!s||!u)return;let c=0,m=0,f=()=>{s.style.height="auto",s.style.overflow="visible"};if(o&&i(!0),!r&&!o)return;let g=h=>{h.target!==s||h.propertyName!=="height"||(s.removeEventListener("transitionend",g),o?f():i(!1))};return(()=>{let h=u.scrollHeight;if(s.style.overflow="hidden",o){s.style.height="0px",c=window.requestAnimationFrame(()=>{s.addEventListener("transitionend",g),s.style.height=`${h}px`}),m=window.setTimeout(f,240);return}s.style.height=`${h}px`,c=window.requestAnimationFrame(()=>{s.addEventListener("transitionend",g),s.style.height="0px"}),m=window.setTimeout(()=>i(!1),240)})(),()=>{window.cancelAnimationFrame(c),window.clearTimeout(m),s.removeEventListener("transitionend",g)}},[o,r]),!r&&!o?null:Qe("div",{id:a,ref:d,"data-state":o?"open":"closed","aria-hidden":!o,className:Rt("ui-collapsible__content",t),...n,children:Qe("div",{ref:l,className:"ui-collapsible__content-inner",children:e})})}var ra=Object.assign(fn,{Root:fn,Trigger:oa,Content:aa}),ut=ra;import{jsx as pt,jsxs as hn}from"react/jsx-runtime";y({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:()=>pt("div",{className:"max-w-lg rounded-xl border border-[var(--ui-surface-border)] bg-[var(--ui-surface-bg)] p-3",children:hn(ut,{defaultOpen:!0,children:[hn(ut.Trigger,{className:"flex w-full items-center justify-between gap-3 rounded-lg px-2 py-2 text-left text-sm font-medium",children:[pt("span",{children:"Reasoning"}),pt(ia,{className:"h-4 w-4"})]}),pt(ut.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 ft}from"clsx";import{createContext as sa,useContext as la,useId as da,useMemo as ca,useState as ua}from"react";import{jsx as Je}from"react/jsx-runtime";var xn=sa(null);function wn(e){let t=la(xn);if(!t)throw new Error(`${e} must be used within Tabs.Root`);return t}function mt(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 d(l){r||a(l),n?.(l)}return[i,d]}function yn({children:e,value:t,defaultValue:n,onValueChange:o,className:a,...r}){let[i,d]=pa({value:t,defaultValue:n,onValueChange:o}),l=da(),s=ca(()=>({value:i,setValue:d,baseId:l}),[l,i,d]);return Je(xn.Provider,{value:s,children:Je("div",{className:ft("ui-tabs",a),...r,children:e})})}function ma({children:e,className:t,ariaLabel:n,...o}){return Je("div",{role:"tablist","aria-label":n,className:ft("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:d,setValue:l,baseId:s}=wn("Tabs.Trigger"),u=d===n,c=`${s}-trigger-${mt(n)}`,m=`${s}-panel-${mt(n)}`;function f(g,N){let h=g.closest('[role="tablist"]');if(!h)return;let v=Array.from(h.querySelectorAll('[role="tab"]:not([disabled])')),S=v.indexOf(g);if(S<0)return;let x;N==="first"&&(x=v[0]),N==="last"&&(x=v[v.length-1]),N==="next"&&(x=v[(S+1)%v.length]),N==="prev"&&(x=v[(S-1+v.length)%v.length]),x&&(x.focus(),x.click())}return Je("button",{type:"button",id:c,role:"tab","aria-selected":u,"aria-controls":m,tabIndex:u?0:-1,"data-state":u?"active":"inactive",disabled:o,className:ft("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:g=>{a?.(g),!g.defaultPrevented&&!o&&l(n)},onKeyDown:g=>{if(r?.(g),g.defaultPrevented||o)return;let N=g.currentTarget;switch(g.key){case"ArrowRight":g.preventDefault(),f(N,"next");break;case"ArrowLeft":g.preventDefault(),f(N,"prev");break;case"Home":g.preventDefault(),f(N,"first");break;case"End":g.preventDefault(),f(N,"last");break}},...i,children:e})}function ga({children:e,className:t,value:n,...o}){let{value:a,baseId:r}=wn("Tabs.Content"),i=a===n,d=`${r}-trigger-${mt(n)}`,l=`${r}-panel-${mt(n)}`;return i?Je("div",{id:l,role:"tabpanel","aria-labelledby":d,"data-state":"active",className:ft("ui-tabs__content pt-4",t),...o,children:e}):null}var ba=Object.assign(yn,{Root:yn,List:ma,Trigger:fa,Content:ga}),Ce=ba;import{jsx as ve,jsxs as Nn}from"react/jsx-runtime";y({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:()=>ve("div",{className:"max-w-2xl",children:Nn(Ce,{defaultValue:"settings",children:[Nn(Ce.List,{ariaLabel:"Settings sections",children:[ve(Ce.Trigger,{value:"settings",children:"Settings"}),ve(Ce.Trigger,{value:"account",children:"Account"}),ve(Ce.Trigger,{value:"admin",disabled:!0,children:"Admin"})]}),ve(Ce.Content,{value:"settings",children:ve("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."})}),ve(Ce.Content,{value:"account",children:ve("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."})}),ve(Ce.Content,{value:"admin",children:ve("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 K({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 j,jsxs as Ve}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:()=>Ve("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:()=>Ve("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:()=>Ve("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=>Ve("div",{className:"flex items-center gap-3",children:[Ve(K,{size:"sm",tone:e,variant:"soft",children:[e," soft"]}),Ve(K,{size:"sm",tone:e,variant:"outline",children:[e," outline"]})]},e))})}]});import{Info as Na,CheckCircle2 as Ta,TriangleAlert as Ca,CircleAlert as Sa}from"lucide-react";import{clsx as ya}from"clsx";import{Fragment as xa,jsx as Bt,jsxs as wa}from"react/jsx-runtime";function ue({tone:e="neutral",icon:t,className:n,children:o,...a}){return Bt("div",{"data-tone":e,className:ya("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?wa(xa,{children:[Bt("span",{className:"ui-status-notice__icon mt-0.5 shrink-0","aria-hidden":"true",children:t}),Bt("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(Na,{size:16}),children:"Background indexing is still in progress."}),ee(ue,{tone:"success",icon:ee(Ta,{size:16}),children:"Draft and main are fully aligned."}),ee(ue,{tone:"warning",icon:ee(Ca,{size:16}),children:"One route conflict still needs manual review."}),ee(ue,{tone:"danger",icon:ee(Sa,{size:16}),children:"Publishing failed. Retry after refreshing the snapshot."})]})}]});import{clsx as Da}from"clsx";import{jsx as je,jsxs as ka}from"react/jsx-runtime";function Pe({tone:e="neutral",icon:t,title:n,description:o,action:a,className:r,children:i,...d}){let l=t||n||o||a;return je("div",{"data-tone":e,className:Da("ui-empty-state rounded-lg border px-4 py-3 text-sm",r),...d,children:l?ka("div",{className:"flex flex-col items-center gap-2 py-4 text-center",children:[t&&je("div",{className:"ui-empty-state__icon text-lg",children:t}),n&&je("div",{className:"ui-empty-state__title font-medium",children:n}),o&&je("div",{className:"ui-empty-state__description",children:o}),a&&je("div",{className:"mt-2",children:a})]}):i})}import{jsx as Me,jsxs as Pa}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:()=>Me(Pe,{children:"No items found."})},{id:"structured",title:"Structured Slots",description:"Using title, description, and action slots.",render:()=>Me(Pe,{title:"No posts yet",description:"Create your first post to get started.",action:Me(p,{variant:"primary",size:"sm",children:"Create Post"})})},{id:"tones",title:"Tones",description:"neutral / notice / warning",render:()=>Pa("div",{className:"space-y-4",children:[Me(Pe,{tone:"neutral",title:"Neutral",description:"Default empty state."}),Me(Pe,{tone:"notice",title:"Notice",description:"Informational empty state."}),Me(Pe,{tone:"warning",title:"Warning",description:"Attention-drawing empty state."})]})},{id:"with-icon",title:"With Icon",render:()=>Me(Pe,{icon:Me("span",{className:"text-2xl",children:"\u{1F4ED}"}),title:"Inbox empty",description:"You have no new messages."})}]});import{jsx as te,jsxs as We}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(re,{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=>We("div",{className:"flex flex-col items-center gap-2",children:[te(re,{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:()=>We("div",{className:"flex items-center gap-4",children:[te(re,{size:"xs"}),te(re,{size:"sm"}),te(re,{size:"md"}),te(re,{size:"lg"})]})},{id:"with-text",title:"Inline with Text",render:()=>We("div",{className:"space-y-3",children:[We("div",{className:"flex items-center gap-2 text-sm text-[var(--color-n600)]",children:[te(re,{variant:"ring",size:"sm"}),te("span",{children:"Loading data\u2026"})]}),We("div",{className:"flex items-center gap-2 text-sm text-[var(--color-n600)]",children:[te(re,{variant:"flow",size:"sm"}),te("span",{children:"Processing\u2026"})]}),We("div",{className:"flex items-center gap-2 text-sm text-[var(--color-n600)]",children:[te(re,{variant:"bounce",size:"sm"}),te("span",{children:"Waiting for response\u2026"})]})]})}]});import{clsx as Ma}from"clsx";import{jsx as Ra}from"react/jsx-runtime";var Ia={slow:"4s",default:"3s",fast:"2s"};function H({className:e,animation:t="scan",tone:n="default",speed:o="default",style:a,...r}){let i=n==="warm"?"emphasis":n,d={...a,"--ui-skeleton-scan-duration":Ia[o]};return Ra("div",{className:Ma("ui-skeleton rounded",e),"data-animation":t,"data-tone":i,"aria-hidden":"true",style:d,...r})}import{jsx as R,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:[R(H,{animation:e.animation,tone:e.tone,speed:e.speed,className:"h-4 w-48"}),R(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:[R(H,{className:"h-4 w-48"}),R(H,{className:"h-4 w-64"}),R(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:[R("div",{className:"text-xs font-medium text-[var(--color-n500)]",children:"Slow \xB7 4s"}),R(H,{speed:"slow",className:"h-4 w-64"})]}),se("div",{className:"space-y-2",children:[R("div",{className:"text-xs font-medium text-[var(--color-n500)]",children:"Default \xB7 3s"}),R(H,{className:"h-4 w-64"})]}),se("div",{className:"space-y-2",children:[R("div",{className:"text-xs font-medium text-[var(--color-n500)]",children:"Fast \xB7 2s"}),R(H,{speed:"fast",className:"h-4 w-64"})]})]})},{id:"pulse",title:"Pulse",render:()=>se("div",{className:"space-y-4",children:[R(H,{animation:"pulse",className:"h-4 w-48"}),R(H,{animation:"pulse",className:"h-4 w-64"}),R(H,{animation:"pulse",className:"h-4 w-32"})]})},{id:"on-surfaces",title:"On Different Surfaces",description:"Verifies shimmer visibility against various backgrounds.",render:()=>R("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:[R("p",{className:"mb-2 text-[11px] font-medium text-[var(--color-n500)]",children:e}),se("div",{className:"space-y-2",children:[R(H,{className:"h-4 w-full"}),R(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:[R(H,{className:"h-5 w-3/4"}),R(H,{className:"h-4 w-full"}),R(H,{className:"h-4 w-5/6"}),se("div",{className:"flex gap-2 pt-2",children:[R(H,{animation:"pulse",className:"h-8 w-20 rounded-md"}),R(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:[R(H,{className:"h-10 w-10 shrink-0 rounded-full"}),se("div",{className:"flex-1 space-y-2",children:[R(H,{animation:"pulse",className:"h-4 w-32"}),R(H,{className:"h-3 w-48"})]})]})}]});import{useState as gt}from"react";import{clsx as et}from"clsx";import{useEffect as Ba,useRef as Cn,useCallback as La}from"react";import{jsx as tt,jsxs as Ha}from"react/jsx-runtime";function za({className:e,children:t,...n}){return tt("div",{className:et("ui-dialog__header px-5 pt-5 pb-1 text-base font-semibold",e),...n,children:t})}function Ea({className:e,children:t,...n}){return tt("div",{className:et("ui-dialog__body px-5 py-3 text-sm",e),...n,children:t})}function Aa({className:e,children:t,...n}){return tt("div",{className:et("ui-dialog__footer flex items-center justify-end gap-2 px-5 pt-3 pb-5",e),...n,children:t})}function B({open:e,onClose:t,size:n="sm",children:o,className:a,overlayClassName:r,panelClassName:i,...d}){let l=Cn(null),s=Cn(null),u=La(c=>{c.key==="Escape"&&(c.stopPropagation(),t())},[t]);return Ba(()=>(e?(s.current=document.activeElement,document.body.style.overflow="hidden",requestAnimationFrame(()=>{let c=l.current;if(!c)return;let m=c.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');m?m.focus():c.focus()}),document.addEventListener("keydown",u)):(document.body.style.overflow="",s.current?.focus()),()=>{document.removeEventListener("keydown",u),document.body.style.overflow=""}),[e,u]),e?Ha("div",{"data-state":"open",className:"ui-dialog-overlay fixed inset-0 z-50 flex items-center justify-center",children:[tt("button",{type:"button","aria-label":"Close dialog","data-state":"open",className:et("ui-dialog-backdrop absolute inset-0 bg-black/30",r),onClick:t}),tt("div",{ref:l,role:"dialog","aria-modal":"true",tabIndex:-1,"data-state":"open","data-size":n,className:et("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),...d,children:o})]}):null}B.Header=za;B.Body=Ea;B.Footer=Aa;import{createContext as Oa,useCallback as Sn,useContext as _a,useRef as Fa,useState as Va}from"react";import{Fragment as Wa,jsx as $e,jsxs as Lt}from"react/jsx-runtime";var Dn=Oa(null);function kn(){let e=_a(Dn);if(!e)throw new Error("useConfirm must be used within <ConfirmProvider>");return e}function Pn({children:e}){let[t,n]=Va(null),o=Fa(null),a=Sn(i=>(o.current&&o.current.resolve(!1),new Promise(d=>{let l={options:i,resolve:d};o.current=l,n(l)})),[]),r=Sn(i=>{o.current&&(o.current.resolve(i),o.current=null),n(null)},[]);return Lt(Dn.Provider,{value:a,children:[e,$e(B,{open:t!==null,onClose:()=>r(!1),children:t&&Lt(Wa,{children:[$e(B.Header,{children:t.options.title}),$e(B.Body,{children:typeof t.options.description=="string"?$e("p",{className:"whitespace-pre-wrap",children:t.options.description}):t.options.description}),Lt(B.Footer,{children:[$e(p,{variant:"ghost",size:"sm",onClick:()=>r(!1),children:t.options.cancelLabel??"\u53D6\u6D88"}),$e(p,{variant:t.options.variant??"primary",size:"sm",onClick:()=>r(!0),children:t.options.confirmLabel??"\u786E\u8BA4"})]})]})})]})}import{Fragment as zt,jsx as w,jsxs as L}from"react/jsx-runtime";function $a(){let[e,t]=gt(!1);return L(zt,{children:[w(p,{variant:"primary",size:"sm",onClick:()=>t(!0),children:"Open Dialog"}),L(B,{open:e,onClose:()=>t(!1),children:[w(B.Header,{children:"Basic Dialog"}),w(B.Body,{children:w("p",{children:"This is a basic dialog with header, body, and footer sections."})}),L(B.Footer,{children:[w(p,{variant:"ghost",size:"sm",onClick:()=>t(!1),children:"Cancel"}),w(p,{variant:"primary",size:"sm",onClick:()=>t(!1),children:"Confirm"})]})]})]})}function Ga(){let[e,t]=gt(!1);return L(zt,{children:[w(p,{variant:"danger",size:"sm",onClick:()=>t(!0),children:"Delete Item"}),L(B,{open:e,onClose:()=>t(!1),children:[w(B.Header,{children:"Delete Draft"}),L(B.Body,{children:[w("p",{children:"Are you sure you want to delete the ZH locale draft?"}),L("p",{className:"mt-2",children:["Article ID: post-20260320-example",w("br",{}),"Category: post"]}),w("p",{className:"mt-2",children:"This action cannot be undone."})]}),L(B.Footer,{children:[w(p,{variant:"ghost",size:"sm",onClick:()=>t(!1),children:"Cancel"}),w(p,{variant:"danger",size:"sm",onClick:()=>t(!1),children:"Delete"})]})]})]})}function Ua(){let[e,t]=gt(!1);return L(zt,{children:[w(p,{variant:"secondary",size:"sm",onClick:()=>t(!0),children:"Open Medium Dialog"}),L(B,{open:e,onClose:()=>t(!1),size:"md",children:[w(B.Header,{children:"Publish Confirmation"}),L(B.Body,{children:[w("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:[w("span",{children:"Articles:"}),w("span",{children:"3"})]}),L("div",{className:"flex justify-between",children:[w("span",{children:"Languages:"}),w("span",{children:"ZH, EN"})]}),L("div",{className:"flex justify-between",children:[w("span",{children:"Branch:"}),w("span",{children:"draft"})]})]}),w("p",{className:"mt-3",children:"This will trigger a Cloudflare deployment."})]}),L(B.Footer,{children:[w(p,{variant:"ghost",size:"sm",onClick:()=>t(!1),children:"Cancel"}),w(p,{variant:"primary",size:"sm",onClick:()=>t(!1),children:"Publish"})]})]})]})}function Ka(){let e=kn(),[t,n]=gt("");return L("div",{className:"flex flex-col gap-3",children:[L("div",{className:"flex gap-2",children:[w(p,{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()"}),w(p,{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&&L("p",{className:"text-sm text-[var(--color-n600)]",children:["Result: ",t]})]})}function qa(){return w(Pn,{children:w(Ka,{})})}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(p,{variant:"primary",size:"sm",onClick:()=>t("open",!0),children:["Open Dialog (",n,")"]}),L(B,{open:o,onClose:()=>t("open",!1),size:n,children:[w(B.Header,{children:"Playground Dialog"}),w(B.Body,{children:L("p",{children:["Toggle the ",w("code",{className:"rounded bg-[var(--color-surface-subtle)] px-1 py-0.5 text-xs",children:"open"})," and ",w("code",{className:"rounded bg-[var(--color-surface-subtle)] px-1 py-0.5 text-xs",children:"size"})," controls below."]})}),L(B.Footer,{children:[w(p,{variant:"ghost",size:"sm",onClick:()=>t("open",!1),children:"Cancel"}),w(p,{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:()=>L("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:[
|
|
34
|
+
}`,render:()=>L("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:[w("p",{className:"font-medium text-[var(--color-n800)]",children:"Provider is already mounted in admin layout."}),L("p",{className:"mt-1",children:["Click the ",w("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:()=>w($a,{})},{id:"danger",title:"Danger Dialog",description:"Destructive action confirmation with danger-styled button.",render:()=>w(Ga,{})},{id:"medium",title:"Medium Size",description:"Wider dialog for content-heavy confirmations.",render:()=>w(Ua,{})},{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:()=>w(qa,{})}]});import{clsx as Mn}from"clsx";import{createContext as Ya,useCallback as In,useContext as Xa,useMemo as Za,useRef as Rn,useState as Qa}from"react";import{jsx as G,jsxs as nt}from"react/jsx-runtime";var Ln=Ya(null),Et=5,Bn=4e3;function zn(){let e=Xa(Ln);if(!e)throw new Error("useToast must be used within <ToastProvider>");return e}function Ja({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 G("svg",{...t,children:G("path",{d:"M3.5 8.5l3 3 6-7"})});case"warning":return nt("svg",{...t,children:[G("path",{d:"M8 5v4"}),G("circle",{cx:"8",cy:"11.5",r:"0.5",fill:"currentColor",stroke:"none"})]});case"danger":return G("svg",{...t,children:G("path",{d:"M4.5 4.5l7 7M11.5 4.5l-7 7"})});case"info":return nt("svg",{...t,children:[G("circle",{cx:"8",cy:"3.5",r:"1.2",fill:"currentColor",stroke:"none"}),G("path",{d:"M8 7v5.5"})]})}}function ja(e,t){return typeof e=="string"?{message:e,duration:t??Bn}:{title:e.title,message:e.message,duration:e.duration??t??Bn}}function er({item:e,onDismiss:t,renderToast:n}){let o=()=>t(e.id),a=G(Ja,{tone:e.tone});return n?G("div",{role:"status","aria-live":"polite","data-state":"open","data-tone":e.tone,className:Mn("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})}):nt("div",{role:"status","aria-live":"polite","data-state":"open","data-tone":e.tone,className:Mn("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:[G("span",{className:"ui-toast__icon mt-0.5 shrink-0","aria-hidden":"true",children:a}),nt("span",{className:"min-w-0 flex-1",children:[e.title?G("span",{className:"ui-toast__title block font-medium",children:e.title}):null,G("span",{className:"block",children:e.message})]}),G("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:G("svg",{width:"14",height:"14",viewBox:"0 0 16 16",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",children:G("path",{d:"M4 4l8 8M12 4l-8 8"})})})]})}function En({children:e,renderToast:t}){let[n,o]=Qa([]),a=Rn(0),r=Rn(new Map),i=In(s=>{let u=r.current.get(s);u&&clearTimeout(u),r.current.delete(s),o(c=>c.filter(m=>m.id!==s))},[]),d=In((s,u,c)=>{let m=a.current++,f=ja(u,c),g={id:m,tone:s,...f};o(N=>{let h=[...N,g];if(h.length>Et){let v=h.slice(0,h.length-Et);for(let S of v){let x=r.current.get(S.id);x&&clearTimeout(x),r.current.delete(S.id)}return h.slice(-Et)}return h}),g.duration>0&&r.current.set(m,setTimeout(()=>i(m),g.duration))},[i]),l=Za(()=>({success:(s,u)=>d("success",s,u),warning:(s,u)=>d("warning",s,u),danger:(s,u)=>d("danger",s,u),info:(s,u)=>d("info",s,u)}),[d]);return nt(Ln.Provider,{value:l,children:[e,G("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=>G(er,{item:s,onDismiss:i,renderToast:t},s.id))})]})}import{jsx as he,jsxs as At}from"react/jsx-runtime";function tr(){let e=zn();return At("div",{className:"flex flex-wrap gap-2",children:[he(p,{size:"sm",variant:"secondary",onClick:()=>e.success("Changes saved successfully."),children:"Success"}),he(p,{size:"sm",variant:"secondary",onClick:()=>e.warning("Draft has unsaved changes."),children:"Warning"}),he(p,{size:"sm",variant:"secondary",onClick:()=>e.danger("Failed to publish post."),children:"Danger"}),he(p,{size:"sm",variant:"secondary",onClick:()=>e.info("New version available."),children:"Info"}),he(p,{size:"sm",variant:"secondary",onClick:()=>e.success({title:"Draft Saved",message:"All local changes are now synced to the draft branch."}),children:"With Title"})]})}function nr(){return he(En,{children:he(tr,{})})}y({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:()=>At("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:[he("p",{className:"font-medium text-[var(--color-n800)]",children:"ToastProvider is not yet mounted in admin layout."}),At("p",{className:"mt-1",children:["Add it to the layout before using useToast(). Click the ",he("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:()=>he(nr,{})}]});import{clsx as or}from"clsx";import{useState as ar}from"react";import{jsx as Ht}from"react/jsx-runtime";var rr={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 ir(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:r}){let[i,d]=ar(!1),l=e&&!i,s=n?ir(n):"?";return Ht("span",{"data-tone":a,className:or("ui-avatar inline-flex shrink-0 items-center justify-center overflow-hidden rounded-full font-medium select-none",rr[o],r),children:l?Ht("img",{src:e,alt:t??n??"",className:"h-full w-full object-cover",onError:()=>d(!0)}):Ht("span",{"aria-label":t??n,children:s})})}import{jsx as oe,jsxs as Ge}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:()=>Ge("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:()=>Ge("div",{className:"flex items-center gap-4",children:[Ge("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"})]}),Ge("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:()=>Ge("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:()=>Ge("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 sr}from"clsx";import{cloneElement as lr,isValidElement as dr,useCallback as bt,useEffect as An,useId as cr,useLayoutEffect as ur,useRef as vt,useState as Ot}from"react";import{createPortal as pr}from"react-dom";import{Fragment as hr,jsx as _t,jsxs as Fn}from"react/jsx-runtime";var ot=6,Hn=8,ht=4,mr={top:"bottom",bottom:"top",left:"right",right:"left"},fr={top:{left:"50%",top:"100%",transform:"translateX(-50%)"},bottom:{left:"50%",top:-ot,transform:"translateX(-50%) rotate(180deg)"},left:{top:"50%",left:"100%",transform:"translateY(-50%) rotate(-90deg)"},right:{top:"50%",left:-ot,transform:"translateY(-50%) rotate(90deg)"}};function On(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 _n(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 gr(e,t,n,o){let a=o?Hn+ot:Hn,r=On(n,e,t,a),i=n,d=r;if(!_n(r,t)){let m=mr[n],f=On(m,e,t,a);_n(f,t)&&(i=m,d=f)}let l=window.innerWidth,s=window.innerHeight,u=Math.max(ht,Math.min(d.left,l-t.width-ht)),c=Math.max(ht,Math.min(d.top,s-t.height-ht));return{placement:i,top:c,left:u}}function br(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 vr={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:r=!0,renderArrow:i,className:d,children:l}){let[s,u]=Ot(!1),[c,m]=Ot(null),[f,g]=Ot(t),N=vt(null),h=vt(null),v=vt(void 0),S=vt(void 0),x=cr(),z=bt(()=>{clearTimeout(v.current),clearTimeout(S.current)},[]),C=bt(()=>{z(),v.current=setTimeout(()=>u(!0),o)},[z,o]),W=bt(()=>{z(),S.current=setTimeout(()=>u(!1),a)},[z,a]),$=bt(I=>{I.key==="Escape"&&s&&u(!1)},[s]);if(ur(()=>{if(!s||!N.current||!h.current)return;function I(){if(!N.current||!h.current)return;let b=N.current.getBoundingClientRect(),P=h.current.getBoundingClientRect(),Q=gr(b,P,t,r),Le=document.body.getBoundingClientRect();m({top:Q.top+window.scrollY-Le.top,left:Q.left+window.scrollX-Le.left}),g(Q.placement)}return I(),window.addEventListener("scroll",I,!0),window.addEventListener("resize",I),()=>{window.removeEventListener("scroll",I,!0),window.removeEventListener("resize",I)}},[s,t,r]),An(()=>{if(s)return document.addEventListener("keydown",$),()=>document.removeEventListener("keydown",$)},[s,$]),An(()=>z,[z]),!dr(l))return l;let q=lr(l,{ref:br(N,l),"data-state":s?"open":"closed",onMouseEnter:I=>{C();let b=l.props.onMouseEnter;b?.(I)},onMouseLeave:I=>{W();let b=l.props.onMouseLeave;b?.(I)},onFocus:I=>{C();let b=l.props.onFocus;b?.(I)},onBlur:I=>{W();let b=l.props.onBlur;b?.(I)},"aria-describedby":s?x:void 0});return Fn(hr,{children:[q,s&&pr(Fn("div",{ref:h,id:x,role:"tooltip","data-state":s?"open":"closed","data-placement":f,"data-density":n,className:sr("ui-tooltip absolute z-[9999] rounded-lg leading-relaxed",vr[n],"animate-[tooltip-in_0.15s_var(--ease-standard)]",d),style:c?{top:c.top,left:c.left}:{position:"fixed",visibility:"hidden"},onMouseEnter:C,onMouseLeave:W,children:[e,r&&_t("span",{className:"ui-tooltip__arrow absolute",style:fr[f],children:i?i({placement:f}):_t("svg",{width:ot*2,height:ot,viewBox:"0 0 12 6",children:_t("path",{d:"M0 0l6 6 6-6z",fill:"currentColor"})})})]}),document.body)]})}import{Settings as yr}from"lucide-react";import{jsx as A,jsxs as Ft}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:()=>Ft("div",{className:"flex flex-wrap items-center justify-center gap-4 py-12",children:[A(fe,{content:"Placed on top",placement:"top",children:A(p,{variant:"secondary",size:"sm",children:"Top"})}),A(fe,{content:"Placed on bottom",placement:"bottom",children:A(p,{variant:"secondary",size:"sm",children:"Bottom"})}),A(fe,{content:"Placed on left",placement:"left",children:A(p,{variant:"secondary",size:"sm",children:"Left"})}),A(fe,{content:"Placed on right",placement:"right",children:A(p,{variant:"secondary",size:"sm",children:"Right"})})]})},{id:"density",title:"Density",description:"compact vs default \u2014 compact is tighter for icon labels.",render:()=>Ft("div",{className:"flex flex-wrap items-center justify-center gap-6 py-12",children:[A(fe,{content:"Compact tooltip",density:"compact",children:A(p,{variant:"secondary",size:"sm",children:"Compact"})}),A(fe,{content:"Default density tooltip with more room for content",density:"default",children:A(p,{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:Ft("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(p,{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(X,{label:"Settings",icon:A(yr,{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(p,{variant:"secondary",size:"sm",children:"Hover me"})})})}]});import{useState as Ar}from"react";import{clsx as Re}from"clsx";import{Children as xr,cloneElement as wr,createContext as Vn,isValidElement as Nr,useCallback as Z,useContext as Vt,useEffect as He,useId as yt,useLayoutEffect as Tr,useMemo as wt,useRef as Ie,useState as at}from"react";import{createPortal as Cr}from"react-dom";import{jsx as ae,jsxs as Kn}from"react/jsx-runtime";var Wn=Vn(null),Wt=Vn(null);function $t(e){let t=Vt(Wn);if(!t)throw new Error(`${e} must be used within DropdownMenu.`);return t}function $n(e){let t=Vt(Wt);if(!t)throw new Error(`${e} must be used within DropdownMenu.Content.`);return t}function Ue(e,t){return n=>{e?.(n),t(n)}}function Gn(...e){return t=>{for(let n of e)n&&(typeof n=="function"?n(t):n.current=t)}}function xt(e){return typeof e=="string"||typeof e=="number"?String(e):Array.isArray(e)?e.map(xt).join(" "):!e||typeof e=="boolean"?"":Nr(e)?xt(e.props.children):""}function Sr(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 Dr(e){let{anchorRect:t,contentRect:n,sideOffset:o,alignOffset:a,collisionPadding:r}=e,i=window.innerWidth,d=window.innerHeight;function l(h,v){let S=0,x=0;return h==="bottom"?(S=t.bottom+o,v==="start"?x=t.left+a:v==="end"?x=t.right-n.width+a:x=t.left+(t.width-n.width)/2+a):h==="top"?(S=t.top-n.height-o,v==="start"?x=t.left+a:v==="end"?x=t.right-n.width+a:x=t.left+(t.width-n.width)/2+a):h==="right"?(x=t.right+o,v==="start"?S=t.top+a:v==="end"?S=t.bottom-n.height+a:S=t.top+(t.height-n.height)/2+a):(x=t.left-n.width-o,v==="start"?S=t.top+a:v==="end"?S=t.bottom-n.height+a:S=t.top+(t.height-n.height)/2+a),{top:S,left:x}}let s={top:"bottom",bottom:"top",left:"right",right:"left"},u=e.side,c=e.align,m=l(u,c);if(m.left<r||m.top<r||m.left+n.width>i-r||m.top+n.height>d-r){let h=l(s[u],c);h.left>=r&&h.top>=r&&h.left+n.width<=i-r&&h.top+n.height<=d-r&&(u=s[u],m=h)}let g=i-n.width-r,N=d-n.height-r;return m.left=Math.max(r,Math.min(m.left,g)),m.top=Math.max(r,Math.min(m.top,N)),{top:m.top,left:m.left,side:u,align:c}}function Un({open:e,defaultOpen:t=!1,onOpenChange:n,side:o="bottom",align:a="start",sideOffset:r=8,alignOffset:i=0,collisionPadding:d=8,portal:l=!0,contentRole:s="menu",children:u}){let c=Vt(Wt),[m,f]=at(t),g=e!==void 0,N=g?e:m,h=Ie(null),v=Ie(null),S=Ie("selected"),x=yt(),z=yt(),C=Z(P=>{g||f(P),n?.(P)},[g,n]),W=Z(()=>{C(!1)},[C]),$=Z(()=>{C(!1),c?.closeTree()},[c,C]),q=Z(()=>{C(!N)},[N,C]),I=Z(()=>{h.current?.focus()},[]),b=wt(()=>({open:N,setOpen:C,toggleOpen:q,triggerRef:h,contentRef:v,side:o,align:a,sideOffset:r,alignOffset:i,collisionPadding:d,portal:l,contentRole:s,triggerId:x,contentId:z,focusIntentRef:S,parentList:c,isSubmenu:!!c,closeSelf:W,closeTree:$,focusTrigger:I}),[N,a,i,W,$,d,s,c,l,C,o,r,q,x,z,I]);return ae(Wn.Provider,{value:b,children:u})}function kr({asChild:e=!1,disabled:t=!1,className:n,children:o}){let{open:a,setOpen:r,toggleOpen:i,triggerRef:d,contentRole:l,triggerId:s,contentId:u,focusIntentRef:c,isSubmenu:m}=$t("DropdownMenu.Trigger"),f=xr.only(o),g=f.props??{},N=typeof g.className=="string"?g.className:void 0,h={id:s,"data-state":a?"open":"closed","aria-expanded":a,"aria-haspopup":l,"aria-controls":a?u:void 0,onClick:Ue(g.onClick,v=>{if(t){v.preventDefault();return}c.current="selected",i()}),onKeyDown:Ue(g.onKeyDown,v=>{t||(v.key==="ArrowDown"?(v.preventDefault(),c.current="first",r(!0)):v.key==="ArrowUp"?(v.preventDefault(),c.current="last",r(!0)):!m&&(v.key==="Enter"||v.key===" ")&&(v.preventDefault(),c.current="selected",i()))})};return e?wr(f,{...h,ref:Gn(d,g.ref),className:Re(n,N),type:f.type==="button"?g.type??"button":g.type}):ae("button",{ref:d,disabled:t,type:"button",className:Re("ui-dropdown-menu__trigger",n),...h,children:f})}function Pr({className:e,children:t,style:n,matchTriggerWidth:o=!1,maxHeight:a=320,...r}){let{open:i,setOpen:d,triggerRef:l,contentRef:s,side:u,align:c,sideOffset:m,alignOffset:f,collisionPadding:g,portal:N,contentRole:h,triggerId:v,contentId:S,focusIntentRef:x,parentList:z,isSubmenu:C,closeSelf:W,closeTree:$,focusTrigger:q}=$t("DropdownMenu.Content"),I=Ie([]),[b,P]=at(null),[Q,Le]=at(null),[rt,Jn]=at(null),[Ct,jn]=at(!1),St=Ie(""),Oe=Ie(null),Kt=Z(T=>(I.current=[...I.current.filter(O=>O.id!==T.id),T],()=>{I.current=I.current.filter(O=>O.id!==T.id)}),[]),le=Z(()=>Sr(I.current),[]),qt=Z(T=>{x.current=T},[x]);He(()=>{jn(!0)},[]);let eo=wt(()=>({role:h,highlightedId:b,setHighlightedId:P,registerItem:Kt,getItems:le,requestFocusIntent:qt,closeTree:$,closeSelf:W,focusTrigger:q,activeSubmenuId:Q,setActiveSubmenuId:Le,contentRef:s}),[Q,W,$,s,h,q,le,b,Kt,qt]),_e=Z(()=>{if(!l.current||!s.current)return;let T=l.current.getBoundingClientRect(),O=s.current.getBoundingClientRect();Jn(Dr({anchorRect:T,contentRect:O,side:u,align:c,sideOffset:m,alignOffset:f,collisionPadding:g}))},[c,f,g,s,u,m,l]);Tr(()=>{if(!(!i||!Ct))return _e(),window.addEventListener("resize",_e),window.addEventListener("scroll",_e,!0),()=>{window.removeEventListener("resize",_e),window.removeEventListener("scroll",_e,!0)}},[Ct,i,_e]),He(()=>{if(!i){P(null),Le(null);return}let T=le().filter(k=>!k.disabled);if(T.length===0)return;let O=T[0];x.current==="last"?O=T[T.length-1]:x.current==="selected"&&(O=T.find(k=>k.selected)??T[0]),P(O.id),requestAnimationFrame(()=>{s.current?.focus(),O.ref.current?.scrollIntoView({block:"nearest"})})},[s,x,le,i]),He(()=>{if(!i)return;function T(O){let k=O.target,Y=l.current?.contains(k),xe=s.current?.contains(k);if(!Y&&!xe){let ge=z?.contentRef.current?.contains(k);if(C&&ge){W(),z?.setActiveSubmenuId(null);return}$()}}return document.addEventListener("mousedown",T),()=>document.removeEventListener("mousedown",T)},[W,$,s,C,i,z,l]),He(()=>{if(i)return()=>{Oe.current&&clearTimeout(Oe.current)}},[i]);let Se=Z(T=>{if(P(T),!T){Le(null);return}le().find(k=>k.id===T)?.submenu||Le(null)},[le]),Dt=Z((T,O="first")=>{let k=le().filter(we=>!we.disabled);if(k.length===0)return;let Y=k.findIndex(we=>we.id===b);if(Y===-1){Se(O==="last"?k[k.length-1].id:k[0].id);return}let xe=(Y+T+k.length)%k.length,ge=k[xe];Se(ge.id),ge.ref.current?.scrollIntoView({block:"nearest"})},[le,b,Se]),Yt=Z(T=>{let O=T.length===1?T.toLowerCase():"";if(!O)return;Oe.current&&clearTimeout(Oe.current),St.current+=O,Oe.current=setTimeout(()=>{St.current="",Oe.current=null},350);let k=le().filter(we=>!we.disabled);if(k.length===0)return;let Y=k.findIndex(we=>we.id===b),ge=(Y>=0?[...k.slice(Y+1),...k.slice(0,Y+1)]:k).find(we=>we.textValue.toLowerCase().startsWith(St.current));ge&&(Se(ge.id),ge.ref.current?.scrollIntoView({block:"nearest"}))},[le,b,Se]),to=Z(T=>{let O=le(),k=O.find(Y=>Y.id===b)??null;switch(T.key){case"ArrowDown":T.preventDefault(),Dt(1);break;case"ArrowUp":T.preventDefault(),Dt(-1,"last");break;case"Home":T.preventDefault();{let Y=O.find(xe=>!xe.disabled);Y&&Se(Y.id)}break;case"End":T.preventDefault();{let Y=O.filter(ge=>!ge.disabled),xe=Y[Y.length-1];xe&&Se(xe.id)}break;case"Enter":case" ":k&&!k.disabled&&(T.preventDefault(),k.click());break;case"ArrowRight":k?.submenu&&(T.preventDefault(),k.openSubmenu?.());break;case"ArrowLeft":C&&(T.preventDefault(),W(),q(),z?.setActiveSubmenuId(null));break;case"Tab":$();break;case"Escape":T.preventDefault(),W(),q(),C&&z?.setActiveSubmenuId(null);break;default:Yt(T.key)}},[W,$,q,le,Yt,b,Se,C,Dt,z]);if(!i||!Ct)return null;let Xt=ae(Wt.Provider,{value:eo,children:ae("div",{ref:s,id:S,role:h,tabIndex:-1,"aria-labelledby":h==="menu"?v:void 0,"data-state":"open","data-side":rt?.side??u,"data-align":rt?.align??c,className:Re("ui-dropdown-menu__content",C&&"ui-dropdown-menu__content--submenu",e),style:{...n,position:"fixed",top:rt?.top??0,left:rt?.left??0,maxHeight:a,minWidth:o?l.current?.getBoundingClientRect().width:void 0},onKeyDown:to,...r,children:t})});return N?Cr(Xt,document.body):Xt}function Mr({className:e,children:t,...n}){return ae("div",{className:Re("ui-dropdown-menu__group",e),...n,children:t})}function Ir({className:e,children:t,...n}){return ae("div",{className:Re("ui-dropdown-menu__label",e),...n,children:t})}function Rr({className:e,...t}){return ae("div",{role:"separator",className:Re("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:d,indicator:l,onSelect:s,onMouseEnter:u,onClick:c,...m}){let f=yt(),g=Ie(null),{role:N,highlightedId:h,setHighlightedId:v,registerItem:S,closeTree:x,setActiveSubmenuId:z}=$n("DropdownMenu.Item"),C=wt(()=>xt(t),[t]),W=h===f,$=Z(()=>{o||(s?.(),i&&x())},[i,x,o,s]);return He(()=>S({id:f,ref:g,disabled:o,submenu:!1,selected:a,textValue:C,closeOnSelect:i,click:$}),[i,o,$,f,S,a,C]),Kn("button",{ref:g,id:f,type:"button",role:N==="listbox"?"option":"menuitem",tabIndex:-1,disabled:o,"aria-selected":N==="listbox"?a:void 0,"data-highlighted":W||void 0,"data-selected":a||void 0,"data-disabled":o||void 0,"data-destructive":r||void 0,className:Re("ui-dropdown-menu__item",n&&"ui-dropdown-menu__item--inset",e),onMouseEnter:Ue(u,()=>{o||(v(f),z(null))}),onClick:Ue(c,q=>{q.preventDefault(),$()}),...m,children:[ae("span",{className:"ui-dropdown-menu__item-main",children:t}),d?ae("span",{className:"ui-dropdown-menu__shortcut",children:d}):null,a?ae("span",{className:"ui-dropdown-menu__indicator",children:l??"\u2713"}):null]})}function Lr(e){return ae(Un,{side:"right",align:"start",sideOffset:6,...e,contentRole:"menu"})}function zr({className:e,children:t,inset:n=!1,disabled:o=!1,destructive:a=!1,shortcut:r,onSelect:i,onMouseEnter:d,onClick:l,...s}){let u=yt(),c=Ie(null),m=$t("DropdownMenu.SubTrigger"),{highlightedId:f,setHighlightedId:g,registerItem:N,setActiveSubmenuId:h,activeSubmenuId:v}=$n("DropdownMenu.SubTrigger"),S=wt(()=>xt(t),[t]),x=f===u,z=m.open&&v===u,C=Z(()=>{o||(m.focusIntentRef.current="first",g(u),h(u),m.setOpen(!0))},[o,u,h,g,m]);return He(()=>N({id:u,ref:c,disabled:o,submenu:!0,selected:!1,textValue:S,closeOnSelect:!1,click:C,openSubmenu:C}),[o,u,C,N,S]),He(()=>{v!==u&&m.open&&m.setOpen(!1)},[v,u,m]),Kn("button",{ref:Gn(c,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":x||void 0,"data-state":z?"open":"closed","data-disabled":o||void 0,"data-destructive":a||void 0,className:Re("ui-dropdown-menu__item ui-dropdown-menu__sub-trigger",n&&"ui-dropdown-menu__item--inset",e),onMouseEnter:Ue(d,()=>{C()}),onClick:Ue(l,W=>{W.preventDefault(),C(),i?.()}),...s,children:[ae("span",{className:"ui-dropdown-menu__item-main",children:t}),r?ae("span",{className:"ui-dropdown-menu__shortcut",children:r}):null,ae("span",{className:"ui-dropdown-menu__submenu-indicator","aria-hidden":"true",children:"\u203A"})]})}var Er=Object.assign(Un,{Trigger:kr,Content:Pr,Group:Mr,Label:Ir,Item:Br,Separator:Rr,Submenu:Lr,SubTrigger:zr}),E=Er;import{jsx as V,jsxs as ye}from"react/jsx-runtime";function Hr(){return V("div",{className:"flex min-h-52 items-start justify-start pb-48",children:ye(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"})}),ye(E.Content,{children:[ye(E.Group,{children:[V(E.Item,{children:"Open settings"}),V(E.Item,{children:"Duplicate workspace"})]}),V(E.Separator,{}),ye(E.Submenu,{children:[V(E.SubTrigger,{children:"Theme"}),ye(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 Or(){let[e,t]=Ar("gpt-4.1-mini");return V("div",{className:"flex min-h-64 items-end pb-44",children:ye(E,{contentRole:"listbox",side:"top",align:"end",children:[V(E.Trigger,{asChild:!0,children:ye("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"})]})}),ye(E.Content,{className:"w-64",children:[ye(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))]}),ye(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(Hr,{})},{id:"picker",title:"Grouped Picker",description:"Model-picker style listbox with selected state.",render:()=>V(Or,{})}]});import{useState as Vr}from"react";import{clsx as qn}from"clsx";import{Fragment as _r,jsx as Yn,jsxs as Fr}from"react/jsx-runtime";function Gt({as:e="aside",open:t,children:n,side:o="right",position:a="fixed",showBackdrop:r=!0,onClose:i,closeLabel:d="\u5173\u95ED\u62BD\u5C49",backdropClassName:l,className:s,...u}){let c=o==="left"?"-translate-x-full":"translate-x-full",m=o==="left"?"left-0 top-0":"right-0 top-0",f=a==="fixed"?"fixed":"absolute";return Fr(_r,{children:[r&&t&&i&&Yn("button",{type:"button","aria-label":d,"data-state":"open",className:qn("ui-drawer-backdrop inset-0 z-10",f,l),onClick:i}),Yn(e,{"aria-hidden":!t,"data-state":t?"open":"closed","data-side":o,className:qn("ui-drawer",f,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 ${c}`,s),...u,children:n})]})}import{jsx as U,jsxs as Be}from"react/jsx-runtime";function Ut({side:e="right",showBackdrop:t=!0}){let[n,o]=Vr(!1);return Be("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(p,{variant:"primary",size:"sm",onClick:()=>o(!0),children:"Open Drawer"})}),U(Gt,{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:Be("div",{className:"flex h-full flex-col",children:[Be("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(p,{variant:"ghost",size:"sm",onClick:()=>o(!1),children:"Close"})]}),Be("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."})]}),Be("div",{className:"flex justify-end gap-2 border-t border-[var(--panel-section-border,var(--color-surface-border))] px-4 py-3",children:[U(p,{variant:"ghost",size:"sm",onClick:()=>o(!1),children:"Cancel"}),U(p,{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
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:()=>U(
|
|
86
|
+
</Drawer>`,render:()=>U(Ut,{side:"right"})},{id:"left",title:"Left Drawer",description:"Left-side variant for navigation or contextual tools.",render:()=>U(Ut,{side:"left"})},{id:"without-backdrop",title:"Without Backdrop",description:"Useful inside bounded shells where overlay dimming is not desired.",render:()=>U(Ut,{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:()=>U("div",{className:"rounded-xl bg-[var(--color-surface-subtle)] p-5",children:Be("div",{className:"relative h-[20rem] overflow-hidden rounded-xl border border-[var(--color-surface-border)] bg-[var(--color-surface-canvas)]",children:[U("div",{className:"absolute inset-0 bg-[var(--color-overlay-strong)]"}),Be("div",{className:"ui-drawer absolute inset-y-0 right-0 flex w-80 max-w-full flex-col border-l",children:[U("div",{className:"border-b border-[var(--drawer-border)] px-4 py-3 text-sm font-semibold text-[var(--color-n800)]",children:"Drawer Surface"}),Be("div",{className:"flex-1 space-y-3 p-4 text-sm text-[var(--color-n600)]",children:[U("p",{children:"Backdrop handles separation from the page."}),U("p",{children:"Surface defines the drawer body."}),U("p",{children:"Shadow confirms it is a floating layer, not a static card."})]})]})]})})}]});import{clsx as Nt}from"clsx";import{jsx as Tt}from"react/jsx-runtime";function Wr(e){switch(e){case"none":return"";case"sm":return"p-4";case"lg":return"p-6";default:return"p-5"}}function pe({as:e="section",variant:t="default",padding:n="none",className:o,children:a,...r}){return Tt(e,{"data-variant":t,className:Nt("ui-panel rounded-lg border",Wr(n),o),...r,children:a})}function Xn({className:e,children:t,...n}){return Tt("div",{className:Nt("ui-panel-header border-b px-6 py-5",e),...n,children:t})}function Zn({className:e,children:t,...n}){return Tt("div",{className:Nt("px-6 py-5",e),...n,children:t})}function Qn({className:e,children:t,...n}){return Tt("div",{className:Nt("ui-panel-footer border-t px-6 py-4",e),...n,children:t})}import{jsx as M,jsxs as me}from"react/jsx-runtime";y({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=>M(pe,{variant:e.variant,padding:e.padding,children:M("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:()=>me("div",{className:"grid gap-4 sm:grid-cols-3",children:[me(pe,{variant:"default",padding:"md",children:[M("p",{className:"text-sm font-medium",children:"Default"}),M("p",{className:"mt-1 text-xs text-[var(--color-n500)]",children:"Standard container."})]}),me(pe,{variant:"subtle",padding:"md",children:[M("p",{className:"text-sm font-medium",children:"Subtle"}),M("p",{className:"mt-1 text-xs text-[var(--color-n500)]",children:"Reduced emphasis."})]}),me(pe,{variant:"raised",padding:"md",children:[M("p",{className:"text-sm font-medium",children:"Raised"}),M("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:()=>me(pe,{variant:"default",className:"max-w-md",children:[
|
|
97
|
+
</Panel>`,render:()=>me(pe,{variant:"default",className:"max-w-md",children:[M(Xn,{children:M("h3",{className:"text-sm font-semibold",children:"Panel Title"})}),M(Zn,{children:M("p",{className:"text-sm text-[var(--color-n600)]",children:"This is the body content of the panel. It can contain any elements."})}),M(Qn,{children:me("div",{className:"flex justify-end gap-2",children:[M(p,{variant:"ghost",size:"sm",children:"Cancel"}),M(p,{variant:"primary",size:"sm",children:"Confirm"})]})})]})},{id:"on-surfaces",title:"On Different Surfaces",description:"Verifies panel contrast against canvas, subtle, and inset backgrounds.",render:()=>M("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})=>me("div",{className:"rounded-lg p-4",style:{backgroundColor:t},children:[M("p",{className:"mb-2 text-[11px] font-medium text-[var(--color-n500)]",children:e}),M(pe,{variant:"default",padding:"md",children:M("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:()=>M("div",{className:"rounded-xl bg-[var(--color-surface-subtle)] p-5",children:me("div",{className:"grid gap-4 lg:grid-cols-3",children:[me(pe,{variant:"default",padding:"md",children:[M("p",{className:"text-sm font-medium",children:"Default"}),M("p",{className:"mt-1 text-xs text-[var(--color-n500)]",children:"Primary reading card."})]}),me(pe,{variant:"subtle",padding:"md",children:[M("p",{className:"text-sm font-medium",children:"Subtle"}),M("p",{className:"mt-1 text-xs text-[var(--color-n500)]",children:"Secondary summary area."})]}),me(pe,{variant:"raised",padding:"md",children:[M("p",{className:"text-sm font-medium",children:"Raised"}),M("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:()=>M("div",{className:"space-y-3",children:["none","sm","md","lg"].map(e=>M(pe,{variant:"default",padding:e,children:me("span",{className:"text-xs",children:["padding=","\u201C",e,"\u201D"]})},e))})}]});export{wo as getGroupedStories,xo as getStoriesByGroupAndComponent,No as groupLabels,To as groupOrder,y as registerStories,yo as storybookStoryPaths};
|