analytica-frontend-lib
Version:
Repositório público dos componentes utilizados nas plataformas da Analytica Ensino
1 lines • 4.78 kB
Source Map (JSON)
{"version":3,"sources":["../src/components/CalendarCard/CalendarCard.tsx"],"sourcesContent":["import { CalendarBlankIcon } from '@phosphor-icons/react/dist/csr/CalendarBlank';\nimport type { ReactNode } from 'react';\nimport { useCallback, useState } from 'react';\nimport DropdownMenu, {\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from '../DropdownMenu/DropdownMenu';\nimport IconButton from '../IconButton/IconButton';\nimport Modal from '../Modal/Modal';\nimport { useMobile } from '../../hooks/useMobile';\n\nexport interface CalendarCardProps {\n /** Content rendered inside the calendar (calendar grid + activities list). */\n content: ReactNode;\n /**\n * Whether the calendar surface is currently open.\n * When provided, the component is **controlled**: the consumer is the source of truth.\n * When omitted, the component manages internal state.\n */\n isOpen?: boolean;\n /**\n * Fired whenever the open state changes (user click, outside click,\n * programmatic close, ESC, etc.).\n */\n onOpenChange?: (open: boolean) => void;\n /** Title displayed in the mobile Modal. Default: \"Calendário\". */\n title?: string;\n /** Optional className applied to the trigger button. */\n className?: string;\n}\n\n/**\n * Calendar widget for the app header. Renders a calendar icon trigger that\n * opens a `DropdownMenu` on tablet/desktop and a `Modal` on mobile (<500px).\n *\n * Pairs naturally with `AppHeader`'s `calendarContent` prop. Use the\n * controlled `isOpen` + `onOpenChange` pair when the consumer needs to close\n * the surface programmatically (e.g. on route change).\n */\nexport const CalendarCard = ({\n content,\n isOpen,\n onOpenChange,\n title = 'Calendário',\n className,\n}: CalendarCardProps) => {\n const { isMobile } = useMobile();\n const [internalOpen, setInternalOpen] = useState(false);\n\n const isControlled = isOpen !== undefined;\n const effectiveOpen = isControlled ? isOpen : internalOpen;\n\n // `useCallback` keeps the reference stable across renders, so the\n // `DropdownMenu`'s `useEffect [open, onOpenChange]` doesn't re-fire on\n // every parent re-render (which is what triggers the infinite update loop\n // observed before).\n const handleOpenChange = useCallback(\n (open: boolean) => {\n if (!isControlled) {\n setInternalOpen(open);\n }\n onOpenChange?.(open);\n },\n [isControlled, onOpenChange]\n );\n\n const iconColor = effectiveOpen ? 'text-primary-950' : 'text-primary';\n const triggerIcon = <CalendarBlankIcon size={24} className={iconColor} />;\n\n if (isMobile) {\n return (\n <>\n <IconButton\n active={effectiveOpen}\n onClick={() => handleOpenChange(!effectiveOpen)}\n icon={triggerIcon}\n className={className}\n />\n <Modal\n isOpen={effectiveOpen}\n onClose={() => handleOpenChange(false)}\n title={title}\n >\n <div className=\"flex justify-center\">{content}</div>\n </Modal>\n </>\n );\n }\n\n return (\n <DropdownMenu open={effectiveOpen} onOpenChange={handleOpenChange}>\n <DropdownMenuTrigger\n className={`text-primary cursor-pointer ${className ?? ''}`}\n >\n <IconButton active={effectiveOpen} icon={triggerIcon} />\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className=\"w-[320px] max-w-[calc(100vw-16px)] max-h-[80vh] overflow-y-auto\"\n align=\"end\"\n side=\"bottom\"\n >\n {content}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n};\n\nexport default CalendarCard;\n"],"mappings":";;;;;;;;;;;;;;;;AAAA,SAAS,yBAAyB;AAElC,SAAS,aAAa,gBAAgB;AAiEhB,SAIhB,UAJgB,KAIhB,YAJgB;AA5Bf,IAAM,eAAe,CAAC;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AACF,MAAyB;AACvB,QAAM,EAAE,SAAS,IAAI,UAAU;AAC/B,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AAEtD,QAAM,eAAe,WAAW;AAChC,QAAM,gBAAgB,eAAe,SAAS;AAM9C,QAAM,mBAAmB;AAAA,IACvB,CAAC,SAAkB;AACjB,UAAI,CAAC,cAAc;AACjB,wBAAgB,IAAI;AAAA,MACtB;AACA,qBAAe,IAAI;AAAA,IACrB;AAAA,IACA,CAAC,cAAc,YAAY;AAAA,EAC7B;AAEA,QAAM,YAAY,gBAAgB,qBAAqB;AACvD,QAAM,cAAc,oBAAC,qBAAkB,MAAM,IAAI,WAAW,WAAW;AAEvE,MAAI,UAAU;AACZ,WACE,iCACE;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,QAAQ;AAAA,UACR,SAAS,MAAM,iBAAiB,CAAC,aAAa;AAAA,UAC9C,MAAM;AAAA,UACN;AAAA;AAAA,MACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,QAAQ;AAAA,UACR,SAAS,MAAM,iBAAiB,KAAK;AAAA,UACrC;AAAA,UAEA,8BAAC,SAAI,WAAU,uBAAuB,mBAAQ;AAAA;AAAA,MAChD;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,qBAAC,wBAAa,MAAM,eAAe,cAAc,kBAC/C;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,+BAA+B,aAAa,EAAE;AAAA,QAEzD,8BAAC,sBAAW,QAAQ,eAAe,MAAM,aAAa;AAAA;AAAA,IACxD;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAM;AAAA,QACN,MAAK;AAAA,QAEJ;AAAA;AAAA,IACH;AAAA,KACF;AAEJ;AAEA,IAAO,uBAAQ;","names":[]}