@qumra/fanar 0.0.26 → 0.0.28
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/dist/ai.js +1 -1
- package/dist/charts.js +1 -1
- package/dist/{chunk-ZYLYQZBE.js → chunk-5E7KR3JO.js} +1 -1
- package/dist/{chunk-XAQJL7FX.js → chunk-EM4MF5B3.js} +1 -1
- package/dist/{chunk-TWZR3X5H.js → chunk-JOHJNMV2.js} +1 -1
- package/dist/{chunk-ZG3I7YUW.js → chunk-QFJSDPEB.js} +1 -1
- package/dist/{chunk-GCIOTDW6.js → chunk-V7VYOWMO.js} +1 -1
- package/dist/{chunk-N6V3LTIS.js → chunk-YJ45RGS6.js} +1 -1
- package/dist/editor.js +1 -1
- package/dist/index.d.ts +56 -3
- package/dist/index.js +1 -1
- package/dist/notifications.js +1 -1
- package/package.json +1 -1
package/dist/ai.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{BarChart,ChoiceCards,DataTable,Money,TrendChart,isCurrency}from"./chunk-ZG3I7YUW.js";import{Button,Input,Textarea}from"./chunk-XAQJL7FX.js";import{Badge,Card,StatCard,formatTime}from"./chunk-TWZR3X5H.js";import{Alert,Modal}from"./chunk-ZYLYQZBE.js";import{cn,useUIText}from"./chunk-N6V3LTIS.js";import{useEffect,useRef,useState}from"react";import{Bot,Check,Copy,ExternalLink,RotateCcw,ThumbsDown,ThumbsUp,TriangleAlert}from"lucide-react";import{Fragment,jsx,jsxs}from"react/jsx-runtime";function AiAvatar({state="idle",level,size="md",icon:Icon=Bot}){const ring=useRef(null);useEffect(()=>{if(state!=="speaking"||!level)return;let raf=0;const loop=()=>{const v=level.current??0;if(ring.current){ring.current.style.transform=`scale(${1+v**1.6*.9})`;ring.current.style.opacity=String(Math.min(.45,v))}raf=requestAnimationFrame(loop)};raf=requestAnimationFrame(loop);const el=ring.current;return()=>{cancelAnimationFrame(raf);if(el)el.style.opacity="0"}},[state,level]);const box={sm:"size-8",md:"size-9",lg:"size-12"}[size];const px={sm:16,md:18,lg:24}[size];return jsxs("span",{className:"relative inline-flex shrink-0",children:[jsx("span",{ref:ring,"aria-hidden":"true",className:cn("absolute inset-0 rounded-sm bg-brand opacity-0",box),style:{transition:"transform 90ms linear, opacity 90ms linear"}}),jsx("span",{"aria-hidden":"true",className:cn("relative rounded-sm bg-soft border border-soft2 flex items-center justify-center",box,state==="thinking"&&"animate-pulse"),children:jsx(Icon,{size:px,strokeWidth:2,className:"text-brand"})})]})}function AiThinking({label}){const ui=useUIText();return jsxs("span",{role:"status","aria-live":"polite",className:"flex items-center gap-2.5",children:[jsx(AiAvatar,{size:"sm",state:"thinking"}),jsxs("span",{className:"flex items-center gap-2 py-2.5 px-3.5 rounded-card bg-bg border border-line",children:[jsx("span",{"aria-hidden":"true",className:"flex items-center gap-1",children:[0,1,2].map(i=>jsx("span",{className:"size-1.5 rounded-full bg-muted2 animate-bounce",style:{animationDelay:`${i*140}ms`,animationDuration:"900ms"}},i))}),jsx("span",{className:"text-caption text-muted",children:label??ui.shehabThinking})]})]})}function AiToolCall({icon:Icon,title,detail,state="done",onUndo,undoLabel}){const ui=useUIText();const tone={running:"bg-bg border-line text-muted",done:"bg-green-bg2 border-green-line text-green",failed:"bg-red-bg border-red-line text-red",reverted:"bg-bg border-line text-muted2"}[state];const off=state==="reverted";return jsxs("div",{className:cn("flex items-start gap-2.5 p-3 rounded-card border",tone),children:[jsx("span",{"aria-hidden":"true",className:"shrink-0 mt-0.5",children:state==="failed"?jsx(TriangleAlert,{size:15}):off?jsx(RotateCcw,{size:15}):state==="done"?jsx(Check,{size:15}):Icon?jsx(Icon,{size:15}):jsx("span",{className:"block size-3.5 rounded-full border-2 border-current border-t-transparent animate-spin"})}),jsxs("span",{className:"flex flex-col gap-1 min-w-0 flex-1",children:[jsx("span",{className:cn("text-ui font-bold",off?"text-muted":"text-ink"),children:title}),detail&&jsx("span",{className:cn("text-caption leading-[1.7]",off?"text-muted2 line-through":"text-ink2"),children:detail})]}),onUndo&&state==="done"&&jsx("button",{type:"button",onClick:onUndo,className:"shrink-0 text-caption font-bold text-brand-ink cursor-pointer hover:underline underline-offset-4",children:undoLabel??ui.undo})]})}function AiSources({sources,label}){const ui=useUIText();if(sources.length===0)return null;return jsxs("span",{className:"flex items-center gap-1.5 flex-wrap",children:[jsx("span",{className:"text-micro text-muted2",children:label??ui.from}),sources.map(s=>{const inner=jsxs(Fragment,{children:[s.label,jsx(ExternalLink,{size:10,"aria-hidden":"true"})]});const cls="inline-flex items-center gap-1 h-6 px-2 rounded-full bg-soft text-brand-ink text-micro font-bold no-underline cursor-pointer transition-colors hover:bg-soft2";return s.href?jsx("a",{href:s.href,className:cls,children:inner},s.id):jsx("button",{type:"button",onClick:s.onOpen,className:cls,children:inner},s.id)})]})}function AiMessage({role,children,streaming,sources,copyText,onRetry,onFeedback,tools,fill}){const ui=useUIText();const[copied,setCopied]=useState(false);const[vote,setVote]=useState(null);const user=role==="user";const actionable=!user&&!streaming&&(copyText||onRetry||onFeedback);return jsxs("div",{className:cn("flex gap-2.5",fill?"w-full":"max-w-[88%]",user?"self-end":"self-start"),children:[!user&&jsx(AiAvatar,{size:"sm"}),jsxs("div",{className:cn("flex flex-col gap-2 min-w-0",fill&&"flex-1"),children:[jsxs("div",{dir:"auto",className:cn("py-2.5 px-3.5 rounded-card text-ui leading-[1.85] whitespace-pre-line",user?"bg-brand text-white":"bg-bg text-ink border border-line"),children:[children,streaming&&jsx("span",{"aria-hidden":"true",className:"inline-block w-[2px] h-[1em] align-[-2px] ms-0.5 bg-brand animate-pulse"})]}),tools,sources&&sources.length>0&&!streaming&&jsx(AiSources,{sources}),actionable&&jsxs("div",{className:"flex items-center gap-0.5",children:[copyText&&jsx(ActionBtn,{label:copied?"\u0627\u062A\u0646\u0633\u062E":"\u0646\u0633\u062E",onClick:()=>{navigator.clipboard?.writeText(copyText);setCopied(true);setTimeout(()=>setCopied(false),1400)},children:copied?jsx(Check,{size:13,className:"text-green"}):jsx(Copy,{size:13})}),onRetry&&jsx(ActionBtn,{label:ui.tryAnotherReply,onClick:onRetry,children:jsx(RotateCcw,{size:13})}),onFeedback&&jsxs(Fragment,{children:[jsx(ActionBtn,{label:ui.helpfulReply,active:vote==="up",onClick:()=>{setVote("up");onFeedback("up")},children:jsx(ThumbsUp,{size:13})}),jsx(ActionBtn,{label:ui.unhelpfulReply,active:vote==="down",onClick:()=>{setVote("down");onFeedback("down")},children:jsx(ThumbsDown,{size:13})})]})]})]})]})}function ActionBtn({onClick,label,active,children}){return jsx("button",{type:"button",onClick,"aria-label":label,title:label,"aria-pressed":active,className:cn("size-7 rounded-xs inline-flex items-center justify-center cursor-pointer transition-colors",active?"bg-soft text-brand-ink":"text-muted2 hover:bg-hover hover:text-ink"),children})}function AiDisclaimer({children}){const ui=useUIText();return jsx("span",{className:"block text-center text-micro leading-[1.7] text-muted2 [text-wrap:pretty]",children:children??ui.aiDisclaimer})}import{useEffect as useEffect3,useRef as useRef3}from"react";import{ArrowUp,Mic,Paperclip,Square,Trash2}from"lucide-react";import{useCallback,useEffect as useEffect2,useRef as useRef2,useState as useState2}from"react";function useStreamingText({speed=18}={}){const[shown,setShown]=useState2("");const[streaming,setStreaming]=useState2(false);const full=useRef2("");const timer=useRef2(void 0);const stopTimer=useCallback(()=>{clearInterval(timer.current);timer.current=void 0},[]);useEffect2(()=>stopTimer,[stopTimer]);const run=useCallback(()=>{if(timer.current)return;timer.current=setInterval(()=>{setShown(s=>{if(s.length>=full.current.length){stopTimer();setStreaming(false);return s}return full.current.slice(0,s.length+1)})},speed)},[speed,stopTimer]);const start=useCallback(text=>{stopTimer();full.current=text;setShown("");setStreaming(true);run()},[run,stopTimer]);const push=useCallback(chunk=>{full.current+=chunk;setStreaming(true);run()},[run]);const stop=useCallback(()=>{stopTimer();full.current=shown;setStreaming(false)},[shown,stopTimer]);const finish=useCallback(()=>{stopTimer();setShown(full.current);setStreaming(false)},[stopTimer]);const reset=useCallback(()=>{stopTimer();full.current="";setShown("");setStreaming(false)},[stopTimer]);return{text:shown,streaming,start,push,stop,finish,reset}}function useMicLevel(){const level=useRef2(0);const[recording,setRecording]=useState2(false);const[seconds,setSeconds]=useState2(0);const[denied,setDenied]=useState2(false);const stream=useRef2(null);const ctx=useRef2(null);const raf=useRef2(0);const tick=useRef2(void 0);const stop=useCallback(()=>{cancelAnimationFrame(raf.current);clearInterval(tick.current);stream.current?.getTracks().forEach(t=>t.stop());void ctx.current?.close();stream.current=null;ctx.current=null;level.current=0;setRecording(false);setSeconds(0)},[]);useEffect2(()=>stop,[stop]);const start=useCallback(async()=>{if(recording)return;try{const media=await navigator.mediaDevices.getUserMedia({audio:true});const Ctx=window.AudioContext??window.webkitAudioContext;if(!Ctx)throw new Error("\u0645\u0627\u0641\u064A\u0634 Web Audio");const c=new Ctx;const src=c.createMediaStreamSource(media);const analyser=c.createAnalyser();analyser.fftSize=512;analyser.smoothingTimeConstant=.7;src.connect(analyser);stream.current=media;ctx.current=c;setDenied(false);setRecording(true);setSeconds(0);const data=new Uint8Array(analyser.frequencyBinCount);const loop=()=>{analyser.getByteTimeDomainData(data);let sum=0;for(let i=0;i<data.length;i++){const v=(data[i]-128)/128;sum+=v*v}level.current=Math.min(1,Math.sqrt(sum/data.length)*3);raf.current=requestAnimationFrame(loop)};raf.current=requestAnimationFrame(loop);tick.current=setInterval(()=>setSeconds(s=>s+1),1e3)}catch{setDenied(true);setRecording(false)}},[recording]);return{level,recording,seconds,start,stop,denied}}import{jsx as jsx2,jsxs as jsxs2}from"react/jsx-runtime";function AiPromptChips({prompts,onPick}){if(prompts.length===0)return null;return jsx2("div",{className:"flex gap-2 overflow-x-auto pb-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",children:prompts.map(p=>jsx2("button",{type:"button",dir:"auto",onClick:()=>onPick(p),className:"shrink-0 h-8 px-3 rounded-full border border-border bg-surface text-caption font-bold text-ink2 whitespace-nowrap cursor-pointer transition-colors hover:border-brand hover:text-brand-ink",children:p},p))})}function LiveBars({level,count=28}){const bars=useRef3([]);const history=useRef3(Array.from({length:count},()=>0));useEffect3(()=>{let raf=0;let last=0;const loop=t=>{if(t-last>60){last=t;history.current=[...history.current.slice(1),level.current??0];for(let i=0;i<bars.current.length;i++){const el=bars.current[i];if(el)el.style.height=`${Math.max(10,(history.current[i]??0)*100)}%`}}raf=requestAnimationFrame(loop)};raf=requestAnimationFrame(loop);return()=>cancelAnimationFrame(raf)},[level]);return jsx2("span",{dir:"ltr","aria-hidden":"true",className:"flex-1 min-w-0 h-7 flex items-center gap-0.5",children:Array.from({length:count},(_,i)=>jsx2("span",{ref:el=>{bars.current[i]=el},className:"flex-1 rounded-full bg-brand",style:{height:"10%",transition:"height 70ms linear"}},i))})}function AiComposer({value,onChange,onSend,placeholder,busy,onStop,onVoice,onAttach,disabled,className}){const ui=useUIText();const mic=useMicLevel();const area=useRef3(null);useEffect3(()=>{const el=area.current;if(!el)return;el.style.height="auto";el.style.height=`${Math.min(el.scrollHeight,120)}px`},[value]);function submit(){const text=value.trim();if(!text||busy)return;onSend(text)}if(mic.recording){return jsxs2("div",{className:cn("flex items-center gap-3 h-14 px-3 rounded-lg bg-surface border border-brand",className),children:[jsx2("button",{type:"button",onClick:mic.stop,"aria-label":ui.cancelRecording,className:"size-9 rounded-sm shrink-0 flex items-center justify-center text-muted cursor-pointer transition-colors hover:bg-red-bg hover:text-red",children:jsx2(Trash2,{size:17,"aria-hidden":"true"})}),jsx2(LiveBars,{level:mic.level}),jsx2("span",{"data-num":true,className:"text-ui font-bold text-ink2 shrink-0 tabular-nums",children:formatTime(mic.seconds)}),jsx2("button",{type:"button",onClick:()=>{const s=mic.seconds;mic.stop();onVoice?.(s)},"aria-label":ui.sendRecording,className:"size-9 rounded-sm shrink-0 flex items-center justify-center bg-brand text-white cursor-pointer transition-colors hover:bg-brand-hover",children:jsx2(ArrowUp,{size:17,strokeWidth:2.4,"aria-hidden":"true"})})]})}const canSend=value.trim().length>0;return jsxs2("div",{className:cn("flex flex-col gap-1.5",className),children:[jsxs2("div",{className:cn("flex items-end gap-2 p-2 ps-3.5 rounded-lg bg-surface border border-border","focus-within:border-brand transition-colors",disabled&&"opacity-60 pointer-events-none"),children:[jsx2("label",{htmlFor:"ai-composer",className:"sr-only",children:placeholder??ui.askShehab}),jsx2("textarea",{id:"ai-composer",ref:area,rows:1,value,disabled,placeholder:placeholder??ui.askShehab,onChange:e=>onChange(e.target.value),onKeyDown:e=>{if(e.key==="Enter"&&!e.shiftKey){e.preventDefault();submit()}},className:"flex-1 min-w-0 py-2 bg-transparent border-none outline-none resize-none text-body text-ink placeholder:text-muted2"}),jsxs2("span",{className:"flex items-center gap-0.5 shrink-0",children:[onAttach&&jsx2("button",{type:"button",onClick:onAttach,"aria-label":ui.attachFile,className:"size-9 rounded-sm flex items-center justify-center text-muted cursor-pointer transition-colors hover:bg-hover hover:text-ink",children:jsx2(Paperclip,{size:17,"aria-hidden":"true"})}),onVoice&&!canSend&&!busy&&jsx2("button",{type:"button",onClick:()=>void mic.start(),"aria-label":ui.recordVoice,className:"size-9 rounded-sm flex items-center justify-center text-muted cursor-pointer transition-colors hover:bg-hover hover:text-ink",children:jsx2(Mic,{size:17,"aria-hidden":"true"})}),jsx2("button",{type:"button",onClick:busy?onStop:submit,disabled:!busy&&!canSend,"aria-label":busy?"\u0623\u0648\u0642\u0641 \u0627\u0644\u062A\u0648\u0644\u064A\u062F":"\u0625\u0631\u0633\u0627\u0644",className:cn("size-9 rounded-sm flex items-center justify-center shrink-0 transition-colors",busy?"bg-ink2 text-surface cursor-pointer hover:bg-ink":canSend?"bg-brand text-white cursor-pointer hover:bg-brand-hover":"bg-soft text-brand-ink/40 cursor-not-allowed"),children:busy?jsx2(Square,{size:13,fill:"currentColor","aria-hidden":"true"}):jsx2(ArrowUp,{size:17,strokeWidth:2.4,"aria-hidden":"true"})})]})]}),mic.denied&&jsx2("span",{className:"text-caption text-red",children:"\u0627\u0644\u0645\u064A\u0643\u0631\u0648\u0641\u0648\u0646 \u0645\u0631\u0641\u0648\u0636 \u2014 \u0627\u0633\u0645\u062D \u0644\u0644\u0645\u0648\u0642\u0639 \u0628\u0627\u0644\u0648\u0635\u0648\u0644 \u0644\u0644\u0645\u064A\u0643\u0631\u0648\u0641\u0648\u0646 \u0645\u0646 \u0625\u0639\u062F\u0627\u062F\u0627\u062A \u0627\u0644\u0645\u062A\u0635\u0641\u0651\u062D."})]})}import{useState as useState5}from"react";import{useState as useState3}from"react";import{ArrowRight,Check as Check2,MessageSquarePlus}from"lucide-react";import{OTHER_PREFIX}from"@qumra/jawab-ai";import{jsx as jsx3,jsxs as jsxs3}from"react/jsx-runtime";function AskCard({block,onAnswer,live=true}){const[at,setAt]=useState3(0);const[picked,setPicked]=useState3({});const[other,setOther]=useState3({});const[notes,setNotes]=useState3({});const[noting,setNoting]=useState3({});const[sent,setSent]=useState3(null);const answerable=live&&Boolean(onAnswer)&&!sent;const total=block.questions.length;const q=block.questions[at];const last=at===total-1;function toggle(question,value){setPicked(prev=>{const cur=prev[question.key]??[];if(!question.multi)return{...prev,[question.key]:[value]};return{...prev,[question.key]:cur.includes(value)?cur.filter(v=>v!==value):[...cur,value]}})}function valuesFor(question){const base=picked[question.key]??[];const typed=other[question.key]?.trim();return typed?[...base,OTHER_PREFIX+typed]:base}function labelsFor(question){return valuesFor(question).map(v=>v.startsWith(OTHER_PREFIX)?v.slice(OTHER_PREFIX.length):question.options.find(o=>o.value===v)?.label??v)}const answered=valuesFor(q).length>0;const canGo=q.required===false||answered;function submit(){const result={answers:{},values:{}};const notesOut={};for(const question of block.questions){const values=valuesFor(question);if(values.length===0)continue;result.values[question.key]=values;result.answers[question.label]=labelsFor(question).join("\u060C ");const note=notes[question.key]?.trim();if(note)notesOut[question.label]={notes:note}}if(Object.keys(notesOut).length)result.annotations=notesOut;setSent(result);onAnswer?.(block.id,result)}if(sent){return jsxs3("div",{className:"flex flex-col gap-3 p-4 rounded-card border border-line bg-bg",children:[block.questions.map(question=>jsxs3("div",{className:"flex flex-col gap-1.5",children:[jsx3("span",{className:"text-caption text-muted [text-wrap:pretty]",children:question.label}),jsx3(Picked,{labels:(sent.answers[question.label]??"").split("\u060C ").filter(Boolean),note:sent.annotations?.[question.label]?.notes})]},question.key)),jsxs3("span",{className:"flex items-center gap-1.5 text-caption font-bold text-green",children:[jsx3(Check2,{size:13,strokeWidth:2.6,"aria-hidden":"true"}),"\u0627\u062A\u0628\u0639\u062A"]})]})}return jsxs3("div",{className:"flex flex-col gap-3.5 p-4 rounded-card border border-soft2 bg-tint",children:[jsxs3("span",{className:"flex items-center justify-between gap-3",children:[q.header?jsx3("span",{className:"px-2 h-5 rounded-mark bg-soft text-brand-ink text-micro font-extrabold flex items-center",children:q.header}):jsx3("span",{}),total>1&&jsxs3("span",{className:"flex items-center gap-2 shrink-0",children:[jsx3("span",{"aria-hidden":"true",className:"flex items-center gap-1",children:block.questions.map((qq,i)=>jsx3("span",{className:cn("size-1.5 rounded-full transition-colors",i===at?"bg-brand":i<at?"bg-brand/40":"bg-border/40")},qq.key))}),jsxs3("span",{"data-num":true,className:"text-micro font-bold text-muted whitespace-nowrap",children:[at+1," \u0645\u0646 ",total]})]})]}),jsxs3("div",{className:"flex flex-col gap-2",children:[jsx3("span",{className:"text-ui font-extrabold text-ink [text-wrap:pretty]",children:q.label}),q.hint&&jsx3("span",{className:"text-caption leading-[1.7] text-muted",children:q.hint}),jsx3(ChoiceCards,{name:`${block.id}-${q.key}`,multiple:q.multi,disabled:!answerable,value:q.multi?picked[q.key]??[]:picked[q.key]?.[0]??null,onChange:v=>toggle(q,v),options:q.options.map(o=>({value:o.value,label:o.label,meta:o.description}))}),q.other!==false&&jsx3(Input,{size:"sm",value:other[q.key]??"",onChange:e=>setOther(p=>({...p,[q.key]:e.target.value})),disabled:!answerable,placeholder:q.other?.placeholder??"\u0623\u0648 \u0627\u0643\u062A\u0628 \u0625\u062C\u0627\u0628\u062A\u0643\u2026","aria-label":`\u0625\u062C\u0627\u0628\u0629 \u0623\u062E\u0631\u0649 \u0639\u0644\u0649: ${q.label}`}),noting[q.key]?jsx3(Textarea,{rows:2,value:notes[q.key]??"",onChange:e=>setNotes(p=>({...p,[q.key]:e.target.value})),disabled:!answerable,placeholder:"\u062D\u0627\u062C\u0629 \u062A\u062D\u0628\u0651 \u062A\u0642\u0648\u0644\u0647\u0627 \u0645\u0639 \u0627\u062E\u062A\u064A\u0627\u0631\u0643\u2026","aria-label":`\u0645\u0644\u0627\u062D\u0638\u0629 \u0639\u0644\u0649: ${q.label}`}):answerable&&jsxs3("button",{type:"button",onClick:()=>setNoting(p=>({...p,[q.key]:true})),className:"self-start inline-flex items-center gap-1.5 text-micro font-bold text-muted hover:text-brand cursor-pointer transition-colors",children:[jsx3(MessageSquarePlus,{size:13,"aria-hidden":"true"}),"\u0636\u064A\u0641 \u0645\u0644\u0627\u062D\u0638\u0629"]})]}),answerable&&jsxs3("span",{className:"flex items-center gap-2.5",children:[at>0&&jsx3(Button,{size:"sm",variant:"ghost",onClick:()=>setAt(i=>i-1),children:"\u0631\u062C\u0648\u0639"}),last?jsx3(Button,{size:"sm",onClick:submit,disabled:!canGo,children:block.submitLabel??"\u0627\u0628\u0639\u062A"}):jsx3(Button,{size:"sm",onClick:()=>setAt(i=>i+1),disabled:!canGo,iconEnd:jsx3(ArrowRight,{size:13,className:"rtl:rotate-180","aria-hidden":"true"}),children:"\u0627\u0644\u062A\u0627\u0644\u064A"}),!canGo&&jsx3("span",{className:"text-micro text-muted2",children:"\u0627\u062E\u062A\u0627\u0631 \u0625\u062C\u0627\u0628\u0629 \u0627\u0644\u0623\u0648\u0644"})]})]})}function Picked({labels,note}){if(labels.length===0)return jsx3("span",{className:"text-caption text-muted2",children:"\u0627\u062A\u062E\u0637\u0651\u0649"});return jsxs3("span",{className:"flex flex-col gap-1.5",children:[jsx3("span",{className:"flex flex-wrap gap-1.5",children:labels.map((l,i)=>jsxs3("span",{className:"inline-flex items-center gap-1 h-6 px-2 rounded-mark bg-soft text-brand-ink text-caption font-bold",children:[jsx3(Check2,{size:11,strokeWidth:3,"aria-hidden":"true"}),l]},i))}),note&&jsx3("span",{className:"text-micro leading-[1.7] text-muted border-s-2 border-line ps-2",children:note})]})}import{useEffect as useEffect4,useState as useState4}from"react";import{Check as Check3,Copy as Copy2,RotateCcw as RotateCcw2,Sparkles,X}from"lucide-react";import{Fragment as Fragment2,jsx as jsx4,jsxs as jsxs4}from"react/jsx-runtime";function DraftPanel({draft:source,basis,label,onInsert,onClose,insertLabel="\u0623\u062F\u0631\u0650\u062C",className}){const[attempt,setAttempt]=useState4(0);const[done,setDone]=useState4(false);const{text,streaming,start,finish}=useStreamingText({speed:12});const dynamic=typeof source==="function";useEffect4(()=>{start(dynamic?source(attempt):source)},[attempt,source]);return jsxs4("div",{className:cn("flex flex-col gap-2.5 p-3.5 rounded-card bg-bg border border-line","basis-full order-last w-full",className),children:[jsxs4("span",{className:"flex items-start justify-between gap-3",children:[jsxs4("span",{className:"flex flex-col gap-0.5 min-w-0",children:[jsxs4("span",{className:"flex items-center gap-1.5 text-caption font-extrabold text-ink",children:[jsx4(Sparkles,{size:13,className:"text-brand shrink-0","aria-hidden":"true"}),label]}),jsx4("span",{className:"text-micro leading-[1.65] text-muted",children:basis})]}),onClose&&jsx4("button",{type:"button",onClick:onClose,"aria-label":"\u0625\u063A\u0644\u0627\u0642",className:"shrink-0 size-6 rounded-mark flex items-center justify-center text-muted2 hover:bg-hover hover:text-ink cursor-pointer transition-colors",children:jsx4(X,{size:14,"aria-hidden":"true"})})]}),text===""&&streaming?jsx4(AiThinking,{label:"\u0628\u064A\u0643\u062A\u0628\u2026"}):jsxs4("span",{className:"block text-caption leading-[1.9] text-ink whitespace-pre-wrap [text-wrap:pretty]","aria-live":"polite",children:[text,streaming&&jsx4("span",{"aria-hidden":"true",className:"inline-block w-[2px] h-[1em] align-[-0.15em] ms-0.5 bg-brand animate-pulse"})]}),jsx4("span",{className:"flex items-center gap-2 flex-wrap",children:streaming?jsx4(Button,{size:"sm",variant:"outline",onClick:finish,children:"\u0627\u0639\u0631\u0636\u0647\u0627 \u0643\u0644\u0647\u0627"}):jsxs4(Fragment2,{children:[onInsert&&jsx4(Button,{size:"sm",onClick:()=>{onInsert(text);setDone(true);onClose?.()},icon:jsx4(Check3,{size:13,"aria-hidden":"true"}),children:insertLabel}),jsx4(Button,{size:"sm",variant:"outline",onClick:()=>navigator.clipboard?.writeText(text),icon:jsx4(Copy2,{size:13,"aria-hidden":"true"}),children:"\u0627\u0646\u0633\u062E"}),dynamic&&jsx4(Button,{size:"sm",variant:"ghost",onClick:()=>setAttempt(a=>a+1),icon:jsx4(RotateCcw2,{size:13,"aria-hidden":"true"}),children:"\u0627\u0643\u062A\u0628 \u063A\u064A\u0631\u0647\u0627"})]})}),!streaming&&!done&&jsx4(AiDisclaimer,{children:"\u0645\u0645\u0643\u0646 \u064A\u063A\u0644\u0637 \u2014 \u0627\u0642\u0631\u0627\u0647\u0627 \u0642\u0628\u0644 \u0645\u0627 \u062A\u0646\u0634\u0631\u0647\u0627."})]})}function AiDraft({size="sm",...panel}){const[open,setOpen]=useState4(false);if(!open){return jsx4(Button,{variant:"outline",size,onClick:()=>setOpen(true),icon:jsx4(Sparkles,{size:size==="sm"?13:15,"aria-hidden":"true"}),className:panel.className,children:panel.label})}return jsx4(DraftPanel,{...panel,onClose:()=>setOpen(false)})}import{Fragment as Fragment3,jsx as jsx5}from"react/jsx-runtime";function Markdown({md}){const chunks=md.split(/\n{2,}/);return jsx5(Fragment3,{children:chunks.map((chunk,i)=>{const lines=chunk.split("\n");const bullets=lines.every(l=>/^\s*[-•]\s+/.test(l));const numbers=lines.every(l=>/^\s*\d+[.)]\s+/.test(l));if(bullets||numbers){const items=lines.map(l=>l.replace(/^\s*(?:[-•]|\d+[.)])\s+/,""));const List=numbers?"ol":"ul";return jsx5(List,{className:numbers?"my-2 ps-5 list-decimal marker:text-muted2 flex flex-col gap-1":"my-2 ps-5 list-disc marker:text-muted2 flex flex-col gap-1",children:items.map((it,j)=>jsx5("li",{children:inline(it)},j))},i)}return jsx5("p",{className:"my-2 first:mt-0 last:mb-0 [text-wrap:pretty]",children:inline(chunk)},i)})})}var TOKEN=/(`[^`\n]+`)|(\*\*[^*\n]+\*\*)|(\*[^*\n]+\*)/g;function inline(src){const out=[];let last=0;let m;TOKEN.lastIndex=0;while((m=TOKEN.exec(src))!==null){if(m.index>last)out.push(src.slice(last,m.index));const[full]=m;const key=`${m.index}`;if(full.startsWith("`")){out.push(jsx5("code",{dir:"ltr",className:"px-1 py-px rounded-mark bg-hover text-[0.9em] font-mono text-brand-ink",children:full.slice(1,-1)},key))}else if(full.startsWith("**")){out.push(jsx5("strong",{className:"font-extrabold text-ink",children:full.slice(2,-2)},key))}else{out.push(jsx5("em",{className:"not-italic font-bold",children:full.slice(1,-1)},key))}last=m.index+full.length}if(last<src.length)out.push(src.slice(last));return out}import{Fragment as Fragment4,jsx as jsx6,jsxs as jsxs5}from"react/jsx-runtime";var TONE={good:"green",warn:"amber",bad:"red",plain:"neutral"};var NOTICE_TONE={info:"brand",warn:"amber",danger:"red"};function major(a){return a.minor/10**(a.decimals??2)}function TextBlockView({block}){if(!block.md)return null;return jsx6("div",{className:"text-body leading-[1.95] text-ink2",children:jsx6(Markdown,{md:block.md})})}function MetricBlockView({block}){return jsx6("div",{className:"grid gap-2.5 grid-cols-[repeat(auto-fit,minmax(9.5rem,1fr))]",children:block.items.map((m,i)=>jsx6(StatCard,{tone:TONE[m.tone??"plain"]??"neutral",label:m.label,value:m.amount?jsx6(Money,{value:major(m.amount),currency:isCurrency(m.amount.currency)?m.amount.currency:void 0,compact:true,trimZeros:true}):m.value,hint:m.delta!==void 0?deltaHint(m.delta,m.deltaBasis):void 0},i))})}function deltaHint(delta,basis){const up=delta>0;const flat=delta===0;return jsxs5("span",{className:cn("font-bold",flat?"text-muted2":up?"text-green":"text-red"),children:[flat?"=":up?"\u25B2":"\u25BC"," ",Math.abs(delta),"\u066A",basis?` ${basis}`:""]})}function TableBlockView({block}){const rows=block.rows.map((cells,i)=>{const row={__key:String(i)};block.cols.forEach((c,j)=>{row[c.key]=cells[j]??null});return row});const columns=block.cols.map(c=>({key:c.key,header:c.label,end:c.align==="end",cell:row=>renderCell(row[c.key],c)}));return jsxs5("span",{className:"flex flex-col gap-1.5",children:[block.caption&&jsx6("span",{className:"text-micro text-muted2",children:block.caption}),jsx6(DataTable,{columns,rows,rowKey:r=>r.__key,grid:block.cols.map(c=>c.align==="end"?"1fr":"1.6fr").join("_"),minWidth:block.cols.length*120,mobileCard:row=>jsx6("span",{className:"flex flex-col gap-1",children:block.cols.map(c=>jsxs5("span",{className:"flex items-baseline justify-between gap-3",children:[jsx6("span",{className:"text-micro text-muted2",children:c.label}),jsx6("span",{className:"text-caption text-ink",children:renderCell(row[c.key],c)})]},c.key))})})]})}function renderCell(v,col){if(v===null||v==="")return jsx6("span",{className:"text-muted2",children:"\u2014"});switch(col.format){case"money":return typeof v==="number"?jsx6(Money,{value:v,trimZeros:true}):v;case"badge":return jsx6(Badge,{size:"sm",children:v});case"number":return jsx6("span",{"data-num":true,children:v});default:return v}}function CardsBlockView({block,intents}){return jsx6("div",{className:"grid gap-2.5 grid-cols-[repeat(auto-fill,minmax(13rem,1fr))]",children:block.items.map(c=>jsx6(Card,{children:jsxs5("span",{className:"flex gap-3 items-start",children:[c.img&&jsx6("img",{src:c.img,alt:"",className:"size-12 rounded-sm object-cover bg-hover shrink-0"}),jsxs5("span",{className:"flex flex-col gap-1 min-w-0",children:[jsx6("span",{className:"text-ui font-bold text-ink truncate",children:c.title}),c.subtitle&&jsx6("span",{className:"text-micro text-muted",children:c.subtitle}),c.badge&&jsx6("span",{children:jsx6(Badge,{size:"sm",tone:"brand",children:c.badge})}),c.action&&jsx6(ActionButton,{action:c.action,intents,size:"sm"})]})]})},c.id))})}function ChartBlockView({block}){const labels=block.series.map(p=>String(p.x));const values=block.series.map(p=>p.y);const money=block.unit?.kind==="money";const fmt=v=>block.unit?.kind==="percent"?`${v}\u066A`:v.toLocaleString("ar-EG");if(block.kind==="bar"){return jsx6(BarChart,{labels,series:[{label:"",values}],formatValue:fmt})}return jsx6(TrendChart,{labels:axisLabels(labels),values,pointLabels:labels,formatValue:money?v=>v.toLocaleString("ar-EG"):fmt,height:170})}function axisLabels(all){if(all.length<=3)return all;return[all[0],all[Math.floor(all.length/2)],all[all.length-1]]}function ActionBlockView({block,intents}){const runnable=block.items.filter(a=>intents[a.intent]);if(runnable.length===0)return null;return jsx6("span",{className:"flex flex-wrap gap-2",children:runnable.map((a,i)=>jsx6(ActionButton,{action:a,intents},i))})}function ActionButton({action,intents,size="sm"}){const[asking,setAsking]=useState5(false);const run=intents[action.intent];if(!run)return null;function fire(){setAsking(false);run(action.args)}return jsxs5(Fragment4,{children:[jsx6(Button,{size,variant:action.style==="quiet"?"outline":"primary",onClick:()=>action.confirm?setAsking(true):fire(),children:action.label}),jsx6(Modal,{open:asking,title:action.label,description:action.confirm,onClose:()=>setAsking(false),size:"sm",footer:jsxs5(Fragment4,{children:[jsx6(Button,{variant:"outline",onClick:()=>setAsking(false),children:"\u0625\u0644\u063A\u0627\u0621"}),jsx6(Button,{onClick:fire,children:action.label})]})})]})}function ToolBlockView({block,intents}){const undo=block.undo;const run=undo?intents[undo.intent]:void 0;return jsx6(AiToolCall,{title:block.title,detail:block.detail,state:block.state,onUndo:run&&undo?()=>run(undo.args):void 0,undoLabel:undo?.label})}function NoticeBlockView({block}){return jsx6(Alert,{tone:NOTICE_TONE[block.tone],children:block.text})}function ChipsBlockView({block,onSend}){if(!onSend)return null;const byLabel=new Map(block.items.map(c=>[c.label,c.send]));return jsx6(AiPromptChips,{prompts:block.items.map(c=>c.label),onPick:label=>onSend(byLabel.get(label)??label)})}function BlockView({block,intents,onSend,onInsertDraft,onAnswer,live=true}){switch(block.type){case"text":return jsx6(TextBlockView,{block});case"metric":return jsx6(MetricBlockView,{block});case"table":return jsx6(TableBlockView,{block});case"cards":return jsx6(CardsBlockView,{block,intents});case"chart":return jsx6(ChartBlockView,{block});case"action":return jsx6(ActionBlockView,{block,intents});case"tool":return jsx6(ToolBlockView,{block,intents});case"notice":return jsx6(NoticeBlockView,{block});case"chips":return jsx6(ChipsBlockView,{block,onSend});case"ask":return jsx6(AskCard,{block,onAnswer,live});case"draft":return jsx6(DraftPanel,{draft:block.text,basis:block.basis,label:"\u0645\u0633\u0648\u0651\u062F\u0629",onInsert:onInsertDraft});default:return null}}import{jsx as jsx7,jsxs as jsxs6}from"react/jsx-runtime";var NO_INTENTS={};function ReplyView({reply,streaming,intents=NO_INTENTS,onSend,onInsertDraft,onAnswer,live=true,onRetry,onFeedback,className}){return jsx7(AiMessage,{role:"assistant",fill:true,streaming,sources:reply.sources,copyText:plainText(reply),onRetry,onFeedback,children:jsxs6("span",{className:cn("flex flex-col gap-3",className),children:[reply.blocks.map((block,i)=>jsx7(BlockView,{block,intents,onSend,onInsertDraft,onAnswer,live},i)),reply.disclaimer!==false&&!streaming&&jsx7(AiDisclaimer,{})]})})}function plainText(reply){const parts=[];for(const b of reply.blocks){switch(b.type){case"text":parts.push(b.md);break;case"metric":parts.push(b.items.map(m=>`${m.label}: ${m.value}`).join(" \xB7 "));break;case"table":parts.push([b.cols.map(c=>c.label).join(" "),...b.rows.map(r=>r.map(c=>c??"").join(" "))].join("\n"));break;case"cards":parts.push(b.items.map(c=>c.title).join("\n"));break;case"draft":parts.push(b.text);break;case"tool":parts.push(b.detail?`${b.title} \u2014 ${b.detail}`:b.title);break;case"notice":parts.push(b.text);break;case"ask":parts.push(b.questions.map(q=>q.label).join("\n"));break;case"chart":case"action":case"chips":break}}return parts.filter(Boolean).join("\n\n")}import{useCallback as useCallback2,useEffect as useEffect5,useRef as useRef4,useState as useState6}from"react";import{parseEvent,parseSSE,reduce}from"@qumra/jawab-ai";function useReplyStream(url,init){const[reply,setReply]=useState6(null);const[streaming,setStreaming]=useState6(false);const[error,setError]=useState6(null);const abort=useRef4(null);const lastInput=useRef4("");useEffect5(()=>()=>abort.current?.abort(),[]);const stop=useCallback2(()=>{abort.current?.abort();abort.current=null;setStreaming(false)},[]);const send=useCallback2(text=>{const question=text.trim();if(!question)return;abort.current?.abort();const ctrl=new AbortController;abort.current=ctrl;lastInput.current=question;setError(null);setReply(null);setStreaming(true);void(async()=>{try{const res=await fetch(url,{method:"POST",headers:{"content-type":"application/json",accept:"text/event-stream"},body:JSON.stringify({input:question}),signal:ctrl.signal,...init});if(!res.ok||!res.body){throw new StreamError("http_"+res.status,`\u0627\u0644\u062E\u0627\u062F\u0645 \u0631\u062C\u0651\u0639 ${res.status}`)}const decoder=new TextDecoder;const readerStream=res.body.getReader();let rest="";let state=null;for(;;){const{done,value}=await readerStream.read();if(done)break;rest+=decoder.decode(value,{stream:true});const{events,rest:tail}=parseSSE(rest);rest=tail;for(const raw of events){const ev=parseEvent(raw);if(!ev)continue;if(ev.e==="error")throw new StreamError(ev.code,ev.message);state=reduce(state,ev);setReply(state);if(ev.e==="done")break}}setStreaming(false)}catch(e){if(ctrl.signal.aborted)return;const se=e;setError({code:se.code??"unknown",message:se.message??"\u0627\u0644\u0627\u062A\u0635\u0627\u0644 \u0627\u062A\u0642\u0637\u0639.",lastInput:lastInput.current});setStreaming(false)}})()},[url,init]);return{reply,streaming,error,send,stop}}var StreamError=class extends Error{code;constructor(code,message){super(message);this.name="StreamError";this.code=code}};export{AiAvatar,AiComposer,AiDisclaimer,AiDraft,AiMessage,AiPromptChips,AiSources,AiThinking,AiToolCall,AskCard,DraftPanel,ReplyView,useMicLevel,useReplyStream,useStreamingText};
|
|
2
|
+
import{BarChart,ChoiceCards,DataTable,Money,TrendChart,isCurrency}from"./chunk-QFJSDPEB.js";import{Button,Input,Textarea}from"./chunk-EM4MF5B3.js";import{Badge,Card,StatCard,formatTime}from"./chunk-JOHJNMV2.js";import{Alert,Modal}from"./chunk-5E7KR3JO.js";import{cn,useUIText}from"./chunk-YJ45RGS6.js";import{useEffect,useRef,useState}from"react";import{Bot,Check,Copy,ExternalLink,RotateCcw,ThumbsDown,ThumbsUp,TriangleAlert}from"lucide-react";import{Fragment,jsx,jsxs}from"react/jsx-runtime";function AiAvatar({state="idle",level,size="md",icon:Icon=Bot}){const ring=useRef(null);useEffect(()=>{if(state!=="speaking"||!level)return;let raf=0;const loop=()=>{const v=level.current??0;if(ring.current){ring.current.style.transform=`scale(${1+v**1.6*.9})`;ring.current.style.opacity=String(Math.min(.45,v))}raf=requestAnimationFrame(loop)};raf=requestAnimationFrame(loop);const el=ring.current;return()=>{cancelAnimationFrame(raf);if(el)el.style.opacity="0"}},[state,level]);const box={sm:"size-8",md:"size-9",lg:"size-12"}[size];const px={sm:16,md:18,lg:24}[size];return jsxs("span",{className:"relative inline-flex shrink-0",children:[jsx("span",{ref:ring,"aria-hidden":"true",className:cn("absolute inset-0 rounded-sm bg-brand opacity-0",box),style:{transition:"transform 90ms linear, opacity 90ms linear"}}),jsx("span",{"aria-hidden":"true",className:cn("relative rounded-sm bg-soft border border-soft2 flex items-center justify-center",box,state==="thinking"&&"animate-pulse"),children:jsx(Icon,{size:px,strokeWidth:2,className:"text-brand"})})]})}function AiThinking({label}){const ui=useUIText();return jsxs("span",{role:"status","aria-live":"polite",className:"flex items-center gap-2.5",children:[jsx(AiAvatar,{size:"sm",state:"thinking"}),jsxs("span",{className:"flex items-center gap-2 py-2.5 px-3.5 rounded-card bg-bg border border-line",children:[jsx("span",{"aria-hidden":"true",className:"flex items-center gap-1",children:[0,1,2].map(i=>jsx("span",{className:"size-1.5 rounded-full bg-muted2 animate-bounce",style:{animationDelay:`${i*140}ms`,animationDuration:"900ms"}},i))}),jsx("span",{className:"text-caption text-muted",children:label??ui.shehabThinking})]})]})}function AiToolCall({icon:Icon,title,detail,state="done",onUndo,undoLabel}){const ui=useUIText();const tone={running:"bg-bg border-line text-muted",done:"bg-green-bg2 border-green-line text-green",failed:"bg-red-bg border-red-line text-red",reverted:"bg-bg border-line text-muted2"}[state];const off=state==="reverted";return jsxs("div",{className:cn("flex items-start gap-2.5 p-3 rounded-card border",tone),children:[jsx("span",{"aria-hidden":"true",className:"shrink-0 mt-0.5",children:state==="failed"?jsx(TriangleAlert,{size:15}):off?jsx(RotateCcw,{size:15}):state==="done"?jsx(Check,{size:15}):Icon?jsx(Icon,{size:15}):jsx("span",{className:"block size-3.5 rounded-full border-2 border-current border-t-transparent animate-spin"})}),jsxs("span",{className:"flex flex-col gap-1 min-w-0 flex-1",children:[jsx("span",{className:cn("text-ui font-bold",off?"text-muted":"text-ink"),children:title}),detail&&jsx("span",{className:cn("text-caption leading-[1.7]",off?"text-muted2 line-through":"text-ink2"),children:detail})]}),onUndo&&state==="done"&&jsx("button",{type:"button",onClick:onUndo,className:"shrink-0 text-caption font-bold text-brand-ink cursor-pointer hover:underline underline-offset-4",children:undoLabel??ui.undo})]})}function AiSources({sources,label}){const ui=useUIText();if(sources.length===0)return null;return jsxs("span",{className:"flex items-center gap-1.5 flex-wrap",children:[jsx("span",{className:"text-micro text-muted2",children:label??ui.from}),sources.map(s=>{const inner=jsxs(Fragment,{children:[s.label,jsx(ExternalLink,{size:10,"aria-hidden":"true"})]});const cls="inline-flex items-center gap-1 h-6 px-2 rounded-full bg-soft text-brand-ink text-micro font-bold no-underline cursor-pointer transition-colors hover:bg-soft2";return s.href?jsx("a",{href:s.href,className:cls,children:inner},s.id):jsx("button",{type:"button",onClick:s.onOpen,className:cls,children:inner},s.id)})]})}function AiMessage({role,children,streaming,sources,copyText,onRetry,onFeedback,tools,fill}){const ui=useUIText();const[copied,setCopied]=useState(false);const[vote,setVote]=useState(null);const user=role==="user";const actionable=!user&&!streaming&&(copyText||onRetry||onFeedback);return jsxs("div",{className:cn("flex gap-2.5",fill?"w-full":"max-w-[88%]",user?"self-end":"self-start"),children:[!user&&jsx(AiAvatar,{size:"sm"}),jsxs("div",{className:cn("flex flex-col gap-2 min-w-0",fill&&"flex-1"),children:[jsxs("div",{dir:"auto",className:cn("py-2.5 px-3.5 rounded-card text-ui leading-[1.85] whitespace-pre-line",user?"bg-brand text-white":"bg-bg text-ink border border-line"),children:[children,streaming&&jsx("span",{"aria-hidden":"true",className:"inline-block w-[2px] h-[1em] align-[-2px] ms-0.5 bg-brand animate-pulse"})]}),tools,sources&&sources.length>0&&!streaming&&jsx(AiSources,{sources}),actionable&&jsxs("div",{className:"flex items-center gap-0.5",children:[copyText&&jsx(ActionBtn,{label:copied?"\u0627\u062A\u0646\u0633\u062E":"\u0646\u0633\u062E",onClick:()=>{navigator.clipboard?.writeText(copyText);setCopied(true);setTimeout(()=>setCopied(false),1400)},children:copied?jsx(Check,{size:13,className:"text-green"}):jsx(Copy,{size:13})}),onRetry&&jsx(ActionBtn,{label:ui.tryAnotherReply,onClick:onRetry,children:jsx(RotateCcw,{size:13})}),onFeedback&&jsxs(Fragment,{children:[jsx(ActionBtn,{label:ui.helpfulReply,active:vote==="up",onClick:()=>{setVote("up");onFeedback("up")},children:jsx(ThumbsUp,{size:13})}),jsx(ActionBtn,{label:ui.unhelpfulReply,active:vote==="down",onClick:()=>{setVote("down");onFeedback("down")},children:jsx(ThumbsDown,{size:13})})]})]})]})]})}function ActionBtn({onClick,label,active,children}){return jsx("button",{type:"button",onClick,"aria-label":label,title:label,"aria-pressed":active,className:cn("size-7 rounded-xs inline-flex items-center justify-center cursor-pointer transition-colors",active?"bg-soft text-brand-ink":"text-muted2 hover:bg-hover hover:text-ink"),children})}function AiDisclaimer({children}){const ui=useUIText();return jsx("span",{className:"block text-center text-micro leading-[1.7] text-muted2 [text-wrap:pretty]",children:children??ui.aiDisclaimer})}import{useEffect as useEffect3,useRef as useRef3}from"react";import{ArrowUp,Mic,Paperclip,Square,Trash2}from"lucide-react";import{useCallback,useEffect as useEffect2,useRef as useRef2,useState as useState2}from"react";function useStreamingText({speed=18}={}){const[shown,setShown]=useState2("");const[streaming,setStreaming]=useState2(false);const full=useRef2("");const timer=useRef2(void 0);const stopTimer=useCallback(()=>{clearInterval(timer.current);timer.current=void 0},[]);useEffect2(()=>stopTimer,[stopTimer]);const run=useCallback(()=>{if(timer.current)return;timer.current=setInterval(()=>{setShown(s=>{if(s.length>=full.current.length){stopTimer();setStreaming(false);return s}return full.current.slice(0,s.length+1)})},speed)},[speed,stopTimer]);const start=useCallback(text=>{stopTimer();full.current=text;setShown("");setStreaming(true);run()},[run,stopTimer]);const push=useCallback(chunk=>{full.current+=chunk;setStreaming(true);run()},[run]);const stop=useCallback(()=>{stopTimer();full.current=shown;setStreaming(false)},[shown,stopTimer]);const finish=useCallback(()=>{stopTimer();setShown(full.current);setStreaming(false)},[stopTimer]);const reset=useCallback(()=>{stopTimer();full.current="";setShown("");setStreaming(false)},[stopTimer]);return{text:shown,streaming,start,push,stop,finish,reset}}function useMicLevel(){const level=useRef2(0);const[recording,setRecording]=useState2(false);const[seconds,setSeconds]=useState2(0);const[denied,setDenied]=useState2(false);const stream=useRef2(null);const ctx=useRef2(null);const raf=useRef2(0);const tick=useRef2(void 0);const stop=useCallback(()=>{cancelAnimationFrame(raf.current);clearInterval(tick.current);stream.current?.getTracks().forEach(t=>t.stop());void ctx.current?.close();stream.current=null;ctx.current=null;level.current=0;setRecording(false);setSeconds(0)},[]);useEffect2(()=>stop,[stop]);const start=useCallback(async()=>{if(recording)return;try{const media=await navigator.mediaDevices.getUserMedia({audio:true});const Ctx=window.AudioContext??window.webkitAudioContext;if(!Ctx)throw new Error("\u0645\u0627\u0641\u064A\u0634 Web Audio");const c=new Ctx;const src=c.createMediaStreamSource(media);const analyser=c.createAnalyser();analyser.fftSize=512;analyser.smoothingTimeConstant=.7;src.connect(analyser);stream.current=media;ctx.current=c;setDenied(false);setRecording(true);setSeconds(0);const data=new Uint8Array(analyser.frequencyBinCount);const loop=()=>{analyser.getByteTimeDomainData(data);let sum=0;for(let i=0;i<data.length;i++){const v=(data[i]-128)/128;sum+=v*v}level.current=Math.min(1,Math.sqrt(sum/data.length)*3);raf.current=requestAnimationFrame(loop)};raf.current=requestAnimationFrame(loop);tick.current=setInterval(()=>setSeconds(s=>s+1),1e3)}catch{setDenied(true);setRecording(false)}},[recording]);return{level,recording,seconds,start,stop,denied}}import{jsx as jsx2,jsxs as jsxs2}from"react/jsx-runtime";function AiPromptChips({prompts,onPick}){if(prompts.length===0)return null;return jsx2("div",{className:"flex gap-2 overflow-x-auto pb-1 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden",children:prompts.map(p=>jsx2("button",{type:"button",dir:"auto",onClick:()=>onPick(p),className:"shrink-0 h-8 px-3 rounded-full border border-border bg-surface text-caption font-bold text-ink2 whitespace-nowrap cursor-pointer transition-colors hover:border-brand hover:text-brand-ink",children:p},p))})}function LiveBars({level,count=28}){const bars=useRef3([]);const history=useRef3(Array.from({length:count},()=>0));useEffect3(()=>{let raf=0;let last=0;const loop=t=>{if(t-last>60){last=t;history.current=[...history.current.slice(1),level.current??0];for(let i=0;i<bars.current.length;i++){const el=bars.current[i];if(el)el.style.height=`${Math.max(10,(history.current[i]??0)*100)}%`}}raf=requestAnimationFrame(loop)};raf=requestAnimationFrame(loop);return()=>cancelAnimationFrame(raf)},[level]);return jsx2("span",{dir:"ltr","aria-hidden":"true",className:"flex-1 min-w-0 h-7 flex items-center gap-0.5",children:Array.from({length:count},(_,i)=>jsx2("span",{ref:el=>{bars.current[i]=el},className:"flex-1 rounded-full bg-brand",style:{height:"10%",transition:"height 70ms linear"}},i))})}function AiComposer({value,onChange,onSend,placeholder,busy,onStop,onVoice,onAttach,disabled,className}){const ui=useUIText();const mic=useMicLevel();const area=useRef3(null);useEffect3(()=>{const el=area.current;if(!el)return;el.style.height="auto";el.style.height=`${Math.min(el.scrollHeight,120)}px`},[value]);function submit(){const text=value.trim();if(!text||busy)return;onSend(text)}if(mic.recording){return jsxs2("div",{className:cn("flex items-center gap-3 h-14 px-3 rounded-lg bg-surface border border-brand",className),children:[jsx2("button",{type:"button",onClick:mic.stop,"aria-label":ui.cancelRecording,className:"size-9 rounded-sm shrink-0 flex items-center justify-center text-muted cursor-pointer transition-colors hover:bg-red-bg hover:text-red",children:jsx2(Trash2,{size:17,"aria-hidden":"true"})}),jsx2(LiveBars,{level:mic.level}),jsx2("span",{"data-num":true,className:"text-ui font-bold text-ink2 shrink-0 tabular-nums",children:formatTime(mic.seconds)}),jsx2("button",{type:"button",onClick:()=>{const s=mic.seconds;mic.stop();onVoice?.(s)},"aria-label":ui.sendRecording,className:"size-9 rounded-sm shrink-0 flex items-center justify-center bg-brand text-white cursor-pointer transition-colors hover:bg-brand-hover",children:jsx2(ArrowUp,{size:17,strokeWidth:2.4,"aria-hidden":"true"})})]})}const canSend=value.trim().length>0;return jsxs2("div",{className:cn("flex flex-col gap-1.5",className),children:[jsxs2("div",{className:cn("flex items-end gap-2 p-2 ps-3.5 rounded-lg bg-surface border border-border","focus-within:border-brand transition-colors",disabled&&"opacity-60 pointer-events-none"),children:[jsx2("label",{htmlFor:"ai-composer",className:"sr-only",children:placeholder??ui.askShehab}),jsx2("textarea",{id:"ai-composer",ref:area,rows:1,value,disabled,placeholder:placeholder??ui.askShehab,onChange:e=>onChange(e.target.value),onKeyDown:e=>{if(e.key==="Enter"&&!e.shiftKey){e.preventDefault();submit()}},className:"flex-1 min-w-0 py-2 bg-transparent border-none outline-none resize-none text-body text-ink placeholder:text-muted2"}),jsxs2("span",{className:"flex items-center gap-0.5 shrink-0",children:[onAttach&&jsx2("button",{type:"button",onClick:onAttach,"aria-label":ui.attachFile,className:"size-9 rounded-sm flex items-center justify-center text-muted cursor-pointer transition-colors hover:bg-hover hover:text-ink",children:jsx2(Paperclip,{size:17,"aria-hidden":"true"})}),onVoice&&!canSend&&!busy&&jsx2("button",{type:"button",onClick:()=>void mic.start(),"aria-label":ui.recordVoice,className:"size-9 rounded-sm flex items-center justify-center text-muted cursor-pointer transition-colors hover:bg-hover hover:text-ink",children:jsx2(Mic,{size:17,"aria-hidden":"true"})}),jsx2("button",{type:"button",onClick:busy?onStop:submit,disabled:!busy&&!canSend,"aria-label":busy?"\u0623\u0648\u0642\u0641 \u0627\u0644\u062A\u0648\u0644\u064A\u062F":"\u0625\u0631\u0633\u0627\u0644",className:cn("size-9 rounded-sm flex items-center justify-center shrink-0 transition-colors",busy?"bg-ink2 text-surface cursor-pointer hover:bg-ink":canSend?"bg-brand text-white cursor-pointer hover:bg-brand-hover":"bg-soft text-brand-ink/40 cursor-not-allowed"),children:busy?jsx2(Square,{size:13,fill:"currentColor","aria-hidden":"true"}):jsx2(ArrowUp,{size:17,strokeWidth:2.4,"aria-hidden":"true"})})]})]}),mic.denied&&jsx2("span",{className:"text-caption text-red",children:"\u0627\u0644\u0645\u064A\u0643\u0631\u0648\u0641\u0648\u0646 \u0645\u0631\u0641\u0648\u0636 \u2014 \u0627\u0633\u0645\u062D \u0644\u0644\u0645\u0648\u0642\u0639 \u0628\u0627\u0644\u0648\u0635\u0648\u0644 \u0644\u0644\u0645\u064A\u0643\u0631\u0648\u0641\u0648\u0646 \u0645\u0646 \u0625\u0639\u062F\u0627\u062F\u0627\u062A \u0627\u0644\u0645\u062A\u0635\u0641\u0651\u062D."})]})}import{useState as useState5}from"react";import{useState as useState3}from"react";import{ArrowRight,Check as Check2,MessageSquarePlus}from"lucide-react";import{OTHER_PREFIX}from"@qumra/jawab-ai";import{jsx as jsx3,jsxs as jsxs3}from"react/jsx-runtime";function AskCard({block,onAnswer,live=true}){const[at,setAt]=useState3(0);const[picked,setPicked]=useState3({});const[other,setOther]=useState3({});const[notes,setNotes]=useState3({});const[noting,setNoting]=useState3({});const[sent,setSent]=useState3(null);const answerable=live&&Boolean(onAnswer)&&!sent;const total=block.questions.length;const q=block.questions[at];const last=at===total-1;function toggle(question,value){setPicked(prev=>{const cur=prev[question.key]??[];if(!question.multi)return{...prev,[question.key]:[value]};return{...prev,[question.key]:cur.includes(value)?cur.filter(v=>v!==value):[...cur,value]}})}function valuesFor(question){const base=picked[question.key]??[];const typed=other[question.key]?.trim();return typed?[...base,OTHER_PREFIX+typed]:base}function labelsFor(question){return valuesFor(question).map(v=>v.startsWith(OTHER_PREFIX)?v.slice(OTHER_PREFIX.length):question.options.find(o=>o.value===v)?.label??v)}const answered=valuesFor(q).length>0;const canGo=q.required===false||answered;function submit(){const result={answers:{},values:{}};const notesOut={};for(const question of block.questions){const values=valuesFor(question);if(values.length===0)continue;result.values[question.key]=values;result.answers[question.label]=labelsFor(question).join("\u060C ");const note=notes[question.key]?.trim();if(note)notesOut[question.label]={notes:note}}if(Object.keys(notesOut).length)result.annotations=notesOut;setSent(result);onAnswer?.(block.id,result)}if(sent){return jsxs3("div",{className:"flex flex-col gap-3 p-4 rounded-card border border-line bg-bg",children:[block.questions.map(question=>jsxs3("div",{className:"flex flex-col gap-1.5",children:[jsx3("span",{className:"text-caption text-muted [text-wrap:pretty]",children:question.label}),jsx3(Picked,{labels:(sent.answers[question.label]??"").split("\u060C ").filter(Boolean),note:sent.annotations?.[question.label]?.notes})]},question.key)),jsxs3("span",{className:"flex items-center gap-1.5 text-caption font-bold text-green",children:[jsx3(Check2,{size:13,strokeWidth:2.6,"aria-hidden":"true"}),"\u0627\u062A\u0628\u0639\u062A"]})]})}return jsxs3("div",{className:"flex flex-col gap-3.5 p-4 rounded-card border border-soft2 bg-tint",children:[jsxs3("span",{className:"flex items-center justify-between gap-3",children:[q.header?jsx3("span",{className:"px-2 h-5 rounded-mark bg-soft text-brand-ink text-micro font-extrabold flex items-center",children:q.header}):jsx3("span",{}),total>1&&jsxs3("span",{className:"flex items-center gap-2 shrink-0",children:[jsx3("span",{"aria-hidden":"true",className:"flex items-center gap-1",children:block.questions.map((qq,i)=>jsx3("span",{className:cn("size-1.5 rounded-full transition-colors",i===at?"bg-brand":i<at?"bg-brand/40":"bg-border/40")},qq.key))}),jsxs3("span",{"data-num":true,className:"text-micro font-bold text-muted whitespace-nowrap",children:[at+1," \u0645\u0646 ",total]})]})]}),jsxs3("div",{className:"flex flex-col gap-2",children:[jsx3("span",{className:"text-ui font-extrabold text-ink [text-wrap:pretty]",children:q.label}),q.hint&&jsx3("span",{className:"text-caption leading-[1.7] text-muted",children:q.hint}),jsx3(ChoiceCards,{name:`${block.id}-${q.key}`,multiple:q.multi,disabled:!answerable,value:q.multi?picked[q.key]??[]:picked[q.key]?.[0]??null,onChange:v=>toggle(q,v),options:q.options.map(o=>({value:o.value,label:o.label,meta:o.description}))}),q.other!==false&&jsx3(Input,{size:"sm",value:other[q.key]??"",onChange:e=>setOther(p=>({...p,[q.key]:e.target.value})),disabled:!answerable,placeholder:q.other?.placeholder??"\u0623\u0648 \u0627\u0643\u062A\u0628 \u0625\u062C\u0627\u0628\u062A\u0643\u2026","aria-label":`\u0625\u062C\u0627\u0628\u0629 \u0623\u062E\u0631\u0649 \u0639\u0644\u0649: ${q.label}`}),noting[q.key]?jsx3(Textarea,{rows:2,value:notes[q.key]??"",onChange:e=>setNotes(p=>({...p,[q.key]:e.target.value})),disabled:!answerable,placeholder:"\u062D\u0627\u062C\u0629 \u062A\u062D\u0628\u0651 \u062A\u0642\u0648\u0644\u0647\u0627 \u0645\u0639 \u0627\u062E\u062A\u064A\u0627\u0631\u0643\u2026","aria-label":`\u0645\u0644\u0627\u062D\u0638\u0629 \u0639\u0644\u0649: ${q.label}`}):answerable&&jsxs3("button",{type:"button",onClick:()=>setNoting(p=>({...p,[q.key]:true})),className:"self-start inline-flex items-center gap-1.5 text-micro font-bold text-muted hover:text-brand cursor-pointer transition-colors",children:[jsx3(MessageSquarePlus,{size:13,"aria-hidden":"true"}),"\u0636\u064A\u0641 \u0645\u0644\u0627\u062D\u0638\u0629"]})]}),answerable&&jsxs3("span",{className:"flex items-center gap-2.5",children:[at>0&&jsx3(Button,{size:"sm",variant:"ghost",onClick:()=>setAt(i=>i-1),children:"\u0631\u062C\u0648\u0639"}),last?jsx3(Button,{size:"sm",onClick:submit,disabled:!canGo,children:block.submitLabel??"\u0627\u0628\u0639\u062A"}):jsx3(Button,{size:"sm",onClick:()=>setAt(i=>i+1),disabled:!canGo,iconEnd:jsx3(ArrowRight,{size:13,className:"rtl:rotate-180","aria-hidden":"true"}),children:"\u0627\u0644\u062A\u0627\u0644\u064A"}),!canGo&&jsx3("span",{className:"text-micro text-muted2",children:"\u0627\u062E\u062A\u0627\u0631 \u0625\u062C\u0627\u0628\u0629 \u0627\u0644\u0623\u0648\u0644"})]})]})}function Picked({labels,note}){if(labels.length===0)return jsx3("span",{className:"text-caption text-muted2",children:"\u0627\u062A\u062E\u0637\u0651\u0649"});return jsxs3("span",{className:"flex flex-col gap-1.5",children:[jsx3("span",{className:"flex flex-wrap gap-1.5",children:labels.map((l,i)=>jsxs3("span",{className:"inline-flex items-center gap-1 h-6 px-2 rounded-mark bg-soft text-brand-ink text-caption font-bold",children:[jsx3(Check2,{size:11,strokeWidth:3,"aria-hidden":"true"}),l]},i))}),note&&jsx3("span",{className:"text-micro leading-[1.7] text-muted border-s-2 border-line ps-2",children:note})]})}import{useEffect as useEffect4,useState as useState4}from"react";import{Check as Check3,Copy as Copy2,RotateCcw as RotateCcw2,Sparkles,X}from"lucide-react";import{Fragment as Fragment2,jsx as jsx4,jsxs as jsxs4}from"react/jsx-runtime";function DraftPanel({draft:source,basis,label,onInsert,onClose,insertLabel="\u0623\u062F\u0631\u0650\u062C",className}){const[attempt,setAttempt]=useState4(0);const[done,setDone]=useState4(false);const{text,streaming,start,finish}=useStreamingText({speed:12});const dynamic=typeof source==="function";useEffect4(()=>{start(dynamic?source(attempt):source)},[attempt,source]);return jsxs4("div",{className:cn("flex flex-col gap-2.5 p-3.5 rounded-card bg-bg border border-line","basis-full order-last w-full",className),children:[jsxs4("span",{className:"flex items-start justify-between gap-3",children:[jsxs4("span",{className:"flex flex-col gap-0.5 min-w-0",children:[jsxs4("span",{className:"flex items-center gap-1.5 text-caption font-extrabold text-ink",children:[jsx4(Sparkles,{size:13,className:"text-brand shrink-0","aria-hidden":"true"}),label]}),jsx4("span",{className:"text-micro leading-[1.65] text-muted",children:basis})]}),onClose&&jsx4("button",{type:"button",onClick:onClose,"aria-label":"\u0625\u063A\u0644\u0627\u0642",className:"shrink-0 size-6 rounded-mark flex items-center justify-center text-muted2 hover:bg-hover hover:text-ink cursor-pointer transition-colors",children:jsx4(X,{size:14,"aria-hidden":"true"})})]}),text===""&&streaming?jsx4(AiThinking,{label:"\u0628\u064A\u0643\u062A\u0628\u2026"}):jsxs4("span",{className:"block text-caption leading-[1.9] text-ink whitespace-pre-wrap [text-wrap:pretty]","aria-live":"polite",children:[text,streaming&&jsx4("span",{"aria-hidden":"true",className:"inline-block w-[2px] h-[1em] align-[-0.15em] ms-0.5 bg-brand animate-pulse"})]}),jsx4("span",{className:"flex items-center gap-2 flex-wrap",children:streaming?jsx4(Button,{size:"sm",variant:"outline",onClick:finish,children:"\u0627\u0639\u0631\u0636\u0647\u0627 \u0643\u0644\u0647\u0627"}):jsxs4(Fragment2,{children:[onInsert&&jsx4(Button,{size:"sm",onClick:()=>{onInsert(text);setDone(true);onClose?.()},icon:jsx4(Check3,{size:13,"aria-hidden":"true"}),children:insertLabel}),jsx4(Button,{size:"sm",variant:"outline",onClick:()=>navigator.clipboard?.writeText(text),icon:jsx4(Copy2,{size:13,"aria-hidden":"true"}),children:"\u0627\u0646\u0633\u062E"}),dynamic&&jsx4(Button,{size:"sm",variant:"ghost",onClick:()=>setAttempt(a=>a+1),icon:jsx4(RotateCcw2,{size:13,"aria-hidden":"true"}),children:"\u0627\u0643\u062A\u0628 \u063A\u064A\u0631\u0647\u0627"})]})}),!streaming&&!done&&jsx4(AiDisclaimer,{children:"\u0645\u0645\u0643\u0646 \u064A\u063A\u0644\u0637 \u2014 \u0627\u0642\u0631\u0627\u0647\u0627 \u0642\u0628\u0644 \u0645\u0627 \u062A\u0646\u0634\u0631\u0647\u0627."})]})}function AiDraft({size="sm",...panel}){const[open,setOpen]=useState4(false);if(!open){return jsx4(Button,{variant:"outline",size,onClick:()=>setOpen(true),icon:jsx4(Sparkles,{size:size==="sm"?13:15,"aria-hidden":"true"}),className:panel.className,children:panel.label})}return jsx4(DraftPanel,{...panel,onClose:()=>setOpen(false)})}import{Fragment as Fragment3,jsx as jsx5}from"react/jsx-runtime";function Markdown({md}){const chunks=md.split(/\n{2,}/);return jsx5(Fragment3,{children:chunks.map((chunk,i)=>{const lines=chunk.split("\n");const bullets=lines.every(l=>/^\s*[-•]\s+/.test(l));const numbers=lines.every(l=>/^\s*\d+[.)]\s+/.test(l));if(bullets||numbers){const items=lines.map(l=>l.replace(/^\s*(?:[-•]|\d+[.)])\s+/,""));const List=numbers?"ol":"ul";return jsx5(List,{className:numbers?"my-2 ps-5 list-decimal marker:text-muted2 flex flex-col gap-1":"my-2 ps-5 list-disc marker:text-muted2 flex flex-col gap-1",children:items.map((it,j)=>jsx5("li",{children:inline(it)},j))},i)}return jsx5("p",{className:"my-2 first:mt-0 last:mb-0 [text-wrap:pretty]",children:inline(chunk)},i)})})}var TOKEN=/(`[^`\n]+`)|(\*\*[^*\n]+\*\*)|(\*[^*\n]+\*)/g;function inline(src){const out=[];let last=0;let m;TOKEN.lastIndex=0;while((m=TOKEN.exec(src))!==null){if(m.index>last)out.push(src.slice(last,m.index));const[full]=m;const key=`${m.index}`;if(full.startsWith("`")){out.push(jsx5("code",{dir:"ltr",className:"px-1 py-px rounded-mark bg-hover text-[0.9em] font-mono text-brand-ink",children:full.slice(1,-1)},key))}else if(full.startsWith("**")){out.push(jsx5("strong",{className:"font-extrabold text-ink",children:full.slice(2,-2)},key))}else{out.push(jsx5("em",{className:"not-italic font-bold",children:full.slice(1,-1)},key))}last=m.index+full.length}if(last<src.length)out.push(src.slice(last));return out}import{Fragment as Fragment4,jsx as jsx6,jsxs as jsxs5}from"react/jsx-runtime";var TONE={good:"green",warn:"amber",bad:"red",plain:"neutral"};var NOTICE_TONE={info:"brand",warn:"amber",danger:"red"};function major(a){return a.minor/10**(a.decimals??2)}function TextBlockView({block}){if(!block.md)return null;return jsx6("div",{className:"text-body leading-[1.95] text-ink2",children:jsx6(Markdown,{md:block.md})})}function MetricBlockView({block}){return jsx6("div",{className:"grid gap-2.5 grid-cols-[repeat(auto-fit,minmax(9.5rem,1fr))]",children:block.items.map((m,i)=>jsx6(StatCard,{tone:TONE[m.tone??"plain"]??"neutral",label:m.label,value:m.amount?jsx6(Money,{value:major(m.amount),currency:isCurrency(m.amount.currency)?m.amount.currency:void 0,compact:true,trimZeros:true}):m.value,hint:m.delta!==void 0?deltaHint(m.delta,m.deltaBasis):void 0},i))})}function deltaHint(delta,basis){const up=delta>0;const flat=delta===0;return jsxs5("span",{className:cn("font-bold",flat?"text-muted2":up?"text-green":"text-red"),children:[flat?"=":up?"\u25B2":"\u25BC"," ",Math.abs(delta),"\u066A",basis?` ${basis}`:""]})}function TableBlockView({block}){const rows=block.rows.map((cells,i)=>{const row={__key:String(i)};block.cols.forEach((c,j)=>{row[c.key]=cells[j]??null});return row});const columns=block.cols.map(c=>({key:c.key,header:c.label,end:c.align==="end",cell:row=>renderCell(row[c.key],c)}));return jsxs5("span",{className:"flex flex-col gap-1.5",children:[block.caption&&jsx6("span",{className:"text-micro text-muted2",children:block.caption}),jsx6(DataTable,{columns,rows,rowKey:r=>r.__key,grid:block.cols.map(c=>c.align==="end"?"1fr":"1.6fr").join("_"),minWidth:block.cols.length*120,mobileCard:row=>jsx6("span",{className:"flex flex-col gap-1",children:block.cols.map(c=>jsxs5("span",{className:"flex items-baseline justify-between gap-3",children:[jsx6("span",{className:"text-micro text-muted2",children:c.label}),jsx6("span",{className:"text-caption text-ink",children:renderCell(row[c.key],c)})]},c.key))})})]})}function renderCell(v,col){if(v===null||v==="")return jsx6("span",{className:"text-muted2",children:"\u2014"});switch(col.format){case"money":return typeof v==="number"?jsx6(Money,{value:v,trimZeros:true}):v;case"badge":return jsx6(Badge,{size:"sm",children:v});case"number":return jsx6("span",{"data-num":true,children:v});default:return v}}function CardsBlockView({block,intents}){return jsx6("div",{className:"grid gap-2.5 grid-cols-[repeat(auto-fill,minmax(13rem,1fr))]",children:block.items.map(c=>jsx6(Card,{children:jsxs5("span",{className:"flex gap-3 items-start",children:[c.img&&jsx6("img",{src:c.img,alt:"",className:"size-12 rounded-sm object-cover bg-hover shrink-0"}),jsxs5("span",{className:"flex flex-col gap-1 min-w-0",children:[jsx6("span",{className:"text-ui font-bold text-ink truncate",children:c.title}),c.subtitle&&jsx6("span",{className:"text-micro text-muted",children:c.subtitle}),c.badge&&jsx6("span",{children:jsx6(Badge,{size:"sm",tone:"brand",children:c.badge})}),c.action&&jsx6(ActionButton,{action:c.action,intents,size:"sm"})]})]})},c.id))})}function ChartBlockView({block}){const labels=block.series.map(p=>String(p.x));const values=block.series.map(p=>p.y);const money=block.unit?.kind==="money";const fmt=v=>block.unit?.kind==="percent"?`${v}\u066A`:v.toLocaleString("ar-EG");if(block.kind==="bar"){return jsx6(BarChart,{labels,series:[{label:"",values}],formatValue:fmt})}return jsx6(TrendChart,{labels:axisLabels(labels),values,pointLabels:labels,formatValue:money?v=>v.toLocaleString("ar-EG"):fmt,height:170})}function axisLabels(all){if(all.length<=3)return all;return[all[0],all[Math.floor(all.length/2)],all[all.length-1]]}function ActionBlockView({block,intents}){const runnable=block.items.filter(a=>intents[a.intent]);if(runnable.length===0)return null;return jsx6("span",{className:"flex flex-wrap gap-2",children:runnable.map((a,i)=>jsx6(ActionButton,{action:a,intents},i))})}function ActionButton({action,intents,size="sm"}){const[asking,setAsking]=useState5(false);const run=intents[action.intent];if(!run)return null;function fire(){setAsking(false);run(action.args)}return jsxs5(Fragment4,{children:[jsx6(Button,{size,variant:action.style==="quiet"?"outline":"primary",onClick:()=>action.confirm?setAsking(true):fire(),children:action.label}),jsx6(Modal,{open:asking,title:action.label,description:action.confirm,onClose:()=>setAsking(false),size:"sm",footer:jsxs5(Fragment4,{children:[jsx6(Button,{variant:"outline",onClick:()=>setAsking(false),children:"\u0625\u0644\u063A\u0627\u0621"}),jsx6(Button,{onClick:fire,children:action.label})]})})]})}function ToolBlockView({block,intents}){const undo=block.undo;const run=undo?intents[undo.intent]:void 0;return jsx6(AiToolCall,{title:block.title,detail:block.detail,state:block.state,onUndo:run&&undo?()=>run(undo.args):void 0,undoLabel:undo?.label})}function NoticeBlockView({block}){return jsx6(Alert,{tone:NOTICE_TONE[block.tone],children:block.text})}function ChipsBlockView({block,onSend}){if(!onSend)return null;const byLabel=new Map(block.items.map(c=>[c.label,c.send]));return jsx6(AiPromptChips,{prompts:block.items.map(c=>c.label),onPick:label=>onSend(byLabel.get(label)??label)})}function BlockView({block,intents,onSend,onInsertDraft,onAnswer,live=true}){switch(block.type){case"text":return jsx6(TextBlockView,{block});case"metric":return jsx6(MetricBlockView,{block});case"table":return jsx6(TableBlockView,{block});case"cards":return jsx6(CardsBlockView,{block,intents});case"chart":return jsx6(ChartBlockView,{block});case"action":return jsx6(ActionBlockView,{block,intents});case"tool":return jsx6(ToolBlockView,{block,intents});case"notice":return jsx6(NoticeBlockView,{block});case"chips":return jsx6(ChipsBlockView,{block,onSend});case"ask":return jsx6(AskCard,{block,onAnswer,live});case"draft":return jsx6(DraftPanel,{draft:block.text,basis:block.basis,label:"\u0645\u0633\u0648\u0651\u062F\u0629",onInsert:onInsertDraft});default:return null}}import{jsx as jsx7,jsxs as jsxs6}from"react/jsx-runtime";var NO_INTENTS={};function ReplyView({reply,streaming,intents=NO_INTENTS,onSend,onInsertDraft,onAnswer,live=true,onRetry,onFeedback,className}){return jsx7(AiMessage,{role:"assistant",fill:true,streaming,sources:reply.sources,copyText:plainText(reply),onRetry,onFeedback,children:jsxs6("span",{className:cn("flex flex-col gap-3",className),children:[reply.blocks.map((block,i)=>jsx7(BlockView,{block,intents,onSend,onInsertDraft,onAnswer,live},i)),reply.disclaimer!==false&&!streaming&&jsx7(AiDisclaimer,{})]})})}function plainText(reply){const parts=[];for(const b of reply.blocks){switch(b.type){case"text":parts.push(b.md);break;case"metric":parts.push(b.items.map(m=>`${m.label}: ${m.value}`).join(" \xB7 "));break;case"table":parts.push([b.cols.map(c=>c.label).join(" "),...b.rows.map(r=>r.map(c=>c??"").join(" "))].join("\n"));break;case"cards":parts.push(b.items.map(c=>c.title).join("\n"));break;case"draft":parts.push(b.text);break;case"tool":parts.push(b.detail?`${b.title} \u2014 ${b.detail}`:b.title);break;case"notice":parts.push(b.text);break;case"ask":parts.push(b.questions.map(q=>q.label).join("\n"));break;case"chart":case"action":case"chips":break}}return parts.filter(Boolean).join("\n\n")}import{useCallback as useCallback2,useEffect as useEffect5,useRef as useRef4,useState as useState6}from"react";import{parseEvent,parseSSE,reduce}from"@qumra/jawab-ai";function useReplyStream(url,init){const[reply,setReply]=useState6(null);const[streaming,setStreaming]=useState6(false);const[error,setError]=useState6(null);const abort=useRef4(null);const lastInput=useRef4("");useEffect5(()=>()=>abort.current?.abort(),[]);const stop=useCallback2(()=>{abort.current?.abort();abort.current=null;setStreaming(false)},[]);const send=useCallback2(text=>{const question=text.trim();if(!question)return;abort.current?.abort();const ctrl=new AbortController;abort.current=ctrl;lastInput.current=question;setError(null);setReply(null);setStreaming(true);void(async()=>{try{const res=await fetch(url,{method:"POST",headers:{"content-type":"application/json",accept:"text/event-stream"},body:JSON.stringify({input:question}),signal:ctrl.signal,...init});if(!res.ok||!res.body){throw new StreamError("http_"+res.status,`\u0627\u0644\u062E\u0627\u062F\u0645 \u0631\u062C\u0651\u0639 ${res.status}`)}const decoder=new TextDecoder;const readerStream=res.body.getReader();let rest="";let state=null;for(;;){const{done,value}=await readerStream.read();if(done)break;rest+=decoder.decode(value,{stream:true});const{events,rest:tail}=parseSSE(rest);rest=tail;for(const raw of events){const ev=parseEvent(raw);if(!ev)continue;if(ev.e==="error")throw new StreamError(ev.code,ev.message);state=reduce(state,ev);setReply(state);if(ev.e==="done")break}}setStreaming(false)}catch(e){if(ctrl.signal.aborted)return;const se=e;setError({code:se.code??"unknown",message:se.message??"\u0627\u0644\u0627\u062A\u0635\u0627\u0644 \u0627\u062A\u0642\u0637\u0639.",lastInput:lastInput.current});setStreaming(false)}})()},[url,init]);return{reply,streaming,error,send,stop}}var StreamError=class extends Error{code;constructor(code,message){super(message);this.name="StreamError";this.code=code}};export{AiAvatar,AiComposer,AiDisclaimer,AiDraft,AiMessage,AiPromptChips,AiSources,AiThinking,AiToolCall,AskCard,DraftPanel,ReplyView,useMicLevel,useReplyStream,useStreamingText};
|
package/dist/charts.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{TOKENS,cn,useMoneyLocale,useUIText}from"./chunk-N6V3LTIS.js";import"react";import{CartesianGrid,Legend,ResponsiveContainer,Tooltip,XAxis,YAxis}from"recharts";import{useCallback,useSyncExternalStore}from"react";var VAR={brand:"var(--color-brand)",amber:"var(--color-amber)",violet:"var(--color-violet)",green:"var(--color-green)",red:"var(--color-red)",mint:"var(--color-mint)",muted:"var(--color-brand-100)"};var SERIES_ORDER=["brand","amber","violet","green","red","mint"];function toneColor(tone){return VAR[tone]}function toneAt(index){return SERIES_ORDER[index%SERIES_ORDER.length]}var AXIS_COLOR="var(--color-muted)";var GRID_COLOR="var(--color-line)";var SURFACE_COLOR="var(--color-surface)";var dirStore={subscribe(cb){if(typeof MutationObserver==="undefined")return()=>{};const o=new MutationObserver(cb);o.observe(document.documentElement,{attributes:true,attributeFilter:["dir"]});return()=>o.disconnect()},get:()=>typeof document==="undefined"?"rtl":document.documentElement.dir||"rtl"};function useRtl(){const locale=useMoneyLocale();const serverSnapshot=useCallback(()=>locale.startsWith("en")?"ltr":"rtl",[locale]);return useSyncExternalStore(dirStore.subscribe,dirStore.get,serverSnapshot)!=="ltr"}var BAR_RADIUS=Number.parseFloat(TOKENS["--radius-mark"]);import{jsx,jsxs}from"react/jsx-runtime";function useFormatters(formatValue,formatAxis){const locale=useMoneyLocale();return{value:formatValue??(v=>new Intl.NumberFormat(locale).format(v)),axis:formatAxis??(v=>new Intl.NumberFormat(locale,{notation:"compact",maximumFractionDigits:1}).format(v))}}function ChartEmpty({height,children}){const ui=useUIText();return jsx("div",{className:"text-caption text-muted2 flex items-center justify-center",style:{height},role:"status",children:children??ui.noData})}function ChartTooltipContent({active,payload,label,format,formatX}){if(!active||!payload?.length)return null;return jsxs("div",{className:"bg-surface border-line rounded-card shadow-tip min-w-32 border p-2.5 whitespace-nowrap",children:[label!==void 0&&label!==""&&jsx("p",{className:"text-caption text-muted mb-1.5",children:formatX?formatX(label):String(label)}),jsx("ul",{className:"space-y-1",children:payload.map((entry,i)=>jsxs("li",{className:"flex items-center gap-2",children:[jsx("span",{className:"rounded-mark size-2 shrink-0",style:{backgroundColor:entry.color},"aria-hidden":"true"}),jsx("span",{className:"text-caption text-muted grow",children:entry.name}),jsx("span",{className:"text-ui text-ink font-bold","data-num":true,children:typeof entry.value==="number"?format(entry.value):String(entry.value??"")})]},`${entry.dataKey??"k"}-${i}`))})]})}function ChartTooltipLine({active,payload,label,format}){const point=payload?.[0];if(!active||!point)return null;const named=label!==void 0&&label!=="";return jsxs("div",{className:"bg-surface border-line rounded-sm shadow-tip flex items-center gap-1.5 border px-2 py-1 whitespace-nowrap",children:[named&&jsx("span",{className:"text-micro text-muted",children:label}),named&&jsx("span",{className:"text-micro text-muted2","aria-hidden":"true",children:"\xB7"}),jsx("span",{className:"text-caption text-ink font-bold","data-num":true,children:typeof point.value==="number"?format(point.value):String(point.value??"")})]})}function ChartLegendContent({payload}){if(!payload?.length)return null;return jsx("ul",{className:"text-caption text-muted flex flex-wrap items-center justify-center gap-x-4 gap-y-1 pt-2",children:payload.map((entry,i)=>jsxs("li",{className:"flex items-center gap-1.5",children:[jsx("span",{className:"rounded-mark size-2 shrink-0",style:{backgroundColor:entry.color},"aria-hidden":"true"}),entry.value]},`${entry.dataKey??"k"}-${i}`))})}function chartGrid(){return jsx(CartesianGrid,{stroke:GRID_COLOR,strokeDasharray:"3 3",vertical:false})}function chartXAxis({dataKey,rtl,axis,formatX}){return jsx(XAxis,{dataKey,reversed:rtl&&axis==="category",tickFormatter:formatX,tick:{fill:AXIS_COLOR,className:"text-caption"},tickLine:false,axisLine:{stroke:GRID_COLOR},tickMargin:8,minTickGap:4})}function chartYAxis({rtl,format,id,side="primary"}){const onRight=side==="primary"?rtl:!rtl;return jsx(YAxis,{yAxisId:id,orientation:onRight?"right":"left",tickFormatter:format,tick:{fill:AXIS_COLOR,className:"text-caption",textAnchor:onRight===rtl?"end":"start"},tickLine:false,axisLine:false,width:"auto"})}var TOOLTIP_WRAPPER={zIndex:50};function chartTooltip({format,formatX}){return jsx(Tooltip,{cursor:{fill:GRID_COLOR,fillOpacity:.6},wrapperStyle:TOOLTIP_WRAPPER,content:jsx(ChartTooltipContent,{format,formatX})})}function chartLegend(){return jsx(Legend,{content:jsx(ChartLegendContent,{}),verticalAlign:"bottom"})}function ChartFrame({label,height,empty,isEmpty,className,children}){return jsx("div",{className:cn("w-full",className),role:"img","aria-label":label,children:isEmpty?jsx(ChartEmpty,{height,children:empty}):jsx(ResponsiveContainer,{width:"100%",height,children})})}function resolveSeries(series){return series.map((s,i)=>({...s,name:s.label??s.key,color:toneColor(s.tone??toneAt(i))}))}function chartMargin(rtl){return{top:8,bottom:0,left:rtl?4:0,right:rtl?0:4}}import{useId}from"react";import{Area,AreaChart as RAreaChart,Bar,BarChart as RBarChart,ComposedChart as RComposedChart,Line,LineChart as RLineChart,ResponsiveContainer as ResponsiveContainer2,Scatter,Tooltip as Tooltip2,ScatterChart as RScatterChart,XAxis as XAxis2,YAxis as YAxis2,ZAxis}from"recharts";import{Fragment,jsx as jsx2,jsxs as jsxs2}from"react/jsx-runtime";var DEFAULT_HEIGHT=220;function BarChart({data,x,series,bars="columns",height=DEFAULT_HEIGHT,label,formatValue,formatAxis,formatX,axis="category",grid=true,legend,empty,className}){const rtl=useRtl();const fmt=useFormatters(formatValue,formatAxis);const items=resolveSeries(series);const showLegend=legend??items.length>1;const rows=bars==="rows";return jsx2(ChartFrame,{label,height,isEmpty:data.length===0,empty,className,children:jsxs2(RBarChart,{data,layout:rows?"vertical":"horizontal",margin:chartMargin(rtl),accessibilityLayer:true,children:[grid&&chartGrid(),rows?jsxs2(Fragment,{children:[jsx2(XAxis2,{type:"number",tickFormatter:fmt.axis,tick:{fill:AXIS_COLOR,className:"text-caption"},tickLine:false,axisLine:{stroke:GRID_COLOR},reversed:rtl}),jsx2(YAxis2,{type:"category",dataKey:x,tickFormatter:formatX,tick:{fill:AXIS_COLOR,className:"text-caption",textAnchor:"end"},tickLine:false,axisLine:false,orientation:rtl?"right":"left",width:"auto"})]}):jsxs2(Fragment,{children:[chartXAxis({dataKey:x,rtl,axis,formatX}),chartYAxis({rtl,format:fmt.axis})]}),chartTooltip({format:fmt.value,formatX}),showLegend&&chartLegend(),items.map(s=>jsx2(Bar,{dataKey:s.key,name:s.name,fill:s.color,stackId:s.stackId,radius:rows?[0,BAR_RADIUS,BAR_RADIUS,0]:[BAR_RADIUS,BAR_RADIUS,0,0],maxBarSize:rows?24:48,isAnimationActive:false},s.key))]})})}function LineChart({data,x,series,height=DEFAULT_HEIGHT,label,formatValue,formatAxis,formatX,axis="time",grid=true,legend,dots=false,straight=false,empty,className}){const rtl=useRtl();const fmt=useFormatters(formatValue,formatAxis);const items=resolveSeries(series);const showLegend=legend??items.length>1;return jsx2(ChartFrame,{label,height,isEmpty:data.length===0,empty,className,children:jsxs2(RLineChart,{data,margin:chartMargin(rtl),accessibilityLayer:true,children:[grid&&chartGrid(),chartXAxis({dataKey:x,rtl,axis,formatX}),chartYAxis({rtl,format:fmt.axis}),chartTooltip({format:fmt.value,formatX}),showLegend&&chartLegend(),items.map(s=>jsx2(Line,{type:straight?"linear":"monotone",dataKey:s.key,name:s.name,stroke:s.color,strokeWidth:2,dot:dots?{r:3,fill:SURFACE_COLOR,strokeWidth:2}:false,activeDot:{r:4,fill:SURFACE_COLOR,strokeWidth:2},connectNulls:false,isAnimationActive:false},s.key))]})})}function AreaChart({data,x,series,height=DEFAULT_HEIGHT,label,formatValue,formatAxis,formatX,axis="time",grid=true,legend,empty,className}){const rtl=useRtl();const fmt=useFormatters(formatValue,formatAxis);const items=resolveSeries(series);const showLegend=legend??items.length>1;const gid=useId().replace(/:/g,"");return jsx2(ChartFrame,{label,height,isEmpty:data.length===0,empty,className,children:jsxs2(RAreaChart,{data,margin:chartMargin(rtl),accessibilityLayer:true,children:[jsx2("defs",{children:items.map(s=>jsxs2("linearGradient",{id:`${gid}-${s.key}`,x1:"0",y1:"0",x2:"0",y2:"1",children:[jsx2("stop",{offset:"0%",stopColor:s.color,stopOpacity:.28}),jsx2("stop",{offset:"100%",stopColor:s.color,stopOpacity:.02})]},s.key))}),grid&&chartGrid(),chartXAxis({dataKey:x,rtl,axis,formatX}),chartYAxis({rtl,format:fmt.axis}),chartTooltip({format:fmt.value,formatX}),showLegend&&chartLegend(),items.map(s=>jsx2(Area,{type:"monotone",dataKey:s.key,name:s.name,stackId:s.stackId,stroke:s.color,strokeWidth:2,fill:`url(#${gid}-${s.key})`,activeDot:{r:4,fill:SURFACE_COLOR,strokeWidth:2},connectNulls:false,isAnimationActive:false},s.key))]})})}function ComposedChart({data,x,series,height=DEFAULT_HEIGHT,label,formatValue,formatAxis,formatX,axis="category",grid=true,legend,empty,className}){const rtl=useRtl();const fmt=useFormatters(formatValue,formatAxis);const items=resolveSeries(series);const showLegend=legend??items.length>1;const gid=useId().replace(/:/g,"");const split=items.some(s=>s.scale==="secondary");const axisOf=s=>split?s.scale==="secondary"?"r":"l":void 0;return jsx2(ChartFrame,{label,height,isEmpty:data.length===0,empty,className,children:jsxs2(RComposedChart,{data,margin:chartMargin(rtl),accessibilityLayer:true,children:[jsx2("defs",{children:items.filter(s=>s.as==="area").map(s=>jsxs2("linearGradient",{id:`${gid}-${s.key}`,x1:"0",y1:"0",x2:"0",y2:"1",children:[jsx2("stop",{offset:"0%",stopColor:s.color,stopOpacity:.28}),jsx2("stop",{offset:"100%",stopColor:s.color,stopOpacity:.02})]},s.key))}),grid&&chartGrid(),chartXAxis({dataKey:x,rtl,axis,formatX}),chartYAxis({rtl,format:fmt.axis,id:split?"l":void 0}),split&&chartYAxis({rtl,format:fmt.axis,id:"r",side:"secondary"}),chartTooltip({format:fmt.value,formatX}),showLegend&&chartLegend(),items.map(s=>s.as==="line"?jsx2(Line,{type:"monotone",dataKey:s.key,name:s.name,yAxisId:axisOf(s),stroke:s.color,strokeWidth:2,dot:false,activeDot:{r:4,fill:SURFACE_COLOR,strokeWidth:2},isAnimationActive:false},s.key):s.as==="area"?jsx2(Area,{type:"monotone",dataKey:s.key,name:s.name,yAxisId:axisOf(s),stackId:s.stackId,stroke:s.color,strokeWidth:2,fill:`url(#${gid}-${s.key})`,isAnimationActive:false},s.key):jsx2(Bar,{dataKey:s.key,name:s.name,yAxisId:axisOf(s),fill:s.color,stackId:s.stackId,radius:[BAR_RADIUS,BAR_RADIUS,0,0],maxBarSize:48,isAnimationActive:false},s.key))]})})}function ScatterChart({groups,height=DEFAULT_HEIGHT,label,xLabel,yLabel,formatValue,formatAxis,grid=true,legend,empty,className}){const rtl=useRtl();const fmt=useFormatters(formatValue,formatAxis);const showLegend=legend??groups.length>1;const isEmpty=groups.every(g=>g.points.length===0);return jsx2(ChartFrame,{label,height,isEmpty,empty,className,children:jsxs2(RScatterChart,{margin:chartMargin(rtl),accessibilityLayer:true,children:[grid&&chartGrid(),jsx2(XAxis2,{type:"number",dataKey:"x",name:xLabel,tickFormatter:fmt.axis,tick:{fill:AXIS_COLOR,className:"text-caption"},tickLine:false,axisLine:{stroke:GRID_COLOR}}),jsx2(YAxis2,{type:"number",dataKey:"y",name:yLabel,tickFormatter:fmt.axis,tick:{fill:AXIS_COLOR,className:"text-caption",textAnchor:"end"},tickLine:false,axisLine:false,orientation:rtl?"right":"left",width:"auto"}),jsx2(ZAxis,{type:"number",dataKey:"z",range:[36,300]}),chartTooltip({format:fmt.value}),showLegend&&chartLegend(),groups.map((g,i)=>jsx2(Scatter,{name:g.label??g.key,data:g.points,fill:toneColor(g.tone??toneAt(i)),fillOpacity:.75,isAnimationActive:false},g.key))]})})}function Sparkline({values,label,labels,formatValue,tone="brand",height=36,filled,className}){const gid=useId().replace(/:/g,"");const fmt=useFormatters(formatValue);const color=toneColor(tone);const named=labels!==void 0&&labels.length>0;const data=values.map((v,i)=>({i,v,at:labels?.[i]??""}));if(values.length===0)return null;return jsx2("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx2(ResponsiveContainer2,{width:"100%",height,children:jsxs2(RAreaChart,{data,margin:{top:2,bottom:2,left:0,right:0},accessibilityLayer:true,children:[jsx2("defs",{children:jsxs2("linearGradient",{id:`${gid}-spark`,x1:"0",y1:"0",x2:"0",y2:"1",children:[jsx2("stop",{offset:"0%",stopColor:color,stopOpacity:.3}),jsx2("stop",{offset:"100%",stopColor:color,stopOpacity:0})]})}),named&&jsx2(XAxis2,{dataKey:"at",hide:true}),named&&jsx2(Tooltip2,{cursor:{stroke:color,strokeWidth:1},wrapperStyle:TOOLTIP_WRAPPER,content:jsx2(ChartTooltipLine,{format:fmt.value})}),jsx2(Area,{type:"monotone",dataKey:"v",name:label,stroke:color,strokeWidth:1.5,fill:filled?`url(#${gid}-spark)`:"none",dot:false,isAnimationActive:false})]})})})}import{Cell,Legend as Legend2,Pie,PieChart as RPieChart,PolarAngleAxis,PolarGrid,PolarRadiusAxis,Radar,RadarChart as RRadarChart,RadialBar,RadialBarChart as RRadialBarChart,ResponsiveContainer as ResponsiveContainer3,Tooltip as Tooltip3}from"recharts";import{jsx as jsx3,jsxs as jsxs3}from"react/jsx-runtime";var DEFAULT_HEIGHT2=220;function slices(items){return items.map((s,i)=>({name:s.label??s.key,value:s.value,color:toneColor(s.tone??toneAt(i)),key:s.key}))}function PieChart({items,height=DEFAULT_HEIGHT2,label,formatValue,legend=true,empty,className}){return jsx3(Ring,{items,height,label,formatValue,legend,empty,className,inner:0})}function DonutChart({items,height=DEFAULT_HEIGHT2,label,formatValue,legend=true,centerValue,centerLabel,empty,className}){return jsx3(Ring,{items,height,label,formatValue,legend,empty,className,inner:62,centerValue,centerLabel})}function Ring({items,height,label,formatValue,legend,empty,className,inner,centerValue,centerLabel}){const locale=useMoneyLocale();const fmt=useFormatters(formatValue);const data=slices(items);const isEmpty=data.length===0||data.every(d=>!d.value);const total=data.reduce((sum,d)=>sum+(d.value||0),0);if(isEmpty){return jsx3("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx3(ChartEmpty,{height:height??DEFAULT_HEIGHT2,children:empty})})}return jsxs3("div",{className:cn("relative w-full",className),role:"img","aria-label":label,children:[jsx3(ResponsiveContainer3,{width:"100%",height:height??DEFAULT_HEIGHT2,children:jsxs3(RPieChart,{children:[jsx3(Tooltip3,{wrapperStyle:TOOLTIP_WRAPPER,content:jsx3(ChartTooltipContent,{format:fmt.value})}),legend&&jsx3(Legend2,{content:jsx3(ChartLegendContent,{}),verticalAlign:"bottom"}),jsx3(Pie,{data,dataKey:"value",nameKey:"name",innerRadius:inner?`${inner}%`:0,outerRadius:"88%",stroke:SURFACE_COLOR,strokeWidth:2,isAnimationActive:false,startAngle:90,endAngle:-270,children:data.map(d=>jsx3(Cell,{fill:d.color},d.key))})]})}),inner>0&&jsxs3("div",{className:"pointer-events-none absolute inset-0 flex flex-col items-center justify-center",children:[jsx3("span",{className:"text-h3 text-ink font-extrabold","data-num":true,children:centerValue??new Intl.NumberFormat(locale).format(total)}),centerLabel&&jsx3("span",{className:"text-caption text-muted",children:centerLabel})]})]})}function RadarChart({data,x,series,height=DEFAULT_HEIGHT2,label,formatValue,legend,empty,className}){const fmt=useFormatters(formatValue);const items=resolveSeries(series);const showLegend=legend??items.length>1;if(data.length===0){return jsx3("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx3(ChartEmpty,{height,children:empty})})}return jsx3("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx3(ResponsiveContainer3,{width:"100%",height,children:jsxs3(RRadarChart,{data,outerRadius:"72%",children:[jsx3(PolarGrid,{stroke:GRID_COLOR}),jsx3(PolarAngleAxis,{dataKey:x,tick:{fill:AXIS_COLOR,className:"text-caption"}}),jsx3(PolarRadiusAxis,{tick:false,axisLine:false}),jsx3(Tooltip3,{wrapperStyle:TOOLTIP_WRAPPER,content:jsx3(ChartTooltipContent,{format:fmt.value})}),showLegend&&jsx3(Legend2,{content:jsx3(ChartLegendContent,{}),verticalAlign:"bottom"}),items.map(s=>jsx3(Radar,{dataKey:s.key,name:s.name,stroke:s.color,strokeWidth:2,fill:s.color,fillOpacity:.18,isAnimationActive:false},s.key))]})})})}function RadialChart({items,max,height=DEFAULT_HEIGHT2,label,formatValue,legend=true,empty,className}){const fmt=useFormatters(formatValue);const data=slices(items);const isEmpty=data.length===0;if(isEmpty){return jsx3("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx3(ChartEmpty,{height,children:empty})})}const ceiling=max??Math.max(...data.map(d=>d.value||0));return jsx3("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx3(ResponsiveContainer3,{width:"100%",height,children:jsxs3(RRadialBarChart,{data,innerRadius:"30%",outerRadius:"95%",startAngle:90,endAngle:-270,barSize:12,children:[jsx3(PolarAngleAxis,{type:"number",domain:[0,ceiling],tick:false}),jsx3(Tooltip3,{wrapperStyle:TOOLTIP_WRAPPER,content:jsx3(ChartTooltipContent,{format:fmt.value})}),legend&&jsx3(Legend2,{content:jsx3(ChartLegendContent,{}),verticalAlign:"bottom"}),jsx3(RadialBar,{dataKey:"value",background:{fill:GRID_COLOR},cornerRadius:"50%",isAnimationActive:false,children:data.map(d=>jsx3(Cell,{fill:d.color},d.key))})]})})})}import{useMemo}from"react";import{Funnel,FunnelChart as RFunnelChart,LabelList,useChartWidth,useMargin,ResponsiveContainer as ResponsiveContainer4,Sankey,Tooltip as Tooltip4,Treemap}from"recharts";import{jsx as jsx4,jsxs as jsxs4}from"react/jsx-runtime";var DEFAULT_HEIGHT3=240;function FunnelChart({steps,height=DEFAULT_HEIGHT3,label,formatValue,showRate=true,empty,className}){const rtl=useRtl();const locale=useMoneyLocale();const fmt=useFormatters(formatValue);const isEmpty=steps.length===0||steps.every(s=>!s.value);if(isEmpty){return jsx4("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx4(ChartEmpty,{height,children:empty})})}const first=steps[0]?.value||0;const data=steps.map(s=>({name:s.label??s.key,value:s.value,fill:toneColor(s.tone??"brand"),rate:first?s.value/first:0}));return jsx4("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx4(ResponsiveContainer4,{width:"100%",height,children:jsxs4(RFunnelChart,{margin:rtl?{left:56,right:104}:{left:104,right:56},children:[jsx4(Tooltip4,{wrapperStyle:TOOLTIP_WRAPPER,content:jsx4(ChartTooltipContent,{format:fmt.value})}),jsx4(Funnel,{dataKey:"value",data,stroke:SURFACE_COLOR,strokeWidth:2,isAnimationActive:false,children:jsx4(LabelList,{dataKey:"name",content:jsx4(FunnelBandLabel,{rtl,rows:data,showRate,formatRate:v=>new Intl.NumberFormat(locale,{style:"percent",maximumFractionDigits:1}).format(v)})})})]})})})}function TreemapChart({nodes,height=DEFAULT_HEIGHT3,label,formatValue,empty,className}){const fmt=useFormatters(formatValue);const isEmpty=nodes.length===0;if(isEmpty){return jsx4("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx4(ChartEmpty,{height,children:empty})})}const data=nodes.map((n,i)=>({...n,fill:toneColor(n.tone??toneAt(i))}));return jsx4("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx4(ResponsiveContainer4,{width:"100%",height,children:jsx4(Treemap,{data,dataKey:"value",stroke:SURFACE_COLOR,isAnimationActive:false,content:jsx4(TreemapCell,{}),children:jsx4(Tooltip4,{wrapperStyle:TOOLTIP_WRAPPER,content:jsx4(ChartTooltipContent,{format:fmt.value})})})})})}function TreemapCell(props){const{x=0,y=0,width=0,height=0,name,fill}=props;const roomy=width>64&&height>24;return jsxs4("g",{children:[jsx4("rect",{x,y,width,height,fill,stroke:SURFACE_COLOR,strokeWidth:2}),roomy&&name&&jsx4("text",{x:x+width/2,y:y+height/2,textAnchor:"middle",dominantBaseline:"middle",fill:SURFACE_COLOR,className:"text-caption",children:name})]})}function SankeyChart({nodes,links,height=DEFAULT_HEIGHT3,label,formatValue,empty,className}){const rtl=useRtl();const fmt=useFormatters(formatValue);const isEmpty=nodes.length===0||links.length===0;const ends=useMemo(()=>{const withIncoming=new Set(links.map(l=>l.target));const withOutgoing=new Set(links.map(l=>l.source));return{first:new Set(nodes.map((_,i)=>i).filter(i=>!withIncoming.has(i))),last:new Set(nodes.map((_,i)=>i).filter(i=>!withOutgoing.has(i)))}},[nodes,links]);if(isEmpty){return jsx4("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx4(ChartEmpty,{height,children:empty})})}return jsx4("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx4(ResponsiveContainer4,{width:"100%",height,children:jsx4(Sankey,{data:{nodes,links},nodePadding:24,node:jsx4(SankeyNodeShape,{rtl,ends}),link:{stroke:toneColor("brand"),strokeOpacity:.16},margin:{top:24,bottom:8,left:72,right:72},children:jsx4(Tooltip4,{wrapperStyle:TOOLTIP_WRAPPER,content:jsx4(ChartTooltipContent,{format:fmt.value})})})})})}function SankeyNodeShape(props){const{x=0,y=0,width=0,height=0,index=0,rtl=false,ends,payload}=props;const isFirst=ends?.first.has(index)??false;const isLast=ends?.last.has(index)??false;const at=isFirst&&!isLast?{x:x-8,y:y+height/2,anchor:rtl?"start":"end"}:isLast?{x:x+width+8,y:y+height/2,anchor:rtl?"end":"start"}:{x:x+width/2,y:y-8,anchor:"middle"};return jsxs4("g",{children:[jsx4("rect",{x,y,width,height,fill:toneColor("brand"),rx:BAR_RADIUS}),jsx4("text",{x:at.x,y:at.y,textAnchor:at.anchor,dominantBaseline:at.anchor==="middle"?"auto":"middle",fill:AXIS_COLOR,className:"text-caption",children:payload?.name})]})}function FunnelBandLabel(props){const{y=0,height=0,index=0,rtl=false,showRate,rows,formatRate,value}=props;const chartWidth=useChartWidth()??0;const margin=useMargin()??{left:0,right:0};const left=margin.left??0;const right=margin.right??0;const rate=rows?.[index]?.rate;const mid=y+height/2;const pad=8;const nameX=rtl?chartWidth-right+pad:left-pad;const rateX=rtl?left-pad:chartWidth-right+pad;return jsxs4("g",{children:[jsx4("text",{x:nameX,y:mid,textAnchor:"end",dominantBaseline:"middle",fill:AXIS_COLOR,className:"text-caption",children:value}),showRate&&rate!==void 0&&jsx4("text",{x:rateX,y:mid,textAnchor:"start",dominantBaseline:"middle",fill:AXIS_COLOR,className:"text-caption",children:formatRate?.(rate)})]})}export{AreaChart,BarChart,ChartEmpty,ChartFrame,ComposedChart,DonutChart,FunnelChart,LineChart,PieChart,RadarChart,RadialChart,SERIES_ORDER,SankeyChart,ScatterChart,Sparkline,TreemapChart,toneAt,toneColor,useRtl};
|
|
2
|
+
import{TOKENS,cn,useMoneyLocale,useUIText}from"./chunk-YJ45RGS6.js";import"react";import{CartesianGrid,Legend,ResponsiveContainer,Tooltip,XAxis,YAxis}from"recharts";import{useCallback,useSyncExternalStore}from"react";var VAR={brand:"var(--color-brand)",amber:"var(--color-amber)",violet:"var(--color-violet)",green:"var(--color-green)",red:"var(--color-red)",mint:"var(--color-mint)",muted:"var(--color-brand-100)"};var SERIES_ORDER=["brand","amber","violet","green","red","mint"];function toneColor(tone){return VAR[tone]}function toneAt(index){return SERIES_ORDER[index%SERIES_ORDER.length]}var AXIS_COLOR="var(--color-muted)";var GRID_COLOR="var(--color-line)";var SURFACE_COLOR="var(--color-surface)";var dirStore={subscribe(cb){if(typeof MutationObserver==="undefined")return()=>{};const o=new MutationObserver(cb);o.observe(document.documentElement,{attributes:true,attributeFilter:["dir"]});return()=>o.disconnect()},get:()=>typeof document==="undefined"?"rtl":document.documentElement.dir||"rtl"};function useRtl(){const locale=useMoneyLocale();const serverSnapshot=useCallback(()=>locale.startsWith("en")?"ltr":"rtl",[locale]);return useSyncExternalStore(dirStore.subscribe,dirStore.get,serverSnapshot)!=="ltr"}var BAR_RADIUS=Number.parseFloat(TOKENS["--radius-mark"]);import{jsx,jsxs}from"react/jsx-runtime";function useFormatters(formatValue,formatAxis){const locale=useMoneyLocale();return{value:formatValue??(v=>new Intl.NumberFormat(locale).format(v)),axis:formatAxis??(v=>new Intl.NumberFormat(locale,{notation:"compact",maximumFractionDigits:1}).format(v))}}function ChartEmpty({height,children}){const ui=useUIText();return jsx("div",{className:"text-caption text-muted2 flex items-center justify-center",style:{height},role:"status",children:children??ui.noData})}function ChartTooltipContent({active,payload,label,format,formatX}){if(!active||!payload?.length)return null;return jsxs("div",{className:"bg-surface border-line rounded-card shadow-tip min-w-32 border p-2.5 whitespace-nowrap",children:[label!==void 0&&label!==""&&jsx("p",{className:"text-caption text-muted mb-1.5",children:formatX?formatX(label):String(label)}),jsx("ul",{className:"space-y-1",children:payload.map((entry,i)=>jsxs("li",{className:"flex items-center gap-2",children:[jsx("span",{className:"rounded-mark size-2 shrink-0",style:{backgroundColor:entry.color},"aria-hidden":"true"}),jsx("span",{className:"text-caption text-muted grow",children:entry.name}),jsx("span",{className:"text-ui text-ink font-bold","data-num":true,children:typeof entry.value==="number"?format(entry.value):String(entry.value??"")})]},`${entry.dataKey??"k"}-${i}`))})]})}function ChartTooltipLine({active,payload,label,format}){const point=payload?.[0];if(!active||!point)return null;const named=label!==void 0&&label!=="";return jsxs("div",{className:"bg-surface border-line rounded-sm shadow-tip flex items-center gap-1.5 border px-2 py-1 whitespace-nowrap",children:[named&&jsx("span",{className:"text-micro text-muted",children:label}),named&&jsx("span",{className:"text-micro text-muted2","aria-hidden":"true",children:"\xB7"}),jsx("span",{className:"text-caption text-ink font-bold","data-num":true,children:typeof point.value==="number"?format(point.value):String(point.value??"")})]})}function ChartLegendContent({payload}){if(!payload?.length)return null;return jsx("ul",{className:"text-caption text-muted flex flex-wrap items-center justify-center gap-x-4 gap-y-1 pt-2",children:payload.map((entry,i)=>jsxs("li",{className:"flex items-center gap-1.5",children:[jsx("span",{className:"rounded-mark size-2 shrink-0",style:{backgroundColor:entry.color},"aria-hidden":"true"}),entry.value]},`${entry.dataKey??"k"}-${i}`))})}function chartGrid(){return jsx(CartesianGrid,{stroke:GRID_COLOR,strokeDasharray:"3 3",vertical:false})}function chartXAxis({dataKey,rtl,axis,formatX}){return jsx(XAxis,{dataKey,reversed:rtl&&axis==="category",tickFormatter:formatX,tick:{fill:AXIS_COLOR,className:"text-caption"},tickLine:false,axisLine:{stroke:GRID_COLOR},tickMargin:8,minTickGap:4})}function chartYAxis({rtl,format,id,side="primary"}){const onRight=side==="primary"?rtl:!rtl;return jsx(YAxis,{yAxisId:id,orientation:onRight?"right":"left",tickFormatter:format,tick:{fill:AXIS_COLOR,className:"text-caption",textAnchor:onRight===rtl?"end":"start"},tickLine:false,axisLine:false,width:"auto"})}var TOOLTIP_WRAPPER={zIndex:50};function chartTooltip({format,formatX}){return jsx(Tooltip,{cursor:{fill:GRID_COLOR,fillOpacity:.6},wrapperStyle:TOOLTIP_WRAPPER,content:jsx(ChartTooltipContent,{format,formatX})})}function chartLegend(){return jsx(Legend,{content:jsx(ChartLegendContent,{}),verticalAlign:"bottom"})}function ChartFrame({label,height,empty,isEmpty,className,children}){return jsx("div",{className:cn("w-full",className),role:"img","aria-label":label,children:isEmpty?jsx(ChartEmpty,{height,children:empty}):jsx(ResponsiveContainer,{width:"100%",height,children})})}function resolveSeries(series){return series.map((s,i)=>({...s,name:s.label??s.key,color:toneColor(s.tone??toneAt(i))}))}function chartMargin(rtl){return{top:8,bottom:0,left:rtl?4:0,right:rtl?0:4}}import{useId}from"react";import{Area,AreaChart as RAreaChart,Bar,BarChart as RBarChart,ComposedChart as RComposedChart,Line,LineChart as RLineChart,ResponsiveContainer as ResponsiveContainer2,Scatter,Tooltip as Tooltip2,ScatterChart as RScatterChart,XAxis as XAxis2,YAxis as YAxis2,ZAxis}from"recharts";import{Fragment,jsx as jsx2,jsxs as jsxs2}from"react/jsx-runtime";var DEFAULT_HEIGHT=220;function BarChart({data,x,series,bars="columns",height=DEFAULT_HEIGHT,label,formatValue,formatAxis,formatX,axis="category",grid=true,legend,empty,className}){const rtl=useRtl();const fmt=useFormatters(formatValue,formatAxis);const items=resolveSeries(series);const showLegend=legend??items.length>1;const rows=bars==="rows";return jsx2(ChartFrame,{label,height,isEmpty:data.length===0,empty,className,children:jsxs2(RBarChart,{data,layout:rows?"vertical":"horizontal",margin:chartMargin(rtl),accessibilityLayer:true,children:[grid&&chartGrid(),rows?jsxs2(Fragment,{children:[jsx2(XAxis2,{type:"number",tickFormatter:fmt.axis,tick:{fill:AXIS_COLOR,className:"text-caption"},tickLine:false,axisLine:{stroke:GRID_COLOR},reversed:rtl}),jsx2(YAxis2,{type:"category",dataKey:x,tickFormatter:formatX,tick:{fill:AXIS_COLOR,className:"text-caption",textAnchor:"end"},tickLine:false,axisLine:false,orientation:rtl?"right":"left",width:"auto"})]}):jsxs2(Fragment,{children:[chartXAxis({dataKey:x,rtl,axis,formatX}),chartYAxis({rtl,format:fmt.axis})]}),chartTooltip({format:fmt.value,formatX}),showLegend&&chartLegend(),items.map(s=>jsx2(Bar,{dataKey:s.key,name:s.name,fill:s.color,stackId:s.stackId,radius:rows?[0,BAR_RADIUS,BAR_RADIUS,0]:[BAR_RADIUS,BAR_RADIUS,0,0],maxBarSize:rows?24:48,isAnimationActive:false},s.key))]})})}function LineChart({data,x,series,height=DEFAULT_HEIGHT,label,formatValue,formatAxis,formatX,axis="time",grid=true,legend,dots=false,straight=false,empty,className}){const rtl=useRtl();const fmt=useFormatters(formatValue,formatAxis);const items=resolveSeries(series);const showLegend=legend??items.length>1;return jsx2(ChartFrame,{label,height,isEmpty:data.length===0,empty,className,children:jsxs2(RLineChart,{data,margin:chartMargin(rtl),accessibilityLayer:true,children:[grid&&chartGrid(),chartXAxis({dataKey:x,rtl,axis,formatX}),chartYAxis({rtl,format:fmt.axis}),chartTooltip({format:fmt.value,formatX}),showLegend&&chartLegend(),items.map(s=>jsx2(Line,{type:straight?"linear":"monotone",dataKey:s.key,name:s.name,stroke:s.color,strokeWidth:2,dot:dots?{r:3,fill:SURFACE_COLOR,strokeWidth:2}:false,activeDot:{r:4,fill:SURFACE_COLOR,strokeWidth:2},connectNulls:false,isAnimationActive:false},s.key))]})})}function AreaChart({data,x,series,height=DEFAULT_HEIGHT,label,formatValue,formatAxis,formatX,axis="time",grid=true,legend,empty,className}){const rtl=useRtl();const fmt=useFormatters(formatValue,formatAxis);const items=resolveSeries(series);const showLegend=legend??items.length>1;const gid=useId().replace(/:/g,"");return jsx2(ChartFrame,{label,height,isEmpty:data.length===0,empty,className,children:jsxs2(RAreaChart,{data,margin:chartMargin(rtl),accessibilityLayer:true,children:[jsx2("defs",{children:items.map(s=>jsxs2("linearGradient",{id:`${gid}-${s.key}`,x1:"0",y1:"0",x2:"0",y2:"1",children:[jsx2("stop",{offset:"0%",stopColor:s.color,stopOpacity:.28}),jsx2("stop",{offset:"100%",stopColor:s.color,stopOpacity:.02})]},s.key))}),grid&&chartGrid(),chartXAxis({dataKey:x,rtl,axis,formatX}),chartYAxis({rtl,format:fmt.axis}),chartTooltip({format:fmt.value,formatX}),showLegend&&chartLegend(),items.map(s=>jsx2(Area,{type:"monotone",dataKey:s.key,name:s.name,stackId:s.stackId,stroke:s.color,strokeWidth:2,fill:`url(#${gid}-${s.key})`,activeDot:{r:4,fill:SURFACE_COLOR,strokeWidth:2},connectNulls:false,isAnimationActive:false},s.key))]})})}function ComposedChart({data,x,series,height=DEFAULT_HEIGHT,label,formatValue,formatAxis,formatX,axis="category",grid=true,legend,empty,className}){const rtl=useRtl();const fmt=useFormatters(formatValue,formatAxis);const items=resolveSeries(series);const showLegend=legend??items.length>1;const gid=useId().replace(/:/g,"");const split=items.some(s=>s.scale==="secondary");const axisOf=s=>split?s.scale==="secondary"?"r":"l":void 0;return jsx2(ChartFrame,{label,height,isEmpty:data.length===0,empty,className,children:jsxs2(RComposedChart,{data,margin:chartMargin(rtl),accessibilityLayer:true,children:[jsx2("defs",{children:items.filter(s=>s.as==="area").map(s=>jsxs2("linearGradient",{id:`${gid}-${s.key}`,x1:"0",y1:"0",x2:"0",y2:"1",children:[jsx2("stop",{offset:"0%",stopColor:s.color,stopOpacity:.28}),jsx2("stop",{offset:"100%",stopColor:s.color,stopOpacity:.02})]},s.key))}),grid&&chartGrid(),chartXAxis({dataKey:x,rtl,axis,formatX}),chartYAxis({rtl,format:fmt.axis,id:split?"l":void 0}),split&&chartYAxis({rtl,format:fmt.axis,id:"r",side:"secondary"}),chartTooltip({format:fmt.value,formatX}),showLegend&&chartLegend(),items.map(s=>s.as==="line"?jsx2(Line,{type:"monotone",dataKey:s.key,name:s.name,yAxisId:axisOf(s),stroke:s.color,strokeWidth:2,dot:false,activeDot:{r:4,fill:SURFACE_COLOR,strokeWidth:2},isAnimationActive:false},s.key):s.as==="area"?jsx2(Area,{type:"monotone",dataKey:s.key,name:s.name,yAxisId:axisOf(s),stackId:s.stackId,stroke:s.color,strokeWidth:2,fill:`url(#${gid}-${s.key})`,isAnimationActive:false},s.key):jsx2(Bar,{dataKey:s.key,name:s.name,yAxisId:axisOf(s),fill:s.color,stackId:s.stackId,radius:[BAR_RADIUS,BAR_RADIUS,0,0],maxBarSize:48,isAnimationActive:false},s.key))]})})}function ScatterChart({groups,height=DEFAULT_HEIGHT,label,xLabel,yLabel,formatValue,formatAxis,grid=true,legend,empty,className}){const rtl=useRtl();const fmt=useFormatters(formatValue,formatAxis);const showLegend=legend??groups.length>1;const isEmpty=groups.every(g=>g.points.length===0);return jsx2(ChartFrame,{label,height,isEmpty,empty,className,children:jsxs2(RScatterChart,{margin:chartMargin(rtl),accessibilityLayer:true,children:[grid&&chartGrid(),jsx2(XAxis2,{type:"number",dataKey:"x",name:xLabel,tickFormatter:fmt.axis,tick:{fill:AXIS_COLOR,className:"text-caption"},tickLine:false,axisLine:{stroke:GRID_COLOR}}),jsx2(YAxis2,{type:"number",dataKey:"y",name:yLabel,tickFormatter:fmt.axis,tick:{fill:AXIS_COLOR,className:"text-caption",textAnchor:"end"},tickLine:false,axisLine:false,orientation:rtl?"right":"left",width:"auto"}),jsx2(ZAxis,{type:"number",dataKey:"z",range:[36,300]}),chartTooltip({format:fmt.value}),showLegend&&chartLegend(),groups.map((g,i)=>jsx2(Scatter,{name:g.label??g.key,data:g.points,fill:toneColor(g.tone??toneAt(i)),fillOpacity:.75,isAnimationActive:false},g.key))]})})}function Sparkline({values,label,labels,formatValue,tone="brand",height=36,filled,className}){const gid=useId().replace(/:/g,"");const fmt=useFormatters(formatValue);const color=toneColor(tone);const named=labels!==void 0&&labels.length>0;const data=values.map((v,i)=>({i,v,at:labels?.[i]??""}));if(values.length===0)return null;return jsx2("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx2(ResponsiveContainer2,{width:"100%",height,children:jsxs2(RAreaChart,{data,margin:{top:2,bottom:2,left:0,right:0},accessibilityLayer:true,children:[jsx2("defs",{children:jsxs2("linearGradient",{id:`${gid}-spark`,x1:"0",y1:"0",x2:"0",y2:"1",children:[jsx2("stop",{offset:"0%",stopColor:color,stopOpacity:.3}),jsx2("stop",{offset:"100%",stopColor:color,stopOpacity:0})]})}),named&&jsx2(XAxis2,{dataKey:"at",hide:true}),named&&jsx2(Tooltip2,{cursor:{stroke:color,strokeWidth:1},wrapperStyle:TOOLTIP_WRAPPER,content:jsx2(ChartTooltipLine,{format:fmt.value})}),jsx2(Area,{type:"monotone",dataKey:"v",name:label,stroke:color,strokeWidth:1.5,fill:filled?`url(#${gid}-spark)`:"none",dot:false,isAnimationActive:false})]})})})}import{Cell,Legend as Legend2,Pie,PieChart as RPieChart,PolarAngleAxis,PolarGrid,PolarRadiusAxis,Radar,RadarChart as RRadarChart,RadialBar,RadialBarChart as RRadialBarChart,ResponsiveContainer as ResponsiveContainer3,Tooltip as Tooltip3}from"recharts";import{jsx as jsx3,jsxs as jsxs3}from"react/jsx-runtime";var DEFAULT_HEIGHT2=220;function slices(items){return items.map((s,i)=>({name:s.label??s.key,value:s.value,color:toneColor(s.tone??toneAt(i)),key:s.key}))}function PieChart({items,height=DEFAULT_HEIGHT2,label,formatValue,legend=true,empty,className}){return jsx3(Ring,{items,height,label,formatValue,legend,empty,className,inner:0})}function DonutChart({items,height=DEFAULT_HEIGHT2,label,formatValue,legend=true,centerValue,centerLabel,empty,className}){return jsx3(Ring,{items,height,label,formatValue,legend,empty,className,inner:62,centerValue,centerLabel})}function Ring({items,height,label,formatValue,legend,empty,className,inner,centerValue,centerLabel}){const locale=useMoneyLocale();const fmt=useFormatters(formatValue);const data=slices(items);const isEmpty=data.length===0||data.every(d=>!d.value);const total=data.reduce((sum,d)=>sum+(d.value||0),0);if(isEmpty){return jsx3("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx3(ChartEmpty,{height:height??DEFAULT_HEIGHT2,children:empty})})}return jsxs3("div",{className:cn("relative w-full",className),role:"img","aria-label":label,children:[jsx3(ResponsiveContainer3,{width:"100%",height:height??DEFAULT_HEIGHT2,children:jsxs3(RPieChart,{children:[jsx3(Tooltip3,{wrapperStyle:TOOLTIP_WRAPPER,content:jsx3(ChartTooltipContent,{format:fmt.value})}),legend&&jsx3(Legend2,{content:jsx3(ChartLegendContent,{}),verticalAlign:"bottom"}),jsx3(Pie,{data,dataKey:"value",nameKey:"name",innerRadius:inner?`${inner}%`:0,outerRadius:"88%",stroke:SURFACE_COLOR,strokeWidth:2,isAnimationActive:false,startAngle:90,endAngle:-270,children:data.map(d=>jsx3(Cell,{fill:d.color},d.key))})]})}),inner>0&&jsxs3("div",{className:"pointer-events-none absolute inset-0 flex flex-col items-center justify-center",children:[jsx3("span",{className:"text-h3 text-ink font-extrabold","data-num":true,children:centerValue??new Intl.NumberFormat(locale).format(total)}),centerLabel&&jsx3("span",{className:"text-caption text-muted",children:centerLabel})]})]})}function RadarChart({data,x,series,height=DEFAULT_HEIGHT2,label,formatValue,legend,empty,className}){const fmt=useFormatters(formatValue);const items=resolveSeries(series);const showLegend=legend??items.length>1;if(data.length===0){return jsx3("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx3(ChartEmpty,{height,children:empty})})}return jsx3("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx3(ResponsiveContainer3,{width:"100%",height,children:jsxs3(RRadarChart,{data,outerRadius:"72%",children:[jsx3(PolarGrid,{stroke:GRID_COLOR}),jsx3(PolarAngleAxis,{dataKey:x,tick:{fill:AXIS_COLOR,className:"text-caption"}}),jsx3(PolarRadiusAxis,{tick:false,axisLine:false}),jsx3(Tooltip3,{wrapperStyle:TOOLTIP_WRAPPER,content:jsx3(ChartTooltipContent,{format:fmt.value})}),showLegend&&jsx3(Legend2,{content:jsx3(ChartLegendContent,{}),verticalAlign:"bottom"}),items.map(s=>jsx3(Radar,{dataKey:s.key,name:s.name,stroke:s.color,strokeWidth:2,fill:s.color,fillOpacity:.18,isAnimationActive:false},s.key))]})})})}function RadialChart({items,max,height=DEFAULT_HEIGHT2,label,formatValue,legend=true,empty,className}){const fmt=useFormatters(formatValue);const data=slices(items);const isEmpty=data.length===0;if(isEmpty){return jsx3("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx3(ChartEmpty,{height,children:empty})})}const ceiling=max??Math.max(...data.map(d=>d.value||0));return jsx3("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx3(ResponsiveContainer3,{width:"100%",height,children:jsxs3(RRadialBarChart,{data,innerRadius:"30%",outerRadius:"95%",startAngle:90,endAngle:-270,barSize:12,children:[jsx3(PolarAngleAxis,{type:"number",domain:[0,ceiling],tick:false}),jsx3(Tooltip3,{wrapperStyle:TOOLTIP_WRAPPER,content:jsx3(ChartTooltipContent,{format:fmt.value})}),legend&&jsx3(Legend2,{content:jsx3(ChartLegendContent,{}),verticalAlign:"bottom"}),jsx3(RadialBar,{dataKey:"value",background:{fill:GRID_COLOR},cornerRadius:"50%",isAnimationActive:false,children:data.map(d=>jsx3(Cell,{fill:d.color},d.key))})]})})})}import{useMemo}from"react";import{Funnel,FunnelChart as RFunnelChart,LabelList,useChartWidth,useMargin,ResponsiveContainer as ResponsiveContainer4,Sankey,Tooltip as Tooltip4,Treemap}from"recharts";import{jsx as jsx4,jsxs as jsxs4}from"react/jsx-runtime";var DEFAULT_HEIGHT3=240;function FunnelChart({steps,height=DEFAULT_HEIGHT3,label,formatValue,showRate=true,empty,className}){const rtl=useRtl();const locale=useMoneyLocale();const fmt=useFormatters(formatValue);const isEmpty=steps.length===0||steps.every(s=>!s.value);if(isEmpty){return jsx4("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx4(ChartEmpty,{height,children:empty})})}const first=steps[0]?.value||0;const data=steps.map(s=>({name:s.label??s.key,value:s.value,fill:toneColor(s.tone??"brand"),rate:first?s.value/first:0}));return jsx4("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx4(ResponsiveContainer4,{width:"100%",height,children:jsxs4(RFunnelChart,{margin:rtl?{left:56,right:104}:{left:104,right:56},children:[jsx4(Tooltip4,{wrapperStyle:TOOLTIP_WRAPPER,content:jsx4(ChartTooltipContent,{format:fmt.value})}),jsx4(Funnel,{dataKey:"value",data,stroke:SURFACE_COLOR,strokeWidth:2,isAnimationActive:false,children:jsx4(LabelList,{dataKey:"name",content:jsx4(FunnelBandLabel,{rtl,rows:data,showRate,formatRate:v=>new Intl.NumberFormat(locale,{style:"percent",maximumFractionDigits:1}).format(v)})})})]})})})}function TreemapChart({nodes,height=DEFAULT_HEIGHT3,label,formatValue,empty,className}){const fmt=useFormatters(formatValue);const isEmpty=nodes.length===0;if(isEmpty){return jsx4("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx4(ChartEmpty,{height,children:empty})})}const data=nodes.map((n,i)=>({...n,fill:toneColor(n.tone??toneAt(i))}));return jsx4("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx4(ResponsiveContainer4,{width:"100%",height,children:jsx4(Treemap,{data,dataKey:"value",stroke:SURFACE_COLOR,isAnimationActive:false,content:jsx4(TreemapCell,{}),children:jsx4(Tooltip4,{wrapperStyle:TOOLTIP_WRAPPER,content:jsx4(ChartTooltipContent,{format:fmt.value})})})})})}function TreemapCell(props){const{x=0,y=0,width=0,height=0,name,fill}=props;const roomy=width>64&&height>24;return jsxs4("g",{children:[jsx4("rect",{x,y,width,height,fill,stroke:SURFACE_COLOR,strokeWidth:2}),roomy&&name&&jsx4("text",{x:x+width/2,y:y+height/2,textAnchor:"middle",dominantBaseline:"middle",fill:SURFACE_COLOR,className:"text-caption",children:name})]})}function SankeyChart({nodes,links,height=DEFAULT_HEIGHT3,label,formatValue,empty,className}){const rtl=useRtl();const fmt=useFormatters(formatValue);const isEmpty=nodes.length===0||links.length===0;const ends=useMemo(()=>{const withIncoming=new Set(links.map(l=>l.target));const withOutgoing=new Set(links.map(l=>l.source));return{first:new Set(nodes.map((_,i)=>i).filter(i=>!withIncoming.has(i))),last:new Set(nodes.map((_,i)=>i).filter(i=>!withOutgoing.has(i)))}},[nodes,links]);if(isEmpty){return jsx4("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx4(ChartEmpty,{height,children:empty})})}return jsx4("div",{className:cn("w-full",className),role:"img","aria-label":label,children:jsx4(ResponsiveContainer4,{width:"100%",height,children:jsx4(Sankey,{data:{nodes,links},nodePadding:24,node:jsx4(SankeyNodeShape,{rtl,ends}),link:{stroke:toneColor("brand"),strokeOpacity:.16},margin:{top:24,bottom:8,left:72,right:72},children:jsx4(Tooltip4,{wrapperStyle:TOOLTIP_WRAPPER,content:jsx4(ChartTooltipContent,{format:fmt.value})})})})})}function SankeyNodeShape(props){const{x=0,y=0,width=0,height=0,index=0,rtl=false,ends,payload}=props;const isFirst=ends?.first.has(index)??false;const isLast=ends?.last.has(index)??false;const at=isFirst&&!isLast?{x:x-8,y:y+height/2,anchor:rtl?"start":"end"}:isLast?{x:x+width+8,y:y+height/2,anchor:rtl?"end":"start"}:{x:x+width/2,y:y-8,anchor:"middle"};return jsxs4("g",{children:[jsx4("rect",{x,y,width,height,fill:toneColor("brand"),rx:BAR_RADIUS}),jsx4("text",{x:at.x,y:at.y,textAnchor:at.anchor,dominantBaseline:at.anchor==="middle"?"auto":"middle",fill:AXIS_COLOR,className:"text-caption",children:payload?.name})]})}function FunnelBandLabel(props){const{y=0,height=0,index=0,rtl=false,showRate,rows,formatRate,value}=props;const chartWidth=useChartWidth()??0;const margin=useMargin()??{left:0,right:0};const left=margin.left??0;const right=margin.right??0;const rate=rows?.[index]?.rate;const mid=y+height/2;const pad=8;const nameX=rtl?chartWidth-right+pad:left-pad;const rateX=rtl?left-pad:chartWidth-right+pad;return jsxs4("g",{children:[jsx4("text",{x:nameX,y:mid,textAnchor:"end",dominantBaseline:"middle",fill:AXIS_COLOR,className:"text-caption",children:value}),showRate&&rate!==void 0&&jsx4("text",{x:rateX,y:mid,textAnchor:"start",dominantBaseline:"middle",fill:AXIS_COLOR,className:"text-caption",children:formatRate?.(rate)})]})}export{AreaChart,BarChart,ChartEmpty,ChartFrame,ComposedChart,DonutChart,FunnelChart,LineChart,PieChart,RadarChart,RadialChart,SERIES_ORDER,SankeyChart,ScatterChart,Sparkline,TreemapChart,toneAt,toneColor,useRtl};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{TONE_SOFT,cn,useUIText}from"./chunk-
|
|
2
|
+
import{TONE_SOFT,cn,useUIText}from"./chunk-YJ45RGS6.js";import{useEffect,useId}from"react";import{AlertTriangle,CheckCircle2,Info,X,XCircle}from"lucide-react";import{jsx,jsxs}from"react/jsx-runtime";function Sheet({open,title,onClose,action,children,closeLabel}){const ui=useUIText();useEffect(()=>{if(!open)return;function onKey(e){if(e.key==="Escape")onClose()}document.addEventListener("keydown",onKey);return()=>document.removeEventListener("keydown",onKey)},[open,onClose]);if(!open)return null;return jsxs("div",{className:"fixed inset-0 z-50 flex flex-col justify-end",role:"dialog","aria-modal":"true","aria-label":title,children:[jsx("button",{type:"button","aria-label":closeLabel??ui.close,onClick:onClose,className:"flex-1 bg-black/50 backdrop-blur-[3px] cursor-default animate-[fade-in_0.2s_ease-out]"}),jsxs("div",{className:cn("bg-surface rounded-t-section max-h-[82dvh] flex flex-col overflow-clip shadow-sheet","animate-[sheet-up_0.26s_cubic-bezier(.22,.61,.36,1)]","pb-[env(safe-area-inset-bottom)]"),children:[jsx("button",{type:"button",onClick:onClose,"aria-label":closeLabel??ui.close,className:"shrink-0 pt-3 pb-1.5 flex justify-center cursor-grab active:cursor-grabbing",children:jsx("span",{"aria-hidden":"true",className:"h-1.5 w-11 rounded-full bg-border"})}),jsxs("div",{className:"shrink-0 flex items-center justify-between gap-3 px-5 pb-3",children:[jsx("span",{className:"text-h4 font-black tracking-tight",children:title}),jsxs("span",{className:"flex items-center gap-3",children:[action,jsx("button",{type:"button",onClick:onClose,"aria-label":closeLabel??ui.close,className:"size-9 rounded-full bg-bg flex items-center justify-center text-muted active:bg-hover active:scale-95 transition-transform cursor-pointer",children:jsx(X,{size:17,strokeWidth:2.4,"aria-hidden":"true"})})]})]}),jsx("div",{className:"flex-1 min-h-0 overflow-y-auto px-3 pb-4 flex flex-col overscroll-contain",children})]})]})}function Modal({open,title,description,onClose,footer,children,size="md",closeLabel}){const ui=useUIText();const titleId=useId();useEffect(()=>{if(!open)return;function onKey(e){if(e.key==="Escape")onClose()}document.addEventListener("keydown",onKey);return()=>document.removeEventListener("keydown",onKey)},[open,onClose]);if(!open)return null;const widths={sm:"max-w-md",md:"max-w-xl",lg:"max-w-3xl"};return jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center p-4",role:"dialog","aria-modal":"true","aria-labelledby":titleId,children:[jsx("button",{type:"button","aria-label":closeLabel??ui.close,onClick:onClose,className:"absolute inset-0 bg-black/45 backdrop-blur-[2px] cursor-default"}),jsxs("div",{className:cn("relative w-full bg-surface rounded-lg border border-line flex flex-col max-h-[85dvh] animate-qfade shadow-modal",widths[size]),children:[jsxs("header",{className:"shrink-0 flex items-start justify-between gap-4 p-5 border-b border-line",children:[jsxs("div",{className:"flex flex-col gap-1 min-w-0",children:[jsx("h2",{id:titleId,className:"text-h4 font-extrabold text-ink m-0",children:title}),description&&jsx("p",{className:"text-ui text-muted m-0",children:description})]}),jsx("button",{type:"button",onClick:onClose,"aria-label":closeLabel??ui.close,className:"shrink-0 size-8 rounded-sm flex items-center justify-center text-muted hover:bg-hover hover:text-ink transition-colors cursor-pointer",children:jsx(X,{size:17,"aria-hidden":"true"})})]}),children&&jsx("div",{className:"flex-1 min-h-0 overflow-y-auto p-5",children}),footer&&jsx("footer",{className:"shrink-0 flex items-center justify-end gap-2.5 p-5 border-t border-line",children:footer})]})]})}function Drawer({open,title,description,onClose,footer,children,bodyClassName,closeLabel}){const ui=useUIText();const titleId=useId();useEffect(()=>{if(!open)return;function onKey(e){if(e.key==="Escape")onClose()}document.addEventListener("keydown",onKey);return()=>document.removeEventListener("keydown",onKey)},[open,onClose]);if(!open)return null;return jsxs("div",{className:"fixed inset-0 z-50 flex",role:"dialog","aria-modal":"true","aria-labelledby":titleId,children:[jsx("button",{type:"button","aria-label":closeLabel??ui.close,onClick:onClose,className:"flex-1 bg-black/45 backdrop-blur-[2px] cursor-default"}),jsxs("aside",{className:"w-full sm:w-[420px] bg-surface border-s border-line flex flex-col animate-qfade",children:[jsxs("header",{className:"shrink-0 h-16 px-4 border-b border-line flex items-center justify-between gap-3",children:[jsxs("span",{className:"flex flex-col gap-0.5 min-w-0",children:[jsx("span",{id:titleId,className:"text-lead font-extrabold truncate",children:title}),description&&jsx("span",{className:"text-caption text-muted truncate",children:description})]}),jsx("button",{type:"button",onClick:onClose,"aria-label":closeLabel??ui.close,className:"shrink-0 size-8 rounded-sm flex items-center justify-center text-muted hover:bg-hover hover:text-ink transition-colors cursor-pointer",children:jsx(X,{size:17,"aria-hidden":"true"})})]}),children&&jsx("div",{className:cn("flex-1 min-h-0 overflow-y-auto",bodyClassName??"p-4"),children}),footer&&jsx("footer",{className:"shrink-0 p-4 border-t border-line flex gap-2.5",children:footer})]})]})}var ALERT_ICON={neutral:Info,brand:Info,amber:AlertTriangle,green:CheckCircle2,red:XCircle,violet:Info};var ALERT_BORDER={neutral:"border-line",brand:"border-soft2",amber:"border-amber-line",green:"border-green-line",red:"border-red-line",violet:"border-violet-line"};function Alert({tone="brand",title,children,actions}){const Icon=ALERT_ICON[tone];const urgent=tone==="red"||tone==="amber";return jsxs("div",{role:urgent?"alert":"status",className:cn("flex items-start gap-3 p-4 rounded-card border",TONE_SOFT[tone],ALERT_BORDER[tone]),children:[jsx(Icon,{size:18,strokeWidth:2,"aria-hidden":"true"}),jsxs("div",{className:"flex flex-col gap-1.5 flex-1 min-w-0",children:[title&&jsx("span",{className:"text-body font-extrabold",children:title}),children&&jsx("span",{className:"text-ui leading-[1.7] opacity-90 [text-wrap:pretty]",children}),actions&&jsx("span",{className:"flex items-center gap-2 mt-1",children:actions})]})]})}function Toast({children,action,icon}){return jsxs("div",{role:"status","aria-live":"polite",className:"flex items-center gap-3 px-4 py-3.5 rounded-card bg-brand-900 shadow-toast animate-[fade-in_0.18s_ease-out]",children:[icon??jsx(CheckCircle2,{size:17,className:"text-brand-100 shrink-0","aria-hidden":"true"}),jsx("span",{className:"text-body font-bold text-white flex-1",children}),action]})}function EmptyState({icon:Icon,title,description,action}){return jsxs("div",{className:"flex flex-col items-center justify-center gap-2.5 py-12 px-5 text-center",children:[Icon&&jsx("span",{"aria-hidden":"true",className:"size-12 rounded-card bg-hover flex items-center justify-center text-muted mb-1",children:jsx(Icon,{size:21})}),jsx("span",{className:"text-lead font-extrabold text-ink",children:title}),description&&jsx("span",{className:"text-ui leading-[1.75] text-muted max-w-note [text-wrap:pretty]",children:description}),action&&jsx("span",{className:"mt-1",children:action})]})}export{Sheet,Modal,Drawer,Alert,Toast,EmptyState};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import{buttonClasses,cn,toLatinDigits,useUIText}from"./chunk-N6V3LTIS.js";import{forwardRef}from"react";import{Loader2}from"lucide-react";import{jsx,jsxs}from"react/jsx-runtime";var ICON_ONLY={sm:"w-9 px-0!",md:"w-10 px-0!",lg:"w-12 px-0!",xl:"w-14 px-0!"};var SPINNER={sm:14,md:15,lg:17,xl:20};var Button=forwardRef(function Button2({variant="primary",size="md",icon,iconEnd,iconOnly,loading,block,disabled,className,children,type="button",...rest},ref){return jsxs("button",{ref,type,disabled:disabled||loading,"aria-busy":loading||void 0,className:buttonClasses(variant,size,cn("disabled:opacity-50 disabled:cursor-not-allowed",iconOnly&&ICON_ONLY[size],block&&"w-full",className)),...rest,children:[loading?jsx(Loader2,{size:SPINNER[size],className:"animate-spin shrink-0","aria-hidden":"true"}):icon&&jsx("span",{className:"flex shrink-0",children:icon}),!iconOnly&&children,!loading&&iconEnd&&jsx("span",{className:"flex shrink-0",children:iconEnd})]})});import{useMemo,useState}from"react";import{ChevronLeft,ChevronRight}from"lucide-react";import{Fragment,jsx as jsx2,jsxs as jsxs2}from"react/jsx-runtime";var MONTHS_AR=["\u064A\u0646\u0627\u064A\u0631","\u0641\u0628\u0631\u0627\u064A\u0631","\u0645\u0627\u0631\u0633","\u0623\u0628\u0631\u064A\u0644","\u0645\u0627\u064A\u0648","\u064A\u0648\u0646\u064A\u0648","\u064A\u0648\u0644\u064A\u0648","\u0623\u063A\u0633\u0637\u0633","\u0633\u0628\u062A\u0645\u0628\u0631","\u0623\u0643\u062A\u0648\u0628\u0631","\u0646\u0648\u0641\u0645\u0628\u0631","\u062F\u064A\u0633\u0645\u0628\u0631"];var WEEKDAYS_AR=["\u0633","\u062D","\u0646","\u062B","\u0631","\u062E","\u062C"];var weekIndex=d=>(d.getDay()+1)%7;var sameDay=(a,b)=>a.getFullYear()===b.getFullYear()&&a.getMonth()===b.getMonth()&&a.getDate()===b.getDate();var startOfDay=d=>new Date(d.getFullYear(),d.getMonth(),d.getDate());function monthCells(month){const first=new Date(month.getFullYear(),month.getMonth(),1);const total=new Date(month.getFullYear(),month.getMonth()+1,0).getDate();return[...Array.from({length:weekIndex(first)},()=>null),...Array.from({length:total},(_,i)=>new Date(month.getFullYear(),month.getMonth(),i+1))]}function daysBetween(from,to){return Math.round((startOfDay(to).getTime()-startOfDay(from).getTime())/864e5)+1}function formatDate(d){return`${d.getDate()} ${MONTHS_AR[d.getMonth()]}`}function formatRange(r){if(!r.from)return"\u0627\u062E\u062A\u0631 \u064A\u0648\u0645 \u0627\u0644\u0628\u062F\u0627\u064A\u0629";if(!r.to)return`${formatDate(r.from)} \u2014 \u0627\u062E\u062A\u0631 \u064A\u0648\u0645 \u0627\u0644\u0646\u0647\u0627\u064A\u0629`;if(sameDay(r.from,r.to))return formatDate(r.from);return`${formatDate(r.from)} \u2014 ${formatDate(r.to)}`}function presets(today){const mk=backDays=>{const to=startOfDay(today);const from=new Date(to);from.setDate(from.getDate()-backDays+1);return{from,to}};return[{key:"today",label:"\u0627\u0644\u0646\u0647\u0627\u0631\u062F\u0647",range:mk(1)},{key:"d7",label:"\u0622\u062E\u0631 \u0667 \u0623\u064A\u0627\u0645",range:mk(7)},{key:"d30",label:"\u0622\u062E\u0631 \u0663\u0660 \u064A\u0648\u0645",range:mk(30)},{key:"month",label:"\u0627\u0644\u0634\u0647\u0631 \u062F\u0647",range:{from:new Date(today.getFullYear(),today.getMonth(),1),to:startOfDay(today)}}]}function DateRangePicker({value,onChange,month,onMonthChange,today,className}){const[hover,setHover]=useState(null);const cells=useMemo(()=>monthCells(month),[month]);const provisionalTo=value.from&&!value.to?hover:value.to;function inRange(d){if(!value.from||!provisionalTo)return false;const[a,b]=value.from<=provisionalTo?[value.from,provisionalTo]:[provisionalTo,value.from];return d>=startOfDay(a)&&d<=startOfDay(b)}function pick(d){if(!value.from||value.to)return onChange({from:d,to:null});if(d<value.from)return onChange({from:d,to:value.from});onChange({from:value.from,to:d})}const shift=by=>onMonthChange(new Date(month.getFullYear(),month.getMonth()+by,1));return jsxs2("div",{className:cn("flex flex-col gap-3",className),children:[jsx2(MonthNav,{month,onShift:shift}),jsxs2("div",{className:"grid grid-cols-7 gap-0.5",role:"grid",children:[jsx2(Weekdays,{}),cells.map((d,i)=>{if(!d)return jsx2("span",{},`p${i}`);const isFrom=value.from&&sameDay(d,value.from);const isTo=provisionalTo&&sameDay(d,provisionalTo);const edge=isFrom||isTo;const mid=inRange(d)&&!edge;const isToday=sameDay(d,today);return jsxs2("button",{type:"button",onClick:()=>pick(d),onMouseEnter:()=>setHover(d),"aria-pressed":Boolean(edge||mid),className:cn("h-9 flex items-center justify-center text-ui font-bold cursor-pointer transition-colors relative",mid&&"bg-soft text-brand-ink rounded-none",edge&&"bg-brand text-white rounded-sm z-10",!edge&&!mid&&"text-ink2 rounded-sm hover:bg-hover",isToday&&!edge&&"text-brand-ink"),children:[jsx2("span",{"data-num":true,children:d.getDate()}),isToday&&!edge&&jsx2("span",{"aria-hidden":"true",className:"absolute bottom-1 size-1 rounded-full bg-brand"})]},d.toISOString())})]})]})}function MonthNav({month,onShift}){const ui=useUIText();return jsxs2("div",{className:"flex items-center justify-between gap-3",children:[jsx2("button",{type:"button",onClick:()=>onShift(-1),"aria-label":ui.previousMonth,className:"size-8 rounded-sm flex items-center justify-center text-muted cursor-pointer transition-colors hover:bg-hover hover:text-ink",children:jsx2(ChevronRight,{size:16,"aria-hidden":"true"})}),jsxs2("span",{className:"text-body font-extrabold text-ink",children:[MONTHS_AR[month.getMonth()]," ",jsx2("span",{"data-num":true,children:month.getFullYear()})]}),jsx2("button",{type:"button",onClick:()=>onShift(1),"aria-label":ui.nextMonth,className:"size-8 rounded-sm flex items-center justify-center text-muted cursor-pointer transition-colors hover:bg-hover hover:text-ink",children:jsx2(ChevronLeft,{size:16,"aria-hidden":"true"})})]})}function Weekdays(){return jsx2(Fragment,{children:WEEKDAYS_AR.map((w,i)=>jsx2("span",{className:"h-7 flex items-center justify-center text-micro font-bold text-muted2",children:w},i))})}function Calendar({value,onChange,month,onMonthChange,today,min,max,className}){const cells=useMemo(()=>monthCells(month),[month]);const shift=by=>onMonthChange(new Date(month.getFullYear(),month.getMonth()+by,1));function blocked(d){if(min&&startOfDay(d)<startOfDay(min))return true;if(max&&startOfDay(d)>startOfDay(max))return true;return false}return jsxs2("div",{className:cn("flex flex-col gap-3",className),children:[jsx2(MonthNav,{month,onShift:shift}),jsxs2("div",{className:"grid grid-cols-7 gap-0.5",role:"grid",children:[jsx2(Weekdays,{}),cells.map((d,i)=>{if(!d)return jsx2("span",{},`p${i}`);const picked=Boolean(value&&sameDay(d,value));const isToday=sameDay(d,today);const off=blocked(d);return jsxs2("button",{type:"button",onClick:()=>!off&&onChange(d),"aria-pressed":picked,"aria-disabled":off||void 0,className:cn("h-9 flex items-center justify-center text-ui font-bold rounded-sm transition-colors relative",off?"text-muted2 opacity-45 cursor-not-allowed":picked?"bg-brand text-white cursor-pointer":cn("text-ink2 cursor-pointer hover:bg-hover",isToday&&"text-brand-ink")),children:[jsx2("span",{"data-num":true,children:d.getDate()}),isToday&&!picked&&jsx2("span",{"aria-hidden":"true",className:"absolute bottom-1 size-1 rounded-full bg-brand"})]},d.toISOString())})]})]})}import{forwardRef as forwardRef2,useCallback,useEffect,useId,useRef,useState as useState2}from"react";import{createPortal}from"react-dom";import{AlertCircle,CalendarDays,Check,ChevronDown,Minus,Search,X}from"lucide-react";import{jsx as jsx3,jsxs as jsxs3}from"react/jsx-runtime";function FieldShell({id,label,labelAside,labelSize,hint,error,required,hideLabel,className,children}){const labelEl=label&&jsxs3("label",{id:`${id}-label`,htmlFor:id,className:cn(labelSize??"text-ui","font-bold text-ink2",hideLabel&&"sr-only"),children:[label,required&&jsx3("span",{className:"text-danger ms-1","aria-hidden":"true",children:"*"})]});return jsxs3("div",{className:cn("flex flex-col gap-1.5",className),children:[labelAside?jsxs3("div",{className:"flex items-center justify-between gap-3 flex-wrap",children:[labelEl,labelAside]}):labelEl,children,error?jsxs3("span",{id:`${id}-error`,role:"alert",className:"flex items-center gap-1.5 text-caption text-red",children:[jsx3(AlertCircle,{size:12,className:"shrink-0","aria-hidden":"true"}),error]}):hint?jsx3("span",{id:`${id}-hint`,className:"text-caption text-muted",children:hint}):null]})}var SIZES={sm:"h-9 text-ui",md:"h-11 text-body",lg:"h-14 text-base border-[1.5px]!"};var base=invalid=>cn("w-full bg-surface text-ink rounded-field border transition-colors outline-none","placeholder:text-muted2","focus:border-brand","disabled:bg-bg disabled:text-muted disabled:cursor-not-allowed",invalid?"border-danger":"border-border hover:border-brand");var Input=forwardRef2(function Input2({label,labelAside,hint,error,size="md",hideLabel,icon,suffix,action,numeric,required,className,wrapperClassName,id:idProp,onChange,type,inputMode,...rest},ref){const auto=useId();const id=idProp??auto;const invalid=Boolean(error);const lg=size==="lg";return jsx3(FieldShell,{id,label,labelAside,labelSize:lg?"text-body":void 0,hint,error,required,hideLabel,className:wrapperClassName,children:jsxs3("div",{className:"relative flex items-center",children:[icon&&jsx3("span",{className:cn("absolute flex text-muted pointer-events-none",lg?"start-4.5":"start-3.5"),"aria-hidden":"true",children:icon}),jsx3("input",{ref,id,required,type:numeric?"text":type,inputMode:numeric?inputMode??"decimal":inputMode,"aria-invalid":invalid||void 0,"aria-describedby":error?`${id}-error`:hint?`${id}-hint`:void 0,"data-num":numeric||void 0,"data-suffix":numeric&&suffix?"":void 0,"data-icon":numeric&&icon?"":void 0,onChange:numeric?e=>{const fixed=toLatinDigits(e.target.value);if(fixed!==e.target.value)e.target.value=fixed;onChange?.(e)}:onChange,className:cn(base(invalid),SIZES[size],lg?"px-4.5":"px-3.5",icon&&(lg?"ps-12":"ps-10"),suffix&&"pe-14",action&&(lg?"pe-14":"pe-11"),className),...rest}),suffix&&jsx3("span",{className:cn("absolute text-ui text-muted pointer-events-none",lg?"end-4.5":"end-3.5"),children:suffix}),action&&jsx3("span",{className:cn("absolute flex",lg?"end-4":"end-3"),children:action})]})})});var SearchInput=forwardRef2(function SearchInput2(props,ref){return jsx3(Input,{ref,icon:jsx3(Search,{size:16}),hideLabel:true,...props})});var Textarea=forwardRef2(function Textarea2({label,hint,error,required,hideLabel,rows=3,className,wrapperClassName,id:idProp,...rest},ref){const auto=useId();const id=idProp??auto;return jsx3(FieldShell,{id,label,hint,error,required,hideLabel,className:wrapperClassName,children:jsx3("textarea",{ref,id,rows,required,"aria-invalid":Boolean(error)||void 0,className:cn(base(Boolean(error)),"text-body px-3.5 py-3 resize-y min-h-20",className),...rest})})});var Select=forwardRef2(function Select2({label,hint,error,size="md",hideLabel,options,required,className,wrapperClassName,id:idProp,...rest},ref){const auto=useId();const id=idProp??auto;return jsx3(FieldShell,{id,label,hint,error,required,hideLabel,className:wrapperClassName,children:jsxs3("div",{className:"relative flex items-center",children:[jsx3("select",{ref,id,required,className:cn(base(Boolean(error)),SIZES[size],"appearance-none ps-3.5 pe-9 cursor-pointer font-medium",className),...rest,children:options.map(o=>jsx3("option",{value:o.value,children:o.label},o.value))}),jsx3(ChevronDown,{size:15,"aria-hidden":"true",className:"absolute end-3.5 text-muted2 pointer-events-none"})]})})});var CONTROL="peer appearance-none size-[19px] shrink-0 bg-surface border-[1.5px] border-border cursor-pointer transition-colors checked:bg-brand checked:border-brand hover:border-brand focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand disabled:bg-bg disabled:cursor-not-allowed";var Checkbox=forwardRef2(function Checkbox2({label,description,indeterminate,className,id:idProp,...rest},ref){const auto=useId();const id=idProp??auto;return jsxs3("span",{className:"flex items-start gap-2.5",children:[jsxs3("span",{className:"relative inline-flex items-center justify-center mt-px",children:[jsx3("input",{ref:el=>{if(el)el.indeterminate=Boolean(indeterminate);if(typeof ref==="function")ref(el);else if(ref)ref.current=el},id,type:"checkbox",className:cn(CONTROL,"rounded-xs",indeterminate&&"bg-brand border-brand",className),...rest}),indeterminate?jsx3(Minus,{size:12,strokeWidth:3,"aria-hidden":"true",className:"absolute text-white pointer-events-none"}):jsx3(Check,{size:12,strokeWidth:3,"aria-hidden":"true",className:"absolute text-white opacity-0 peer-checked:opacity-100 pointer-events-none transition-opacity"})]}),(label||description)&&jsxs3("label",{htmlFor:id,className:"flex flex-col gap-0.5 cursor-pointer select-none",children:[label&&jsx3("span",{className:"text-body text-ink",children:label}),description&&jsx3("span",{className:"text-caption text-muted",children:description})]})]})});var Radio=forwardRef2(function Radio2({label,description,className,id:idProp,...rest},ref){const auto=useId();const id=idProp??auto;return jsxs3("span",{className:"flex items-start gap-2.5",children:[jsxs3("span",{className:"relative inline-flex items-center justify-center mt-px",children:[jsx3("input",{ref,id,type:"radio",className:cn(CONTROL,"rounded-full",className),...rest}),jsx3("span",{"aria-hidden":"true",className:"absolute size-1.5 rounded-full bg-white opacity-0 peer-checked:opacity-100 pointer-events-none transition-opacity"})]}),(label||description)&&jsxs3("label",{htmlFor:id,className:"flex flex-col gap-0.5 cursor-pointer select-none",children:[label&&jsx3("span",{className:"text-body text-ink",children:label}),description&&jsx3("span",{className:"text-caption text-muted",children:description})]})]})});function RadioGroup({label,children,inline}){return jsxs3("fieldset",{className:"flex flex-col gap-2.5 border-0 p-0 m-0",children:[jsx3("legend",{className:"text-ui font-bold text-ink2 p-0 mb-1",children:label}),jsx3("div",{className:cn("flex gap-3",inline?"flex-row flex-wrap gap-5":"flex-col"),children})]})}function Switch({checked,onCheckedChange,label,description,disabled,id:idProp}){const auto=useId();const id=idProp??auto;const control=jsx3("button",{id,type:"button",role:"switch","aria-checked":checked,"aria-labelledby":label?`${id}-label`:void 0,disabled,onClick:()=>onCheckedChange(!checked),className:cn("relative shrink-0 w-11 h-6 rounded-full cursor-pointer transition-colors duration-200","focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand","disabled:opacity-50 disabled:cursor-not-allowed",checked?"bg-brand":"bg-border"),children:jsx3("span",{"aria-hidden":"true",className:cn("absolute top-1/2 -translate-y-1/2 size-5 rounded-full bg-white shadow-sm transition-all duration-200",checked?"start-[calc(100%-1.375rem)]":"start-0.5")})});if(!label)return control;return jsxs3("span",{className:"flex items-start gap-3",children:[control,jsxs3("span",{className:"flex flex-col gap-0.5",children:[jsx3("span",{id:`${id}-label`,className:"text-body text-ink",children:label}),description&&jsx3("span",{className:"text-caption text-muted",children:description})]})]})}var pad2=n=>String(n).padStart(2,"0");function toValue(d,time){const day=`${d.getFullYear()}-${pad2(d.getMonth()+1)}-${pad2(d.getDate())}`;return time?`${day}T${time}`:day}function fromValue(v){const m=/^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2}))?/.exec(v.trim());if(!m)return{day:null,time:""};const day=new Date(Number(m[1]),Number(m[2])-1,Number(m[3]));return{day:Number.isNaN(day.getTime())?null:day,time:m[4]?`${m[4]}:${m[5]}`:""}}var EDGE=8;var GAP=6;function DateField({value,onChange,withTime=false,min,max,label,hint,error,required,hideLabel,placeholder,disabled,size="md",id:idProp,className}){const ui=useUIText();const auto=useId();const id=idProp??auto;const invalid=Boolean(error);const lg=size==="lg";const{day,time}=fromValue(value);const[open,setOpen]=useState2(false);const[month,setMonth]=useState2(()=>startOfMonth(day??new Date));const anchor=useRef(null);const panel=useRef(null);const[wasOpen,setWasOpen]=useState2(open);if(wasOpen!==open){setWasOpen(open);if(open)setMonth(startOfMonth(day??new Date))}const place=useCallback(()=>{const el=panel.current;const host=anchor.current;if(!el||!host)return;const r=host.getBoundingClientRect();const w=el.offsetWidth;const h=el.offsetHeight;const vw=document.documentElement.clientWidth;const vh=document.documentElement.clientHeight;const left=Math.min(Math.max(r.left,EDGE),Math.max(EDGE,vw-EDGE-w));const below=r.bottom+GAP+h<=vh-EDGE;const top=below?r.bottom+GAP:Math.max(EDGE,r.top-GAP-h);el.style.left=`${left}px`;el.style.top=`${top}px`;el.style.visibility="visible"},[]);useEffect(()=>{if(!open)return;window.addEventListener("scroll",place,{capture:true,passive:true});window.addEventListener("resize",place,{passive:true});return()=>{window.removeEventListener("scroll",place,{capture:true});window.removeEventListener("resize",place)}},[open,place]);useEffect(()=>{if(!open)return;function onDown(e){const t=e.target;if(panel.current?.contains(t)||anchor.current?.contains(t))return;setOpen(false)}function onKey(e){if(e.key==="Escape")setOpen(false)}document.addEventListener("mousedown",onDown);document.addEventListener("keydown",onKey);return()=>{document.removeEventListener("mousedown",onDown);document.removeEventListener("keydown",onKey)}},[open]);const mount=useCallback(el=>{panel.current=el;if(el)place()},[place]);function pickDay(d){onChange(toValue(d,withTime?time||"00:00":null));if(!withTime)setOpen(false)}function pickTime(next){onChange(toValue(day??new Date,next||"00:00"))}function pickNow(){const d=new Date;onChange(toValue(d,withTime?`${pad2(d.getHours())}:${pad2(d.getMinutes())}`:null));if(!withTime)setOpen(false)}return jsx3(FieldShell,{id,label,labelSize:lg?"text-body":void 0,hint,error,required,hideLabel,className,children:jsxs3("div",{ref:anchor,className:"relative flex items-center",children:[jsxs3("button",{type:"button",id,disabled,onClick:()=>setOpen(o=>!o),"aria-haspopup":"dialog","aria-expanded":open,"aria-labelledby":label?`${id}-label ${id}-value`:`${id}-value`,"aria-describedby":error?`${id}-error`:hint?`${id}-hint`:void 0,className:cn(base(invalid),SIZES[size],lg?"px-4.5":"px-3.5","flex items-center gap-2 text-start cursor-pointer","disabled:cursor-not-allowed"),children:[jsx3(CalendarDays,{size:lg?18:16,className:"shrink-0 text-muted","aria-hidden":"true"}),jsx3("span",{id:`${id}-value`,className:cn("flex-1 min-w-0 truncate",!day&&"text-muted2"),children:day?jsx3("span",{"data-num":true,children:withTime&&time?`${labelOf(day)} \xB7 ${time}`:labelOf(day)}):placeholder??ui.pickDate}),day&&!disabled&&jsx3("span",{role:"button",tabIndex:0,"aria-label":ui.clear,onClick:e=>{e.stopPropagation();onChange("")},onKeyDown:e=>{if(e.key!=="Enter"&&e.key!==" ")return;e.preventDefault();e.stopPropagation();onChange("")},className:"shrink-0 size-5 rounded-xs flex items-center justify-center text-muted transition-colors hover:bg-hover hover:text-ink",children:jsx3(X,{size:13,"aria-hidden":"true"})})]}),open&&typeof document!=="undefined"&&createPortal(jsxs3("div",{ref:mount,role:"dialog","aria-label":typeof label==="string"?label:ui.pickDate,style:{visibility:"hidden",left:0,top:0},className:cn("fixed z-[60] w-[19rem] p-3 rounded-card","bg-surface border border-line shadow-modal animate-[fade-in_.12s_ease-out]"),children:[jsx3(Calendar,{value:day,onChange:pickDay,month,onMonthChange:setMonth,today:new Date,min:min?fromValue(min).day:null,max:max?fromValue(max).day:null}),withTime&&jsxs3("label",{className:"mt-3 pt-3 border-t border-line flex items-center justify-between gap-3",children:[jsx3("span",{className:"text-caption font-bold text-ink2",children:ui.time}),jsx3("input",{type:"time",value:time,onChange:e=>pickTime(e.target.value),className:cn(base(false),"h-9 w-32 px-2.5 text-ui")})]}),jsxs3("div",{className:"mt-3 flex items-center justify-between gap-2",children:[jsx3("button",{type:"button",onClick:pickNow,className:"px-2.5 h-8 rounded-sm text-caption font-bold text-brand-ink cursor-pointer transition-colors hover:bg-hover",children:withTime?ui.now:ui.today}),jsx3("button",{type:"button",onClick:()=>setOpen(false),className:"px-2.5 h-8 rounded-sm text-caption font-bold text-muted cursor-pointer transition-colors hover:bg-hover hover:text-ink",children:ui.close})]})]}),document.body)]})})}var startOfMonth=d=>new Date(d.getFullYear(),d.getMonth(),1);function labelOf(d){return`${d.getDate()} ${MONTHS_AR[d.getMonth()]} ${d.getFullYear()}`}export{Button,daysBetween,formatDate,formatRange,presets,DateRangePicker,Calendar,Input,SearchInput,Textarea,Select,Checkbox,Radio,RadioGroup,Switch,DateField};
|
|
2
|
+
import{buttonClasses,cn,toLatinDigits,useUIText}from"./chunk-YJ45RGS6.js";import{forwardRef}from"react";import{Loader2}from"lucide-react";import{jsx,jsxs}from"react/jsx-runtime";var ICON_ONLY={sm:"w-9 px-0!",md:"w-10 px-0!",lg:"w-12 px-0!",xl:"w-14 px-0!"};var SPINNER={sm:14,md:15,lg:17,xl:20};var Button=forwardRef(function Button2({variant="primary",size="md",icon,iconEnd,iconOnly,loading,block,disabled,className,children,type="button",...rest},ref){return jsxs("button",{ref,type,disabled:disabled||loading,"aria-busy":loading||void 0,className:buttonClasses(variant,size,cn("disabled:opacity-50 disabled:cursor-not-allowed",iconOnly&&ICON_ONLY[size],block&&"w-full",className)),...rest,children:[loading?jsx(Loader2,{size:SPINNER[size],className:"animate-spin shrink-0","aria-hidden":"true"}):icon&&jsx("span",{className:"flex shrink-0",children:icon}),!iconOnly&&children,!loading&&iconEnd&&jsx("span",{className:"flex shrink-0",children:iconEnd})]})});import{useMemo,useState}from"react";import{ChevronLeft,ChevronRight}from"lucide-react";import{Fragment,jsx as jsx2,jsxs as jsxs2}from"react/jsx-runtime";var MONTHS_AR=["\u064A\u0646\u0627\u064A\u0631","\u0641\u0628\u0631\u0627\u064A\u0631","\u0645\u0627\u0631\u0633","\u0623\u0628\u0631\u064A\u0644","\u0645\u0627\u064A\u0648","\u064A\u0648\u0646\u064A\u0648","\u064A\u0648\u0644\u064A\u0648","\u0623\u063A\u0633\u0637\u0633","\u0633\u0628\u062A\u0645\u0628\u0631","\u0623\u0643\u062A\u0648\u0628\u0631","\u0646\u0648\u0641\u0645\u0628\u0631","\u062F\u064A\u0633\u0645\u0628\u0631"];var WEEKDAYS_AR=["\u0633","\u062D","\u0646","\u062B","\u0631","\u062E","\u062C"];var weekIndex=d=>(d.getDay()+1)%7;var sameDay=(a,b)=>a.getFullYear()===b.getFullYear()&&a.getMonth()===b.getMonth()&&a.getDate()===b.getDate();var startOfDay=d=>new Date(d.getFullYear(),d.getMonth(),d.getDate());function monthCells(month){const first=new Date(month.getFullYear(),month.getMonth(),1);const total=new Date(month.getFullYear(),month.getMonth()+1,0).getDate();return[...Array.from({length:weekIndex(first)},()=>null),...Array.from({length:total},(_,i)=>new Date(month.getFullYear(),month.getMonth(),i+1))]}function daysBetween(from,to){return Math.round((startOfDay(to).getTime()-startOfDay(from).getTime())/864e5)+1}function formatDate(d){return`${d.getDate()} ${MONTHS_AR[d.getMonth()]}`}function formatRange(r){if(!r.from)return"\u0627\u062E\u062A\u0631 \u064A\u0648\u0645 \u0627\u0644\u0628\u062F\u0627\u064A\u0629";if(!r.to)return`${formatDate(r.from)} \u2014 \u0627\u062E\u062A\u0631 \u064A\u0648\u0645 \u0627\u0644\u0646\u0647\u0627\u064A\u0629`;if(sameDay(r.from,r.to))return formatDate(r.from);return`${formatDate(r.from)} \u2014 ${formatDate(r.to)}`}function presets(today){const mk=backDays=>{const to=startOfDay(today);const from=new Date(to);from.setDate(from.getDate()-backDays+1);return{from,to}};return[{key:"today",label:"\u0627\u0644\u0646\u0647\u0627\u0631\u062F\u0647",range:mk(1)},{key:"d7",label:"\u0622\u062E\u0631 \u0667 \u0623\u064A\u0627\u0645",range:mk(7)},{key:"d30",label:"\u0622\u062E\u0631 \u0663\u0660 \u064A\u0648\u0645",range:mk(30)},{key:"month",label:"\u0627\u0644\u0634\u0647\u0631 \u062F\u0647",range:{from:new Date(today.getFullYear(),today.getMonth(),1),to:startOfDay(today)}}]}function DateRangePicker({value,onChange,month,onMonthChange,today,className}){const[hover,setHover]=useState(null);const cells=useMemo(()=>monthCells(month),[month]);const provisionalTo=value.from&&!value.to?hover:value.to;function inRange(d){if(!value.from||!provisionalTo)return false;const[a,b]=value.from<=provisionalTo?[value.from,provisionalTo]:[provisionalTo,value.from];return d>=startOfDay(a)&&d<=startOfDay(b)}function pick(d){if(!value.from||value.to)return onChange({from:d,to:null});if(d<value.from)return onChange({from:d,to:value.from});onChange({from:value.from,to:d})}const shift=by=>onMonthChange(new Date(month.getFullYear(),month.getMonth()+by,1));return jsxs2("div",{className:cn("flex flex-col gap-3",className),children:[jsx2(MonthNav,{month,onShift:shift}),jsxs2("div",{className:"grid grid-cols-7 gap-0.5",role:"grid",children:[jsx2(Weekdays,{}),cells.map((d,i)=>{if(!d)return jsx2("span",{},`p${i}`);const isFrom=value.from&&sameDay(d,value.from);const isTo=provisionalTo&&sameDay(d,provisionalTo);const edge=isFrom||isTo;const mid=inRange(d)&&!edge;const isToday=sameDay(d,today);return jsxs2("button",{type:"button",onClick:()=>pick(d),onMouseEnter:()=>setHover(d),"aria-pressed":Boolean(edge||mid),className:cn("h-9 flex items-center justify-center text-ui font-bold cursor-pointer transition-colors relative",mid&&"bg-soft text-brand-ink rounded-none",edge&&"bg-brand text-white rounded-sm z-10",!edge&&!mid&&"text-ink2 rounded-sm hover:bg-hover",isToday&&!edge&&"text-brand-ink"),children:[jsx2("span",{"data-num":true,children:d.getDate()}),isToday&&!edge&&jsx2("span",{"aria-hidden":"true",className:"absolute bottom-1 size-1 rounded-full bg-brand"})]},d.toISOString())})]})]})}function MonthNav({month,onShift}){const ui=useUIText();return jsxs2("div",{className:"flex items-center justify-between gap-3",children:[jsx2("button",{type:"button",onClick:()=>onShift(-1),"aria-label":ui.previousMonth,className:"size-8 rounded-sm flex items-center justify-center text-muted cursor-pointer transition-colors hover:bg-hover hover:text-ink",children:jsx2(ChevronRight,{size:16,"aria-hidden":"true"})}),jsxs2("span",{className:"text-body font-extrabold text-ink",children:[MONTHS_AR[month.getMonth()]," ",jsx2("span",{"data-num":true,children:month.getFullYear()})]}),jsx2("button",{type:"button",onClick:()=>onShift(1),"aria-label":ui.nextMonth,className:"size-8 rounded-sm flex items-center justify-center text-muted cursor-pointer transition-colors hover:bg-hover hover:text-ink",children:jsx2(ChevronLeft,{size:16,"aria-hidden":"true"})})]})}function Weekdays(){return jsx2(Fragment,{children:WEEKDAYS_AR.map((w,i)=>jsx2("span",{className:"h-7 flex items-center justify-center text-micro font-bold text-muted2",children:w},i))})}function Calendar({value,onChange,month,onMonthChange,today,min,max,className}){const cells=useMemo(()=>monthCells(month),[month]);const shift=by=>onMonthChange(new Date(month.getFullYear(),month.getMonth()+by,1));function blocked(d){if(min&&startOfDay(d)<startOfDay(min))return true;if(max&&startOfDay(d)>startOfDay(max))return true;return false}return jsxs2("div",{className:cn("flex flex-col gap-3",className),children:[jsx2(MonthNav,{month,onShift:shift}),jsxs2("div",{className:"grid grid-cols-7 gap-0.5",role:"grid",children:[jsx2(Weekdays,{}),cells.map((d,i)=>{if(!d)return jsx2("span",{},`p${i}`);const picked=Boolean(value&&sameDay(d,value));const isToday=sameDay(d,today);const off=blocked(d);return jsxs2("button",{type:"button",onClick:()=>!off&&onChange(d),"aria-pressed":picked,"aria-disabled":off||void 0,className:cn("h-9 flex items-center justify-center text-ui font-bold rounded-sm transition-colors relative",off?"text-muted2 opacity-45 cursor-not-allowed":picked?"bg-brand text-white cursor-pointer":cn("text-ink2 cursor-pointer hover:bg-hover",isToday&&"text-brand-ink")),children:[jsx2("span",{"data-num":true,children:d.getDate()}),isToday&&!picked&&jsx2("span",{"aria-hidden":"true",className:"absolute bottom-1 size-1 rounded-full bg-brand"})]},d.toISOString())})]})]})}import{forwardRef as forwardRef2,useCallback,useEffect,useId,useRef,useState as useState2}from"react";import{createPortal}from"react-dom";import{AlertCircle,CalendarDays,Check,ChevronDown,Minus,Search,X}from"lucide-react";import{jsx as jsx3,jsxs as jsxs3}from"react/jsx-runtime";function FieldShell({id,label,labelAside,labelSize,hint,error,required,hideLabel,className,children}){const labelEl=label&&jsxs3("label",{id:`${id}-label`,htmlFor:id,className:cn(labelSize??"text-ui","font-bold text-ink2",hideLabel&&"sr-only"),children:[label,required&&jsx3("span",{className:"text-danger ms-1","aria-hidden":"true",children:"*"})]});return jsxs3("div",{className:cn("flex flex-col gap-1.5",className),children:[labelAside?jsxs3("div",{className:"flex items-center justify-between gap-3 flex-wrap",children:[labelEl,labelAside]}):labelEl,children,error?jsxs3("span",{id:`${id}-error`,role:"alert",className:"flex items-center gap-1.5 text-caption text-red",children:[jsx3(AlertCircle,{size:12,className:"shrink-0","aria-hidden":"true"}),error]}):hint?jsx3("span",{id:`${id}-hint`,className:"text-caption text-muted",children:hint}):null]})}var SIZES={sm:"h-9 text-ui",md:"h-11 text-body",lg:"h-14 text-base border-[1.5px]!"};var base=invalid=>cn("w-full bg-surface text-ink rounded-field border transition-colors outline-none","placeholder:text-muted2","focus:border-brand","disabled:bg-bg disabled:text-muted disabled:cursor-not-allowed",invalid?"border-danger":"border-border hover:border-brand");var Input=forwardRef2(function Input2({label,labelAside,hint,error,size="md",hideLabel,icon,suffix,action,numeric,required,className,wrapperClassName,id:idProp,onChange,type,inputMode,...rest},ref){const auto=useId();const id=idProp??auto;const invalid=Boolean(error);const lg=size==="lg";return jsx3(FieldShell,{id,label,labelAside,labelSize:lg?"text-body":void 0,hint,error,required,hideLabel,className:wrapperClassName,children:jsxs3("div",{className:"relative flex items-center",children:[icon&&jsx3("span",{className:cn("absolute flex text-muted pointer-events-none",lg?"start-4.5":"start-3.5"),"aria-hidden":"true",children:icon}),jsx3("input",{ref,id,required,type:numeric?"text":type,inputMode:numeric?inputMode??"decimal":inputMode,"aria-invalid":invalid||void 0,"aria-describedby":error?`${id}-error`:hint?`${id}-hint`:void 0,"data-num":numeric||void 0,"data-suffix":numeric&&suffix?"":void 0,"data-icon":numeric&&icon?"":void 0,onChange:numeric?e=>{const fixed=toLatinDigits(e.target.value);if(fixed!==e.target.value)e.target.value=fixed;onChange?.(e)}:onChange,className:cn(base(invalid),SIZES[size],lg?"px-4.5":"px-3.5",icon&&(lg?"ps-12":"ps-10"),suffix&&"pe-14",action&&(lg?"pe-14":"pe-11"),className),...rest}),suffix&&jsx3("span",{className:cn("absolute text-ui text-muted pointer-events-none",lg?"end-4.5":"end-3.5"),children:suffix}),action&&jsx3("span",{className:cn("absolute flex",lg?"end-4":"end-3"),children:action})]})})});var SearchInput=forwardRef2(function SearchInput2(props,ref){return jsx3(Input,{ref,icon:jsx3(Search,{size:16}),hideLabel:true,...props})});var Textarea=forwardRef2(function Textarea2({label,hint,error,required,hideLabel,rows=3,className,wrapperClassName,id:idProp,...rest},ref){const auto=useId();const id=idProp??auto;return jsx3(FieldShell,{id,label,hint,error,required,hideLabel,className:wrapperClassName,children:jsx3("textarea",{ref,id,rows,required,"aria-invalid":Boolean(error)||void 0,className:cn(base(Boolean(error)),"text-body px-3.5 py-3 resize-y min-h-20",className),...rest})})});var Select=forwardRef2(function Select2({label,hint,error,size="md",hideLabel,options,required,className,wrapperClassName,id:idProp,...rest},ref){const auto=useId();const id=idProp??auto;return jsx3(FieldShell,{id,label,hint,error,required,hideLabel,className:wrapperClassName,children:jsxs3("div",{className:"relative flex items-center",children:[jsx3("select",{ref,id,required,className:cn(base(Boolean(error)),SIZES[size],"appearance-none ps-3.5 pe-9 cursor-pointer font-medium",className),...rest,children:options.map(o=>jsx3("option",{value:o.value,children:o.label},o.value))}),jsx3(ChevronDown,{size:15,"aria-hidden":"true",className:"absolute end-3.5 text-muted2 pointer-events-none"})]})})});var CONTROL="peer appearance-none size-[19px] shrink-0 bg-surface border-[1.5px] border-border cursor-pointer transition-colors checked:bg-brand checked:border-brand hover:border-brand focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand disabled:bg-bg disabled:cursor-not-allowed";var Checkbox=forwardRef2(function Checkbox2({label,description,indeterminate,className,id:idProp,...rest},ref){const auto=useId();const id=idProp??auto;return jsxs3("span",{className:"flex items-start gap-2.5",children:[jsxs3("span",{className:"relative inline-flex items-center justify-center mt-px",children:[jsx3("input",{ref:el=>{if(el)el.indeterminate=Boolean(indeterminate);if(typeof ref==="function")ref(el);else if(ref)ref.current=el},id,type:"checkbox",className:cn(CONTROL,"rounded-xs",indeterminate&&"bg-brand border-brand",className),...rest}),indeterminate?jsx3(Minus,{size:12,strokeWidth:3,"aria-hidden":"true",className:"absolute text-white pointer-events-none"}):jsx3(Check,{size:12,strokeWidth:3,"aria-hidden":"true",className:"absolute text-white opacity-0 peer-checked:opacity-100 pointer-events-none transition-opacity"})]}),(label||description)&&jsxs3("label",{htmlFor:id,className:"flex flex-col gap-0.5 cursor-pointer select-none",children:[label&&jsx3("span",{className:"text-body text-ink",children:label}),description&&jsx3("span",{className:"text-caption text-muted",children:description})]})]})});var Radio=forwardRef2(function Radio2({label,description,className,id:idProp,...rest},ref){const auto=useId();const id=idProp??auto;return jsxs3("span",{className:"flex items-start gap-2.5",children:[jsxs3("span",{className:"relative inline-flex items-center justify-center mt-px",children:[jsx3("input",{ref,id,type:"radio",className:cn(CONTROL,"rounded-full",className),...rest}),jsx3("span",{"aria-hidden":"true",className:"absolute size-1.5 rounded-full bg-white opacity-0 peer-checked:opacity-100 pointer-events-none transition-opacity"})]}),(label||description)&&jsxs3("label",{htmlFor:id,className:"flex flex-col gap-0.5 cursor-pointer select-none",children:[label&&jsx3("span",{className:"text-body text-ink",children:label}),description&&jsx3("span",{className:"text-caption text-muted",children:description})]})]})});function RadioGroup({label,children,inline}){return jsxs3("fieldset",{className:"flex flex-col gap-2.5 border-0 p-0 m-0",children:[jsx3("legend",{className:"text-ui font-bold text-ink2 p-0 mb-1",children:label}),jsx3("div",{className:cn("flex gap-3",inline?"flex-row flex-wrap gap-5":"flex-col"),children})]})}function Switch({checked,onCheckedChange,label,description,disabled,id:idProp}){const auto=useId();const id=idProp??auto;const control=jsx3("button",{id,type:"button",role:"switch","aria-checked":checked,"aria-labelledby":label?`${id}-label`:void 0,disabled,onClick:()=>onCheckedChange(!checked),className:cn("relative shrink-0 w-11 h-6 rounded-full cursor-pointer transition-colors duration-200","focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand","disabled:opacity-50 disabled:cursor-not-allowed",checked?"bg-brand":"bg-border"),children:jsx3("span",{"aria-hidden":"true",className:cn("absolute top-1/2 -translate-y-1/2 size-5 rounded-full bg-white shadow-sm transition-all duration-200",checked?"start-[calc(100%-1.375rem)]":"start-0.5")})});if(!label)return control;return jsxs3("span",{className:"flex items-start gap-3",children:[control,jsxs3("span",{className:"flex flex-col gap-0.5",children:[jsx3("span",{id:`${id}-label`,className:"text-body text-ink",children:label}),description&&jsx3("span",{className:"text-caption text-muted",children:description})]})]})}var pad2=n=>String(n).padStart(2,"0");function toValue(d,time){const day=`${d.getFullYear()}-${pad2(d.getMonth()+1)}-${pad2(d.getDate())}`;return time?`${day}T${time}`:day}function fromValue(v){const m=/^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2}))?/.exec(v.trim());if(!m)return{day:null,time:""};const day=new Date(Number(m[1]),Number(m[2])-1,Number(m[3]));return{day:Number.isNaN(day.getTime())?null:day,time:m[4]?`${m[4]}:${m[5]}`:""}}var EDGE=8;var GAP=6;function DateField({value,onChange,withTime=false,min,max,label,hint,error,required,hideLabel,placeholder,disabled,size="md",id:idProp,className}){const ui=useUIText();const auto=useId();const id=idProp??auto;const invalid=Boolean(error);const lg=size==="lg";const{day,time}=fromValue(value);const[open,setOpen]=useState2(false);const[month,setMonth]=useState2(()=>startOfMonth(day??new Date));const anchor=useRef(null);const panel=useRef(null);const[wasOpen,setWasOpen]=useState2(open);if(wasOpen!==open){setWasOpen(open);if(open)setMonth(startOfMonth(day??new Date))}const place=useCallback(()=>{const el=panel.current;const host=anchor.current;if(!el||!host)return;const r=host.getBoundingClientRect();const w=el.offsetWidth;const h=el.offsetHeight;const vw=document.documentElement.clientWidth;const vh=document.documentElement.clientHeight;const left=Math.min(Math.max(r.left,EDGE),Math.max(EDGE,vw-EDGE-w));const below=r.bottom+GAP+h<=vh-EDGE;const top=below?r.bottom+GAP:Math.max(EDGE,r.top-GAP-h);el.style.left=`${left}px`;el.style.top=`${top}px`;el.style.visibility="visible"},[]);useEffect(()=>{if(!open)return;window.addEventListener("scroll",place,{capture:true,passive:true});window.addEventListener("resize",place,{passive:true});return()=>{window.removeEventListener("scroll",place,{capture:true});window.removeEventListener("resize",place)}},[open,place]);useEffect(()=>{if(!open)return;function onDown(e){const t=e.target;if(panel.current?.contains(t)||anchor.current?.contains(t))return;setOpen(false)}function onKey(e){if(e.key==="Escape")setOpen(false)}document.addEventListener("mousedown",onDown);document.addEventListener("keydown",onKey);return()=>{document.removeEventListener("mousedown",onDown);document.removeEventListener("keydown",onKey)}},[open]);const mount=useCallback(el=>{panel.current=el;if(el)place()},[place]);function pickDay(d){onChange(toValue(d,withTime?time||"00:00":null));if(!withTime)setOpen(false)}function pickTime(next){onChange(toValue(day??new Date,next||"00:00"))}function pickNow(){const d=new Date;onChange(toValue(d,withTime?`${pad2(d.getHours())}:${pad2(d.getMinutes())}`:null));if(!withTime)setOpen(false)}return jsx3(FieldShell,{id,label,labelSize:lg?"text-body":void 0,hint,error,required,hideLabel,className,children:jsxs3("div",{ref:anchor,className:"relative flex items-center",children:[jsxs3("button",{type:"button",id,disabled,onClick:()=>setOpen(o=>!o),"aria-haspopup":"dialog","aria-expanded":open,"aria-labelledby":label?`${id}-label ${id}-value`:`${id}-value`,"aria-describedby":error?`${id}-error`:hint?`${id}-hint`:void 0,className:cn(base(invalid),SIZES[size],lg?"px-4.5":"px-3.5","flex items-center gap-2 text-start cursor-pointer","disabled:cursor-not-allowed"),children:[jsx3(CalendarDays,{size:lg?18:16,className:"shrink-0 text-muted","aria-hidden":"true"}),jsx3("span",{id:`${id}-value`,className:cn("flex-1 min-w-0 truncate",!day&&"text-muted2"),children:day?jsx3("span",{"data-num":true,children:withTime&&time?`${labelOf(day)} \xB7 ${time}`:labelOf(day)}):placeholder??ui.pickDate}),day&&!disabled&&jsx3("span",{role:"button",tabIndex:0,"aria-label":ui.clear,onClick:e=>{e.stopPropagation();onChange("")},onKeyDown:e=>{if(e.key!=="Enter"&&e.key!==" ")return;e.preventDefault();e.stopPropagation();onChange("")},className:"shrink-0 size-5 rounded-xs flex items-center justify-center text-muted transition-colors hover:bg-hover hover:text-ink",children:jsx3(X,{size:13,"aria-hidden":"true"})})]}),open&&typeof document!=="undefined"&&createPortal(jsxs3("div",{ref:mount,role:"dialog","aria-label":typeof label==="string"?label:ui.pickDate,style:{visibility:"hidden",left:0,top:0},className:cn("fixed z-[60] w-[19rem] p-3 rounded-card","bg-surface border border-line shadow-modal animate-[fade-in_.12s_ease-out]"),children:[jsx3(Calendar,{value:day,onChange:pickDay,month,onMonthChange:setMonth,today:new Date,min:min?fromValue(min).day:null,max:max?fromValue(max).day:null}),withTime&&jsxs3("label",{className:"mt-3 pt-3 border-t border-line flex items-center justify-between gap-3",children:[jsx3("span",{className:"text-caption font-bold text-ink2",children:ui.time}),jsx3("input",{type:"time",value:time,onChange:e=>pickTime(e.target.value),className:cn(base(false),"h-9 w-32 px-2.5 text-ui")})]}),jsxs3("div",{className:"mt-3 flex items-center justify-between gap-2",children:[jsx3("button",{type:"button",onClick:pickNow,className:"px-2.5 h-8 rounded-sm text-caption font-bold text-brand-ink cursor-pointer transition-colors hover:bg-hover",children:withTime?ui.now:ui.today}),jsx3("button",{type:"button",onClick:()=>setOpen(false),className:"px-2.5 h-8 rounded-sm text-caption font-bold text-muted cursor-pointer transition-colors hover:bg-hover hover:text-ink",children:ui.close})]})]}),document.body)]})})}var startOfMonth=d=>new Date(d.getFullYear(),d.getMonth(),1);function labelOf(d){return`${d.getDate()} ${MONTHS_AR[d.getMonth()]} ${d.getFullYear()}`}export{Button,daysBetween,formatDate,formatRange,presets,DateRangePicker,Calendar,Input,SearchInput,Textarea,Select,Checkbox,Radio,RadioGroup,Switch,DateField};
|