@zhama/a2ui 0.10.1

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.
@@ -0,0 +1,2 @@
1
+ import Ue from'react-markdown';import {createContext,useState,useCallback,useEffect,useContext}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import*as Me from'lucide-react';var Fe=Object.defineProperty;var Be=(e,t,o)=>t in e?Fe(e,t,{enumerable:true,configurable:true,writable:true,value:o}):e[t]=o;var N=(e,t,o)=>Be(e,typeof t!="symbol"?t+"":t,o);function A(){return {}}var ae={components:{AudioPlayer:A(),Button:{"a2ui-btn":true,"inline-flex":true,"items-center":true,"justify-center":true,"whitespace-nowrap":true,"rounded-xl":true,"text-xs":true,"font-medium":true,"transition-all":true,"duration-300":true,"disabled:pointer-events-none":true,"disabled:opacity-50":true,"active:scale-95":true,"bg-primary":true,"text-primary-foreground":true,"hover:bg-primary/90":true,"shadow-sm":true,"h-9":true,"px-4":true,"py-2":true},Card:{"a2ui-card":true,group:true,relative:true,"rounded-2xl":true,border:true,"border-border/50":true,"bg-card":true,"text-card-foreground":true,"shadow-sm":true,"transition-all":true,"duration-300":true,"hover:shadow-md":true,"hover:border-primary/40":true,"hover:-translate-y-1":true,"p-5":true,"overflow-hidden":true},Column:{"a2ui-column":true,flex:true,"flex-col":true,"space-y-4":true},CheckBox:{container:{"a2ui-checkbox":true,flex:true,"items-center":true,"gap-2":true},element:{"w-4":true,"h-4":true},label:{"text-sm":true,"font-medium":true}},DateTimeInput:{container:{"a2ui-datetime":true,flex:true,"flex-col":true,"gap-1":true},element:{"px-3":true,"py-2":true,border:true,"border-input":true,"rounded-md":true,"bg-background":true,"transition-colors":true},label:{"text-sm":true,"font-medium":true}},Divider:{"a2ui-divider":true,"border-t":true,"border-border/50":true,"my-8":true},Image:{all:{"a2ui-image":true,"max-w-full":true,"h-auto":true},icon:{"w-6":true,"h-6":true},avatar:{"w-10":true,"h-10":true,"rounded-full":true},smallFeature:{"w-24":true,"h-24":true},mediumFeature:{"w-48":true,"h-48":true},largeFeature:{"w-full":true,"max-h-96":true},header:{"w-full":true,"h-32":true,"object-cover":true}},Icon:{"a2ui-icon":true,"w-5":true,"h-5":true},List:{"a2ui-list":true,grid:true,"grid-cols-1":true,"md:grid-cols-2":true,"gap-4":true,"w-full":true},Modal:{backdrop:{fixed:true,"inset-0":true,"bg-black/50":true,flex:true,"items-center":true,"justify-center":true,"z-50":true},element:{"bg-card":true,"rounded-lg":true,"p-6":true,"max-w-lg":true,"w-full":true,"mx-4":true,"shadow-xl":true,border:true,"border-border":true,"border-white/60":true}},MultipleChoice:{container:{"a2ui-multichoice":true,flex:true,"flex-col":true,"gap-2":true},element:{"px-3":true,"py-2":true,border:true,"border-input":true,"rounded-md":true,"bg-background":true,"w-full":true},label:{"text-sm":true,"font-medium":true}},Row:{"a2ui-row":true,flex:true,"flex-row":true,"items-center":true,"justify-between":true,"gap-6":true,"w-full":true},Slider:{container:{"a2ui-slider":true,flex:true,"flex-col":true,"gap-1":true},element:{"w-full":true},label:{"text-sm":true,"font-medium":true}},Tabs:{container:{"a2ui-tabs":true,flex:true,"flex-col":true,"space-y-4":true},element:{flex:true,"border-b":true,"border-border":true},controls:{all:{"px-4":true,"py-2":true,"text-sm":true,"font-medium":true,"cursor-pointer":true,"transition-colors":true,"rounded-t-md":true},selected:{"border-b-2":true,"border-primary":true,"text-primary":true,"-mb-px":true}}},Text:{all:{"a2ui-text":true},h1:{"text-3xl":true,"font-bold":true,"tracking-tight":true,"mb-4":true},h2:{"text-xl":true,"font-semibold":true,"mb-2":true},h3:{"text-lg":true,"font-medium":true,"mb-1":true},h4:{"text-base":true,"font-medium":true},h5:{"text-sm":true,"font-medium":true},h6:{"text-xs":true,"font-medium":true},body:{"text-base":true,"leading-relaxed":true,"text-foreground/90":true},caption:{"text-sm":true,"text-muted-foreground":true,"leading-relaxed":true},label:{"text-sm":true,"font-medium":true,"leading-none":true}},TextField:{container:{"a2ui-textfield":true,flex:true,"flex-col":true,"gap-1.5":true},element:{flex:true,"h-10":true,"w-full":true,"rounded-md":true,border:true,"border-input":true,"bg-background":true,"px-3":true,"py-2":true,"text-sm":true,"ring-offset-background":true,"transition-colors":true,"placeholder:text-muted-foreground":true,"focus-visible:outline-none":true,"focus-visible:ring-2":true,"focus-visible:ring-ring":true,"focus-visible:ring-offset-2":true,"disabled:cursor-not-allowed":true,"disabled:opacity-50":true},label:{"text-sm":true,"font-medium":true,"leading-none":true}},Video:{"a2ui-video":true,"w-full":true,"rounded-2xl":true,border:true,"border-border/50":true}},elements:{a:{"text-primary":true,"underline-offset-4":true,"hover:underline":true,"transition-colors":true},audio:A(),body:{"text-base":true},button:A(),h1:{"text-3xl":true,"font-bold":true,"tracking-tight":true},h2:{"text-xl":true,"font-semibold":true},h3:{"text-lg":true,"font-bold":true},h4:{"text-base":true,"font-semibold":true},h5:{"text-base":true,"font-medium":true},iframe:A(),input:A(),p:{"text-base":true,"leading-relaxed":true},pre:{"font-mono":true,"text-sm":true,"bg-muted":true,"p-4":true,"rounded-md":true,"overflow-x-auto":true,border:true,"border-border":true},textarea:A(),video:A()},markdown:{p:["text-[15px]","leading-[1.7]","mb-3"],h1:["text-xl","font-bold","tracking-tight","mt-6","mb-4"],h2:["text-[17px]","font-semibold","mt-5","mb-3"],h3:["text-[15px]","font-semibold","mt-4","mb-2"],h4:["text-[15px]","font-medium","mt-3","mb-2"],h5:["text-sm","font-medium","mt-3","mb-2"],ul:["list-disc","list-outside","ml-5","mb-3","space-y-1.5"],ol:["list-decimal","list-outside","ml-5","mb-3","space-y-1.5"],li:["text-[15px]","leading-[1.7]","pl-1"],a:["text-primary","underline-offset-2","hover:underline","font-medium"],strong:["font-semibold"],em:["not-italic","opacity-80"],code:["font-mono","text-[13px]","bg-muted/60","px-1.5","py-0.5","rounded","border","border-border/50"],blockquote:["border-l-3","border-primary/40","pl-4","py-2","text-muted-foreground","bg-muted/30","rounded-r","mb-3","text-[14px]"]}};var _e=createContext(ae);function m(){return useContext(_e)}function M(...e){let t={};for(let o of e)if(o)for(let[n,s]of Object.entries(o)){let r=n.split("-").slice(0,-1).join("-")+"-",i=Object.keys(t).filter(a=>a.startsWith(r));for(let a of i)delete t[a];t[n]=s;}return t}function le(e,t){return e==="path"&&typeof t=="string"}function f(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ce(e){return f(e)?"explicitList"in e||"template"in e:false}function I(e){return f(e)&&("path"in e||"literal"in e&&typeof e.literal=="string"||"literalString"in e)}function ze(e){return f(e)&&("path"in e||"literal"in e&&typeof e.literal=="number"||"literalNumber"in e)}function Ke(e){return f(e)&&("path"in e||"literal"in e&&typeof e.literal=="boolean"||"literalBoolean"in e)}function w(e){return f(e)?"id"in e&&"type"in e&&"properties"in e:false}function ue(e){return f(e)&&"url"in e&&I(e.url)}function de(e){return f(e)&&"child"in e&&w(e.child)&&"action"in e}function pe(e){return f(e)?"child"in e?w(e.child):"children"in e?Array.isArray(e.children)&&e.children.every(w):false:false}function me(e){return f(e)&&"label"in e&&I(e.label)&&"value"in e&&Ke(e.value)}function fe(e){return f(e)&&"children"in e&&Array.isArray(e.children)&&e.children.every(w)}function he(e){return f(e)&&"value"in e&&I(e.value)}function ye(e){return f(e)}function ge(e){return f(e)&&"url"in e&&I(e.url)}function xe(e){return f(e)&&"name"in e&&I(e.name)}function be(e){return f(e)&&"children"in e&&Array.isArray(e.children)&&e.children.every(w)}function Re(e){return f(e)&&"entryPointChild"in e&&w(e.entryPointChild)&&"contentChild"in e&&w(e.contentChild)}function Ce(e){return f(e)&&"selections"in e}function ve(e){return f(e)&&"children"in e&&Array.isArray(e.children)&&e.children.every(w)}function Ne(e){return f(e)&&"value"in e&&ze(e.value)}function He(e){return f(e)&&"title"in e&&I(e.title)&&"child"in e&&w(e.child)}function we(e){return f(e)&&"tabItems"in e&&Array.isArray(e.tabItems)&&e.tabItems.every(He)}function Ie(e){return f(e)&&"text"in e&&I(e.text)}function Ae(e){return f(e)&&"label"in e&&I(e.label)}function Te(e){return f(e)&&"url"in e&&I(e.url)}var S=class S{constructor(t={}){N(this,"mapCtor",Map);N(this,"arrayCtor",Array);N(this,"setCtor",Set);N(this,"objCtor",Object);N(this,"surfaces");this.arrayCtor=t.arrayCtor??Array,this.mapCtor=t.mapCtor??Map,this.setCtor=t.setCtor??Set,this.objCtor=t.objCtor??Object,this.surfaces=new this.mapCtor;}getSurfaces(){return this.surfaces}clearSurfaces(){this.surfaces.clear();}processMessages(t){for(let o of t)o.beginRendering&&this.handleBeginRendering(o.beginRendering,o.beginRendering.surfaceId),o.surfaceUpdate&&this.handleSurfaceUpdate(o.surfaceUpdate,o.surfaceUpdate.surfaceId),o.dataModelUpdate&&this.handleDataModelUpdate(o.dataModelUpdate,o.dataModelUpdate.surfaceId),o.deleteSurface&&this.handleDeleteSurface(o.deleteSurface);}getData(t,o,n=S.DEFAULT_SURFACE_ID){let s=this.getOrCreateSurface(n);if(!s)return null;let r;return o==="."||o===""?r=t.dataContextPath??"/":r=this.resolvePath(o,t.dataContextPath),this.getDataByPath(s.dataModel,r)}setData(t,o,n,s=S.DEFAULT_SURFACE_ID){if(!t){console.warn("No component node set");return}let r=this.getOrCreateSurface(s);if(!r)return;let i;o==="."||o===""?i=t.dataContextPath??"/":i=this.resolvePath(o,t.dataContextPath),this.setDataByPath(r.dataModel,i,n);}resolvePath(t,o){return t.startsWith("/")?t:o&&o!=="/"?o.endsWith("/")?`${o}${t}`:`${o}/${t}`:`/${t}`}parseIfJsonString(t){if(typeof t!="string")return t;let o=t.trim();if(o.startsWith("{")&&o.endsWith("}")||o.startsWith("[")&&o.endsWith("]"))try{return JSON.parse(t)}catch{return console.warn(`Failed to parse potential JSON string: "${t.substring(0,50)}..."`),t}return t}convertKeyValueArrayToMap(t){let o=new this.mapCtor;for(let n of t){if(!f(n)||!("key"in n))continue;let s=n.key,r=this.findValueKey(n);if(!r)continue;let i=n[r];r==="valueMap"&&Array.isArray(i)?i=this.convertKeyValueArrayToMap(i):typeof i=="string"&&(i=this.parseIfJsonString(i)),this.setDataByPath(o,s,i);}return o}setDataByPath(t,o,n){if(Array.isArray(n)&&(n.length===0||f(n[0])&&"key"in n[0]))if(n.length===1&&f(n[0])&&n[0].key==="."){let a=n[0],u=this.findValueKey(a);u?(n=a[u],u==="valueMap"&&Array.isArray(n)?n=this.convertKeyValueArrayToMap(n):typeof n=="string"&&(n=this.parseIfJsonString(n))):n=this.convertKeyValueArrayToMap(n);}else n=this.convertKeyValueArrayToMap(n);let s=this.normalizePath(o).split("/").filter(a=>a);if(s.length===0){if(n instanceof Map||f(n)){!(n instanceof Map)&&f(n)&&(n=new this.mapCtor(Object.entries(n))),t.clear();for(let[a,u]of n.entries())t.set(a,u);}else console.error("Cannot set root of DataModel to a non-Map value.");return}let r=t;for(let a=0;a<s.length-1;a++){let u=s[a],p;r instanceof Map?p=r.get(u):Array.isArray(r)&&/^\d+$/.test(u)&&(p=r[parseInt(u,10)]),(p===void 0||typeof p!="object"||p===null)&&(p=new this.mapCtor,r instanceof this.mapCtor?r.set(u,p):Array.isArray(r)&&(r[parseInt(u,10)]=p)),r=p;}let i=s[s.length-1];r instanceof this.mapCtor?r.set(i,n):Array.isArray(r)&&/^\d+$/.test(i)&&(r[parseInt(i,10)]=n);}normalizePath(t){return "/"+t.replace(/\[(\d+)\]/g,".$1").split(".").filter(s=>s.length>0).join("/")}getDataByPath(t,o){let n=this.normalizePath(o).split("/").filter(r=>r),s=t;for(let r of n){if(s==null)return null;if(s instanceof Map)s=s.get(r);else if(Array.isArray(s)&&/^\d+$/.test(r))s=s[parseInt(r,10)];else if(f(s))s=s[r];else return null}return s??null}getOrCreateSurface(t){let o=this.surfaces.get(t);return o||(o={rootComponentId:null,componentTree:null,dataModel:new this.mapCtor,components:new this.mapCtor,styles:{}},this.surfaces.set(t,o)),o}handleBeginRendering(t,o){let n=this.getOrCreateSurface(o);n.rootComponentId=t.root,n.styles=t.styles??{},this.rebuildComponentTree(n);}handleSurfaceUpdate(t,o){let n=this.getOrCreateSurface(o);for(let s of t.components)n.components.set(s.id,s);this.rebuildComponentTree(n);}handleDataModelUpdate(t,o){let n=this.getOrCreateSurface(o),s=t.path??"/";this.setDataByPath(n.dataModel,s,t.contents),this.rebuildComponentTree(n);}handleDeleteSurface(t){this.surfaces.delete(t.surfaceId);}rebuildComponentTree(t){if(!t.rootComponentId){t.componentTree=null;return}let o=new this.setCtor;t.componentTree=this.buildNodeRecursive(t.rootComponentId,t,o,"/","");}findValueKey(t){return Object.keys(t).find(o=>o.startsWith("value"))}buildNodeRecursive(t,o,n,s,r=""){let i=`${t}${r}`,{components:a}=o;if(!a.has(t))return null;if(n.has(i))throw new Error(`Circular dependency for component "${i}".`);n.add(i);let u=a.get(t),p=u.component??{},l=Object.keys(p)[0]??"Unknown",b=p[l],d={};if(f(b))for(let[T,k]of Object.entries(b))d[T]=this.resolvePropertyValue(k,o,n,s,r);n.delete(i);let y={id:i,dataContextPath:s,weight:u.weight??"initial"};switch(l){case "Text":if(!Ie(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"Text",properties:d};case "Image":if(!ge(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"Image",properties:d};case "Icon":if(!xe(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"Icon",properties:d};case "Video":if(!Te(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"Video",properties:d};case "AudioPlayer":if(!ue(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"AudioPlayer",properties:d};case "Row":if(!ve(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"Row",properties:d};case "Column":if(!fe(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"Column",properties:d};case "List":if(!be(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"List",properties:d};case "Card":if(!pe(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"Card",properties:d};case "Tabs":if(!we(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"Tabs",properties:d};case "Divider":if(!ye(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"Divider",properties:d};case "Modal":if(!Re(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"Modal",properties:d};case "Button":if(!de(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"Button",properties:d};case "CheckBox":if(!me(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"CheckBox",properties:d};case "TextField":if(!Ae(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"TextField",properties:d};case "DateTimeInput":if(!he(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"DateTimeInput",properties:d};case "MultipleChoice":if(!Ce(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"MultipleChoice",properties:d};case "Slider":if(!Ne(d))throw new Error(`Invalid data; expected ${l}`);return {...y,type:"Slider",properties:d};default:return {...y,type:l,properties:d}}}resolvePropertyValue(t,o,n,s,r=""){if(typeof t=="string"&&o.components.has(t))return this.buildNodeRecursive(t,o,n,s,r);if(ce(t)){if(t.explicitList)return t.explicitList.map(i=>this.buildNodeRecursive(i,o,n,s,r));if(t.template){let i=this.resolvePath(t.template.dataBinding,s),a=this.getDataByPath(o.dataModel,i),u=t.template;return Array.isArray(a)?a.map((p,l)=>{let y=`:${[...s.split("/").filter(k=>/^\d+$/.test(k)),l].join(":")}`,T=`${i}/${l}`;return this.buildNodeRecursive(u.componentId,o,n,T,y)}):a instanceof Map?Array.from(a.keys(),p=>{let l=`:${p}`,b=`${i}/${p}`;return this.buildNodeRecursive(u.componentId,o,n,b,l)}):[]}}if(Array.isArray(t))return t.map(i=>this.resolvePropertyValue(i,o,n,s,r));if(f(t)){let i={};for(let[a,u]of Object.entries(t)){let p=u;if(le(a,u)&&s!=="/"){p=u.replace(/^\.?\/item/,"").replace(/^\.?\/text/,"").replace(/^\.?\/label/,"").replace(/^\.?\//,""),i[a]=p;continue}i[a]=this.resolvePropertyValue(p,o,n,s,r);}return i}return t}};N(S,"DEFAULT_SURFACE_ID","@default");var R=S;function g(e,t,o,n){if(e!==null&&typeof e=="object"){if("literalString"in e)return e.literalString??"";if("literal"in e&&e.literal!==void 0)return e.literal??"";if(e&&"path"in e&&e.path){if(!o||!t)return "(no model)";let s=o.getData(t,e.path,n??R.DEFAULT_SURFACE_ID);return s===null||typeof s!="string"?"":s}}return ""}function D(e,t,o,n){if(e!==null&&typeof e=="object"){if("literalNumber"in e)return e.literalNumber??0;if("literal"in e&&e.literal!==void 0)return e.literal??0;if(e&&"path"in e&&e.path){if(!o||!t)return -1;let s=o.getData(t,e.path,n??R.DEFAULT_SURFACE_ID);return typeof s=="string"&&(s=Number.parseInt(s,10),Number.isNaN(s)&&(s=null)),s===null||typeof s!="number"?-1:s}}return 0}function c(...e){let t=[];for(let o of e)if(o){if(typeof o=="string")t.push(o);else if(typeof o=="object")for(let[n,s]of Object.entries(o))s&&t.push(n);}return t.join(" ")}function j({component:e,processor:t,surfaceId:o,text:n,usageHint:s="body",markdown:r=true}){let i=m(),a=g(n,e,t,o);if(!a)return jsx("span",{className:"text-gray-400",children:"(empty)"});let u=M(i.components.Text.all,s?i.components.Text[s]:{});if(r){let p=()=>{switch(s){case "h1":return `# ${a}`;case "h2":return `## ${a}`;case "h3":return `### ${a}`;case "h4":return `#### ${a}`;case "h5":return `##### ${a}`;case "caption":return `*${a}*`;default:return a}};return jsx("section",{className:c(u),children:jsx(Ue,{components:{p:({children:l})=>jsx("p",{className:i.markdown.p.join(" "),children:l}),h1:({children:l})=>jsx("h1",{className:i.markdown.h1.join(" "),children:l}),h2:({children:l})=>jsx("h2",{className:i.markdown.h2.join(" "),children:l}),h3:({children:l})=>jsx("h3",{className:i.markdown.h3.join(" "),children:l}),h4:({children:l})=>jsx("h4",{className:i.markdown.h4.join(" "),children:l}),h5:({children:l})=>jsx("h5",{className:i.markdown.h5.join(" "),children:l}),ul:({children:l})=>jsx("ul",{className:i.markdown.ul.join(" "),children:l}),ol:({children:l})=>jsx("ol",{className:i.markdown.ol.join(" "),children:l}),li:({children:l})=>jsx("li",{className:i.markdown.li.join(" "),children:l}),a:({children:l,href:b})=>jsx("a",{href:b,className:i.markdown.a.join(" "),children:l}),strong:({children:l})=>jsx("strong",{className:i.markdown.strong.join(" "),children:l}),em:({children:l})=>jsx("em",{className:i.markdown.em.join(" "),children:l})},children:p()})})}switch(s){case "h1":return jsx("h1",{className:c(u),children:a});case "h2":return jsx("h2",{className:c(u),children:a});case "h3":return jsx("h3",{className:c(u),children:a});case "h4":return jsx("h4",{className:c(u),children:a});case "h5":return jsx("h5",{className:c(u),children:a});case "caption":return jsx("span",{className:c(u),children:a});default:return jsx("p",{className:c(u),children:a})}}function $({component:e,processor:t,surfaceId:o,url:n,usageHint:s,fit:r="cover"}){let i=m(),a=g(n,e,t,o);if(!a)return jsx("div",{className:"text-gray-400",children:"(no image)"});let u=M(i.components.Image.all,s?i.components.Image[s]:{}),p={objectFit:r??"cover"};return jsx("img",{src:a,alt:"",className:c(u),style:p})}function F({component:e,processor:t,surfaceId:o,name:n,size:s=20,className:r,container:i,variant:a}){let u=m(),p=g(n,e,t,o);if(!p)return null;let l=p.split("-").map(k=>k.charAt(0).toUpperCase()+k.slice(1)).join(""),b=Me[l]??Me[p],d={blue:"bg-blue-50 text-blue-600",green:"bg-green-50 text-green-600",purple:"bg-purple-50 text-purple-600",orange:"bg-orange-50 text-orange-600",red:"bg-red-50 text-red-600",primary:"bg-primary/10 text-primary"},y=a?d[a]:d.primary,T=()=>b?jsx(b,{size:s,className:c(u.components.Icon,r)}):jsx("span",{className:c(u.components.Icon,"material-icons",r),style:{fontSize:s},children:p});return i?jsx("div",{className:c("flex shrink-0 items-center justify-center rounded-xl transition-all duration-300","group-hover:scale-110 group-hover:shadow-sm",y),style:{width:40,height:40},children:T()}):T()}function L({component:e,processor:t,surfaceId:o,url:n}){let s=m(),r=g(n,e,t,o);return r?jsx("section",{className:c(s.components.Video),children:jsx("video",{controls:true,src:r,className:"w-full"})}):jsx("div",{className:"text-gray-400",children:"(no video)"})}function _({component:e,processor:t,surfaceId:o,url:n,description:s}){let r=m(),i=g(n,e,t,o),a=s?g(s,e,t,o):void 0;return i?jsxs("section",{className:c(r.components.AudioPlayer),children:[a&&jsx("p",{className:"mb-2 text-sm",children:a}),jsx("audio",{controls:true,src:i,className:"w-full"})]}):jsx("div",{className:"text-gray-400",children:"(no audio)"})}function z({component:e,action:t,children:o,onAction:n}){let s=m(),r=()=>{if(!t||!n)return;let i={eventType:"a2ui.action",action:t,dataContextPath:e.dataContextPath??"/",sourceComponentId:e.id,sourceComponent:e};n(i);};return jsx("button",{type:"button",className:c(s.components.Button),onClick:r,children:o})}var Se={start:"items-start",center:"items-center",end:"items-end",stretch:"items-stretch"},De={start:"justify-start",center:"justify-center",end:"justify-end",spaceBetween:"justify-between",spaceAround:"justify-around",spaceEvenly:"justify-evenly"};function K({component:e,alignment:t="stretch",distribution:o="start",children:n}){let s=m(),r=Se[t]??Se.stretch,i=De[o]??De.start,a=e.properties??{},u=a.gap!==void 0?`gap-${a.gap}`:"";return jsx("section",{className:c(s.components.Row,r,i,u),children:n})}var Pe={start:"items-start",center:"items-center",end:"items-end",stretch:"items-stretch"},Ve={start:"justify-start",center:"justify-center",end:"justify-end",spaceBetween:"justify-between",spaceAround:"justify-around",spaceEvenly:"justify-evenly"};function H({component:e,alignment:t="stretch",distribution:o="start",children:n}){let s=m(),r=Pe[t]??Pe.stretch,i=Ve[o]??Ve.start,a=e.properties??{},u=a.spaceY!==void 0?`space-y-${a.spaceY}`:"";return jsx("section",{className:c(s.components.Column,r,i,u),children:n})}function W({direction:e="vertical",children:t}){let o=m(),n=e==="horizontal"?"flex-row overflow-x-auto":"flex-col";return jsx("section",{className:c(o.components.List,n),children:t})}function J({children:e}){let t=m();return jsx("section",{className:c(t.components.Card),children:e})}function q({component:e,processor:t,surfaceId:o,titles:n,children:s}){let r=m(),[i,a]=useState(0),u=()=>jsx("div",{className:c(r.components.Tabs.element),children:n.map((l,b)=>{let d=g(l,e,t,o),y=i===b?M(r.components.Tabs.controls.all,r.components.Tabs.controls.selected):{...r.components.Tabs.controls.all};return jsx("button",{disabled:i===b,className:c(y),onClick:()=>a(b),children:d},b)})}),p=s?.[i];return jsxs("section",{className:c(r.components.Tabs.container),children:[u(),jsx("div",{className:"mt-4",children:p})]})}function Z({axis:e="horizontal",thickness:t=1,color:o}){let n=m(),s={};o&&(s.borderColor=o),t&&(s.borderWidth=t);let r=e==="vertical"?"border-l h-full":"border-t w-full";return jsx("hr",{className:c(n.components.Divider,r),style:s})}function G({entryPoint:e,content:t}){let o=m(),[n,s]=useState(false),r=useCallback(()=>{s(false);},[]);return useEffect(()=>{if(!n)return;let i=a=>{a.key==="Escape"&&r();};return document.addEventListener("keydown",i),()=>document.removeEventListener("keydown",i)},[n,r]),n?jsx("dialog",{className:c(o.components.Modal.backdrop),open:true,role:"dialog","aria-modal":"true",onClick:i=>{i.target===i.currentTarget&&r();},children:jsxs("section",{className:c(o.components.Modal.element),children:[jsx("div",{className:"mb-2 flex justify-end",children:jsx("button",{type:"button",className:"rounded p-1 hover:bg-gray-100",onClick:r,"aria-label":"Close modal",children:"\u2715"})}),t]})}):jsx("button",{type:"button",onClick:()=>s(true),className:"cursor-pointer",children:e})}function Q({component:e,processor:t,surfaceId:o,label:n,value:s}){let r=m(),i=g(n,e,t,o),a=false;s&&("literalBoolean"in s&&s.literalBoolean!==void 0?a=s.literalBoolean:"path"in s&&s.path&&t&&e&&(a=!!t.getData(e,s.path,o??R.DEFAULT_SURFACE_ID)));let u=p=>{!s||!t||!("path"in s)||!s.path||t.setData(e,s.path,p.target.checked,o??R.DEFAULT_SURFACE_ID);};return jsxs("section",{className:c(r.components.CheckBox.container),children:[jsx("input",{type:"checkbox",id:`checkbox-${e.id}`,className:c(r.components.CheckBox.element),checked:a,onChange:u}),jsx("label",{htmlFor:`checkbox-${e.id}`,className:c(r.components.CheckBox.label),children:i})]})}function ee({component:e,processor:t,surfaceId:o,label:n,text:s,type:r="shortText"}){let i=m(),a=g(n,e,t,o),u=s?g(s,e,t,o):"",p=d=>{!s||!t||!("path"in s)||!s.path||t.setData(e,s.path,d.target.value,o??R.DEFAULT_SURFACE_ID);},l=r==="number"?"number":r==="date"?"date":"text",b=r==="longText";return jsxs("section",{className:c(i.components.TextField.container),children:[a&&jsx("label",{htmlFor:`textfield-${e.id}`,className:c(i.components.TextField.label),children:a}),b?jsx("textarea",{id:`textfield-${e.id}`,className:c(i.components.TextField.element),value:u,onChange:p,placeholder:"Please enter a value",rows:4}):jsx("input",{id:`textfield-${e.id}`,type:l,className:c(i.components.TextField.element),value:u,onChange:p,placeholder:"Please enter a value",autoComplete:"off"})]})}function te({component:e,processor:t,surfaceId:o,value:n,enableDate:s=true,enableTime:r=true}){let i=m(),a=g(n,e,t,o),u=l=>{!n||!t||!("path"in n)||!n.path||t.setData(e,n.path,l.target.value,o??R.DEFAULT_SURFACE_ID);},p="datetime-local";return s&&!r?p="date":!s&&r&&(p="time"),jsx("section",{className:c(i.components.DateTimeInput.container),children:jsx("input",{type:p,id:`datetime-${e.id}`,className:c(i.components.DateTimeInput.element),value:a,onChange:u})})}function oe({component:e,processor:t,surfaceId:o,selections:n,options:s=[]}){let r=m(),i=a=>{!n||!t||!("path"in n)||!n.path||t.setData(e,n.path,[a.target.value],o??R.DEFAULT_SURFACE_ID);};return jsxs("section",{className:c(r.components.MultipleChoice.container),children:[jsx("label",{htmlFor:`multichoice-${e.id}`,className:c(r.components.MultipleChoice.label),children:"Select an item"}),jsx("select",{id:`multichoice-${e.id}`,className:c(r.components.MultipleChoice.element),onChange:i,children:s?.map((a,u)=>{let p=g(a.label,e,t,o);return jsx("option",{value:a.value,children:p},u)})})]})}function ne({component:e,processor:t,surfaceId:o,value:n,minValue:s,maxValue:r}){let i=m(),a=D(n,e,t,o),u=typeof s=="number"?s:s?D(s,e,t,o):0,p=typeof r=="number"?r:r?D(r,e,t,o):100,l=b=>{!n||!t||!("path"in n)||!n.path||t.setData(e,n.path,Number(b.target.value),o??R.DEFAULT_SURFACE_ID);};return jsxs("section",{className:c(i.components.Slider.container),children:[jsx("input",{type:"range",id:`slider-${e.id}`,className:c(i.components.Slider.element),value:a,min:u,max:p,onChange:l}),jsx("span",{className:c(i.components.Slider.label),children:a})]})}var V=class{constructor(){N(this,"registry",new Map);}register(t,o){if(!/^[a-zA-Z0-9]+$/.test(t))throw new Error(`[Registry] Invalid typeName '${t}'. Must be alphanumeric.`);this.registry.set(t,o);}get(t){return this.registry.get(t)}has(t){return this.registry.has(t)}unregister(t){return this.registry.delete(t)}getRegisteredTypes(){return Array.from(this.registry.keys())}},E=new V;function se({processor:e,surfaceId:t,childComponents:o,enableCustomElements:n=false,onAction:s}){return !o||!Array.isArray(o)?null:jsx(Fragment,{children:o.map(r=>jsx(v,{component:r,processor:e,surfaceId:t,enableCustomElements:n,onAction:s},r.id))})}function v({component:e,processor:t,surfaceId:o,enableCustomElements:n,onAction:s}){if(n){let r=E.get(e.type);if(r)return jsx(r,{component:e,processor:t,surfaceId:o,...e.properties},e.id)}switch(e.type){case "Text":{let r=e;return jsx(j,{component:r,processor:t,surfaceId:o,text:r.properties.text,usageHint:r.properties.usageHint},r.id)}case "Image":{let r=e;return jsx($,{component:r,processor:t,surfaceId:o,url:r.properties.url,usageHint:r.properties.usageHint,fit:r.properties.fit},r.id)}case "Icon":{let r=e;return jsx(F,{component:r,processor:t,surfaceId:o,name:r.properties.name,container:r.properties.container,variant:r.properties.variant,size:r.properties.size},r.id)}case "Video":{let r=e;return jsx(L,{component:r,processor:t,surfaceId:o,url:r.properties.url},r.id)}case "AudioPlayer":{let r=e;return jsx(_,{component:r,processor:t,surfaceId:o,url:r.properties.url,description:r.properties.description},r.id)}case "Button":{let r=e;return jsx(z,{component:r,processor:t,surfaceId:o,action:r.properties.action,onAction:s,children:r.properties.child&&jsx(v,{component:r.properties.child,processor:t,surfaceId:o,enableCustomElements:n,onAction:s})},r.id)}case "Row":{let r=e;return jsx(K,{component:r,processor:t,surfaceId:o,alignment:r.properties.alignment,distribution:r.properties.distribution,children:r.properties.children?.map(i=>jsx(v,{component:i,processor:t,surfaceId:o,enableCustomElements:n,onAction:s},i.id))},r.id)}case "Column":{let r=e;return jsx(H,{component:r,processor:t,surfaceId:o,alignment:r.properties.alignment,distribution:r.properties.distribution,children:r.properties.children?.map(i=>jsx(v,{component:i,processor:t,surfaceId:o,enableCustomElements:n,onAction:s},i.id))},r.id)}case "List":{let r=e;return jsx(W,{component:r,processor:t,surfaceId:o,direction:r.properties.direction,children:r.properties.children?.map(i=>jsx(v,{component:i,processor:t,surfaceId:o,enableCustomElements:n,onAction:s},i.id))},r.id)}case "Card":{let r=e,i=r.properties.children??(r.properties.child?[r.properties.child]:[]);return jsx(J,{component:r,processor:t,surfaceId:o,children:i.map(a=>jsx(v,{component:a,processor:t,surfaceId:o,enableCustomElements:n,onAction:s},a.id))},r.id)}case "Tabs":{let r=e,i=r.properties.tabItems?.map(u=>u.title)??[],a=r.properties.tabItems?.map(u=>jsx(v,{component:u.child,processor:t,surfaceId:o,enableCustomElements:n,onAction:s},u.child.id));return jsx(q,{component:r,processor:t,surfaceId:o,titles:i,children:a},r.id)}case "Divider":{let r=e;return jsx(Z,{component:r,processor:t,surfaceId:o,axis:r.properties.axis,thickness:r.properties.thickness,color:r.properties.color},r.id)}case "Modal":{let r=e;return jsx(G,{component:r,processor:t,surfaceId:o,entryPoint:jsx(v,{component:r.properties.entryPointChild,processor:t,surfaceId:o,enableCustomElements:n,onAction:s}),content:jsx(v,{component:r.properties.contentChild,processor:t,surfaceId:o,enableCustomElements:n,onAction:s})},r.id)}case "CheckBox":{let r=e;return jsx(Q,{component:r,processor:t,surfaceId:o,label:r.properties.label,value:r.properties.value},r.id)}case "TextField":{let r=e;return jsx(ee,{component:r,processor:t,surfaceId:o,label:r.properties.label,text:r.properties.text,type:r.properties.type,validationRegexp:r.properties.validationRegexp},r.id)}case "DateTimeInput":{let r=e;return jsx(te,{component:r,processor:t,surfaceId:o,value:r.properties.value,enableDate:r.properties.enableDate,enableTime:r.properties.enableTime},r.id)}case "MultipleChoice":{let r=e;return jsx(oe,{component:r,processor:t,surfaceId:o,selections:r.properties.selections,options:r.properties.options,maxAllowedSelections:r.properties.maxAllowedSelections},r.id)}case "Slider":{let r=e;return jsx(ne,{component:r,processor:t,surfaceId:o,value:r.properties.value,minValue:r.properties.minValue,maxValue:r.properties.maxValue},r.id)}default:{if(n){let r=E.get(e.type);if(r)return jsx(r,{component:e,processor:t,surfaceId:o,...e.properties},e.id)}return jsxs("div",{className:"rounded border border-yellow-300 p-2 text-yellow-600",children:["Unknown component type: ",e.type]},e.id)}}}function pt({surfaceId:e,surface:t,processor:o,enableCustomElements:n=false,onAction:s}){if(!t)return null;let r=()=>t.styles?.logoUrl?jsx("div",{className:"mb-4 flex justify-center",children:jsx("img",{src:t.styles.logoUrl,alt:"Logo",className:"w-1/2 max-w-[220px]"})}):null,i=()=>jsx(se,{surfaceId:e,processor:o,childComponents:t.componentTree?[t.componentTree]:null,enableCustomElements:n,onAction:s});return jsxs("div",{className:"a2ui-surface a2ui-root flex flex-col gap-8 p-10 pb-20",style:{"--p-50":t.styles?.primaryColor??"var(--primary)"},children:[r(),i()]})}function ft({children:e,className:t}){let o=m();return jsx("div",{className:t,children:jsx(Ue,{components:{p:({children:n})=>jsx("p",{className:o.markdown.p.join(" "),children:n}),h1:({children:n})=>jsx("h1",{className:o.markdown.h1.join(" "),children:n}),h2:({children:n})=>jsx("h2",{className:o.markdown.h2.join(" "),children:n}),h3:({children:n})=>jsx("h3",{className:o.markdown.h3.join(" "),children:n}),h4:({children:n})=>jsx("h4",{className:o.markdown.h4.join(" "),children:n}),h5:({children:n})=>jsx("h5",{className:o.markdown.h5.join(" "),children:n}),ul:({children:n})=>jsx("ul",{className:o.markdown.ul.join(" "),children:n}),ol:({children:n})=>jsx("ol",{className:o.markdown.ol.join(" "),children:n}),li:({children:n})=>jsx("li",{className:o.markdown.li.join(" "),children:n}),a:({children:n,href:s})=>jsx("a",{href:s,className:o.markdown.a.join(" "),children:n}),strong:({children:n})=>jsx("strong",{className:o.markdown.strong.join(" "),children:n}),em:({children:n})=>jsx("em",{className:o.markdown.em.join(" "),children:n})},children:e})})}function ht(e){return jsx(Ue,{children:e})}
2
+ export{_ as Audio,z as Button,J as Card,Q as Checkbox,H as Column,V as ComponentRegistry,v as ComponentRenderer,te as DateTimeInput,Z as Divider,F as Icon,$ as Image,W as List,ft as Markdown,G as Modal,oe as MultipleChoice,se as Root,K as Row,ne as Slider,pt as Surface,q as Tabs,j as Text,ee as TextField,L as Video,c as cn,E as componentRegistry,D as extractNumberValue,g as extractStringValue,ht as renderMarkdown};
package/package.json ADDED
@@ -0,0 +1,168 @@
1
+ {
2
+ "name": "@zhama/a2ui",
3
+ "version": "0.10.1",
4
+ "description": "A2UI Protocol - Agent-to-User Interface Protocol React implementation based on Google A2UI",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "development": "./src/index.ts",
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs",
15
+ "default": "./dist/index.js"
16
+ },
17
+ "./types": {
18
+ "types": "./dist/types/index.d.ts",
19
+ "development": "./src/types/index.ts",
20
+ "import": "./dist/types/index.js",
21
+ "require": "./dist/types/index.cjs",
22
+ "default": "./dist/types/index.js"
23
+ },
24
+ "./data": {
25
+ "types": "./dist/data/index.d.ts",
26
+ "development": "./src/data/index.ts",
27
+ "import": "./dist/data/index.js",
28
+ "require": "./dist/data/index.cjs",
29
+ "default": "./dist/data/index.js"
30
+ },
31
+ "./events": {
32
+ "types": "./dist/events/index.d.ts",
33
+ "development": "./src/events/index.ts",
34
+ "import": "./dist/events/index.js",
35
+ "require": "./dist/events/index.cjs",
36
+ "default": "./dist/events/index.js"
37
+ },
38
+ "./styles": {
39
+ "types": "./dist/styles/index.d.ts",
40
+ "development": "./src/styles/index.ts",
41
+ "import": "./dist/styles/index.js",
42
+ "require": "./dist/styles/index.cjs",
43
+ "default": "./dist/styles/index.js"
44
+ },
45
+ "./styles/a2ui-variables.css": "./src/styles/a2ui-variables.css",
46
+ "./styles/a2ui.css": "./src/styles/a2ui.css",
47
+ "./tailwind.preset": {
48
+ "import": "./tailwind.preset.js",
49
+ "require": "./tailwind.preset.js",
50
+ "default": "./tailwind.preset.js"
51
+ },
52
+ "./ui": {
53
+ "types": "./dist/ui/index.d.ts",
54
+ "development": "./src/ui/index.ts",
55
+ "import": "./dist/ui/index.js",
56
+ "require": "./dist/ui/index.cjs",
57
+ "default": "./dist/ui/index.js"
58
+ },
59
+ "./context": {
60
+ "types": "./dist/context/index.d.ts",
61
+ "development": "./src/context/index.tsx",
62
+ "import": "./dist/context/index.js",
63
+ "require": "./dist/context/index.cjs",
64
+ "default": "./dist/context/index.js"
65
+ }
66
+ },
67
+ "files": [
68
+ "dist/**/*.js",
69
+ "dist/**/*.cjs",
70
+ "dist/**/*.d.ts",
71
+ "dist/**/*.d.cts",
72
+ "src/styles/a2ui-variables.css",
73
+ "tailwind.preset.js"
74
+ ],
75
+ "publishConfig": {
76
+ "access": "public"
77
+ },
78
+ "scripts": {
79
+ "build": "tsup",
80
+ "dev": "echo 'Development mode: using source files directly'",
81
+ "lint": "eslint src",
82
+ "lint:fix": "eslint src --fix",
83
+ "format": "prettier --write .",
84
+ "format:check": "prettier --check .",
85
+ "type-check": "tsc --noEmit",
86
+ "test": "vitest run",
87
+ "test:watch": "vitest",
88
+ "test:ui": "vitest --ui",
89
+ "test:coverage": "vitest run --coverage",
90
+ "clean": "rm -rf dist",
91
+ "prepublishOnly": "pnpm run clean && pnpm run build",
92
+ "prepack": "pnpm run type-check && pnpm run lint"
93
+ },
94
+ "peerDependencies": {
95
+ "react": "^18.0.0",
96
+ "react-dom": "^18.0.0"
97
+ },
98
+ "dependencies": {
99
+ "lucide-react": "^0.469.0",
100
+ "react-markdown": "^9.0.1"
101
+ },
102
+ "devDependencies": {
103
+ "@eslint/js": "^9.15.0",
104
+ "@testing-library/jest-dom": "^6.9.1",
105
+ "@testing-library/react": "^16.3.0",
106
+ "@testing-library/user-event": "^14.6.1",
107
+ "@types/node": "^22.16.5",
108
+ "@types/react": "^18.3.18",
109
+ "@types/react-dom": "^18.3.5",
110
+ "@vitejs/plugin-react": "^4.2.1",
111
+ "@vitest/coverage-v8": "^4.0.16",
112
+ "@vitest/ui": "^4.0.16",
113
+ "eslint": "^9.15.0",
114
+ "eslint-config-prettier": "^9.1.0",
115
+ "eslint-plugin-import": "^2.31.0",
116
+ "eslint-plugin-jsx-a11y": "^6.10.2",
117
+ "eslint-plugin-prettier": "^5.2.1",
118
+ "eslint-plugin-react": "^7.37.2",
119
+ "eslint-plugin-react-hooks": "^5.0.0",
120
+ "globals": "^15.12.0",
121
+ "jsdom": "^27.3.0",
122
+ "prettier": "^3.3.3",
123
+ "react": "^18.3.1",
124
+ "react-dom": "^18.3.1",
125
+ "tsup": "^8.3.5",
126
+ "typescript": "^5.7.3",
127
+ "typescript-eslint": "^8.15.0",
128
+ "vitest": "^4.0.16"
129
+ },
130
+ "keywords": [
131
+ "a2ui",
132
+ "agent-to-ui",
133
+ "ai",
134
+ "artificial-intelligence",
135
+ "llm",
136
+ "large-language-model",
137
+ "protocol",
138
+ "ui-generation",
139
+ "dynamic-ui",
140
+ "react",
141
+ "react-components",
142
+ "typescript",
143
+ "tailwind",
144
+ "google-a2ui",
145
+ "conversational-ui",
146
+ "chatbot",
147
+ "agent"
148
+ ],
149
+ "author": {
150
+ "name": "Zhama AI",
151
+ "email": "support@zhama.com",
152
+ "url": "https://zhama.com"
153
+ },
154
+ "license": "MIT",
155
+ "repository": {
156
+ "type": "git",
157
+ "url": "git+https://github.com/zhama/a2ui.git"
158
+ },
159
+ "bugs": {
160
+ "url": "https://github.com/zhama/a2ui/issues",
161
+ "email": "support@zhama.com"
162
+ },
163
+ "homepage": "https://github.com/zhama/a2ui#readme",
164
+ "engines": {
165
+ "node": ">=18.0.0",
166
+ "pnpm": ">=8.0.0"
167
+ }
168
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * A2UI Default CSS Variables
3
+ *
4
+ * 基于 shadcn/ui 的设计系统,提供完整的 CSS 变量定义
5
+ *
6
+ * 使用方式:
7
+ * 1. 直接导入:@import '@zhama/a2ui/styles/a2ui-variables.css';
8
+ * 2. 可选覆盖:在导入后重新定义 :root 中的变量
9
+ */
10
+
11
+ /* ============ 亮色主题 ============ */
12
+ :root {
13
+ /* 基础颜色 */
14
+ --background: 0 0% 100%;
15
+ --foreground: 222.2 84% 4.9%;
16
+
17
+ /* 卡片颜色 */
18
+ --card: 0 0% 100%;
19
+ --card-foreground: 222.2 84% 4.9%;
20
+
21
+ /* 弹出层颜色 */
22
+ --popover: 0 0% 100%;
23
+ --popover-foreground: 222.2 84% 4.9%;
24
+
25
+ /* 主色调 - 蓝色系 */
26
+ --primary: 221.2 83.2% 53.3%;
27
+ --primary-foreground: 210 40% 98%;
28
+
29
+ /* 次要色 */
30
+ --secondary: 210 40% 96.1%;
31
+ --secondary-foreground: 222.2 47.4% 11.2%;
32
+
33
+ /* 柔和色 - 用于背景 */
34
+ --muted: 210 40% 96.1%;
35
+ --muted-foreground: 215.4 16.3% 46.9%;
36
+
37
+ /* 强调色 */
38
+ --accent: 210 40% 96.1%;
39
+ --accent-foreground: 222.2 47.4% 11.2%;
40
+
41
+ /* 危险色 - 红色系 */
42
+ --destructive: 0 84.2% 60.2%;
43
+ --destructive-foreground: 210 40% 98%;
44
+
45
+ /* 边框和输入框 */
46
+ --border: 214.3 31.8% 91.4%;
47
+ --input: 214.3 31.8% 91.4%;
48
+ --ring: 221.2 83.2% 53.3%;
49
+
50
+ /* 圆角 */
51
+ --radius: 0.5rem;
52
+
53
+ /* 字体 */
54
+ --font-sans:
55
+ 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
56
+ 'Helvetica Neue', sans-serif;
57
+ --font-mono:
58
+ 'Fira Code', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New',
59
+ monospace;
60
+ }
61
+
62
+ /* ============ 深色主题 ============ */
63
+ .dark {
64
+ --background: 222.2 84% 4.9%;
65
+ --foreground: 210 40% 98%;
66
+
67
+ --card: 222.2 84% 4.9%;
68
+ --card-foreground: 210 40% 98%;
69
+
70
+ --popover: 222.2 84% 4.9%;
71
+ --popover-foreground: 210 40% 98%;
72
+
73
+ --primary: 217.2 91.2% 59.8%;
74
+ --primary-foreground: 222.2 47.4% 11.2%;
75
+
76
+ --secondary: 217.2 32.6% 17.5%;
77
+ --secondary-foreground: 210 40% 98%;
78
+
79
+ --muted: 217.2 32.6% 17.5%;
80
+ --muted-foreground: 215 20.2% 65.1%;
81
+
82
+ --accent: 217.2 32.6% 17.5%;
83
+ --accent-foreground: 210 40% 98%;
84
+
85
+ --destructive: 0 62.8% 30.6%;
86
+ --destructive-foreground: 210 40% 98%;
87
+
88
+ --border: 217.2 32.6% 17.5%;
89
+ --input: 217.2 32.6% 17.5%;
90
+ --ring: 224.3 76.3% 48%;
91
+ }
92
+
93
+ /*
94
+ * ============ 注意 ============
95
+ *
96
+ * 此文件只包含 CSS 变量定义,不包含全局样式。
97
+ * 全局样式(如 html/body 高度、字体、滚动条等)应由使用方自行定义。
98
+ *
99
+ * 使用方可参考以下样式添加到自己的 globals.css:
100
+ *
101
+ * html, body, #root { height: 100%; width: 100%; }
102
+ * body {
103
+ * background-color: hsl(var(--background));
104
+ * color: hsl(var(--foreground));
105
+ * }
106
+ */