analytica-frontend-lib 1.6.76 → 1.6.78
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/AccessReportModal/index.js +4 -5
- package/dist/AccessReportModal/index.js.map +1 -1
- package/dist/AccessReportModal/index.mjs +3 -4
- package/dist/AccessibilityWidget/index.js +4 -5
- package/dist/AccessibilityWidget/index.js.map +1 -1
- package/dist/AccessibilityWidget/index.mjs +3 -4
- package/dist/Accordation/index.js +4 -4
- package/dist/Accordation/index.mjs +3 -3
- package/dist/ActivitiesHistory/index.js +48 -49
- package/dist/ActivitiesHistory/index.js.map +1 -1
- package/dist/ActivitiesHistory/index.mjs +47 -48
- package/dist/ActivityCardQuestionBanks/index.d.ts.map +1 -1
- package/dist/ActivityCardQuestionBanks/index.js +48 -49
- package/dist/ActivityCardQuestionBanks/index.js.map +1 -1
- package/dist/ActivityCardQuestionBanks/index.mjs +47 -48
- package/dist/ActivityCardQuestionPreview/index.js +48 -49
- package/dist/ActivityCardQuestionPreview/index.js.map +1 -1
- package/dist/ActivityCardQuestionPreview/index.mjs +47 -48
- package/dist/ActivityCreate/ActivityCreateContent/index.js +48 -49
- package/dist/ActivityCreate/ActivityCreateContent/index.js.map +1 -1
- package/dist/ActivityCreate/ActivityCreateContent/index.mjs +47 -48
- package/dist/ActivityCreate/index.js +48 -49
- package/dist/ActivityCreate/index.js.map +1 -1
- package/dist/ActivityCreate/index.mjs +47 -48
- package/dist/ActivityDetails/index.js +48 -49
- package/dist/ActivityDetails/index.js.map +1 -1
- package/dist/ActivityDetails/index.mjs +47 -48
- package/dist/ActivityFilters/index.js +48 -49
- package/dist/ActivityFilters/index.js.map +1 -1
- package/dist/ActivityFilters/index.mjs +47 -48
- package/dist/ActivityPageLayout/index.js +48 -49
- package/dist/ActivityPageLayout/index.js.map +1 -1
- package/dist/ActivityPageLayout/index.mjs +47 -48
- package/dist/ActivityPreview/index.js +48 -49
- package/dist/ActivityPreview/index.js.map +1 -1
- package/dist/ActivityPreview/index.mjs +47 -48
- package/dist/AlertDialog/index.d.ts.map +1 -1
- package/dist/AlertDialog/index.js +3 -3
- package/dist/AlertDialog/index.mjs +2 -2
- package/dist/AlertManager/index.js +48 -49
- package/dist/AlertManager/index.js.map +1 -1
- package/dist/AlertManager/index.mjs +47 -48
- package/dist/AlertManagerView/index.js +4 -5
- package/dist/AlertManagerView/index.js.map +1 -1
- package/dist/AlertManagerView/index.mjs +3 -4
- package/dist/AnnouncementModal/index.js +4 -5
- package/dist/AnnouncementModal/index.js.map +1 -1
- package/dist/AnnouncementModal/index.mjs +3 -4
- package/dist/AnnouncementsGate/index.js +5 -6
- package/dist/AnnouncementsGate/index.js.map +1 -1
- package/dist/AnnouncementsGate/index.mjs +4 -5
- package/dist/AnswerKeyModal/index.js +4 -5
- package/dist/AnswerKeyModal/index.js.map +1 -1
- package/dist/AnswerKeyModal/index.mjs +3 -4
- package/dist/AppHeader/index.js +8 -9
- package/dist/AppHeader/index.js.map +1 -1
- package/dist/AppHeader/index.mjs +7 -8
- package/dist/CalendarCard/index.js +6 -7
- package/dist/CalendarCard/index.js.map +1 -1
- package/dist/CalendarCard/index.mjs +5 -6
- package/dist/Card/index.d.ts.map +1 -1
- package/dist/Card/index.js +3 -3
- package/dist/Card/index.mjs +2 -2
- package/dist/Chat/index.js +4 -5
- package/dist/Chat/index.js.map +1 -1
- package/dist/Chat/index.mjs +3 -4
- package/dist/Chatbot/index.js +4 -5
- package/dist/Chatbot/index.js.map +1 -1
- package/dist/Chatbot/index.mjs +3 -4
- package/dist/CheckBoxGroup/index.js +48 -49
- package/dist/CheckBoxGroup/index.js.map +1 -1
- package/dist/CheckBoxGroup/index.mjs +47 -48
- package/dist/ComparatorChart/ComparatorView/index.js +4 -5
- package/dist/ComparatorChart/ComparatorView/index.js.map +1 -1
- package/dist/ComparatorChart/ComparatorView/index.mjs +3 -4
- package/dist/CorrectActivityModal/index.js +9 -10
- package/dist/CorrectActivityModal/index.js.map +1 -1
- package/dist/CorrectActivityModal/index.mjs +8 -9
- package/dist/DownloadButton/index.js +6 -7
- package/dist/DownloadButton/index.js.map +1 -1
- package/dist/DownloadButton/index.mjs +5 -6
- package/dist/DownloadModal/index.js +4 -5
- package/dist/DownloadModal/index.js.map +1 -1
- package/dist/DownloadModal/index.mjs +3 -4
- package/dist/DropdownMenu/index.js +4 -5
- package/dist/DropdownMenu/index.js.map +1 -1
- package/dist/DropdownMenu/index.mjs +3 -4
- package/dist/EnemClassroomStartModal/index.js +8 -9
- package/dist/EnemClassroomStartModal/index.js.map +1 -1
- package/dist/EnemClassroomStartModal/index.mjs +7 -8
- package/dist/EnemMoment/index.js +110 -94
- package/dist/EnemMoment/index.js.map +1 -1
- package/dist/EnemMoment/index.mjs +74 -58
- package/dist/EnemMoment/index.mjs.map +1 -1
- package/dist/EnemMomentStudentModal/index.js +62 -63
- package/dist/EnemMomentStudentModal/index.js.map +1 -1
- package/dist/EnemMomentStudentModal/index.mjs +48 -49
- package/dist/EnemMomentStudentModal/index.mjs.map +1 -1
- package/dist/EssayThemePicker/index.js +3 -3
- package/dist/EssayThemePicker/index.mjs +2 -2
- package/dist/ExamDetailsLayout/ExamDetailsPage/index.js +48 -49
- package/dist/ExamDetailsLayout/ExamDetailsPage/index.js.map +1 -1
- package/dist/ExamDetailsLayout/ExamDetailsPage/index.mjs +47 -48
- package/dist/ExamPageLayout/index.js +48 -49
- package/dist/ExamPageLayout/index.js.map +1 -1
- package/dist/ExamPageLayout/index.mjs +47 -48
- package/dist/Forum/index.js +6 -7
- package/dist/Forum/index.js.map +1 -1
- package/dist/Forum/index.mjs +5 -6
- package/dist/IconButton/index.js +2 -2
- package/dist/IconButton/index.mjs +1 -1
- package/dist/LessonCardPreview/index.js +48 -49
- package/dist/LessonCardPreview/index.js.map +1 -1
- package/dist/LessonCardPreview/index.mjs +47 -48
- package/dist/LessonMediaSections/index.js +48 -49
- package/dist/LessonMediaSections/index.js.map +1 -1
- package/dist/LessonMediaSections/index.mjs +47 -48
- package/dist/LessonsCatalog/index.js +48 -49
- package/dist/LessonsCatalog/index.js.map +1 -1
- package/dist/LessonsCatalog/index.mjs +47 -48
- package/dist/Modal/index.d.ts +11 -1
- package/dist/Modal/index.d.ts.map +1 -1
- package/dist/Modal/index.js +3 -4
- package/dist/Modal/index.js.map +1 -1
- package/dist/Modal/index.mjs +2 -3
- package/dist/MultiCheckSelect/index.js +5 -6
- package/dist/MultiCheckSelect/index.js.map +1 -1
- package/dist/MultiCheckSelect/index.mjs +4 -5
- package/dist/NotificationCard/index.js +6 -7
- package/dist/NotificationCard/index.js.map +1 -1
- package/dist/NotificationCard/index.mjs +5 -6
- package/dist/PerformanceReportModal/index.js +4 -5
- package/dist/PerformanceReportModal/index.js.map +1 -1
- package/dist/PerformanceReportModal/index.mjs +3 -4
- package/dist/PrintableUsersTable/index.js +48 -49
- package/dist/PrintableUsersTable/index.js.map +1 -1
- package/dist/PrintableUsersTable/index.mjs +47 -48
- package/dist/ProgressModal/index.js +4 -5
- package/dist/ProgressModal/index.js.map +1 -1
- package/dist/ProgressModal/index.mjs +3 -4
- package/dist/QuestionsPerformanceCard/index.js +49 -50
- package/dist/QuestionsPerformanceCard/index.js.map +1 -1
- package/dist/QuestionsPerformanceCard/index.mjs +48 -49
- package/dist/Quiz/QuizResult/index.js +4 -4
- package/dist/Quiz/QuizResult/index.mjs +3 -3
- package/dist/Quiz/index.d.ts.map +1 -1
- package/dist/Quiz/index.js +8 -9
- package/dist/Quiz/index.js.map +1 -1
- package/dist/Quiz/index.mjs +7 -8
- package/dist/QuizTimer/index.d.ts +12 -0
- package/dist/QuizTimer/index.d.ts.map +1 -1
- package/dist/QuizTimer/index.js +4 -2
- package/dist/QuizTimer/index.js.map +1 -1
- package/dist/QuizTimer/index.mjs +4 -2
- package/dist/RecommendedLessonCreate/index.js +48 -49
- package/dist/RecommendedLessonCreate/index.js.map +1 -1
- package/dist/RecommendedLessonCreate/index.mjs +47 -48
- package/dist/RecommendedLessonDetails/index.js +11 -12
- package/dist/RecommendedLessonDetails/index.js.map +1 -1
- package/dist/RecommendedLessonDetails/index.mjs +10 -11
- package/dist/RecommendedLessonsHistory/index.js +48 -49
- package/dist/RecommendedLessonsHistory/index.js.map +1 -1
- package/dist/RecommendedLessonsHistory/index.mjs +47 -48
- package/dist/ReportDetailModal/index.js +5 -6
- package/dist/ReportDetailModal/index.js.map +1 -1
- package/dist/ReportDetailModal/index.mjs +4 -5
- package/dist/RichEditor/index.js +6 -7
- package/dist/RichEditor/index.js.map +1 -1
- package/dist/RichEditor/index.mjs +5 -6
- package/dist/{RichEditorCore-62NIM7PC.js → RichEditorCore-6OT3VNJR.js} +15 -16
- package/dist/RichEditorCore-6OT3VNJR.js.map +1 -0
- package/dist/{RichEditorCore-CCO3SSSU.mjs → RichEditorCore-IF6JQHEO.mjs} +6 -7
- package/dist/{RichEditorCore-CCO3SSSU.mjs.map → RichEditorCore-IF6JQHEO.mjs.map} +1 -1
- package/dist/Search/index.js +5 -6
- package/dist/Search/index.js.map +1 -1
- package/dist/Search/index.mjs +4 -5
- package/dist/SendActivityModal/SendActivityModal.js +48 -49
- package/dist/SendActivityModal/SendActivityModal.js.map +1 -1
- package/dist/SendActivityModal/SendActivityModal.mjs +47 -48
- package/dist/SendActivityModal/index.js +48 -49
- package/dist/SendActivityModal/index.js.map +1 -1
- package/dist/SendActivityModal/index.mjs +47 -48
- package/dist/SendLessonModal/index.js +48 -49
- package/dist/SendLessonModal/index.js.map +1 -1
- package/dist/SendLessonModal/index.mjs +47 -48
- package/dist/SimulatedPerformance/SimulatedPerformanceView/index.js +48 -49
- package/dist/SimulatedPerformance/SimulatedPerformanceView/index.js.map +1 -1
- package/dist/SimulatedPerformance/SimulatedPerformanceView/index.mjs +47 -48
- package/dist/SimulatedPerformance/useSimulatedPerformance/index.js +6 -7
- package/dist/SimulatedPerformance/useSimulatedPerformance/index.js.map +1 -1
- package/dist/SimulatedPerformance/useSimulatedPerformance/index.mjs +5 -6
- package/dist/SimulatedStudentSimulationsModal/index.js +8 -9
- package/dist/SimulatedStudentSimulationsModal/index.js.map +1 -1
- package/dist/SimulatedStudentSimulationsModal/index.mjs +7 -8
- package/dist/SimulationSummaryCards/index.js +5 -5
- package/dist/SimulationSummaryCards/index.mjs +4 -4
- package/dist/SimulationsPage/index.js +48 -49
- package/dist/SimulationsPage/index.js.map +1 -1
- package/dist/SimulationsPage/index.mjs +47 -48
- package/dist/StudentLessonProgressModal/index.js +6 -7
- package/dist/StudentLessonProgressModal/index.js.map +1 -1
- package/dist/StudentLessonProgressModal/index.mjs +5 -6
- package/dist/StudentPerformanceDetailsModal/index.js +9 -10
- package/dist/StudentPerformanceDetailsModal/index.js.map +1 -1
- package/dist/StudentPerformanceDetailsModal/index.mjs +8 -9
- package/dist/Support/TicketModal/index.js +4 -5
- package/dist/Support/TicketModal/index.js.map +1 -1
- package/dist/Support/TicketModal/index.mjs +3 -4
- package/dist/Support/index.js +5 -6
- package/dist/Support/index.js.map +1 -1
- package/dist/Support/index.mjs +4 -5
- package/dist/TableProvider/index.js +48 -49
- package/dist/TableProvider/index.js.map +1 -1
- package/dist/TableProvider/index.mjs +47 -48
- package/dist/UnifiedDraftModelPage/index.js +48 -49
- package/dist/UnifiedDraftModelPage/index.js.map +1 -1
- package/dist/UnifiedDraftModelPage/index.mjs +47 -48
- package/dist/UnifiedHistoryPage/index.js +48 -49
- package/dist/UnifiedHistoryPage/index.js.map +1 -1
- package/dist/UnifiedHistoryPage/index.mjs +47 -48
- package/dist/VideoPlayer/index.js +7 -8
- package/dist/VideoPlayer/index.js.map +1 -1
- package/dist/VideoPlayer/index.mjs +6 -7
- package/dist/Whiteboard/index.js +4 -5
- package/dist/Whiteboard/index.js.map +1 -1
- package/dist/Whiteboard/index.mjs +3 -4
- package/dist/{chunk-EVBQNVQW.mjs → chunk-233FSBU7.mjs} +5 -5
- package/dist/{chunk-JU63EMZM.js → chunk-24DQFREC.js} +3 -3
- package/dist/{chunk-JU63EMZM.js.map → chunk-24DQFREC.js.map} +1 -1
- package/dist/{chunk-QFXSQKW3.mjs → chunk-254EBPMW.mjs} +22 -22
- package/dist/{chunk-QFXSQKW3.mjs.map → chunk-254EBPMW.mjs.map} +1 -1
- package/dist/{chunk-SFQVZ4KQ.js → chunk-2ETPIOCD.js} +3 -3
- package/dist/{chunk-SFQVZ4KQ.js.map → chunk-2ETPIOCD.js.map} +1 -1
- package/dist/{chunk-RCNIBRZY.js → chunk-2VTJ2PKF.js} +10 -10
- package/dist/{chunk-RCNIBRZY.js.map → chunk-2VTJ2PKF.js.map} +1 -1
- package/dist/{chunk-B35D5S4G.js → chunk-2ZMGNCMI.js} +6 -6
- package/dist/{chunk-B35D5S4G.js.map → chunk-2ZMGNCMI.js.map} +1 -1
- package/dist/{chunk-QEPKR6ZF.js → chunk-3KSRDIS2.js} +20 -20
- package/dist/{chunk-QEPKR6ZF.js.map → chunk-3KSRDIS2.js.map} +1 -1
- package/dist/{chunk-MUCV5ZWZ.mjs → chunk-3YF7H577.mjs} +15 -9
- package/dist/chunk-3YF7H577.mjs.map +1 -0
- package/dist/{chunk-MADPP2PW.mjs → chunk-3ZSI2KI5.mjs} +2 -2
- package/dist/{chunk-2W7PTFXS.mjs → chunk-42XKJV56.mjs} +2 -2
- package/dist/{chunk-M6TC6XRQ.mjs → chunk-55ESXRRM.mjs} +2 -2
- package/dist/{chunk-4MURAKPC.mjs → chunk-5DJVOLVX.mjs} +3 -3
- package/dist/{chunk-YVT7CT3G.mjs → chunk-5P6CBDZ6.mjs} +2 -2
- package/dist/{chunk-BHKTJCFD.js → chunk-5QUP5HKB.js} +3 -3
- package/dist/{chunk-BHKTJCFD.js.map → chunk-5QUP5HKB.js.map} +1 -1
- package/dist/{chunk-SFEU7BMY.mjs → chunk-5SFNRXZB.mjs} +2 -2
- package/dist/{chunk-6ALEXGAN.js → chunk-6U4AI5SE.js} +6 -6
- package/dist/{chunk-6ALEXGAN.js.map → chunk-6U4AI5SE.js.map} +1 -1
- package/dist/{chunk-KYY4U5SN.mjs → chunk-6Z5W5J44.mjs} +3 -3
- package/dist/{chunk-XOKBMLW3.js → chunk-7IGUYLSF.js} +3 -3
- package/dist/{chunk-XOKBMLW3.js.map → chunk-7IGUYLSF.js.map} +1 -1
- package/dist/{chunk-GVYGPJH3.mjs → chunk-AU5M2766.mjs} +2 -2
- package/dist/{chunk-2VODGC76.js → chunk-AVEMHDN2.js} +66 -44
- package/dist/chunk-AVEMHDN2.js.map +1 -0
- package/dist/{chunk-HIIOADV4.js → chunk-AZSRKBYS.js} +63 -71
- package/dist/chunk-AZSRKBYS.js.map +1 -0
- package/dist/{chunk-CY2VKNCB.js → chunk-BQIBVC6X.js} +5 -5
- package/dist/{chunk-CY2VKNCB.js.map → chunk-BQIBVC6X.js.map} +1 -1
- package/dist/{chunk-M77TQ5JJ.mjs → chunk-BU32E6BR.mjs} +4 -6
- package/dist/{chunk-M77TQ5JJ.mjs.map → chunk-BU32E6BR.mjs.map} +1 -1
- package/dist/{chunk-5CQVDUDO.js → chunk-BUNF5POU.js} +5 -5
- package/dist/{chunk-5CQVDUDO.js.map → chunk-BUNF5POU.js.map} +1 -1
- package/dist/{chunk-Z6UN4ZPW.mjs → chunk-BVHVYC7Q.mjs} +4 -4
- package/dist/{chunk-WJENEFDG.js → chunk-CAFVLHDV.js} +3 -3
- package/dist/{chunk-WJENEFDG.js.map → chunk-CAFVLHDV.js.map} +1 -1
- package/dist/{chunk-BVUPM6EY.js → chunk-CAQ2Q3ON.js} +2 -2
- package/dist/chunk-CAQ2Q3ON.js.map +1 -0
- package/dist/{chunk-QMPOGLAR.js → chunk-CIASXVWX.js} +3 -3
- package/dist/{chunk-QMPOGLAR.js.map → chunk-CIASXVWX.js.map} +1 -1
- package/dist/{chunk-APKEYUJ3.js → chunk-CIQLC2ZZ.js} +3 -3
- package/dist/{chunk-APKEYUJ3.js.map → chunk-CIQLC2ZZ.js.map} +1 -1
- package/dist/{chunk-36XPNLGQ.js → chunk-CW3FCWR4.js} +16 -16
- package/dist/{chunk-36XPNLGQ.js.map → chunk-CW3FCWR4.js.map} +1 -1
- package/dist/{chunk-J5VEAJN5.mjs → chunk-CWVUGZNK.mjs} +2 -2
- package/dist/{chunk-BCMDP6GK.mjs → chunk-DV3N2K3Y.mjs} +4 -4
- package/dist/{chunk-PP7SEERV.mjs → chunk-DXYSEBK3.mjs} +9 -3
- package/dist/chunk-DXYSEBK3.mjs.map +1 -0
- package/dist/{chunk-754M6HQ5.js → chunk-EJN4OP3D.js} +5 -5
- package/dist/{chunk-754M6HQ5.js.map → chunk-EJN4OP3D.js.map} +1 -1
- package/dist/{chunk-3IM2SBPO.js → chunk-F5K3HMKT.js} +4 -4
- package/dist/{chunk-3IM2SBPO.js.map → chunk-F5K3HMKT.js.map} +1 -1
- package/dist/{chunk-WMDSGVZ7.mjs → chunk-GCGSAS2Z.mjs} +48 -63
- package/dist/chunk-GCGSAS2Z.mjs.map +1 -0
- package/dist/{chunk-EXHGEJ4P.mjs → chunk-GKARHTZ2.mjs} +2 -2
- package/dist/{chunk-2VDCEEXB.js → chunk-GNKFBVW4.js} +3 -3
- package/dist/{chunk-2VDCEEXB.js.map → chunk-GNKFBVW4.js.map} +1 -1
- package/dist/{chunk-CDLOMECB.js → chunk-GTBPMNTJ.js} +3 -3
- package/dist/{chunk-CDLOMECB.js.map → chunk-GTBPMNTJ.js.map} +1 -1
- package/dist/{chunk-YQKAASWM.js → chunk-GXXDSBN2.js} +10 -4
- package/dist/chunk-GXXDSBN2.js.map +1 -0
- package/dist/{chunk-FASVPU6N.js → chunk-H3F4OCXC.js} +10 -10
- package/dist/{chunk-FASVPU6N.js.map → chunk-H3F4OCXC.js.map} +1 -1
- package/dist/{chunk-JCFN6KRS.mjs → chunk-HGWDB73S.mjs} +2 -2
- package/dist/{chunk-JXXMO7PY.mjs → chunk-HN5RW4C3.mjs} +3 -3
- package/dist/{chunk-I2A4EQPH.mjs → chunk-HQ2GXFK5.mjs} +6 -6
- package/dist/{chunk-BIPC6F6D.js → chunk-IDJ37MOU.js} +115 -115
- package/dist/{chunk-BIPC6F6D.js.map → chunk-IDJ37MOU.js.map} +1 -1
- package/dist/{chunk-TBJLNIOY.mjs → chunk-JBLYYTHN.mjs} +2 -2
- package/dist/{chunk-G4NK66PM.js → chunk-JTWXQ267.js} +24 -18
- package/dist/chunk-JTWXQ267.js.map +1 -0
- package/dist/{chunk-V6IC74KH.js → chunk-JXGLDRDC.js} +34 -34
- package/dist/{chunk-V6IC74KH.js.map → chunk-JXGLDRDC.js.map} +1 -1
- package/dist/{chunk-DDFIRQI5.mjs → chunk-K3E5VEBF.mjs} +56 -34
- package/dist/chunk-K3E5VEBF.mjs.map +1 -0
- package/dist/{chunk-MSBEWG26.js → chunk-K5O2IOI4.js} +8 -8
- package/dist/{chunk-MSBEWG26.js.map → chunk-K5O2IOI4.js.map} +1 -1
- package/dist/{chunk-SB5YGKXR.js → chunk-KBMLGQ5J.js} +49 -64
- package/dist/chunk-KBMLGQ5J.js.map +1 -0
- package/dist/chunk-KCZEKV7M.mjs +81 -0
- package/dist/chunk-KCZEKV7M.mjs.map +1 -0
- package/dist/{chunk-GRSN76BV.mjs → chunk-KH2R4STU.mjs} +3 -3
- package/dist/{chunk-7DQM34JT.js → chunk-KHYSXYPO.js} +23 -23
- package/dist/{chunk-7DQM34JT.js.map → chunk-KHYSXYPO.js.map} +1 -1
- package/dist/{chunk-V2YHMPRR.js → chunk-KJHBQQYJ.js} +5 -5
- package/dist/{chunk-V2YHMPRR.js.map → chunk-KJHBQQYJ.js.map} +1 -1
- package/dist/{chunk-ZF5NMQJZ.mjs → chunk-KUKLN3CK.mjs} +4 -4
- package/dist/{chunk-6AYB7CZH.js → chunk-KZQVGSR2.js} +2 -2
- package/dist/{chunk-6AYB7CZH.js.map → chunk-KZQVGSR2.js.map} +1 -1
- package/dist/{chunk-UAKRBNW2.mjs → chunk-L4T76OKM.mjs} +2 -2
- package/dist/{chunk-AUCXJ7LG.js → chunk-M3LQH7Y7.js} +3 -3
- package/dist/{chunk-AUCXJ7LG.js.map → chunk-M3LQH7Y7.js.map} +1 -1
- package/dist/{chunk-FQNJJH7F.js → chunk-MCXRKD56.js} +13 -13
- package/dist/{chunk-FQNJJH7F.js.map → chunk-MCXRKD56.js.map} +1 -1
- package/dist/{chunk-PY5WCBKN.mjs → chunk-MERKXOSI.mjs} +4 -4
- package/dist/{chunk-D3YDZF2G.js → chunk-N472HQPZ.js} +3 -3
- package/dist/{chunk-D3YDZF2G.js.map → chunk-N472HQPZ.js.map} +1 -1
- package/dist/{chunk-UPMYCGXR.js → chunk-N4K4X34Z.js} +4 -4
- package/dist/{chunk-UPMYCGXR.js.map → chunk-N4K4X34Z.js.map} +1 -1
- package/dist/{chunk-RU43UMEH.js → chunk-NFCNAFUK.js} +3 -3
- package/dist/{chunk-RU43UMEH.js.map → chunk-NFCNAFUK.js.map} +1 -1
- package/dist/{chunk-APCB5HWT.mjs → chunk-NLSDZJRR.mjs} +3 -3
- package/dist/{chunk-EWYIXCNF.mjs → chunk-NLUTNCLH.mjs} +5 -5
- package/dist/{chunk-OP4Q2KDS.mjs → chunk-NMKKMY5P.mjs} +2 -2
- package/dist/{chunk-WDPFO4II.mjs → chunk-NMPK336K.mjs} +2 -2
- package/dist/{chunk-X6BZ5IEV.mjs → chunk-NU7O6YKR.mjs} +2 -2
- package/dist/{chunk-ZABDSRX3.js → chunk-NUZ5K3CB.js} +4 -4
- package/dist/{chunk-ZABDSRX3.js.map → chunk-NUZ5K3CB.js.map} +1 -1
- package/dist/{chunk-N5ZGFYLA.js → chunk-NZX3BA62.js} +3 -3
- package/dist/{chunk-N5ZGFYLA.js.map → chunk-NZX3BA62.js.map} +1 -1
- package/dist/{chunk-2TLSEAL2.js → chunk-O4TRDWXJ.js} +3 -3
- package/dist/{chunk-2TLSEAL2.js.map → chunk-O4TRDWXJ.js.map} +1 -1
- package/dist/{chunk-CBI5F4ME.mjs → chunk-OMSSA4NO.mjs} +2 -2
- package/dist/{chunk-YGEEWLGJ.js → chunk-PKKXCX5B.js} +3 -3
- package/dist/{chunk-YGEEWLGJ.js.map → chunk-PKKXCX5B.js.map} +1 -1
- package/dist/{chunk-GYHD6QEA.mjs → chunk-PQGQ3EH5.mjs} +2 -2
- package/dist/{chunk-3LN5GQAC.js → chunk-Q6UIUYNF.js} +6 -8
- package/dist/chunk-Q6UIUYNF.js.map +1 -0
- package/dist/chunk-QLWBGM7H.js +81 -0
- package/dist/chunk-QLWBGM7H.js.map +1 -0
- package/dist/{chunk-IF5GW6ID.js → chunk-QZ5DCDZ2.js} +6 -6
- package/dist/{chunk-IF5GW6ID.js.map → chunk-QZ5DCDZ2.js.map} +1 -1
- package/dist/{chunk-LSUCENYD.mjs → chunk-RBKGHUSR.mjs} +2 -2
- package/dist/{chunk-PIZTI5SJ.js → chunk-RMCZ7C2C.js} +3 -3
- package/dist/{chunk-PIZTI5SJ.js.map → chunk-RMCZ7C2C.js.map} +1 -1
- package/dist/{chunk-LGQNMQOT.mjs → chunk-ROS5XGTQ.mjs} +2 -2
- package/dist/chunk-ROS5XGTQ.mjs.map +1 -0
- package/dist/{chunk-TEUERRDG.mjs → chunk-RV45XVXE.mjs} +2 -2
- package/dist/{chunk-FW6ZI2MC.mjs → chunk-UAFSWXN5.mjs} +2 -2
- package/dist/{chunk-QUGKQYAJ.mjs → chunk-ULVFVLFE.mjs} +4 -6
- package/dist/{chunk-QUGKQYAJ.mjs.map → chunk-ULVFVLFE.mjs.map} +1 -1
- package/dist/{chunk-ANLL2EIX.mjs → chunk-UWCGTH3U.mjs} +2 -2
- package/dist/{chunk-6R2LEEEP.mjs → chunk-UZF2D2GG.mjs} +2 -2
- package/dist/{chunk-62L3PMYE.mjs → chunk-V3OVMHZD.mjs} +2 -2
- package/dist/{chunk-UDITT3N3.mjs → chunk-V6ELDZ2B.mjs} +2 -2
- package/dist/{chunk-G7NUCBD3.js → chunk-VDPV24JJ.js} +3 -3
- package/dist/{chunk-G7NUCBD3.js.map → chunk-VDPV24JJ.js.map} +1 -1
- package/dist/{chunk-IJQOTS5O.mjs → chunk-VJUS3GC4.mjs} +2 -2
- package/dist/{chunk-ZUPP7R2K.js → chunk-W7BBVDBI.js} +17 -3
- package/dist/chunk-W7BBVDBI.js.map +1 -0
- package/dist/{chunk-EHQDQ5RV.js → chunk-XARMPXRN.js} +10 -12
- package/dist/chunk-XARMPXRN.js.map +1 -0
- package/dist/{chunk-MQEAEU6G.mjs → chunk-XGMRYNER.mjs} +2 -2
- package/dist/{chunk-MMQMVVD6.mjs → chunk-XLTD5J74.mjs} +3 -3
- package/dist/{chunk-L3ST5GUJ.js → chunk-XQUK7R7L.js} +17 -17
- package/dist/{chunk-L3ST5GUJ.js.map → chunk-XQUK7R7L.js.map} +1 -1
- package/dist/{chunk-OMBUOOMD.mjs → chunk-XYT542WD.mjs} +2 -2
- package/dist/{chunk-IZNABVXE.js → chunk-Y4IGIWP4.js} +3 -3
- package/dist/{chunk-IZNABVXE.js.map → chunk-Y4IGIWP4.js.map} +1 -1
- package/dist/{chunk-COWOGT7U.mjs → chunk-YZWFDSTC.mjs} +2 -2
- package/dist/{chunk-M2FN7CNS.mjs → chunk-Z4L2DWMX.mjs} +17 -3
- package/dist/chunk-Z4L2DWMX.mjs.map +1 -0
- package/dist/chunk-Z75J66LL.mjs +149 -0
- package/dist/chunk-Z75J66LL.mjs.map +1 -0
- package/dist/{chunk-CWIJ7RXR.js → chunk-ZHUFICW3.js} +3 -3
- package/dist/{chunk-CWIJ7RXR.js.map → chunk-ZHUFICW3.js.map} +1 -1
- package/dist/{chunk-Q5XGBTOY.js → chunk-ZNITTMV5.js} +3 -3
- package/dist/{chunk-Q5XGBTOY.js.map → chunk-ZNITTMV5.js.map} +1 -1
- package/dist/components/EnemMoment/HeaderFilters.d.ts +12 -1
- package/dist/components/EnemMoment/HeaderFilters.d.ts.map +1 -1
- package/dist/components/EnemMoment/types.d.ts +10 -1
- package/dist/components/EnemMoment/types.d.ts.map +1 -1
- package/dist/hooks/useAppContent/index.js +48 -49
- package/dist/hooks/useAppContent/index.js.map +1 -1
- package/dist/hooks/useAppContent/index.mjs +47 -48
- package/dist/hooks/useResizableColumns.d.ts +20 -9
- package/dist/hooks/useResizableColumns.d.ts.map +1 -1
- package/dist/hooks/useScreen/index.js +2 -2
- package/dist/hooks/useScreen/index.mjs +1 -1
- package/dist/index.js +48 -49
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +47 -48
- package/dist/store/layoutPreferencesStore.d.ts +12 -24
- package/dist/store/layoutPreferencesStore.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/RichEditorCore-62NIM7PC.js.map +0 -1
- package/dist/chunk-2EDRPEYL.mjs +0 -157
- package/dist/chunk-2EDRPEYL.mjs.map +0 -1
- package/dist/chunk-2VODGC76.js.map +0 -1
- package/dist/chunk-3LN5GQAC.js.map +0 -1
- package/dist/chunk-BVUPM6EY.js.map +0 -1
- package/dist/chunk-CH6BWMSQ.js +0 -17
- package/dist/chunk-CH6BWMSQ.js.map +0 -1
- package/dist/chunk-DDFIRQI5.mjs.map +0 -1
- package/dist/chunk-EHQDQ5RV.js.map +0 -1
- package/dist/chunk-G4NK66PM.js.map +0 -1
- package/dist/chunk-HIIOADV4.js.map +0 -1
- package/dist/chunk-JSH3BQZ7.mjs +0 -17
- package/dist/chunk-JSH3BQZ7.mjs.map +0 -1
- package/dist/chunk-LGQNMQOT.mjs.map +0 -1
- package/dist/chunk-LMDAF6LA.mjs +0 -51
- package/dist/chunk-LMDAF6LA.mjs.map +0 -1
- package/dist/chunk-M2FN7CNS.mjs.map +0 -1
- package/dist/chunk-MUCV5ZWZ.mjs.map +0 -1
- package/dist/chunk-PJOBOBNJ.js +0 -51
- package/dist/chunk-PJOBOBNJ.js.map +0 -1
- package/dist/chunk-PP7SEERV.mjs.map +0 -1
- package/dist/chunk-SB5YGKXR.js.map +0 -1
- package/dist/chunk-WMDSGVZ7.mjs.map +0 -1
- package/dist/chunk-YQKAASWM.js.map +0 -1
- package/dist/chunk-ZUPP7R2K.js.map +0 -1
- /package/dist/{chunk-EVBQNVQW.mjs.map → chunk-233FSBU7.mjs.map} +0 -0
- /package/dist/{chunk-MADPP2PW.mjs.map → chunk-3ZSI2KI5.mjs.map} +0 -0
- /package/dist/{chunk-2W7PTFXS.mjs.map → chunk-42XKJV56.mjs.map} +0 -0
- /package/dist/{chunk-M6TC6XRQ.mjs.map → chunk-55ESXRRM.mjs.map} +0 -0
- /package/dist/{chunk-4MURAKPC.mjs.map → chunk-5DJVOLVX.mjs.map} +0 -0
- /package/dist/{chunk-YVT7CT3G.mjs.map → chunk-5P6CBDZ6.mjs.map} +0 -0
- /package/dist/{chunk-SFEU7BMY.mjs.map → chunk-5SFNRXZB.mjs.map} +0 -0
- /package/dist/{chunk-KYY4U5SN.mjs.map → chunk-6Z5W5J44.mjs.map} +0 -0
- /package/dist/{chunk-GVYGPJH3.mjs.map → chunk-AU5M2766.mjs.map} +0 -0
- /package/dist/{chunk-Z6UN4ZPW.mjs.map → chunk-BVHVYC7Q.mjs.map} +0 -0
- /package/dist/{chunk-J5VEAJN5.mjs.map → chunk-CWVUGZNK.mjs.map} +0 -0
- /package/dist/{chunk-BCMDP6GK.mjs.map → chunk-DV3N2K3Y.mjs.map} +0 -0
- /package/dist/{chunk-EXHGEJ4P.mjs.map → chunk-GKARHTZ2.mjs.map} +0 -0
- /package/dist/{chunk-JCFN6KRS.mjs.map → chunk-HGWDB73S.mjs.map} +0 -0
- /package/dist/{chunk-JXXMO7PY.mjs.map → chunk-HN5RW4C3.mjs.map} +0 -0
- /package/dist/{chunk-I2A4EQPH.mjs.map → chunk-HQ2GXFK5.mjs.map} +0 -0
- /package/dist/{chunk-TBJLNIOY.mjs.map → chunk-JBLYYTHN.mjs.map} +0 -0
- /package/dist/{chunk-GRSN76BV.mjs.map → chunk-KH2R4STU.mjs.map} +0 -0
- /package/dist/{chunk-ZF5NMQJZ.mjs.map → chunk-KUKLN3CK.mjs.map} +0 -0
- /package/dist/{chunk-UAKRBNW2.mjs.map → chunk-L4T76OKM.mjs.map} +0 -0
- /package/dist/{chunk-PY5WCBKN.mjs.map → chunk-MERKXOSI.mjs.map} +0 -0
- /package/dist/{chunk-APCB5HWT.mjs.map → chunk-NLSDZJRR.mjs.map} +0 -0
- /package/dist/{chunk-EWYIXCNF.mjs.map → chunk-NLUTNCLH.mjs.map} +0 -0
- /package/dist/{chunk-OP4Q2KDS.mjs.map → chunk-NMKKMY5P.mjs.map} +0 -0
- /package/dist/{chunk-WDPFO4II.mjs.map → chunk-NMPK336K.mjs.map} +0 -0
- /package/dist/{chunk-X6BZ5IEV.mjs.map → chunk-NU7O6YKR.mjs.map} +0 -0
- /package/dist/{chunk-CBI5F4ME.mjs.map → chunk-OMSSA4NO.mjs.map} +0 -0
- /package/dist/{chunk-GYHD6QEA.mjs.map → chunk-PQGQ3EH5.mjs.map} +0 -0
- /package/dist/{chunk-LSUCENYD.mjs.map → chunk-RBKGHUSR.mjs.map} +0 -0
- /package/dist/{chunk-TEUERRDG.mjs.map → chunk-RV45XVXE.mjs.map} +0 -0
- /package/dist/{chunk-FW6ZI2MC.mjs.map → chunk-UAFSWXN5.mjs.map} +0 -0
- /package/dist/{chunk-ANLL2EIX.mjs.map → chunk-UWCGTH3U.mjs.map} +0 -0
- /package/dist/{chunk-6R2LEEEP.mjs.map → chunk-UZF2D2GG.mjs.map} +0 -0
- /package/dist/{chunk-62L3PMYE.mjs.map → chunk-V3OVMHZD.mjs.map} +0 -0
- /package/dist/{chunk-UDITT3N3.mjs.map → chunk-V6ELDZ2B.mjs.map} +0 -0
- /package/dist/{chunk-IJQOTS5O.mjs.map → chunk-VJUS3GC4.mjs.map} +0 -0
- /package/dist/{chunk-MQEAEU6G.mjs.map → chunk-XGMRYNER.mjs.map} +0 -0
- /package/dist/{chunk-MMQMVVD6.mjs.map → chunk-XLTD5J74.mjs.map} +0 -0
- /package/dist/{chunk-OMBUOOMD.mjs.map → chunk-XYT542WD.mjs.map} +0 -0
- /package/dist/{chunk-COWOGT7U.mjs.map → chunk-YZWFDSTC.mjs.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Card/Card.tsx"],"sourcesContent":["import {\n forwardRef,\n Fragment,\n HTMLAttributes,\n ReactNode,\n useState,\n useRef,\n MouseEvent,\n ChangeEvent,\n KeyboardEvent,\n Ref,\n useEffect,\n} from 'react';\nimport Button from '../Button/Button';\nimport IconButton from '../IconButton/IconButton';\nimport Badge from '../Badge/Badge';\nimport ProgressBar from '../ProgressBar/ProgressBar';\nimport { CaretRightIcon } from '@phosphor-icons/react/dist/csr/CaretRight';\nimport { ChatCircleTextIcon } from '@phosphor-icons/react/dist/csr/ChatCircleText';\nimport { CheckCircleIcon } from '@phosphor-icons/react/dist/csr/CheckCircle';\nimport { ClockIcon } from '@phosphor-icons/react/dist/csr/Clock';\nimport { DotsThreeVerticalIcon } from '@phosphor-icons/react/dist/csr/DotsThreeVertical';\nimport { PlayIcon } from '@phosphor-icons/react/dist/csr/Play';\nimport { SpeakerHighIcon } from '@phosphor-icons/react/dist/csr/SpeakerHigh';\nimport { SpeakerLowIcon } from '@phosphor-icons/react/dist/csr/SpeakerLow';\nimport { SpeakerSimpleXIcon } from '@phosphor-icons/react/dist/csr/SpeakerSimpleX';\nimport { TrashIcon } from '@phosphor-icons/react/dist/csr/Trash';\nimport { XCircleIcon } from '@phosphor-icons/react/dist/csr/XCircle';\nimport Text from '../Text/Text';\nimport { cn } from '../../utils/utils';\nimport { useMediaVolumePreference } from '../../store/mediaPreferencesStore';\nimport IconRender from '../IconRender/IconRender';\nimport readingFluencyBird from '../../assets/img/readingFluencyBird.png';\n\n// Componente base reutilizável para todos os cards\ninterface CardBaseProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n variant?: 'default' | 'compact' | 'minimal';\n layout?: 'horizontal' | 'vertical';\n padding?: 'none' | 'small' | 'medium' | 'large';\n minHeight?: 'none' | 'small' | 'medium' | 'large';\n cursor?: 'default' | 'pointer';\n}\n\nconst CARD_BASE_CLASSES = {\n default: 'w-full bg-background border border-border-50 rounded-xl',\n compact: 'w-full bg-background border border-border-50 rounded-lg',\n minimal: 'w-full bg-background border border-border-100 rounded-md',\n};\n\nconst CARD_PADDING_CLASSES = {\n none: '',\n small: 'p-2',\n medium: 'p-4',\n large: 'p-6',\n};\n\nconst CARD_MIN_HEIGHT_CLASSES = {\n none: '',\n small: 'min-h-16',\n medium: 'min-h-20',\n large: 'min-h-24',\n};\n\nconst CARD_LAYOUT_CLASSES = {\n horizontal: 'flex flex-row',\n vertical: 'flex flex-col',\n};\n\nconst CARD_CURSOR_CLASSES = {\n default: '',\n pointer: 'cursor-pointer',\n};\n\nconst CardBase = forwardRef<HTMLDivElement, CardBaseProps>(\n (\n {\n children,\n variant = 'default',\n layout = 'horizontal',\n padding = 'medium',\n minHeight = 'medium',\n cursor = 'default',\n className = '',\n onClick,\n onKeyDown,\n ...props\n },\n ref\n ) => {\n const baseClasses = CARD_BASE_CLASSES[variant];\n const paddingClasses = CARD_PADDING_CLASSES[padding];\n const minHeightClasses = CARD_MIN_HEIGHT_CLASSES[minHeight];\n const layoutClasses = CARD_LAYOUT_CLASSES[layout];\n const cursorClasses = CARD_CURSOR_CLASSES[cursor];\n\n // Make cards with onClick focusable and keyboard accessible\n const isInteractive = !!onClick;\n const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (isInteractive && ['Enter', ' '].includes(e.key)) {\n e.preventDefault();\n (e.currentTarget as HTMLElement).click();\n }\n onKeyDown?.(e);\n };\n\n /*\n * Note: Using div with role=\"button\" instead of native <button> element.\n * Rationale:\n * - Card is a complex container component with multiple child elements\n * - Native button has layout/styling constraints incompatible with card design\n * - Full WCAG/ARIA compliance implemented: role, tabIndex, keyboard support\n */\n return (\n <div\n ref={ref}\n className={cn(\n baseClasses,\n paddingClasses,\n minHeightClasses,\n layoutClasses,\n cursorClasses,\n className\n )}\n onClick={onClick}\n onKeyDown={handleKeyDown}\n tabIndex={isInteractive ? 0 : undefined}\n role={isInteractive ? 'button' : undefined}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\ninterface CardActivitiesResultsProps extends HTMLAttributes<HTMLDivElement> {\n icon: ReactNode;\n title: string;\n subTitle: string;\n header: string;\n description?: string;\n extended?: boolean;\n action?: 'warning' | 'success' | 'error' | 'info';\n /** Extra classes of the value line, e.g. a larger size */\n subTitleClassName?: string;\n}\n\nconst ACTION_CARD_CLASSES = {\n warning: 'bg-warning-background',\n success: 'bg-success-200',\n error: 'bg-error-100',\n info: 'bg-info-background',\n};\n\nconst ACTION_ICON_CLASSES = {\n warning: 'bg-warning-300 text-text',\n success: 'bg-indicator-positive text-text-950',\n error: 'bg-indicator-negative text-text',\n info: 'bg-info-500 text-text',\n};\n\nconst ACTION_SUBTITLE_CLASSES = {\n warning: 'text-warning-600',\n success: 'text-success-700',\n error: 'text-error-700',\n info: 'text-info-700',\n};\n\nconst ACTION_HEADER_CLASSES = {\n warning: 'text-warning-300',\n success: 'text-success-300',\n error: 'text-error-300',\n info: 'text-info-300',\n};\n\nconst CardActivitiesResults = forwardRef<\n HTMLDivElement,\n CardActivitiesResultsProps\n>(\n (\n {\n icon,\n title,\n subTitle,\n header,\n extended = false,\n action = 'success',\n description,\n className,\n subTitleClassName,\n ...props\n },\n ref\n ) => {\n const actionCardClasses = ACTION_CARD_CLASSES[action];\n const actionIconClasses = ACTION_ICON_CLASSES[action];\n const actionSubTitleClasses = ACTION_SUBTITLE_CLASSES[action];\n const actionHeaderClasses = ACTION_HEADER_CLASSES[action];\n\n return (\n <div\n ref={ref}\n className={cn(\n // `min-w-0` lets the card shrink inside a grid/flex track, so the\n // truncated texts below get a width to truncate against instead of\n // stretching the card past its column.\n 'w-full min-w-0 flex flex-col rounded-xl',\n extended && 'border border-border-50 bg-background',\n className\n )}\n {...props}\n >\n <div\n className={cn(\n 'flex flex-col gap-1 items-center justify-center p-4',\n actionCardClasses,\n // Without a description below, the coloured block is the whole\n // card: let it fill the height a stretching grid/flex track gives\n // the wrapper, so siblings in the same row end up the same height.\n extended ? 'rounded-t-xl' : 'flex-1 rounded-xl'\n )}\n >\n <span\n className={cn(\n 'size-7.5 rounded-full flex items-center justify-center',\n actionIconClasses\n )}\n >\n {icon}\n </span>\n\n <Text\n size=\"2xs\"\n weight=\"medium\"\n className=\"max-w-full text-center text-text-800 uppercase truncate\"\n >\n {title}\n </Text>\n\n <p\n className={cn(\n 'max-w-full text-center text-lg font-bold truncate',\n actionSubTitleClasses,\n subTitleClassName\n )}\n >\n {subTitle}\n </p>\n </div>\n\n {extended && (\n <div className=\"flex flex-col items-center gap-2.5 pb-9.5 pt-2.5\">\n <p\n className={cn(\n 'text-2xs font-medium uppercase truncate',\n actionHeaderClasses\n )}\n >\n {header}\n </p>\n <Badge size=\"large\" action=\"info\">\n {description}\n </Badge>\n </div>\n )}\n </div>\n );\n }\n);\n\ninterface CardQuestionProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n state?: 'done' | 'undone' | 'pending';\n onClickButton?: (valueButton?: unknown) => void;\n valueButton?: unknown;\n /**\n * Disables the action button while still showing that the lesson has a\n * questionnaire. Used when the viewer may see the content but must not\n * answer it (e.g. a teacher previewing a lesson, where answering would\n * create a questionnaire attempt tied to their own user).\n */\n disabled?: boolean;\n}\n\nconst CardQuestions = forwardRef<HTMLDivElement, CardQuestionProps>(\n (\n {\n header,\n state = 'undone',\n className,\n onClickButton,\n valueButton,\n disabled = false,\n ...props\n },\n ref\n ) => {\n const getStateConfig = () => {\n switch (state) {\n case 'done':\n return {\n label: 'Realizado',\n buttonLabel: 'Ver Resultado',\n badgeAction: 'success' as const,\n };\n case 'pending':\n return {\n label: 'Aguardando correção',\n buttonLabel: 'Ver Resultado',\n badgeAction: 'info' as const,\n };\n default:\n return {\n label: 'Não Realizado',\n buttonLabel: 'Responder',\n badgeAction: 'error' as const,\n };\n }\n };\n\n const { label, buttonLabel, badgeAction } = getStateConfig();\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"medium\"\n className={cn('justify-between gap-4', className)}\n {...props}\n >\n <section className=\"flex flex-col gap-1 flex-1 min-w-0\">\n <p className=\"font-bold text-xs text-text-950 truncate\">{header}</p>\n\n <div className=\"flex flex-row gap-6 items-center\">\n <Badge size=\"medium\" variant=\"solid\" action={badgeAction}>\n {label}\n </Badge>\n </div>\n </section>\n\n <span className=\"flex-shrink-0\">\n <Button\n size=\"extra-small\"\n onClick={() => onClickButton?.(valueButton)}\n disabled={disabled}\n className=\"min-w-fit\"\n >\n {buttonLabel}\n </Button>\n </span>\n </CardBase>\n );\n }\n);\n\ninterface CardProgressProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n subhead?: string;\n initialDate?: string;\n endDate?: string;\n progress?: number;\n direction?: 'horizontal' | 'vertical';\n icon: ReactNode;\n color?: string;\n progressVariant?: 'blue' | 'green';\n showDates?: boolean;\n /**\n * Renders the progress bar and its percentage. Set to `false` for audiences\n * that have no progress of their own (e.g. a teacher previewing a lesson\n * catalogue), where a bar stuck at 0% would read as \"nothing done\" rather\n * than \"not applicable\". Only affects `direction=\"horizontal\"`; the vertical\n * layout never had a bar.\n */\n showProgress?: boolean;\n}\n\nconst CardProgress = forwardRef<HTMLDivElement, CardProgressProps>(\n (\n {\n header,\n subhead,\n initialDate,\n endDate,\n progress = 0,\n direction = 'horizontal',\n icon,\n color = '#B7DFFF',\n progressVariant = 'blue',\n showDates = true,\n showProgress = true,\n className,\n ...props\n },\n ref\n ) => {\n const isHorizontal = direction === 'horizontal';\n const contentComponent = {\n horizontal: (\n <>\n {showDates && (\n <div className=\"flex flex-row gap-6 items-center\">\n {initialDate && (\n <span className=\"flex flex-row gap-1 items-center text-2xs\">\n <p className=\"text-text-800 font-semibold\">Início</p>\n <p className=\"text-text-600\">{initialDate}</p>\n </span>\n )}\n {endDate && (\n <span className=\"flex flex-row gap-1 items-center text-2xs\">\n <p className=\"text-text-800 font-semibold\">Fim</p>\n <p className=\"text-text-600\">{endDate}</p>\n </span>\n )}\n </div>\n )}\n {showProgress && (\n <span className=\"grid grid-cols-[1fr_auto] items-center gap-2\">\n <ProgressBar\n size=\"small\"\n value={progress}\n variant={progressVariant}\n data-testid=\"progress-bar\"\n />\n\n <Text\n size=\"xs\"\n weight=\"medium\"\n className={cn(\n 'text-text-950 leading-none tracking-normal text-center flex-none'\n )}\n >\n {Math.round(progress)}%\n </Text>\n </span>\n )}\n </>\n ),\n vertical: <p className=\"text-sm text-text-800\">{subhead}</p>,\n };\n\n return (\n <CardBase\n ref={ref}\n layout={isHorizontal ? 'horizontal' : 'vertical'}\n padding=\"none\"\n minHeight=\"medium\"\n cursor=\"pointer\"\n className={cn(isHorizontal ? 'h-20' : '', className)}\n {...props}\n >\n <div\n className={cn(\n 'flex justify-center items-center [&>svg]:size-6 text-text-950',\n isHorizontal\n ? 'min-w-[80px] min-h-[80px] rounded-l-xl'\n : 'min-h-[50px] w-full rounded-t-xl',\n !color.startsWith('#') ? `${color}` : ''\n )}\n style={color.startsWith('#') ? { backgroundColor: color } : undefined}\n data-testid=\"icon-container\"\n >\n {icon}\n </div>\n\n <div\n className={cn(\n 'p-4 flex flex-col justify-between w-full h-full',\n !isHorizontal && 'gap-4'\n )}\n >\n <Text size=\"sm\" weight=\"bold\" className=\"text-text-950 truncate\">\n {header}\n </Text>\n {contentComponent[direction]}\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardTopicProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n subHead?: string[];\n progress?: number;\n showPercentage?: boolean;\n progressVariant?: 'blue' | 'green';\n /**\n * Renders the progress bar. Set to `false` for audiences that have no\n * progress of their own (e.g. a teacher previewing a lesson catalogue),\n * where a bar stuck at 0% would read as \"nothing done\" rather than \"not\n * applicable\".\n */\n showProgress?: boolean;\n}\n\nconst CardTopic = forwardRef<HTMLDivElement, CardTopicProps>(\n (\n {\n header,\n subHead,\n progress = 0,\n showPercentage = false,\n progressVariant = 'blue',\n showProgress = true,\n className = '',\n ...props\n },\n ref\n ) => {\n return (\n <CardBase\n ref={ref}\n layout=\"vertical\"\n padding=\"small\"\n minHeight=\"medium\"\n cursor=\"pointer\"\n className={cn('justify-center gap-2 py-2 px-4', className)}\n {...props}\n >\n {subHead && (\n <span className=\"text-text-600 text-2xs flex flex-row gap-1\">\n {subHead.map((text, index) => (\n <Fragment key={`${text} - ${index}`}>\n <p>{text}</p>\n {index < subHead.length - 1 && <p>•</p>}\n </Fragment>\n ))}\n </span>\n )}\n\n <p className=\"text-sm text-text-950 font-bold truncate\">{header}</p>\n\n {showProgress && (\n <span className=\"grid grid-cols-[1fr_auto] items-center gap-2\">\n <ProgressBar\n size=\"small\"\n value={progress}\n variant={progressVariant}\n data-testid=\"progress-bar\"\n />\n {showPercentage && (\n <Text\n size=\"xs\"\n weight=\"medium\"\n className={cn(\n 'text-text-950 leading-none tracking-normal text-center flex-none'\n )}\n >\n {Math.round(progress)}%\n </Text>\n )}\n </span>\n )}\n </CardBase>\n );\n }\n);\n\ninterface CardPerformanceProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n description?: string;\n progress?: number;\n labelProgress?: string;\n actionVariant?: 'button' | 'caret';\n progressVariant?: 'blue' | 'green';\n onClickButton?: (valueButton?: unknown) => void;\n valueButton?: unknown;\n}\n\nconst CardPerformance = forwardRef<HTMLDivElement, CardPerformanceProps>(\n (\n {\n header,\n progress,\n description = 'Sem dados ainda! Você ainda não fez um questionário neste assunto.',\n actionVariant = 'button',\n progressVariant = 'blue',\n labelProgress = '',\n className = '',\n onClickButton,\n valueButton,\n ...props\n },\n ref\n ) => {\n const hasProgress = progress !== undefined;\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n className={cn(\n actionVariant == 'caret' ? 'cursor-pointer' : '',\n className\n )}\n onClick={() => actionVariant == 'caret' && onClickButton?.(valueButton)}\n {...props}\n >\n <div className=\"w-full flex flex-col justify-between gap-2\">\n <div className=\"flex flex-row justify-between items-center gap-2\">\n <p className=\"text-lg font-bold text-text-950 truncate flex-1 min-w-0\">\n {header}\n </p>\n {actionVariant === 'button' && (\n <Button\n variant=\"outline\"\n size=\"extra-small\"\n onClick={() => onClickButton?.(valueButton)}\n className=\"min-w-fit flex-shrink-0\"\n >\n Ver Aula\n </Button>\n )}\n </div>\n\n <div className=\"w-full\">\n {hasProgress ? (\n <ProgressBar\n value={progress}\n label={`${progress}% ${labelProgress}`}\n // O label visível já começa com o percentual, então o nome\n // padrão da barra (\"85% : 85%\") anunciava o número duas vezes.\n accessibleLabel={`${labelProgress.trim() || 'Progresso'}: ${progress}%`}\n variant={progressVariant}\n />\n ) : (\n <p className=\"text-xs text-text-600 truncate\">{description}</p>\n )}\n </div>\n </div>\n\n {actionVariant == 'caret' && (\n <CaretRightIcon\n className=\"size-4.5 text-text-800 cursor-pointer\"\n data-testid=\"caret-icon\"\n />\n )}\n </CardBase>\n );\n }\n);\n\ninterface CardResultsProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n icon: string;\n correct_answers: number;\n incorrect_answers: number;\n direction?: 'row' | 'col';\n color?: string;\n}\n\nconst CardResults = forwardRef<HTMLDivElement, CardResultsProps>(\n (\n {\n header,\n correct_answers,\n incorrect_answers,\n icon,\n direction = 'col',\n color = '#B7DFFF',\n className,\n ...props\n },\n ref\n ) => {\n const isRow = direction == 'row';\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"none\"\n minHeight=\"medium\"\n className={cn('items-stretch cursor-pointer pr-4', className)}\n {...props}\n >\n <div\n className={cn(\n 'flex justify-center items-center [&>svg]:size-8 text-text-950 min-w-20 max-w-20 min-h-full rounded-l-xl'\n )}\n style={{\n backgroundColor: color,\n }}\n >\n <IconRender iconName={icon} color=\"currentColor\" size={20} />\n </div>\n\n <div className=\"w-full flex flex-row justify-between items-center\">\n <div\n className={cn(\n 'p-4 flex flex-wrap justify-between w-full h-full',\n isRow ? 'flex-row items-center gap-2' : 'flex-col'\n )}\n >\n <p className=\"text-sm font-bold text-text-950 flex-1\">{header}</p>\n <span className=\"flex flex-wrap flex-row gap-1 items-center\">\n <Badge\n action=\"success\"\n variant=\"solid\"\n size=\"large\"\n iconLeft={<CheckCircleIcon />}\n >\n {correct_answers} Corretas\n </Badge>\n\n <Badge\n action=\"error\"\n variant=\"solid\"\n size=\"large\"\n iconLeft={<XCircleIcon />}\n >\n {incorrect_answers} Incorretas\n </Badge>\n </span>\n </div>\n\n <CaretRightIcon className=\"min-w-6 min-h-6 text-text-800\" />\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardStatusProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n status?: 'correct' | 'incorrect' | 'unanswered' | 'pending';\n label?: string;\n}\n\nconst CardStatus = forwardRef<HTMLDivElement, CardStatusProps>(\n ({ header, className, status, label, ...props }, ref) => {\n const getLabelBadge = (status: CardStatusProps['status']) => {\n switch (status) {\n case 'correct':\n return 'Correta';\n case 'incorrect':\n return 'Incorreta';\n case 'unanswered':\n return 'Em branco';\n case 'pending':\n return 'Avaliação pendente';\n default:\n return 'Em branco';\n }\n };\n\n const getIconBadge = (status: CardStatusProps['status']) => {\n switch (status) {\n case 'correct':\n return <CheckCircleIcon />;\n case 'incorrect':\n return <XCircleIcon />;\n case 'pending':\n return <ClockIcon />;\n default:\n return <XCircleIcon />;\n }\n };\n\n const getActionBadge = (status: CardStatusProps['status']) => {\n switch (status) {\n case 'correct':\n return 'success';\n case 'incorrect':\n return 'error';\n case 'pending':\n return 'info';\n default:\n return 'info';\n }\n };\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"medium\"\n className={cn('items-center cursor-pointer', className)}\n {...props}\n >\n <div className=\"flex justify-between w-full h-full flex-row items-center gap-2\">\n <p className=\"text-sm font-bold text-text-950 truncate flex-1 min-w-0\">\n {header}\n </p>\n <span className=\"flex flex-row gap-1 items-center flex-shrink-0\">\n {status && (\n <Badge\n action={getActionBadge(status)}\n variant=\"solid\"\n size=\"medium\"\n iconLeft={getIconBadge(status)}\n >\n {getLabelBadge(status)}\n </Badge>\n )}\n {label && <p className=\"text-sm text-text-800\">{label}</p>}\n </span>\n <CaretRightIcon className=\"min-w-6 min-h-6 text-text-800 cursor-pointer flex-shrink-0 ml-2\" />\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardSettingsProps extends HTMLAttributes<HTMLDivElement> {\n icon: ReactNode;\n header: string;\n}\n\nconst CardSettings = forwardRef<HTMLDivElement, CardSettingsProps>(\n ({ header, className, icon, ...props }, ref) => {\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"small\"\n minHeight=\"none\"\n className={cn(\n 'border-none items-center gap-2 text-text-700',\n className\n )}\n {...props}\n >\n <span className=\"[&>svg]:size-6\">{icon}</span>\n\n <p className=\"w-full text-sm truncate\">{header}</p>\n\n <CaretRightIcon size={24} className=\"cursor-pointer\" />\n </CardBase>\n );\n }\n);\n\ninterface CardSupportProps extends HTMLAttributes<HTMLDivElement> {\n header: string;\n direction?: 'row' | 'col';\n children: ReactNode;\n}\n\nconst CardSupport = forwardRef<HTMLDivElement, CardSupportProps>(\n ({ header, className, direction = 'col', children, ...props }, ref) => {\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n className={cn(\n 'border-none items-center gap-2 text-text-700',\n className\n )}\n {...props}\n >\n <div\n className={cn(\n 'w-full flex',\n direction == 'col' ? 'flex-col' : 'flex-row items-center'\n )}\n >\n <span className=\"w-full min-w-0\">\n <p className=\"text-sm text-text-950 font-bold truncate\">{header}</p>\n </span>\n <span className=\"flex flex-row gap-1\">{children}</span>\n </div>\n\n <CaretRightIcon className=\"text-text-800 cursor-pointer\" size={24} />\n </CardBase>\n );\n }\n);\n\ninterface CardForumProps<T = unknown> extends HTMLAttributes<HTMLDivElement> {\n title: string;\n content: string;\n comments: number;\n date: string;\n hour: string;\n onClickComments?: (value?: T) => void;\n valueComments?: T;\n onClickProfile?: (profile?: T) => void;\n valueProfile?: T;\n}\n\nconst CardForum = forwardRef<HTMLDivElement, CardForumProps>(\n (\n {\n title,\n content,\n comments,\n onClickComments,\n valueComments,\n onClickProfile,\n valueProfile,\n className = '',\n date,\n hour,\n ...props\n },\n ref\n ) => {\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n variant=\"minimal\"\n className={cn('w-auto h-auto gap-3', className)}\n {...props}\n >\n <button\n type=\"button\"\n aria-label=\"Ver perfil\"\n onClick={() => onClickProfile?.(valueProfile)}\n className=\"min-w-8 h-8 rounded-full bg-background-950\"\n />\n\n <div className=\"flex flex-col gap-2 flex-1 min-w-0\">\n <div className=\"flex flex-row gap-1 items-center flex-wrap\">\n <p className=\"text-xs font-semibold text-primary-700 truncate\">\n {title}\n </p>\n <p className=\"text-xs text-text-600\">\n • {date} • {hour}\n </p>\n </div>\n\n <p className=\"text-text-950 text-sm line-clamp-2 truncate\">\n {content}\n </p>\n\n <button\n type=\"button\"\n aria-label=\"Ver comentários\"\n onClick={() => onClickComments?.(valueComments)}\n className=\"text-text-600 flex flex-row gap-2 items-center\"\n >\n <ChatCircleTextIcon aria-hidden=\"true\" size={16} />\n <p className=\"text-xs\">{comments} respostas</p>\n </button>\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardAudioProps extends HTMLAttributes<HTMLDivElement> {\n src?: string;\n title?: string;\n onPlay?: () => void;\n onPause?: () => void;\n onEnded?: () => void;\n onAudioTimeUpdate?: (currentTime: number, duration: number) => void;\n loop?: boolean;\n preload?: 'none' | 'metadata' | 'auto';\n tracks?: Array<{\n kind: 'subtitles' | 'captions' | 'descriptions' | 'chapters' | 'metadata';\n src: string;\n srcLang: string;\n label: string;\n default?: boolean;\n }>;\n}\n\n/** Salto do avanço/retrocesso da barra de progresso pelo teclado. */\nconst AUDIO_SEEK_STEP_SECONDS = 5;\n\nconst AUDIO_SPEED_OPTIONS = [\n { speed: 1, label: '1x' },\n { speed: 1.5, label: '1.5x' },\n { speed: 2, label: '2x' },\n];\n\nconst CardAudio = forwardRef<HTMLDivElement, CardAudioProps>(\n (\n {\n src,\n title,\n onPlay,\n onPause,\n onEnded,\n onAudioTimeUpdate,\n loop = false,\n preload = 'metadata',\n tracks,\n className,\n ...props\n },\n ref\n ) => {\n const [isPlaying, setIsPlaying] = useState(false);\n const [currentTime, setCurrentTime] = useState(0);\n const [duration, setDuration] = useState(0);\n // Mesmo store da videoaula: o volume escolhido em qualquer player vale\n // para o próximo, em vez de o podcast recomeçar sempre em 100%.\n const { volume, isMuted, setVolume, setIsMuted } =\n useMediaVolumePreference();\n const [showVolumeControl, setShowVolumeControl] = useState(false);\n const [showSpeedMenu, setShowSpeedMenu] = useState(false);\n const [playbackRate, setPlaybackRate] = useState(1);\n const audioRef = useRef<HTMLAudioElement>(null);\n const volumeControlRef = useRef<HTMLDivElement>(null);\n const speedMenuRef = useRef<HTMLDivElement>(null);\n // Gatilhos e conteúdo dos dois popups: o foco precisa entrar ao abrir e\n // voltar ao gatilho ao fechar, senão o teclado fica preso fora deles.\n const volumeButtonRef = useRef<HTMLButtonElement>(null);\n const volumeSliderRef = useRef<HTMLInputElement>(null);\n const speedButtonRef = useRef<HTMLButtonElement>(null);\n const speedMenuListRef = useRef<HTMLDivElement>(null);\n\n const formatTime = (time: number) => {\n // Transmissão ao vivo reporta duração `Infinity`, e antes dos metadados,\n // `NaN` — sem esta guarda a tela mostrava \"Infinity:NaN\".\n if (!Number.isFinite(time) || time < 0) return '0:00';\n\n const minutes = Math.floor(time / 60);\n const seconds = Math.floor(time % 60);\n return `${minutes}:${seconds.toString().padStart(2, '0')}`;\n };\n\n const handlePlayPause = () => {\n if (isPlaying) {\n audioRef.current?.pause();\n setIsPlaying(false);\n onPause?.();\n } else {\n // play() returns a promise that rejects (AbortError) when interrupted\n // by a pause() before playback starts; swallow it to avoid crashing.\n audioRef.current?.play()?.catch(() => {});\n setIsPlaying(true);\n onPlay?.();\n }\n };\n\n const handleTimeUpdate = () => {\n const current = audioRef.current?.currentTime ?? 0;\n const total = audioRef.current?.duration ?? 0;\n\n setCurrentTime(current);\n setDuration(total);\n onAudioTimeUpdate?.(current, total);\n };\n\n const handleLoadedMetadata = () => {\n setDuration(audioRef.current?.duration ?? 0);\n };\n\n const handleEnded = () => {\n setIsPlaying(false);\n setCurrentTime(0);\n onEnded?.();\n };\n\n /**\n * `audio.duration` vem `Infinity` em transmissão ao vivo e `NaN` antes dos\n * metadados — e o `?? 0` dos handlers não pega nenhum dos dois, porque só\n * trata `null`/`undefined`. O que é exibido e anunciado passa por aqui; o\n * valor cru segue indo para `seekTo`, senão saturar a duração em zero\n * prenderia o avanço de mídia ao vivo no início.\n */\n const hasKnownDuration = Number.isFinite(duration) && duration > 0;\n\n /** Move a reprodução para `time`, preso à faixa [0, duração]. */\n const seekTo = (time: number) => {\n const clamped = Math.min(Math.max(time, 0), duration);\n\n if (audioRef.current && Number.isFinite(clamped)) {\n audioRef.current.currentTime = clamped;\n setCurrentTime(clamped);\n }\n };\n\n const handleProgressClick = (e: MouseEvent<HTMLButtonElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n const clickX = e.clientX - rect.left;\n\n seekTo((clickX / rect.width) * duration);\n };\n\n /**\n * Avanço e retrocesso pelo teclado. Antes, Enter e Espaço sintetizavam um\n * clique — que chega com `clientX` 0 e rebobinava o áudio para o início.\n */\n const handleProgressKeyDown = (e: KeyboardEvent<HTMLButtonElement>) => {\n const timeByKey: Record<string, number> = {\n ArrowRight: currentTime + AUDIO_SEEK_STEP_SECONDS,\n ArrowUp: currentTime + AUDIO_SEEK_STEP_SECONDS,\n ArrowLeft: currentTime - AUDIO_SEEK_STEP_SECONDS,\n ArrowDown: currentTime - AUDIO_SEEK_STEP_SECONDS,\n Home: 0,\n End: duration,\n };\n\n if (e.key in timeByKey) {\n e.preventDefault();\n seekTo(timeByKey[e.key]);\n }\n };\n\n // O card tem um único controle de áudio, então o mudo herdado da videoaula\n // aparece aqui como volume zero — em vez de um slider em 70% sem som.\n const displayVolume = isMuted ? 0 : volume;\n\n /**\n * Salva o volume escolhido. Como o slider é o único controle de áudio do\n * card, zerá-lo é o gesto de mudo, e sair do zero desfaz o mudo herdado.\n */\n const applyVolume = (newVolume: number) => {\n setVolume(newVolume);\n setIsMuted(newVolume === 0);\n };\n\n const handleVolumeChange = (e: ChangeEvent<HTMLInputElement>) => {\n applyVolume(Number.parseFloat(e.target.value));\n };\n\n const toggleVolumeControl = () => {\n setShowVolumeControl(!showVolumeControl);\n setShowSpeedMenu(false);\n };\n\n const toggleSpeedMenu = () => {\n setShowSpeedMenu(!showSpeedMenu);\n setShowVolumeControl(false);\n };\n\n const closeVolumeControl = () => {\n setShowVolumeControl(false);\n volumeButtonRef.current?.focus();\n };\n\n const closeSpeedMenu = () => {\n setShowSpeedMenu(false);\n speedButtonRef.current?.focus();\n };\n\n const handleVolumeKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {\n const stepUp = Math.min(1, Math.round((displayVolume + 0.1) * 10) / 10);\n const stepDown = Math.max(0, Math.round((displayVolume - 0.1) * 10) / 10);\n const volumeByKey: Record<string, number> = {\n ArrowUp: stepUp,\n ArrowRight: stepUp,\n ArrowDown: stepDown,\n ArrowLeft: stepDown,\n };\n\n if (e.key in volumeByKey) {\n e.preventDefault();\n applyVolume(volumeByKey[e.key]);\n } else if (e.key === 'Escape') {\n e.preventDefault();\n closeVolumeControl();\n }\n };\n\n /** Navegação do menu de velocidade, no mesmo padrão da videoaula. */\n const handleSpeedMenuKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n closeSpeedMenu();\n return;\n }\n\n const items = [\n ...(speedMenuListRef.current?.querySelectorAll<HTMLButtonElement>(\n '[role=\"menuitemradio\"]'\n ) ?? []),\n ];\n if (items.length === 0) return;\n\n const currentIndex = items.indexOf(\n document.activeElement as HTMLButtonElement\n );\n const nextIndexByKey: Record<string, number> = {\n ArrowDown: (currentIndex + 1) % items.length,\n ArrowUp: (currentIndex - 1 + items.length) % items.length,\n Home: 0,\n End: items.length - 1,\n };\n\n if (e.key in nextIndexByKey) {\n e.preventDefault();\n items[nextIndexByKey[e.key]]?.focus();\n }\n };\n\n const handleSpeedChange = (speed: number) => {\n setPlaybackRate(speed);\n if (audioRef.current) {\n audioRef.current.playbackRate = speed;\n }\n closeSpeedMenu();\n };\n\n // Abrir um popup sem levar o foco deixa o conteúdo dele fora do alcance de\n // quem abriu pelo teclado — o Escape, inclusive, não teria onde ser ouvido.\n useEffect(() => {\n if (showVolumeControl) volumeSliderRef.current?.focus();\n }, [showVolumeControl]);\n\n useEffect(() => {\n if (!showSpeedMenu) return;\n\n const list = speedMenuListRef.current;\n const checked = list?.querySelector<HTMLButtonElement>(\n '[aria-checked=\"true\"]'\n );\n (\n checked ??\n list?.querySelector<HTMLButtonElement>('[role=\"menuitemradio\"]')\n )?.focus();\n }, [showSpeedMenu]);\n\n const getVolumeIcon = () => {\n if (displayVolume === 0) {\n return <SpeakerSimpleXIcon size={24} />;\n }\n if (displayVolume < 0.5) {\n return <SpeakerLowIcon size={24} />;\n }\n return <SpeakerHighIcon size={24} />;\n };\n\n // Aplica a preferência ao elemento no mount, ao trocar de faixa e quando\n // outro player altera o volume. Sem isso o `<audio>` sempre nasceria em 100%.\n useEffect(() => {\n const audio = audioRef.current;\n if (!audio) return;\n\n audio.volume = volume;\n audio.muted = isMuted;\n }, [volume, isMuted, src]);\n\n useEffect(() => {\n const handleClickOutside = (event: Event) => {\n if (\n volumeControlRef.current &&\n !volumeControlRef.current.contains(event.target as Node)\n ) {\n setShowVolumeControl(false);\n }\n if (\n speedMenuRef.current &&\n !speedMenuRef.current.contains(event.target as Node)\n ) {\n setShowSpeedMenu(false);\n }\n };\n\n document.addEventListener('mousedown', handleClickOutside);\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n };\n }, []);\n\n /**\n * Rótulo do play/pause. O título entra nele pro botão se descrever sozinho:\n * quem chega ali pela navegação do leitor de tela, sem ter passado pelo nome\n * do grupo, ouvia só \"Reproduzir\" sem saber o quê.\n */\n const playPauseAction = isPlaying ? 'Pausar' : 'Reproduzir';\n const playPauseLabel = title\n ? `${playPauseAction} ${title}`\n : playPauseAction;\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n className={cn(\n 'flex flex-row w-auto h-14 items-center gap-2',\n className\n )}\n {...props}\n >\n {/* Audio element */}\n <audio\n ref={audioRef}\n src={src}\n loop={loop}\n preload={preload}\n onTimeUpdate={handleTimeUpdate}\n onLoadedMetadata={handleLoadedMetadata}\n onEnded={handleEnded}\n data-testid=\"audio-element\"\n // Sem `aria-label`: este `<audio>` não tem `controls`, então não há\n // nada pro leitor de tela fazer com ele — e o rótulo repetia o título\n // que o container já anuncia, aparecendo duas vezes na árvore (o caso\n // do card de podcast). Quem nomeia o conjunto é o consumidor, com um\n // `<section>` nomeada em volta (ver `LessonPodcastSection`).\n >\n {tracks ? (\n tracks.map((track) => (\n <track\n key={track.src}\n kind={track.kind}\n src={track.src}\n srcLang={track.srcLang}\n label={track.label}\n default={track.default}\n />\n ))\n ) : (\n <track\n kind=\"captions\"\n src=\"data:text/vtt;base64,\"\n srcLang=\"pt\"\n label=\"Sem legendas disponíveis\"\n />\n )}\n </audio>\n\n {/* Play/Pause Button */}\n <button\n type=\"button\"\n onClick={handlePlayPause}\n disabled={!src}\n className=\"cursor-pointer text-text-950 hover:text-primary-600 disabled:text-text-400 disabled:cursor-not-allowed\"\n aria-label={playPauseLabel}\n >\n {isPlaying ? (\n <div className=\"w-6 h-6 flex items-center justify-center\">\n <div className=\"flex gap-0.5\">\n <div className=\"w-1 h-4 bg-current rounded-sm\"></div>\n <div className=\"w-1 h-4 bg-current rounded-sm\"></div>\n </div>\n </div>\n ) : (\n <PlayIcon size={24} />\n )}\n </button>\n\n {/* Current Time */}\n <p className=\"text-text-800 text-md font-medium min-w-[2.5rem]\">\n {formatTime(currentTime)}\n </p>\n\n {/* Progress Bar */}\n <div className=\"flex-1 relative\" data-testid=\"progress-bar\">\n <button\n type=\"button\"\n className=\"w-full h-2 bg-border-100 rounded-full cursor-pointer\"\n onClick={handleProgressClick}\n onKeyDown={handleProgressKeyDown}\n // O papel nativo de botão não carrega posição nem duração: o leitor\n // anunciava só o rótulo, sem dizer em que ponto do áudio se está.\n role=\"slider\"\n aria-label=\"Barra de progresso do áudio\"\n aria-valuemin={0}\n aria-valuemax={hasKnownDuration ? Math.round(duration) : 0}\n aria-valuenow={hasKnownDuration ? Math.round(currentTime) : 0}\n // Sem duração conhecida, anuncia só o decorrido: dizer \"de 0:00\"\n // afirmaria um total que não existe.\n aria-valuetext={\n hasKnownDuration\n ? `${formatTime(currentTime)} de ${formatTime(duration)}`\n : formatTime(currentTime)\n }\n >\n <div\n className=\"h-full bg-primary-600 rounded-full transition-all duration-100\"\n style={{\n width:\n duration > 0 ? `${(currentTime / duration) * 100}%` : '0%',\n }}\n />\n </button>\n </div>\n\n {/* Duration */}\n <p className=\"text-text-800 text-md font-medium min-w-[2.5rem]\">\n {formatTime(duration)}\n </p>\n\n {/* Volume Control */}\n <div className=\"relative h-6\" ref={volumeControlRef}>\n <button\n ref={volumeButtonRef}\n type=\"button\"\n onClick={toggleVolumeControl}\n className=\"cursor-pointer text-text-950 hover:text-primary-600\"\n aria-label=\"Controle de volume\"\n aria-expanded={showVolumeControl}\n >\n <div className=\"w-6 h-6 flex items-center justify-center\">\n {getVolumeIcon()}\n </div>\n </button>\n\n {showVolumeControl && (\n // Era um <button> envolvendo o slider: além de HTML inválido, o\n // papel de botão achata os filhos, e o slider não chegava ao leitor.\n <div className=\"absolute bottom-full right-0 mb-2 p-2 bg-background border border-border-100 rounded-lg shadow-lg\">\n <input\n ref={volumeSliderRef}\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.1\"\n value={displayVolume}\n onChange={handleVolumeChange}\n onKeyDown={handleVolumeKeyDown}\n className=\"w-20 h-2 bg-border-100 rounded-lg appearance-none cursor-pointer focus:outline-none focus:ring-2 focus:ring-primary-500\"\n style={{\n background: `linear-gradient(to right, #3b82f6 0%, #3b82f6 ${displayVolume * 100}%, #e5e7eb ${displayVolume * 100}%, #e5e7eb 100%)`,\n }}\n aria-label=\"Volume\"\n aria-valuenow={Math.round(displayVolume * 100)}\n aria-valuemin={0}\n aria-valuemax={100}\n // Sem isto o leitor fala o número cru — e aqui seria \"0,5\",\n // porque a faixa nativa vai de 0 a 1, não de 0 a 100.\n aria-valuetext={`${Math.round(displayVolume * 100)} por cento`}\n />\n </div>\n )}\n </div>\n\n {/* Menu Button */}\n <div className=\"relative h-6\" ref={speedMenuRef}>\n <button\n ref={speedButtonRef}\n type=\"button\"\n onClick={toggleSpeedMenu}\n className=\"cursor-pointer text-text-950 hover:text-primary-600\"\n aria-label=\"Opções de velocidade\"\n aria-haspopup=\"menu\"\n aria-expanded={showSpeedMenu}\n >\n <DotsThreeVerticalIcon size={24} />\n </button>\n\n {showSpeedMenu && (\n <div className=\"absolute bottom-full right-0 mb-2 p-2 bg-background border border-border-100 rounded-lg shadow-lg min-w-24 z-10\">\n <div\n ref={speedMenuListRef}\n role=\"menu\"\n aria-label=\"Velocidade de reprodução\"\n // Focável só por script: o foco vive nas velocidades\n tabIndex={-1}\n onKeyDown={handleSpeedMenuKeyDown}\n className=\"flex flex-col gap-1\"\n >\n {AUDIO_SPEED_OPTIONS.map(({ speed, label }) => (\n <button\n key={speed}\n type=\"button\"\n // A velocidade ativa só se distinguia pela cor de fundo:\n // `aria-checked` é o que a torna audível.\n role=\"menuitemradio\"\n aria-checked={playbackRate === speed}\n // Tabindex móvel: as setas andam entre as velocidades\n tabIndex={-1}\n onClick={() => handleSpeedChange(speed)}\n className={cn(\n 'px-3 py-1 text-sm text-left rounded hover:bg-border-50 transition-colors',\n playbackRate === speed\n ? 'bg-primary-950 text-secondary-100 font-medium'\n : 'text-text-950'\n )}\n >\n {label}\n </button>\n ))}\n </div>\n </div>\n )}\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardSimuladoProps extends HTMLAttributes<HTMLDivElement> {\n title: string;\n duration?: string;\n info: string;\n backgroundColor: 'enem' | 'prova' | 'simuladao' | 'vestibular';\n /**\n * Renders the card in a non-interactive \"coming soon\" state: greyed out,\n * not clickable, with an \"Em breve\" badge next to the title.\n */\n comingSoon?: boolean;\n /** Disables interaction (greyed out, not clickable) without a badge. */\n disabled?: boolean;\n}\n\nconst SIMULADO_BACKGROUND_CLASSES = {\n enem: 'bg-exam-1',\n prova: 'bg-exam-2',\n simuladao: 'bg-exam-3',\n vestibular: 'bg-exam-4',\n};\n\nconst CardSimulado = forwardRef<HTMLDivElement, CardSimuladoProps>(\n (\n {\n title,\n duration,\n info,\n backgroundColor,\n comingSoon = false,\n disabled = false,\n className,\n onClick,\n onKeyDown,\n ...props\n },\n ref\n ) => {\n const backgroundClass = SIMULADO_BACKGROUND_CLASSES[backgroundColor];\n const isInteractive = !comingSoon && !disabled;\n\n return (\n <CardBase\n ref={ref}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n cursor={isInteractive ? 'pointer' : 'default'}\n aria-disabled={isInteractive ? undefined : true}\n // Only forward handlers when interactive: CardBase derives tabIndex,\n // role=\"button\" and Enter/Space activation from the presence of onClick,\n // so a disabled/coming-soon card must not receive them.\n onClick={isInteractive ? onClick : undefined}\n onKeyDown={isInteractive ? onKeyDown : undefined}\n className={cn(\n backgroundClass,\n isInteractive\n ? 'hover:shadow-soft-shadow-2 transition-shadow duration-200'\n : 'opacity-60 pointer-events-none',\n className\n )}\n {...props}\n >\n <div className=\"flex justify-between items-center w-full gap-4\">\n <div className=\"flex flex-col gap-1 flex-1 min-w-0\">\n {comingSoon ? (\n <div className=\"flex items-center gap-2 min-w-0\">\n <Text\n size=\"lg\"\n weight=\"bold\"\n className=\"text-text-950 truncate\"\n >\n {title}\n </Text>\n <Badge\n size=\"small\"\n variant=\"solid\"\n action=\"info\"\n className=\"flex-shrink-0\"\n data-testid=\"badge-em-breve\"\n >\n Em breve\n </Badge>\n </div>\n ) : (\n <Text size=\"lg\" weight=\"bold\" className=\"text-text-950 truncate\">\n {title}\n </Text>\n )}\n\n <div className=\"flex items-center gap-4 text-text-700\">\n {duration && (\n <div className=\"flex items-center gap-1\">\n {/* Decorativo: a duração está no texto ao lado. O Phosphor não\n marca os ícones sozinho — sem `alt` ele nem emite\n `<title>`, então o leitor anunciava um gráfico sem nome. */}\n <ClockIcon\n size={16}\n className=\"flex-shrink-0\"\n aria-hidden=\"true\"\n />\n <Text size=\"sm\">{duration}</Text>\n </div>\n )}\n\n <Text size=\"sm\" className=\"truncate\">\n {info}\n </Text>\n </div>\n </div>\n\n {isInteractive && (\n <CaretRightIcon\n size={24}\n className=\"text-text-800 flex-shrink-0\"\n data-testid=\"caret-icon\"\n aria-hidden=\"true\"\n />\n )}\n </div>\n </CardBase>\n );\n }\n);\n\ninterface CardTestProps extends Omit<HTMLAttributes<HTMLElement>, 'onSelect'> {\n title: string;\n duration?: string;\n questionsCount?: number;\n additionalInfo?: string;\n selected?: boolean;\n onSelect?: (selected: boolean) => void;\n}\n\nconst CardTest = forwardRef<HTMLElement, CardTestProps>(\n (\n {\n title,\n duration,\n questionsCount,\n additionalInfo,\n selected = false,\n onSelect,\n className = '',\n ...props\n },\n ref\n ) => {\n const handleClick = () => {\n if (onSelect) {\n onSelect(!selected);\n }\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLElement>) => {\n if ((event.key === 'Enter' || event.key === ' ') && onSelect) {\n event.preventDefault();\n onSelect(!selected);\n }\n };\n\n const isSelectable = !!onSelect;\n const getQuestionsText = (count: number) => {\n const singular = count === 1 ? 'questão' : 'questões';\n return `${count} ${singular}`;\n };\n\n const displayInfo = questionsCount\n ? getQuestionsText(questionsCount)\n : additionalInfo || '';\n const baseClasses =\n 'flex flex-row items-center p-4 gap-2 w-full max-w-full bg-background shadow-soft-shadow-1 rounded-xl isolate border-0 text-left';\n const interactiveClasses = isSelectable\n ? 'cursor-pointer focus:outline-none focus:ring-2 focus:ring-primary-950 focus:ring-offset-2'\n : '';\n const selectedClasses = selected\n ? 'ring-2 ring-primary-950 ring-offset-2'\n : '';\n\n if (isSelectable) {\n return (\n <button\n ref={ref as Ref<HTMLButtonElement>}\n type=\"button\"\n className={cn(\n `${baseClasses} ${interactiveClasses} ${selectedClasses} ${className}`.trim()\n )}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n aria-pressed={selected}\n {...(props as HTMLAttributes<HTMLButtonElement>)}\n >\n <div className=\"flex flex-col justify-between gap-[27px] flex-grow min-h-[67px] w-full min-w-0\">\n <Text\n size=\"md\"\n weight=\"bold\"\n className=\"text-text-950 tracking-[0.2px] leading-[19px] truncate\"\n >\n {title}\n </Text>\n\n <div className=\"flex flex-row justify-start items-end gap-4 w-full\">\n {duration && (\n <div className=\"flex flex-row items-center gap-1 flex-shrink-0\">\n <ClockIcon\n size={16}\n className=\"text-text-700\"\n aria-hidden=\"true\"\n />\n <Text\n size=\"sm\"\n className=\"text-text-700 leading-[21px] whitespace-nowrap\"\n >\n {duration}\n </Text>\n </div>\n )}\n\n <Text\n size=\"sm\"\n className=\"text-text-700 leading-[21px] flex-grow truncate\"\n >\n {displayInfo}\n </Text>\n </div>\n </div>\n </button>\n );\n }\n\n return (\n <div\n ref={ref as Ref<HTMLDivElement>}\n className={cn(`${baseClasses} ${className}`.trim())}\n {...(props as HTMLAttributes<HTMLDivElement>)}\n >\n <div className=\"flex flex-col justify-between gap-[27px] flex-grow min-h-[67px] w-full min-w-0\">\n <Text\n size=\"md\"\n weight=\"bold\"\n className=\"text-text-950 tracking-[0.2px] leading-[19px] truncate\"\n >\n {title}\n </Text>\n\n <div className=\"flex flex-row justify-start items-end gap-4 w-full\">\n {duration && (\n <div className=\"flex flex-row items-center gap-1 flex-shrink-0\">\n <ClockIcon\n size={16}\n className=\"text-text-700\"\n aria-hidden=\"true\"\n />\n <Text\n size=\"sm\"\n className=\"text-text-700 leading-[21px] whitespace-nowrap\"\n >\n {duration}\n </Text>\n </div>\n )}\n\n <Text\n size=\"sm\"\n className=\"text-text-700 leading-[21px] flex-grow truncate min-w-0\"\n >\n {displayInfo}\n </Text>\n </div>\n </div>\n </div>\n );\n }\n);\n\ninterface SimulationItem {\n id: string;\n title: string;\n type: 'enem' | 'prova' | 'simulado' | 'vestibular';\n info: string;\n /**\n * Optional status badge (e.g. \"Em andamento\" / \"Concluído\"). When provided it\n * is rendered next to the type badge. `action` maps to the Badge color action.\n */\n statusBadge?: {\n label: string;\n action: 'success' | 'warning' | 'info' | 'error';\n };\n /**\n * True when the current user authored this simulation and may remove it.\n * Only then is the delete action rendered — a simulation assigned by a\n * teacher never gets one.\n */\n canDelete?: boolean;\n}\n\ninterface SimulationHistoryData {\n date: string;\n simulations: SimulationItem[];\n}\n\ninterface CardSimulationHistoryProps extends HTMLAttributes<HTMLDivElement> {\n data: SimulationHistoryData[];\n onSimulationClick?: (simulation: SimulationItem) => void;\n /**\n * Called when the delete action is triggered for a simulation. The action is\n * only rendered for items flagged with `canDelete`. Confirmation is the\n * caller's responsibility.\n */\n onDeleteClick?: (simulation: SimulationItem) => void;\n}\n\nconst SIMULATION_TYPE_STYLES = {\n enem: {\n background: 'bg-exam-1',\n badge: 'exam1' as const,\n text: 'Enem',\n },\n prova: {\n background: 'bg-exam-2',\n badge: 'exam2' as const,\n text: 'Prova',\n },\n simulado: {\n background: 'bg-exam-3',\n badge: 'exam3' as const,\n text: 'Simuladão',\n },\n vestibular: {\n background: 'bg-exam-4',\n badge: 'exam4' as const,\n text: 'Vestibular',\n },\n};\n\nconst CardSimulationHistory = forwardRef<\n HTMLDivElement,\n CardSimulationHistoryProps\n>(({ data, onSimulationClick, onDeleteClick, className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('w-full max-w-[992px] h-auto', className)}\n {...props}\n >\n {/* Content */}\n <div className=\"flex flex-col gap-0\">\n {data.map((section, sectionIndex) => (\n <div key={section.date} className=\"flex flex-col\">\n {/* Seção com data */}\n <div\n className={cn(\n 'flex flex-row justify-center items-start px-4 py-6 gap-2 w-full bg-background',\n sectionIndex === 0 ? 'rounded-t-3xl' : ''\n )}\n >\n <Text\n size=\"xs\"\n weight=\"bold\"\n className=\"text-text-800 w-11 flex-shrink-0\"\n >\n {section.date}\n </Text>\n\n <div className=\"flex flex-col gap-2 flex-1\">\n {section.simulations.map((simulation) => {\n const typeStyles = SIMULATION_TYPE_STYLES[simulation.type];\n\n return (\n <CardBase\n key={simulation.id}\n layout=\"horizontal\"\n padding=\"medium\"\n minHeight=\"none\"\n cursor=\"pointer\"\n className={cn(\n `${typeStyles.background} rounded-xl hover:shadow-soft-shadow-2 \n transition-shadow duration-200 h-auto min-h-[61px]`\n )}\n onClick={() => onSimulationClick?.(simulation)}\n >\n <div className=\"flex justify-between items-center w-full gap-2\">\n <div className=\"flex flex-wrap flex-col justify-between sm:flex-row gap-2 flex-1 min-w-0\">\n <Text\n size=\"lg\"\n weight=\"bold\"\n className=\"text-text-950 truncate\"\n >\n {simulation.title}\n </Text>\n\n <div className=\"flex items-center gap-2\">\n <Badge\n variant=\"examsOutlined\"\n action={typeStyles.badge}\n size=\"medium\"\n >\n {typeStyles.text}\n </Badge>\n\n {simulation.statusBadge && (\n <Badge\n variant=\"outlined\"\n action={simulation.statusBadge.action}\n size=\"medium\"\n >\n {simulation.statusBadge.label}\n </Badge>\n )}\n\n <Text size=\"sm\" className=\"text-text-800 truncate\">\n {simulation.info}\n </Text>\n </div>\n </div>\n\n <div className=\"flex items-center gap-1 flex-shrink-0\">\n {simulation.canDelete && onDeleteClick && (\n <IconButton\n size=\"sm\"\n icon={<TrashIcon size={20} />}\n aria-label={`Excluir simulado ${simulation.title}`}\n data-testid={`delete-simulation-${simulation.id}`}\n // The whole CardBase is clickable, so the click\n // must not bubble up into onSimulationClick.\n onClick={(event) => {\n event.stopPropagation();\n onDeleteClick(simulation);\n }}\n />\n )}\n\n <CaretRightIcon\n size={24}\n className=\"text-text-800\"\n data-testid=\"caret-icon\"\n />\n </div>\n </div>\n </CardBase>\n );\n })}\n </div>\n </div>\n </div>\n ))}\n\n {/* Footer rounded */}\n {data.length > 0 && (\n <div className=\"w-full h-6 bg-background rounded-b-3xl\" />\n )}\n </div>\n </div>\n );\n});\n\n// ======================================================================\n// CardEssayHistory — histórico de redações agrupado por data\n// ======================================================================\n\nexport enum EssayStatus {\n DRAFT = 'DRAFT',\n SUBMITTED = 'SUBMITTED',\n CORRECTING = 'CORRECTING',\n CORRECTED = 'CORRECTED',\n ERROR = 'ERROR',\n}\n\nexport enum EssayReviewStatus {\n PENDING = 'PENDING',\n APPROVED = 'APPROVED',\n MODIFIED = 'MODIFIED',\n}\n\nexport interface EssayHistoryItem {\n id: string;\n /** Título exibido. Se null/undefined, o componente cai no `fallbackTitle` */\n title: string | null;\n /** Título fallback (ex: título do tema) quando `title` está vazio */\n fallbackTitle?: string;\n status: EssayStatus;\n /** Nota total (0..maxScore). null quando ainda não pontuou */\n totalScore: number | null;\n /** Status da revisão do professor */\n reviewStatus?: EssayReviewStatus | null;\n}\n\nexport interface EssayHistoryData {\n /** Label da data do grupo (ex: \"12 Fev\") */\n date: string;\n essays: EssayHistoryItem[];\n}\n\ninterface CardEssayHistoryProps extends HTMLAttributes<HTMLDivElement> {\n data: EssayHistoryData[];\n /** Nota máxima pra compor o label \"X de {maxScore}\". Default: 1000 */\n maxScore?: number;\n /** Callback ao clicar num item clicável (CORRECTED com score, ou ERROR) */\n onEssayClick?: (essay: EssayHistoryItem) => void;\n}\n\ntype EssayVisualState = {\n background: string;\n text: string;\n clickable: boolean;\n};\n\nconst resolveEssayVisualState = (\n essay: EssayHistoryItem,\n maxScore: number\n): EssayVisualState => {\n // If essay has a score, show it (regardless of status - covers professor review cases)\n if (essay.totalScore != null) {\n return {\n background: 'bg-subject-12',\n text: `${essay.totalScore} de ${maxScore}`,\n clickable: true,\n };\n }\n if (essay.status === EssayStatus.ERROR) {\n return {\n background: 'bg-tertiary-100',\n text: 'Erro na correção',\n clickable: true,\n };\n }\n if (\n essay.status === EssayStatus.CORRECTING ||\n essay.status === EssayStatus.SUBMITTED\n ) {\n return {\n background: 'bg-secondary-200',\n text: 'Gerando resultado...',\n clickable: false,\n };\n }\n if (essay.status === EssayStatus.DRAFT) {\n return {\n background: 'bg-secondary-200',\n text: 'Rascunho',\n clickable: false,\n };\n }\n return {\n background: 'bg-secondary-200',\n text: 'Sem nota ainda',\n clickable: false,\n };\n};\n\ntype ReviewBadgeConfig = {\n label: string;\n action: 'success' | 'info';\n} | null;\n\nconst resolveReviewBadge = (essay: EssayHistoryItem): ReviewBadgeConfig => {\n if (\n essay.reviewStatus === EssayReviewStatus.APPROVED ||\n essay.reviewStatus === EssayReviewStatus.MODIFIED\n ) {\n return { label: 'Revisado', action: 'success' };\n }\n\n if (\n essay.status === EssayStatus.CORRECTED &&\n essay.reviewStatus === EssayReviewStatus.PENDING\n ) {\n return { label: 'Corrigido por IA', action: 'info' };\n }\n\n return null;\n};\n\nconst CardEssayHistory = forwardRef<HTMLDivElement, CardEssayHistoryProps>(\n ({ data, maxScore = 1000, onEssayClick, className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('w-full max-w-248 bg-background rounded-3xl', className)}\n {...props}\n >\n <div className=\"flex flex-col\">\n {data.map((section, sectionIndex) => (\n <div\n key={`${section.date}-${sectionIndex}`}\n className=\"flex flex-row items-start px-4 py-6 gap-2 w-full\"\n >\n <Text\n size=\"xs\"\n weight=\"bold\"\n className=\"text-text-800 w-11 shrink-0 pt-3\"\n >\n {section.date}\n </Text>\n\n <div className=\"flex flex-col gap-2 flex-1 min-w-0\">\n {section.essays.map((essay) => {\n const visual = resolveEssayVisualState(essay, maxScore);\n const isClickable = visual.clickable && !!onEssayClick;\n const label =\n essay.title ?? essay.fallbackTitle ?? 'Sem título';\n const reviewBadge = resolveReviewBadge(essay);\n\n return (\n <button\n key={essay.id}\n type=\"button\"\n disabled={!isClickable}\n onClick={() => isClickable && onEssayClick?.(essay)}\n aria-label={`${label} — ${visual.text}`}\n className={cn(\n visual.background,\n 'rounded-xl p-4 flex flex-row items-center justify-between gap-2 w-full transition-shadow duration-200',\n isClickable\n ? 'cursor-pointer hover:shadow-soft-shadow-2'\n : 'cursor-default'\n )}\n >\n <Text\n size=\"md\"\n weight=\"bold\"\n className=\"text-text-950 truncate text-left\"\n >\n {label}\n </Text>\n\n <div className=\"flex items-center gap-2 shrink-0\">\n {reviewBadge && (\n <Badge\n variant=\"solid\"\n action={reviewBadge.action}\n size=\"small\"\n >\n {reviewBadge.label}\n </Badge>\n )}\n <Text\n size=\"sm\"\n className=\"text-text-800 whitespace-nowrap\"\n >\n {visual.text}\n </Text>\n {isClickable && (\n <CaretRightIcon\n size={20}\n className=\"text-text-800 shrink-0\"\n />\n )}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n }\n);\n\n// ======================================================================\n// CardReadingFluency — card de atividade da variante Reading Fluency\n// ======================================================================\n\ntype CardReadingFluencyState = 'new' | 'coming-soon' | 'done';\n\ninterface CardReadingFluencyProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Estado do card:\n * - `new`: nova atividade (badge \"NOVA ATIVIDADE!\", clicável)\n * - `coming-soon`: em breve (opaco/desativado, borda tracejada, badge \"EM BREVE\")\n * - `done`: atividade concluída (check no canto, clicável)\n */\n state?: CardReadingFluencyState;\n /** Cor de fundo do card em hex (vinda do backend, igual aos subjects). */\n color?: string;\n /** Sobrescreve a imagem do passarinho (default: asset padrão do Reading Fluency). */\n image?: string;\n /** Texto alternativo/aria da imagem. */\n label?: string;\n /**\n * Legenda exibida abaixo do card (bold, xs, text-100). Omitida quando vazia.\n * Nome distinto de `title` para não colidir com o atributo HTML nativo\n * `title` (tooltip), que segue repassável via `...props`.\n */\n activityTitle?: string;\n}\n\n/**\n * Badge dos cards Reading Fluency. Dimensões e tipografia fixas da arte: 117×23,\n * radius 8px, px 8 / py 4, gap 8, texto Quicksand 700/12px. A cor de fundo\n * (preto com opacidade) varia por estado: 70% em \"nova atividade\", 30% em\n * \"em breve\".\n */\nconst PAPOLE_BADGE_CLASSES =\n 'flex items-center justify-center gap-2 w-[117px] h-[23px] rounded-lg px-2 py-1 text-[12px] font-bold text-white whitespace-nowrap';\n\nconst CardReadingFluency = forwardRef<HTMLDivElement, CardReadingFluencyProps>(\n (\n {\n state = 'new',\n // Scent color 2 (verde) do tema do aluno. Era o hex #a3d9b1 cravado, que\n // deixava o default do componente fora do tema.\n color = 'var(--color-scent-2)',\n image,\n label = 'Reading Fluency',\n activityTitle,\n className,\n onClick,\n onKeyDown,\n ...props\n },\n ref\n ) => {\n const isComingSoon = state === 'coming-soon';\n const isDone = state === 'done';\n const isInteractive = !isComingSoon;\n const isClickable = isInteractive && !!onClick;\n\n const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (isClickable && ['Enter', ' '].includes(e.key)) {\n e.preventDefault();\n (e.currentTarget as HTMLElement).click();\n }\n onKeyDown?.(e);\n };\n\n return (\n <div className=\"flex flex-col items-center gap-3\">\n <div\n ref={ref}\n className={cn(\n 'relative flex items-center justify-center w-[240px] h-[182px] rounded-2xl font-quicksand overflow-hidden',\n // Uma capa do banco preenche o card inteiro (full-bleed), então sem\n // padding. O asset padrão (passarinho) segue centralizado com respiro.\n image ? '' : 'px-[82px] py-[28px]',\n isClickable && 'cursor-pointer',\n isComingSoon &&\n 'pointer-events-none border-2 border-dashed border-border-300',\n className\n )}\n style={{ backgroundColor: color }}\n onClick={isInteractive ? onClick : undefined}\n onKeyDown={handleKeyDown}\n tabIndex={isClickable ? 0 : undefined}\n role={isClickable ? 'button' : undefined}\n aria-disabled={isComingSoon ? true : undefined}\n {...props}\n >\n <img\n src={image ?? readingFluencyBird}\n alt={label}\n draggable={false}\n className={cn(\n // Capa do banco de imagens: ocupa exatamente o tamanho do card\n // (240×182), recortando o excesso sem distorcer. O passarinho\n // padrão continua no tamanho original, centralizado.\n image\n ? 'absolute inset-0 w-full h-full object-cover select-none'\n : 'w-full h-auto select-none',\n isComingSoon && 'opacity-40'\n )}\n />\n\n {isDone && (\n <CheckCircleIcon\n weight=\"fill\"\n size={28}\n className=\"absolute top-3 right-3 text-background drop-shadow-sm\"\n data-testid=\"reading-fluency-check\"\n />\n )}\n\n {state === 'new' && (\n <span\n className={cn(\n 'absolute bottom-3 left-1/2 -translate-x-1/2 bg-black/70',\n PAPOLE_BADGE_CLASSES\n )}\n >\n NOVA ATIVIDADE!\n </span>\n )}\n\n {isComingSoon && (\n <span\n className={cn(\n 'absolute bottom-3 left-1/2 -translate-x-1/2 bg-black/30',\n PAPOLE_BADGE_CLASSES\n )}\n >\n EM BREVE\n </span>\n )}\n </div>\n\n {activityTitle && (\n <Text\n size=\"xs\"\n weight=\"bold\"\n color=\"text-text-100\"\n className=\"w-60 text-center font-quicksand uppercase\"\n >\n {activityTitle}\n </Text>\n )}\n </div>\n );\n }\n);\n\nexport {\n CardBase,\n CardActivitiesResults,\n CardQuestions,\n CardProgress,\n CardTopic,\n CardPerformance,\n CardResults,\n CardStatus,\n CardSettings,\n CardSupport,\n CardForum,\n CardAudio,\n CardSimulado,\n CardTest,\n CardSimulationHistory,\n CardEssayHistory,\n CardReadingFluency,\n};\n\nexport type { CardReadingFluencyProps, CardReadingFluencyState };\n"],"mappings":"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","names":["Fragment","status","EssayStatus","EssayReviewStatus"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-SB5YGKXR.js","../src/hooks/useScreen.ts","../src/hooks/useResizableColumns.ts","../src/store/layoutPreferencesStore.ts"],"names":["useState","useEffect"],"mappings":"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","file":"/home/runner/work/analytica-frontend-lib/analytica-frontend-lib/dist/chunk-SB5YGKXR.js","sourcesContent":[null,"import { useState, useEffect } from 'react';\nimport { DESKTOP_MIN_WIDTH } from './useResizableColumns';\n\ntype ScreenSize = {\n width: number;\n height: number;\n};\n\ntype UseScreenSizeOptions = {\n width?: boolean;\n height?: boolean;\n};\n\ntype UseScreenSizeReturn = {\n width?: number;\n height?: number;\n screenSize: ScreenSize;\n};\n\n// Mobile width in pixels\nconst MOBILE_WIDTH = 931;\n/**\n * Largest width that still gets the stacked layout on the creation screens.\n *\n * Derived from the three-column geometry instead of a number of its own: one\n * pixel above it the two side panels and the question bank all fit at their\n * minimum. It used to be a loose 1200, which let the desktop layout render in\n * a width where the bank was already below its floor.\n */\nconst SMALL_SCREEN_WIDTH = DESKTOP_MIN_WIDTH - 1;\n\n/**\n * Hook para capturar o tamanho da tela do usuário\n * @param options - Opções para escolher quais dimensões capturar\n * @returns Objeto com as dimensões solicitadas e o tamanho completo da tela\n */\nexport const useScreenSize = (\n options: UseScreenSizeOptions = {}\n): UseScreenSizeReturn => {\n const [screenSize, setScreenSize] = useState<ScreenSize>({\n width: window.innerWidth,\n height: window.innerHeight,\n });\n\n useEffect(() => {\n const handleResize = () => {\n setScreenSize({\n width: window.innerWidth,\n height: window.innerHeight,\n });\n };\n\n // Adicionar listener para mudanças de tamanho\n window.addEventListener('resize', handleResize);\n\n // Cleanup do listener\n return () => {\n window.removeEventListener('resize', handleResize);\n };\n }, []);\n\n // Retornar apenas as dimensões solicitadas\n const result: UseScreenSizeReturn = {\n screenSize,\n };\n\n if (options.width !== false) {\n result.width = screenSize.width;\n }\n\n if (options.height !== false) {\n result.height = screenSize.height;\n }\n\n return result;\n};\n\n/**\n * Hook para capturar apenas a largura da tela\n */\nexport const useScreenWidth = (): number => {\n const { width } = useScreenSize({ width: true, height: false });\n return width!;\n};\n\n/**\n * Hook para capturar apenas a altura da tela\n */\nexport const useScreenHeight = (): number => {\n const { height } = useScreenSize({ width: false, height: true });\n return height!;\n};\n\n/**\n * Hook para capturar o tamanho completo da tela\n */\nexport const useFullScreenSize = (): ScreenSize => {\n const { screenSize } = useScreenSize();\n return screenSize;\n};\n\n/**\n * Hook to detect screen size\n * @returns true if the screen is mobile, false otherwise\n */\nexport const useMobile = () => {\n const [isMobile, setIsMobile] = useState(false);\n\n useEffect(() => {\n const checkScreenSize = () => {\n setIsMobile(window.innerWidth < MOBILE_WIDTH);\n };\n\n checkScreenSize();\n\n window.addEventListener('resize', checkScreenSize);\n\n return () => window.removeEventListener('resize', checkScreenSize);\n }, []);\n\n return isMobile;\n};\n\n/**\n * Hook to detect the width below which the creation screens stack their\n * columns instead of showing the three resizable ones.\n *\n * Used by ActivityCreate and RecommendedLessonCreate components.\n *\n * @returns true when the three-column layout would not fit at its minimums\n */\nexport const useTabletScreen = () => {\n /*\n Resolved synchronously on the first render. Starting at `false` meant the\n first paint on a phone was always the desktop three-column layout, which\n then jumped to the narrow one as soon as the effect ran.\n */\n const [isSmallScreen, setIsSmallScreen] = useState(\n () => window.innerWidth <= SMALL_SCREEN_WIDTH\n );\n\n useEffect(() => {\n const checkScreenSize = () => {\n setIsSmallScreen(window.innerWidth <= SMALL_SCREEN_WIDTH);\n };\n\n checkScreenSize();\n\n window.addEventListener('resize', checkScreenSize);\n\n return () => window.removeEventListener('resize', checkScreenSize);\n }, []);\n\n return isSmallScreen;\n};\n","import {\n PointerEvent as ReactPointerEvent,\n KeyboardEvent as ReactKeyboardEvent,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport {\n LayoutPanel,\n LayoutScope,\n SIDE_PANEL_DEFAULT_WIDTH,\n usePanelWidthPreference,\n} from '../store/layoutPreferencesStore';\n\n/**\n * Largura mínima da coluna central (banco de questões/aulas) — o quanto os\n * divisores deixam de espaço antes de travar.\n *\n * O valor é ditado pelo conteúdo: abaixo disso o rótulo do botão \"Adicionar à\n * atividade\" do card de questão quebra em duas linhas, e o toolbar do banco\n * fica apertado demais para título e busca na mesma linha.\n *\n * Quem garante que esse mínimo é alcançável é `DESKTOP_MIN_WIDTH`: abaixo\n * dele as telas de criação trocam as três colunas pelo layout empilhado, em\n * vez de espremer o banco.\n */\nexport const BANK_MIN_WIDTH = 320;\n\n/** Ajuste por seta do teclado, em px. */\nexport const RESIZE_KEYBOARD_STEP = 16;\n\n/** Ajuste por seta com Shift, em px. */\nexport const RESIZE_KEYBOARD_STEP_LARGE = 48;\n\n/** `gap-5` entre os 5 filhos do flex row: 4 intervalos de 20px. */\nconst COLUMN_GAP = 20;\nconst GAP_COUNT = 4;\n\n/** Os dois divisores ocupam 1px cada. */\nconst DIVIDERS_WIDTH = 2;\n\n/** Espaço consumido pelo layout antes de sobrar largura para as colunas. */\nconst LAYOUT_OVERHEAD = COLUMN_GAP * GAP_COUNT + DIVIDERS_WIDTH;\n\n/**\n * Menor largura em que as três colunas cabem com todas no mínimo: as duas\n * laterais no padrão e o banco em `BANK_MIN_WIDTH`.\n *\n * É o limiar que `useTabletScreen` usa para escolher entre o layout de três\n * colunas e o empilhado. Derivar daqui, em vez de repetir um número solto,\n * é o que impede o caso de o layout desktop aparecer numa largura onde o\n * banco já nasceria abaixo do mínimo.\n */\nexport const DESKTOP_MIN_WIDTH =\n SIDE_PANEL_DEFAULT_WIDTH * 2 + BANK_MIN_WIDTH + LAYOUT_OVERHEAD;\n\n/**\n * Sentido em que cada coluna cresce: arrastar para a direita alarga os\n * filtros, arrastar para a esquerda alarga a prévia.\n */\nconst GROW_DIRECTION: Record<LayoutPanel, number> = {\n filters: 1,\n preview: -1,\n};\n\n/**\n * Maior largura que uma coluna lateral pode assumir sem empurrar o banco\n * abaixo de `BANK_MIN_WIDTH`.\n *\n * @param containerWidth - Largura medida do container das colunas\n * @param otherPanelWidth - Largura da outra coluna lateral\n * @returns Largura máxima; nunca menor que o padrão\n */\nexport const getMaxPanelWidth = (\n containerWidth: number,\n otherPanelWidth: number\n): number => {\n if (containerWidth <= 0) return SIDE_PANEL_DEFAULT_WIDTH;\n const budget =\n containerWidth - LAYOUT_OVERHEAD - BANK_MIN_WIDTH - otherPanelWidth;\n return Math.max(SIDE_PANEL_DEFAULT_WIDTH, Math.floor(budget));\n};\n\n/**\n * Mantém uma largura entre o padrão e o máximo que cabe na tela.\n *\n * @param width - Largura desejada\n * @param containerWidth - Largura medida do container\n * @param otherPanelWidth - Largura da outra coluna lateral\n * @returns Largura aplicável\n */\nexport const clampPanelToContainer = (\n width: number,\n containerWidth: number,\n otherPanelWidth: number\n): number => {\n const max = getMaxPanelWidth(containerWidth, otherPanelWidth);\n return Math.min(Math.max(width, SIDE_PANEL_DEFAULT_WIDTH), max);\n};\n\n/**\n * Resolve as larguras que serão realmente aplicadas.\n *\n * As duas laterais disputam o mesmo espaço, então não basta clampar uma de\n * cada vez. Quando a soma não cabe — janela encolhida, ou larguras salvas num\n * monitor maior — o excesso é devolvido proporcionalmente ao quanto cada\n * coluna está **acima** do padrão, e nenhuma desce abaixo dele.\n *\n * O resultado é derivado a cada render em vez de sobrescrever o valor salvo:\n * alargar a janela de volta restaura a largura que o usuário escolheu.\n *\n * @param containerWidth - Largura medida do container (0 se ainda não medido)\n * @param preferredFilters - Largura desejada da coluna de filtros\n * @param preferredPreview - Largura desejada da coluna de prévia\n * @returns Larguras aplicáveis das duas colunas\n */\nexport const resolveColumnWidths = (\n containerWidth: number,\n preferredFilters: number,\n preferredPreview: number\n): { filters: number; preview: number } => {\n const filters = Math.max(preferredFilters, SIDE_PANEL_DEFAULT_WIDTH);\n const preview = Math.max(preferredPreview, SIDE_PANEL_DEFAULT_WIDTH);\n\n // Antes da primeira medição não há como saber o que cabe.\n if (containerWidth <= 0) return { filters, preview };\n\n const budget = containerWidth - LAYOUT_OVERHEAD - BANK_MIN_WIDTH;\n const excess = filters + preview - budget;\n if (excess <= 0) return { filters, preview };\n\n const filtersSlack = filters - SIDE_PANEL_DEFAULT_WIDTH;\n const previewSlack = preview - SIDE_PANEL_DEFAULT_WIDTH;\n const totalSlack = filtersSlack + previewSlack;\n\n // Ambas já estão no mínimo: a tela é estreita demais e o banco cede. Encolher\n // mais deixaria as colunas menores que o conteúdo que elas precisam mostrar.\n if (totalSlack <= 0) return { filters, preview };\n\n const reduction = Math.min(excess, totalSlack);\n const filtersCut = Math.round((reduction * filtersSlack) / totalSlack);\n\n return {\n filters: filters - filtersCut,\n preview: preview - (reduction - filtersCut),\n };\n};\n\n/**\n * Traduz a tecla pressionada em variação de largura, no eixo horizontal.\n *\n * @param key - Tecla do evento\n * @param step - Passo em px\n * @returns Variação em px, ou `null` quando a tecla não redimensiona\n */\nconst getHorizontalKeyDelta = (key: string, step: number): number | null => {\n if (key === 'ArrowRight') return step;\n if (key === 'ArrowLeft') return -step;\n return null;\n};\n\n/** Props prontas para o `ResizableDivider` de uma coluna. */\nexport interface ResizableDividerHandlers {\n value: number;\n min: number;\n max: number;\n disabled: boolean;\n isDragging: boolean;\n onPointerDown: (event: ReactPointerEvent<HTMLElement>) => void;\n onPointerMove: (event: ReactPointerEvent<HTMLElement>) => void;\n onPointerUp: (event: ReactPointerEvent<HTMLElement>) => void;\n onKeyDown: (event: ReactKeyboardEvent<HTMLElement>) => void;\n onDoubleClick: () => void;\n}\n\nexport interface UseResizableColumnsResult {\n containerRef: (node: HTMLDivElement | null) => void;\n filtersWidth: number;\n previewWidth: number;\n filtersDividerProps: ResizableDividerHandlers;\n previewDividerProps: ResizableDividerHandlers;\n}\n\n/**\n * Controla as duas colunas laterais redimensionáveis das telas de criação.\n *\n * Um hook só para os dois divisores porque os limites são acoplados: o quanto\n * a prévia pode crescer depende de quanto os filtros já ocuparam.\n *\n * @param scope - Tela cujas larguras devem ser lidas e salvas\n * @returns Larguras aplicáveis e as props de cada divisor\n */\nexport const useResizableColumns = (\n scope: LayoutScope\n): UseResizableColumnsResult => {\n const { filtersWidth, previewWidth, setPanelWidth, resetPanelWidth } =\n usePanelWidthPreference(scope);\n\n const [containerWidth, setContainerWidth] = useState(0);\n const [draft, setDraft] = useState<{\n panel: LayoutPanel;\n width: number;\n } | null>(null);\n\n // `currentWidth` mora aqui, e não só no estado `draft`, para o `pointerup`\n // ler a última largura sem depender do render que o `pointermove` agendou.\n const dragRef = useRef<{\n panel: LayoutPanel;\n startX: number;\n startWidth: number;\n currentWidth: number;\n } | null>(null);\n\n const observerRef = useRef<ResizeObserver | null>(null);\n\n const containerRef = useCallback((node: HTMLDivElement | null) => {\n observerRef.current?.disconnect();\n observerRef.current = null;\n\n if (!node) {\n setContainerWidth(0);\n return;\n }\n\n setContainerWidth(node.getBoundingClientRect().width);\n\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => {\n setContainerWidth(node.getBoundingClientRect().width);\n });\n observer.observe(node);\n observerRef.current = observer;\n }, []);\n\n useEffect(() => () => observerRef.current?.disconnect(), []);\n\n const preferredFilters =\n draft?.panel === 'filters' ? draft.width : filtersWidth;\n const preferredPreview =\n draft?.panel === 'preview' ? draft.width : previewWidth;\n\n const resolved = resolveColumnWidths(\n containerWidth,\n preferredFilters,\n preferredPreview\n );\n\n // Lido dentro dos handlers de pointer, que não podem depender do valor\n // capturado no render em que o arraste começou.\n const geometryRef = useRef({ containerWidth, resolved });\n geometryRef.current = { containerWidth, resolved };\n\n const isDragging = draft !== null;\n\n useEffect(() => {\n if (!isDragging) return;\n\n // O cursor precisa valer para a janela inteira: durante o arraste o ponteiro\n // sai de cima do divisor e passaria a mostrar o cursor de texto ou de link.\n const { body } = document;\n const previousCursor = body.style.cursor;\n const previousUserSelect = body.style.userSelect;\n body.style.cursor = 'col-resize';\n body.style.userSelect = 'none';\n\n return () => {\n body.style.cursor = previousCursor;\n body.style.userSelect = previousUserSelect;\n };\n }, [isDragging]);\n\n const getOtherWidth = useCallback((panel: LayoutPanel): number => {\n const { resolved: current } = geometryRef.current;\n return panel === 'filters' ? current.preview : current.filters;\n }, []);\n\n const commitWidth = useCallback(\n (panel: LayoutPanel, width: number) => {\n const { containerWidth: measured } = geometryRef.current;\n setPanelWidth(\n scope,\n panel,\n clampPanelToContainer(width, measured, getOtherWidth(panel))\n );\n },\n [getOtherWidth, scope, setPanelWidth]\n );\n\n const handlePointerDown = useCallback(\n (panel: LayoutPanel) => (event: ReactPointerEvent<HTMLElement>) => {\n if (event.button !== 0) return;\n\n const { containerWidth: measured, resolved: current } =\n geometryRef.current;\n if (\n getMaxPanelWidth(measured, getOtherWidth(panel)) <=\n SIDE_PANEL_DEFAULT_WIDTH\n ) {\n return;\n }\n\n event.preventDefault();\n // Optional call: o jsdom não implementa a Pointer Capture API.\n event.currentTarget.setPointerCapture?.(event.pointerId);\n\n const startWidth =\n panel === 'filters' ? current.filters : current.preview;\n dragRef.current = {\n panel,\n startX: event.clientX,\n startWidth,\n currentWidth: startWidth,\n };\n setDraft({ panel, width: startWidth });\n },\n [getOtherWidth]\n );\n\n const handlePointerMove = useCallback(\n (event: ReactPointerEvent<HTMLElement>) => {\n const drag = dragRef.current;\n if (!drag) return;\n\n const delta = (event.clientX - drag.startX) * GROW_DIRECTION[drag.panel];\n const { containerWidth: measured } = geometryRef.current;\n\n // Clampar já aqui (e não só na renderização) evita o arraste \"morto\":\n // sem isso o rascunho acumularia 2000px fora do limite e o usuário teria\n // de desfazer todos eles antes da coluna voltar a se mexer.\n const width = clampPanelToContainer(\n drag.startWidth + delta,\n measured,\n getOtherWidth(drag.panel)\n );\n\n drag.currentWidth = width;\n setDraft({ panel: drag.panel, width });\n },\n [getOtherWidth]\n );\n\n const handlePointerUp = useCallback(\n (event: ReactPointerEvent<HTMLElement>) => {\n const drag = dragRef.current;\n if (!drag) return;\n\n event.currentTarget.releasePointerCapture?.(event.pointerId);\n dragRef.current = null;\n\n setDraft(null);\n // Escrito no storage só no fim do arraste, não a cada frame.\n commitWidth(drag.panel, drag.currentWidth);\n },\n [commitWidth]\n );\n\n const handleKeyDown = useCallback(\n (panel: LayoutPanel) => (event: ReactKeyboardEvent<HTMLElement>) => {\n const { containerWidth: measured, resolved: current } =\n geometryRef.current;\n const otherWidth = getOtherWidth(panel);\n const max = getMaxPanelWidth(measured, otherWidth);\n if (max <= SIDE_PANEL_DEFAULT_WIDTH) return;\n\n if (event.key === 'Home') {\n event.preventDefault();\n resetPanelWidth(scope, panel);\n return;\n }\n\n if (event.key === 'End') {\n event.preventDefault();\n setPanelWidth(scope, panel, max);\n return;\n }\n\n const step = event.shiftKey\n ? RESIZE_KEYBOARD_STEP_LARGE\n : RESIZE_KEYBOARD_STEP;\n const delta = getHorizontalKeyDelta(event.key, step);\n if (delta === null) return;\n\n event.preventDefault();\n const currentWidth =\n panel === 'filters' ? current.filters : current.preview;\n commitWidth(panel, currentWidth + delta * GROW_DIRECTION[panel]);\n },\n [commitWidth, getOtherWidth, resetPanelWidth, scope, setPanelWidth]\n );\n\n const buildDividerProps = (panel: LayoutPanel): ResizableDividerHandlers => {\n const value = panel === 'filters' ? resolved.filters : resolved.preview;\n const otherWidth =\n panel === 'filters' ? resolved.preview : resolved.filters;\n const max = getMaxPanelWidth(containerWidth, otherWidth);\n\n return {\n value,\n min: SIDE_PANEL_DEFAULT_WIDTH,\n max,\n disabled: max <= SIDE_PANEL_DEFAULT_WIDTH,\n isDragging: draft?.panel === panel,\n onPointerDown: handlePointerDown(panel),\n onPointerMove: handlePointerMove,\n onPointerUp: handlePointerUp,\n onKeyDown: handleKeyDown(panel),\n onDoubleClick: () => resetPanelWidth(scope, panel),\n };\n };\n\n return {\n containerRef,\n filtersWidth: resolved.filters,\n previewWidth: resolved.preview,\n filtersDividerProps: buildDividerProps('filters'),\n previewDividerProps: buildDividerProps('preview'),\n };\n};\n","import { create } from 'zustand';\nimport { createJSONStorage, persist } from 'zustand/middleware';\nimport { KEYS } from '../utils/keys';\n\n/**\n * Largura das colunas laterais (filtros e prévia) enquanto o usuário nunca\n * arrastou um divisor. É também a largura **mínima**: os divisores só permitem\n * alargar, e encolher devolve no máximo até este valor.\n */\nexport const SIDE_PANEL_DEFAULT_WIDTH = 400;\n\n/** Tela que possui o layout redimensionável. */\nexport type LayoutScope = 'activity' | 'lesson';\n\n/** Coluna lateral controlada por um divisor. */\nexport type LayoutPanel = 'filters' | 'preview';\n\n/** Largura de cada coluna lateral de uma tela. */\nexport interface PanelWidths {\n filters: number;\n preview: number;\n}\n\nexport interface LayoutPreferencesState {\n /** Larguras salvas por tela */\n widths: Record<LayoutScope, PanelWidths>;\n setPanelWidth: (\n scope: LayoutScope,\n panel: LayoutPanel,\n width: number\n ) => void;\n resetPanelWidth: (scope: LayoutScope, panel: LayoutPanel) => void;\n}\n\n/**\n * Mantém a largura acima do mínimo e descarta valores inválidos vindos de um\n * storage corrompido (`NaN`, negativo, string) — um `width` inválido no style\n * inline colapsaria a coluna.\n *\n * Não há teto aqui de propósito: o limite superior depende da largura da tela\n * em runtime e é aplicado por `useResizableColumns`, não pelo storage.\n *\n * @param value - Largura candidata\n * @returns Largura válida, nunca menor que `SIDE_PANEL_DEFAULT_WIDTH`\n */\nexport const clampPanelWidth = (value: unknown): number => {\n const width = Number(value);\n if (!Number.isFinite(width)) return SIDE_PANEL_DEFAULT_WIDTH;\n return Math.max(SIDE_PANEL_DEFAULT_WIDTH, Math.round(width));\n};\n\n/**\n * Larguras iniciais de todas as telas.\n *\n * @returns Mapa de larguras no valor padrão\n */\nconst createDefaultWidths = (): Record<LayoutScope, PanelWidths> => ({\n activity: {\n filters: SIDE_PANEL_DEFAULT_WIDTH,\n preview: SIDE_PANEL_DEFAULT_WIDTH,\n },\n lesson: {\n filters: SIDE_PANEL_DEFAULT_WIDTH,\n preview: SIDE_PANEL_DEFAULT_WIDTH,\n },\n});\n\n/**\n * Revalida as larguras de uma tela vindas do `localStorage`.\n *\n * @param persisted - Valor cru lido do storage\n * @returns Larguras válidas para a tela\n */\nconst mergeScopeWidths = (persisted: unknown): PanelWidths => {\n const saved = (persisted ?? {}) as Partial<Record<LayoutPanel, unknown>>;\n return {\n filters: clampPanelWidth(saved.filters),\n preview: clampPanelWidth(saved.preview),\n };\n};\n\n/**\n * Aplica uma largura a uma coluna sem mutar o restante do mapa.\n *\n * @param widths - Mapa atual\n * @param scope - Tela alvo\n * @param panel - Coluna alvo\n * @param width - Nova largura, já validada\n * @returns Novo mapa de larguras\n */\nconst withPanelWidth = (\n widths: Record<LayoutScope, PanelWidths>,\n scope: LayoutScope,\n panel: LayoutPanel,\n width: number\n): Record<LayoutScope, PanelWidths> => ({\n ...widths,\n [scope]: { ...widths[scope], [panel]: width },\n});\n\n/**\n * Store das larguras das colunas redimensionáveis das telas de criação.\n *\n * É uma preferência do aparelho (como o zoom do navegador), não da conta: a\n * largura que serve num monitor ultrawide não serve num notebook, então a\n * chave não é escopada por usuário e o valor nunca viaja junto do conteúdo\n * salvo. `activity` e `lesson` são independentes — o professor pode querer a\n * prévia larga ao montar uma atividade e estreita ao montar uma aula.\n */\nexport const useLayoutPreferencesStore = create<LayoutPreferencesState>()(\n persist(\n (set) => ({\n widths: createDefaultWidths(),\n\n /**\n * Salva a largura escolhida pelo usuário para uma coluna\n * @param scope - Tela alvo\n * @param panel - Coluna alvo\n * @param width - Largura em px\n * @returns {void}\n */\n setPanelWidth: (\n scope: LayoutScope,\n panel: LayoutPanel,\n width: number\n ): void => {\n set((state) => ({\n widths: withPanelWidth(\n state.widths,\n scope,\n panel,\n clampPanelWidth(width)\n ),\n }));\n },\n\n /**\n * Devolve uma coluna à largura padrão\n * @param scope - Tela alvo\n * @param panel - Coluna alvo\n * @returns {void}\n */\n resetPanelWidth: (scope: LayoutScope, panel: LayoutPanel): void => {\n set((state) => ({\n widths: withPanelWidth(\n state.widths,\n scope,\n panel,\n SIDE_PANEL_DEFAULT_WIDTH\n ),\n }));\n },\n }),\n {\n name: KEYS.LAYOUT_PREFERENCES_STORAGE,\n storage: createJSONStorage(() => localStorage),\n partialize: (state) => ({ widths: state.widths }),\n merge: (persisted, current) => {\n const saved = (persisted ?? {}) as Partial<LayoutPreferencesState>;\n const savedWidths = (saved.widths ?? {}) as Partial<\n Record<LayoutScope, unknown>\n >;\n return {\n ...current,\n widths: {\n activity: mergeScopeWidths(savedWidths.activity),\n lesson: mergeScopeWidths(savedWidths.lesson),\n },\n };\n },\n }\n )\n);\n\n/**\n * Lê as larguras de uma tela com seletores primitivos, evitando o re-render\n * extra que um seletor de objeto causaria a cada `set` do store.\n *\n * @param scope - Tela cujas larguras devem ser lidas\n * @returns Larguras salvas e os setters\n */\nexport const usePanelWidthPreference = (scope: LayoutScope) => {\n const filtersWidth = useLayoutPreferencesStore(\n (state) => state.widths[scope].filters\n );\n const previewWidth = useLayoutPreferencesStore(\n (state) => state.widths[scope].preview\n );\n const setPanelWidth = useLayoutPreferencesStore(\n (state) => state.setPanelWidth\n );\n const resetPanelWidth = useLayoutPreferencesStore(\n (state) => state.resetPanelWidth\n );\n\n return { filtersWidth, previewWidth, setPanelWidth, resetPanelWidth };\n};\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/useScreen.ts","../src/hooks/useResizableColumns.ts","../src/store/layoutPreferencesStore.ts"],"sourcesContent":["import { useState, useEffect } from 'react';\nimport { DESKTOP_MIN_WIDTH } from './useResizableColumns';\n\ntype ScreenSize = {\n width: number;\n height: number;\n};\n\ntype UseScreenSizeOptions = {\n width?: boolean;\n height?: boolean;\n};\n\ntype UseScreenSizeReturn = {\n width?: number;\n height?: number;\n screenSize: ScreenSize;\n};\n\n// Mobile width in pixels\nconst MOBILE_WIDTH = 931;\n/**\n * Largest width that still gets the stacked layout on the creation screens.\n *\n * Derived from the three-column geometry instead of a number of its own: one\n * pixel above it the two side panels and the question bank all fit at their\n * minimum. It used to be a loose 1200, which let the desktop layout render in\n * a width where the bank was already below its floor.\n */\nconst SMALL_SCREEN_WIDTH = DESKTOP_MIN_WIDTH - 1;\n\n/**\n * Hook para capturar o tamanho da tela do usuário\n * @param options - Opções para escolher quais dimensões capturar\n * @returns Objeto com as dimensões solicitadas e o tamanho completo da tela\n */\nexport const useScreenSize = (\n options: UseScreenSizeOptions = {}\n): UseScreenSizeReturn => {\n const [screenSize, setScreenSize] = useState<ScreenSize>({\n width: window.innerWidth,\n height: window.innerHeight,\n });\n\n useEffect(() => {\n const handleResize = () => {\n setScreenSize({\n width: window.innerWidth,\n height: window.innerHeight,\n });\n };\n\n // Adicionar listener para mudanças de tamanho\n window.addEventListener('resize', handleResize);\n\n // Cleanup do listener\n return () => {\n window.removeEventListener('resize', handleResize);\n };\n }, []);\n\n // Retornar apenas as dimensões solicitadas\n const result: UseScreenSizeReturn = {\n screenSize,\n };\n\n if (options.width !== false) {\n result.width = screenSize.width;\n }\n\n if (options.height !== false) {\n result.height = screenSize.height;\n }\n\n return result;\n};\n\n/**\n * Hook para capturar apenas a largura da tela\n */\nexport const useScreenWidth = (): number => {\n const { width } = useScreenSize({ width: true, height: false });\n return width!;\n};\n\n/**\n * Hook para capturar apenas a altura da tela\n */\nexport const useScreenHeight = (): number => {\n const { height } = useScreenSize({ width: false, height: true });\n return height!;\n};\n\n/**\n * Hook para capturar o tamanho completo da tela\n */\nexport const useFullScreenSize = (): ScreenSize => {\n const { screenSize } = useScreenSize();\n return screenSize;\n};\n\n/**\n * Hook to detect screen size\n * @returns true if the screen is mobile, false otherwise\n */\nexport const useMobile = () => {\n const [isMobile, setIsMobile] = useState(false);\n\n useEffect(() => {\n const checkScreenSize = () => {\n setIsMobile(window.innerWidth < MOBILE_WIDTH);\n };\n\n checkScreenSize();\n\n window.addEventListener('resize', checkScreenSize);\n\n return () => window.removeEventListener('resize', checkScreenSize);\n }, []);\n\n return isMobile;\n};\n\n/**\n * Hook to detect the width below which the creation screens stack their\n * columns instead of showing the three resizable ones.\n *\n * Used by ActivityCreate and RecommendedLessonCreate components.\n *\n * @returns true when the three-column layout would not fit at its minimums\n */\nexport const useTabletScreen = () => {\n /*\n Resolved synchronously on the first render. Starting at `false` meant the\n first paint on a phone was always the desktop three-column layout, which\n then jumped to the narrow one as soon as the effect ran.\n */\n const [isSmallScreen, setIsSmallScreen] = useState(\n () => window.innerWidth <= SMALL_SCREEN_WIDTH\n );\n\n useEffect(() => {\n const checkScreenSize = () => {\n setIsSmallScreen(window.innerWidth <= SMALL_SCREEN_WIDTH);\n };\n\n checkScreenSize();\n\n window.addEventListener('resize', checkScreenSize);\n\n return () => window.removeEventListener('resize', checkScreenSize);\n }, []);\n\n return isSmallScreen;\n};\n","import {\n PointerEvent as ReactPointerEvent,\n KeyboardEvent as ReactKeyboardEvent,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport {\n LayoutPanel,\n LayoutScope,\n SIDE_PANEL_DEFAULT_WIDTH,\n usePanelWidthPreference,\n} from '../store/layoutPreferencesStore';\n\n/**\n * Largura mínima da coluna central (banco de questões/aulas) — o quanto os\n * divisores deixam de espaço antes de travar.\n *\n * O valor é ditado pelo conteúdo: abaixo disso o rótulo do botão \"Adicionar à\n * atividade\" do card de questão quebra em duas linhas, e o toolbar do banco\n * fica apertado demais para título e busca na mesma linha.\n *\n * Quem garante que esse mínimo é alcançável é `DESKTOP_MIN_WIDTH`: abaixo\n * dele as telas de criação trocam as três colunas pelo layout empilhado, em\n * vez de espremer o banco.\n */\nexport const BANK_MIN_WIDTH = 320;\n\n/** Ajuste por seta do teclado, em px. */\nexport const RESIZE_KEYBOARD_STEP = 16;\n\n/** Ajuste por seta com Shift, em px. */\nexport const RESIZE_KEYBOARD_STEP_LARGE = 48;\n\n/** `gap-5` entre os 5 filhos do flex row: 4 intervalos de 20px. */\nconst COLUMN_GAP = 20;\nconst GAP_COUNT = 4;\n\n/** Os dois divisores ocupam 1px cada. */\nconst DIVIDERS_WIDTH = 2;\n\n/** Espaço consumido pelo layout antes de sobrar largura para as colunas. */\nconst LAYOUT_OVERHEAD = COLUMN_GAP * GAP_COUNT + DIVIDERS_WIDTH;\n\n/**\n * Menor largura em que as três colunas cabem com todas no mínimo: as duas\n * laterais no padrão e o banco em `BANK_MIN_WIDTH`.\n *\n * É o limiar que `useTabletScreen` usa para escolher entre o layout de três\n * colunas e o empilhado. Derivar daqui, em vez de repetir um número solto,\n * é o que impede o caso de o layout desktop aparecer numa largura onde o\n * banco já nasceria abaixo do mínimo.\n */\nexport const DESKTOP_MIN_WIDTH =\n SIDE_PANEL_DEFAULT_WIDTH * 2 + BANK_MIN_WIDTH + LAYOUT_OVERHEAD;\n\n/**\n * Sentido em que cada coluna cresce: arrastar para a direita alarga os\n * filtros, arrastar para a esquerda alarga a prévia.\n */\nconst GROW_DIRECTION: Record<LayoutPanel, number> = {\n filters: 1,\n preview: -1,\n};\n\n/**\n * Maior largura que uma coluna lateral pode assumir sem empurrar o banco\n * abaixo de `BANK_MIN_WIDTH`.\n *\n * @param containerWidth - Largura medida do container das colunas\n * @param otherPanelWidth - Largura da outra coluna lateral\n * @returns Largura máxima; nunca menor que o padrão\n */\nexport const getMaxPanelWidth = (\n containerWidth: number,\n otherPanelWidth: number\n): number => {\n if (containerWidth <= 0) return SIDE_PANEL_DEFAULT_WIDTH;\n const budget =\n containerWidth - LAYOUT_OVERHEAD - BANK_MIN_WIDTH - otherPanelWidth;\n return Math.max(SIDE_PANEL_DEFAULT_WIDTH, Math.floor(budget));\n};\n\n/**\n * Mantém uma largura entre o padrão e o máximo que cabe na tela.\n *\n * @param width - Largura desejada\n * @param containerWidth - Largura medida do container\n * @param otherPanelWidth - Largura da outra coluna lateral\n * @returns Largura aplicável\n */\nexport const clampPanelToContainer = (\n width: number,\n containerWidth: number,\n otherPanelWidth: number\n): number => {\n const max = getMaxPanelWidth(containerWidth, otherPanelWidth);\n return Math.min(Math.max(width, SIDE_PANEL_DEFAULT_WIDTH), max);\n};\n\n/**\n * Resolve as larguras que serão realmente aplicadas.\n *\n * As duas laterais disputam o mesmo espaço, então não basta clampar uma de\n * cada vez. Quando a soma não cabe — janela encolhida, ou larguras salvas num\n * monitor maior — o excesso é devolvido proporcionalmente ao quanto cada\n * coluna está **acima** do padrão, e nenhuma desce abaixo dele.\n *\n * O resultado é derivado a cada render em vez de sobrescrever o valor salvo:\n * alargar a janela de volta restaura a largura que o usuário escolheu.\n *\n * @param containerWidth - Largura medida do container (0 se ainda não medido)\n * @param preferredFilters - Largura desejada da coluna de filtros\n * @param preferredPreview - Largura desejada da coluna de prévia\n * @returns Larguras aplicáveis das duas colunas\n */\nexport const resolveColumnWidths = (\n containerWidth: number,\n preferredFilters: number,\n preferredPreview: number\n): { filters: number; preview: number } => {\n const filters = Math.max(preferredFilters, SIDE_PANEL_DEFAULT_WIDTH);\n const preview = Math.max(preferredPreview, SIDE_PANEL_DEFAULT_WIDTH);\n\n // Antes da primeira medição não há como saber o que cabe.\n if (containerWidth <= 0) return { filters, preview };\n\n const budget = containerWidth - LAYOUT_OVERHEAD - BANK_MIN_WIDTH;\n const excess = filters + preview - budget;\n if (excess <= 0) return { filters, preview };\n\n const filtersSlack = filters - SIDE_PANEL_DEFAULT_WIDTH;\n const previewSlack = preview - SIDE_PANEL_DEFAULT_WIDTH;\n const totalSlack = filtersSlack + previewSlack;\n\n // Ambas já estão no mínimo: a tela é estreita demais e o banco cede. Encolher\n // mais deixaria as colunas menores que o conteúdo que elas precisam mostrar.\n if (totalSlack <= 0) return { filters, preview };\n\n const reduction = Math.min(excess, totalSlack);\n const filtersCut = Math.round((reduction * filtersSlack) / totalSlack);\n\n return {\n filters: filters - filtersCut,\n preview: preview - (reduction - filtersCut),\n };\n};\n\n/**\n * Traduz a tecla pressionada em variação de largura, no eixo horizontal.\n *\n * @param key - Tecla do evento\n * @param step - Passo em px\n * @returns Variação em px, ou `null` quando a tecla não redimensiona\n */\nconst getHorizontalKeyDelta = (key: string, step: number): number | null => {\n if (key === 'ArrowRight') return step;\n if (key === 'ArrowLeft') return -step;\n return null;\n};\n\n/** Props prontas para o `ResizableDivider` de uma coluna. */\nexport interface ResizableDividerHandlers {\n value: number;\n min: number;\n max: number;\n disabled: boolean;\n isDragging: boolean;\n onPointerDown: (event: ReactPointerEvent<HTMLElement>) => void;\n onPointerMove: (event: ReactPointerEvent<HTMLElement>) => void;\n onPointerUp: (event: ReactPointerEvent<HTMLElement>) => void;\n onKeyDown: (event: ReactKeyboardEvent<HTMLElement>) => void;\n onDoubleClick: () => void;\n}\n\nexport interface UseResizableColumnsResult {\n containerRef: (node: HTMLDivElement | null) => void;\n filtersWidth: number;\n previewWidth: number;\n filtersDividerProps: ResizableDividerHandlers;\n previewDividerProps: ResizableDividerHandlers;\n}\n\n/**\n * Controla as duas colunas laterais redimensionáveis das telas de criação.\n *\n * Um hook só para os dois divisores porque os limites são acoplados: o quanto\n * a prévia pode crescer depende de quanto os filtros já ocuparam.\n *\n * @param scope - Tela cujas larguras devem ser lidas e salvas\n * @returns Larguras aplicáveis e as props de cada divisor\n */\nexport const useResizableColumns = (\n scope: LayoutScope\n): UseResizableColumnsResult => {\n const { filtersWidth, previewWidth, setPanelWidth, resetPanelWidth } =\n usePanelWidthPreference(scope);\n\n const [containerWidth, setContainerWidth] = useState(0);\n const [draft, setDraft] = useState<{\n panel: LayoutPanel;\n width: number;\n } | null>(null);\n\n // `currentWidth` mora aqui, e não só no estado `draft`, para o `pointerup`\n // ler a última largura sem depender do render que o `pointermove` agendou.\n const dragRef = useRef<{\n panel: LayoutPanel;\n startX: number;\n startWidth: number;\n currentWidth: number;\n } | null>(null);\n\n const observerRef = useRef<ResizeObserver | null>(null);\n\n const containerRef = useCallback((node: HTMLDivElement | null) => {\n observerRef.current?.disconnect();\n observerRef.current = null;\n\n if (!node) {\n setContainerWidth(0);\n return;\n }\n\n setContainerWidth(node.getBoundingClientRect().width);\n\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => {\n setContainerWidth(node.getBoundingClientRect().width);\n });\n observer.observe(node);\n observerRef.current = observer;\n }, []);\n\n useEffect(() => () => observerRef.current?.disconnect(), []);\n\n const preferredFilters =\n draft?.panel === 'filters' ? draft.width : filtersWidth;\n const preferredPreview =\n draft?.panel === 'preview' ? draft.width : previewWidth;\n\n const resolved = resolveColumnWidths(\n containerWidth,\n preferredFilters,\n preferredPreview\n );\n\n // Lido dentro dos handlers de pointer, que não podem depender do valor\n // capturado no render em que o arraste começou.\n const geometryRef = useRef({ containerWidth, resolved });\n geometryRef.current = { containerWidth, resolved };\n\n const isDragging = draft !== null;\n\n useEffect(() => {\n if (!isDragging) return;\n\n // O cursor precisa valer para a janela inteira: durante o arraste o ponteiro\n // sai de cima do divisor e passaria a mostrar o cursor de texto ou de link.\n const { body } = document;\n const previousCursor = body.style.cursor;\n const previousUserSelect = body.style.userSelect;\n body.style.cursor = 'col-resize';\n body.style.userSelect = 'none';\n\n return () => {\n body.style.cursor = previousCursor;\n body.style.userSelect = previousUserSelect;\n };\n }, [isDragging]);\n\n const getOtherWidth = useCallback((panel: LayoutPanel): number => {\n const { resolved: current } = geometryRef.current;\n return panel === 'filters' ? current.preview : current.filters;\n }, []);\n\n const commitWidth = useCallback(\n (panel: LayoutPanel, width: number) => {\n const { containerWidth: measured } = geometryRef.current;\n setPanelWidth(\n scope,\n panel,\n clampPanelToContainer(width, measured, getOtherWidth(panel))\n );\n },\n [getOtherWidth, scope, setPanelWidth]\n );\n\n const handlePointerDown = useCallback(\n (panel: LayoutPanel) => (event: ReactPointerEvent<HTMLElement>) => {\n if (event.button !== 0) return;\n\n const { containerWidth: measured, resolved: current } =\n geometryRef.current;\n if (\n getMaxPanelWidth(measured, getOtherWidth(panel)) <=\n SIDE_PANEL_DEFAULT_WIDTH\n ) {\n return;\n }\n\n event.preventDefault();\n // Optional call: o jsdom não implementa a Pointer Capture API.\n event.currentTarget.setPointerCapture?.(event.pointerId);\n\n const startWidth =\n panel === 'filters' ? current.filters : current.preview;\n dragRef.current = {\n panel,\n startX: event.clientX,\n startWidth,\n currentWidth: startWidth,\n };\n setDraft({ panel, width: startWidth });\n },\n [getOtherWidth]\n );\n\n const handlePointerMove = useCallback(\n (event: ReactPointerEvent<HTMLElement>) => {\n const drag = dragRef.current;\n if (!drag) return;\n\n const delta = (event.clientX - drag.startX) * GROW_DIRECTION[drag.panel];\n const { containerWidth: measured } = geometryRef.current;\n\n // Clampar já aqui (e não só na renderização) evita o arraste \"morto\":\n // sem isso o rascunho acumularia 2000px fora do limite e o usuário teria\n // de desfazer todos eles antes da coluna voltar a se mexer.\n const width = clampPanelToContainer(\n drag.startWidth + delta,\n measured,\n getOtherWidth(drag.panel)\n );\n\n drag.currentWidth = width;\n setDraft({ panel: drag.panel, width });\n },\n [getOtherWidth]\n );\n\n const handlePointerUp = useCallback(\n (event: ReactPointerEvent<HTMLElement>) => {\n const drag = dragRef.current;\n if (!drag) return;\n\n event.currentTarget.releasePointerCapture?.(event.pointerId);\n dragRef.current = null;\n\n setDraft(null);\n // Escrito no storage só no fim do arraste, não a cada frame.\n commitWidth(drag.panel, drag.currentWidth);\n },\n [commitWidth]\n );\n\n const handleKeyDown = useCallback(\n (panel: LayoutPanel) => (event: ReactKeyboardEvent<HTMLElement>) => {\n const { containerWidth: measured, resolved: current } =\n geometryRef.current;\n const otherWidth = getOtherWidth(panel);\n const max = getMaxPanelWidth(measured, otherWidth);\n if (max <= SIDE_PANEL_DEFAULT_WIDTH) return;\n\n if (event.key === 'Home') {\n event.preventDefault();\n resetPanelWidth(scope, panel);\n return;\n }\n\n if (event.key === 'End') {\n event.preventDefault();\n setPanelWidth(scope, panel, max);\n return;\n }\n\n const step = event.shiftKey\n ? RESIZE_KEYBOARD_STEP_LARGE\n : RESIZE_KEYBOARD_STEP;\n const delta = getHorizontalKeyDelta(event.key, step);\n if (delta === null) return;\n\n event.preventDefault();\n const currentWidth =\n panel === 'filters' ? current.filters : current.preview;\n commitWidth(panel, currentWidth + delta * GROW_DIRECTION[panel]);\n },\n [commitWidth, getOtherWidth, resetPanelWidth, scope, setPanelWidth]\n );\n\n const buildDividerProps = (panel: LayoutPanel): ResizableDividerHandlers => {\n const value = panel === 'filters' ? resolved.filters : resolved.preview;\n const otherWidth =\n panel === 'filters' ? resolved.preview : resolved.filters;\n const max = getMaxPanelWidth(containerWidth, otherWidth);\n\n return {\n value,\n min: SIDE_PANEL_DEFAULT_WIDTH,\n max,\n disabled: max <= SIDE_PANEL_DEFAULT_WIDTH,\n isDragging: draft?.panel === panel,\n onPointerDown: handlePointerDown(panel),\n onPointerMove: handlePointerMove,\n onPointerUp: handlePointerUp,\n onKeyDown: handleKeyDown(panel),\n onDoubleClick: () => resetPanelWidth(scope, panel),\n };\n };\n\n return {\n containerRef,\n filtersWidth: resolved.filters,\n previewWidth: resolved.preview,\n filtersDividerProps: buildDividerProps('filters'),\n previewDividerProps: buildDividerProps('preview'),\n };\n};\n","import { create } from 'zustand';\nimport { createJSONStorage, persist } from 'zustand/middleware';\nimport { KEYS } from '../utils/keys';\n\n/**\n * Largura das colunas laterais (filtros e prévia) enquanto o usuário nunca\n * arrastou um divisor. É também a largura **mínima**: os divisores só permitem\n * alargar, e encolher devolve no máximo até este valor.\n */\nexport const SIDE_PANEL_DEFAULT_WIDTH = 400;\n\n/** Tela que possui o layout redimensionável. */\nexport type LayoutScope = 'activity' | 'lesson';\n\n/** Coluna lateral controlada por um divisor. */\nexport type LayoutPanel = 'filters' | 'preview';\n\n/** Largura de cada coluna lateral de uma tela. */\nexport interface PanelWidths {\n filters: number;\n preview: number;\n}\n\nexport interface LayoutPreferencesState {\n /** Larguras salvas por tela */\n widths: Record<LayoutScope, PanelWidths>;\n setPanelWidth: (\n scope: LayoutScope,\n panel: LayoutPanel,\n width: number\n ) => void;\n resetPanelWidth: (scope: LayoutScope, panel: LayoutPanel) => void;\n}\n\n/**\n * Mantém a largura acima do mínimo e descarta valores inválidos vindos de um\n * storage corrompido (`NaN`, negativo, string) — um `width` inválido no style\n * inline colapsaria a coluna.\n *\n * Não há teto aqui de propósito: o limite superior depende da largura da tela\n * em runtime e é aplicado por `useResizableColumns`, não pelo storage.\n *\n * @param value - Largura candidata\n * @returns Largura válida, nunca menor que `SIDE_PANEL_DEFAULT_WIDTH`\n */\nexport const clampPanelWidth = (value: unknown): number => {\n const width = Number(value);\n if (!Number.isFinite(width)) return SIDE_PANEL_DEFAULT_WIDTH;\n return Math.max(SIDE_PANEL_DEFAULT_WIDTH, Math.round(width));\n};\n\n/**\n * Larguras iniciais de todas as telas.\n *\n * @returns Mapa de larguras no valor padrão\n */\nconst createDefaultWidths = (): Record<LayoutScope, PanelWidths> => ({\n activity: {\n filters: SIDE_PANEL_DEFAULT_WIDTH,\n preview: SIDE_PANEL_DEFAULT_WIDTH,\n },\n lesson: {\n filters: SIDE_PANEL_DEFAULT_WIDTH,\n preview: SIDE_PANEL_DEFAULT_WIDTH,\n },\n});\n\n/**\n * Revalida as larguras de uma tela vindas do `localStorage`.\n *\n * @param persisted - Valor cru lido do storage\n * @returns Larguras válidas para a tela\n */\nconst mergeScopeWidths = (persisted: unknown): PanelWidths => {\n const saved = (persisted ?? {}) as Partial<Record<LayoutPanel, unknown>>;\n return {\n filters: clampPanelWidth(saved.filters),\n preview: clampPanelWidth(saved.preview),\n };\n};\n\n/**\n * Aplica uma largura a uma coluna sem mutar o restante do mapa.\n *\n * @param widths - Mapa atual\n * @param scope - Tela alvo\n * @param panel - Coluna alvo\n * @param width - Nova largura, já validada\n * @returns Novo mapa de larguras\n */\nconst withPanelWidth = (\n widths: Record<LayoutScope, PanelWidths>,\n scope: LayoutScope,\n panel: LayoutPanel,\n width: number\n): Record<LayoutScope, PanelWidths> => ({\n ...widths,\n [scope]: { ...widths[scope], [panel]: width },\n});\n\n/**\n * Store das larguras das colunas redimensionáveis das telas de criação.\n *\n * É uma preferência do aparelho (como o zoom do navegador), não da conta: a\n * largura que serve num monitor ultrawide não serve num notebook, então a\n * chave não é escopada por usuário e o valor nunca viaja junto do conteúdo\n * salvo. `activity` e `lesson` são independentes — o professor pode querer a\n * prévia larga ao montar uma atividade e estreita ao montar uma aula.\n */\nexport const useLayoutPreferencesStore = create<LayoutPreferencesState>()(\n persist(\n (set) => ({\n widths: createDefaultWidths(),\n\n /**\n * Salva a largura escolhida pelo usuário para uma coluna\n * @param scope - Tela alvo\n * @param panel - Coluna alvo\n * @param width - Largura em px\n * @returns {void}\n */\n setPanelWidth: (\n scope: LayoutScope,\n panel: LayoutPanel,\n width: number\n ): void => {\n set((state) => ({\n widths: withPanelWidth(\n state.widths,\n scope,\n panel,\n clampPanelWidth(width)\n ),\n }));\n },\n\n /**\n * Devolve uma coluna à largura padrão\n * @param scope - Tela alvo\n * @param panel - Coluna alvo\n * @returns {void}\n */\n resetPanelWidth: (scope: LayoutScope, panel: LayoutPanel): void => {\n set((state) => ({\n widths: withPanelWidth(\n state.widths,\n scope,\n panel,\n SIDE_PANEL_DEFAULT_WIDTH\n ),\n }));\n },\n }),\n {\n name: KEYS.LAYOUT_PREFERENCES_STORAGE,\n storage: createJSONStorage(() => localStorage),\n partialize: (state) => ({ widths: state.widths }),\n merge: (persisted, current) => {\n const saved = (persisted ?? {}) as Partial<LayoutPreferencesState>;\n const savedWidths = (saved.widths ?? {}) as Partial<\n Record<LayoutScope, unknown>\n >;\n return {\n ...current,\n widths: {\n activity: mergeScopeWidths(savedWidths.activity),\n lesson: mergeScopeWidths(savedWidths.lesson),\n },\n };\n },\n }\n )\n);\n\n/**\n * Lê as larguras de uma tela com seletores primitivos, evitando o re-render\n * extra que um seletor de objeto causaria a cada `set` do store.\n *\n * @param scope - Tela cujas larguras devem ser lidas\n * @returns Larguras salvas e os setters\n */\nexport const usePanelWidthPreference = (scope: LayoutScope) => {\n const filtersWidth = useLayoutPreferencesStore(\n (state) => state.widths[scope].filters\n );\n const previewWidth = useLayoutPreferencesStore(\n (state) => state.widths[scope].preview\n );\n const setPanelWidth = useLayoutPreferencesStore(\n (state) => state.setPanelWidth\n );\n const resetPanelWidth = useLayoutPreferencesStore(\n (state) => state.resetPanelWidth\n );\n\n return { filtersWidth, previewWidth, setPanelWidth, resetPanelWidth };\n};\n"],"mappings":"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","names":["useState","useEffect","useState","useEffect"]}
|