xertica-ui 2.2.1 → 2.4.0
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/CHANGELOG.md +564 -525
- package/README.md +417 -382
- package/bin/cli.ts +1244 -748
- package/bin/generate-tokens.ts +262 -262
- package/bin/language-config.ts +5 -8
- package/components/assets/xertica-orbe-animation.ts +1162 -1162
- package/components/assistant/code-block/CodeBlock.tsx +268 -268
- package/components/assistant/code-block/code-block.stories.tsx +57 -57
- package/components/assistant/code-block/code-block.test.tsx +44 -44
- package/components/assistant/code-block/index.ts +1 -1
- package/components/assistant/formatted-document/FormattedDocument.tsx +147 -147
- package/components/assistant/formatted-document/formatted-document.stories.tsx +51 -51
- package/components/assistant/formatted-document/formatted-document.test.tsx +42 -42
- package/components/assistant/formatted-document/index.ts +1 -1
- package/components/assistant/index.ts +6 -6
- package/components/assistant/markdown-message/MarkdownMessage.tsx +152 -152
- package/components/assistant/markdown-message/index.ts +1 -1
- package/components/assistant/markdown-message/markdown-message.stories.tsx +50 -50
- package/components/assistant/markdown-message/markdown-message.test.tsx +33 -33
- package/components/assistant/modern-chat-input/ModernChatInput.tsx +17 -7
- package/components/assistant/modern-chat-input/index.ts +1 -1
- package/components/assistant/modern-chat-input/modern-chat-input.stories.tsx +131 -131
- package/components/assistant/modern-chat-input/modern-chat-input.test.tsx +79 -79
- package/components/assistant/xertica-assistant/index.ts +3 -3
- package/components/assistant/xertica-assistant/parts/AssistantCollapsedView.tsx +99 -99
- package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +104 -106
- package/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.tsx +81 -81
- package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +88 -78
- package/components/assistant/xertica-assistant/parts/AssistantHeader.tsx +75 -75
- package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +564 -560
- package/components/assistant/xertica-assistant/parts/AssistantTabBar.tsx +67 -67
- package/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.tsx +41 -41
- package/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.tsx +103 -103
- package/components/assistant/xertica-assistant/parts/index.ts +16 -16
- package/components/assistant/xertica-assistant/types.ts +134 -134
- package/components/assistant/xertica-assistant/use-assistant.ts +615 -615
- package/components/assistant/xertica-assistant/xertica-assistant.stories.tsx +407 -407
- package/components/assistant/xertica-assistant/xertica-assistant.test.tsx +65 -65
- package/components/assistant/xertica-assistant/xertica-assistant.tsx +611 -613
- package/components/blocks/card-patterns/ActivityCard.tsx +100 -100
- package/components/blocks/card-patterns/FeatureCard.tsx +109 -109
- package/components/blocks/card-patterns/FeatureCardSkeleton.tsx +1 -6
- package/components/blocks/card-patterns/NotificationCard.tsx +140 -140
- package/components/blocks/card-patterns/ProfileCard.tsx +112 -114
- package/components/blocks/card-patterns/ProjectCard.tsx +123 -123
- package/components/blocks/card-patterns/ProjectCardSkeleton.tsx +1 -6
- package/components/blocks/card-patterns/QuickActionCard.tsx +68 -68
- package/components/blocks/card-patterns/card-patterns.mdx +123 -123
- package/components/blocks/card-patterns/card-patterns.stories.tsx +594 -594
- package/components/blocks/card-patterns/index.ts +29 -29
- package/components/blocks/index.ts +1 -1
- package/components/brand/branding/branding.stories.tsx +57 -57
- package/components/brand/index.ts +6 -6
- package/components/brand/language-selector/index.ts +1 -1
- package/components/brand/language-selector/language-selector.mdx +126 -126
- package/components/brand/language-selector/language-selector.stories.tsx +1 -4
- package/components/brand/theme-toggle/ThemeToggle.tsx +74 -70
- package/components/brand/theme-toggle/index.ts +1 -1
- package/components/brand/theme-toggle/theme-toggle.stories.tsx +34 -34
- package/components/brand/theme-toggle/theme-toggle.test.tsx +34 -34
- package/components/brand/xertica-logo/XerticaLogo.stories.tsx +82 -82
- package/components/brand/xertica-logo/XerticaLogo.tsx +104 -104
- package/components/brand/xertica-logo/index.ts +1 -1
- package/components/brand/xertica-logo/xertica-logo.test.tsx +26 -26
- package/components/brand/xertica-orbe/XerticaOrbe.tsx +1927 -1927
- package/components/brand/xertica-orbe/index.ts +1 -1
- package/components/brand/xertica-orbe/xertica-orbe.stories.tsx +40 -40
- package/components/brand/xertica-orbe/xertica-orbe.test.tsx +19 -19
- package/components/brand/xertica-provider/XerticaProvider.tsx +1 -4
- package/components/brand/xertica-provider/index.ts +1 -1
- package/components/brand/xertica-provider/xertica-provider.test.tsx +74 -74
- package/components/brand/xertica-xlogo/XerticaXLogo.stories.tsx +79 -79
- package/components/brand/xertica-xlogo/XerticaXLogo.tsx +65 -65
- package/components/brand/xertica-xlogo/index.ts +1 -1
- package/components/brand/xertica-xlogo/xertica-xlogo.test.tsx +16 -16
- package/components/examples/ApiKeyMapExample.tsx +71 -71
- package/components/examples/DrawingMapExample.tsx +565 -565
- package/components/examples/FilterableMapExample.tsx +393 -393
- package/components/examples/LocationPickerExample.tsx +348 -348
- package/components/examples/MapExamples.tsx +268 -268
- package/components/examples/MapGmpExample.tsx +169 -169
- package/components/examples/MapShowcase.tsx +471 -471
- package/components/examples/RouteMapExamples.tsx +329 -329
- package/components/examples/SidebarLogoExample.tsx +65 -65
- package/components/examples/SimpleFilterableMap.tsx +219 -219
- package/components/examples/index.ts +45 -45
- package/components/figma/ImageWithFallback.tsx +27 -27
- package/components/hooks/index.ts +13 -13
- package/components/hooks/use-layout-shortcuts.ts +43 -43
- package/components/index.ts +86 -90
- package/components/layout/header/header.stories.tsx +204 -204
- package/components/layout/header/header.test.tsx +75 -75
- package/components/layout/header/header.tsx +349 -349
- package/components/layout/header/index.ts +1 -1
- package/components/layout/index.ts +2 -2
- package/components/layout/sidebar/index.ts +3 -3
- package/components/layout/sidebar/sidebar.stories.tsx +586 -586
- package/components/layout/sidebar/sidebar.test.tsx +76 -76
- package/components/layout/sidebar/sidebar.tsx +1079 -1073
- package/components/layout/sidebar/use-sidebar.ts +104 -104
- package/components/media/FloatingMediaWrapper.tsx +371 -371
- package/components/media/audio-player/AudioPlayer.stories.tsx +124 -124
- package/components/media/audio-player/AudioPlayer.test.tsx +106 -106
- package/components/media/audio-player/AudioPlayer.tsx +767 -765
- package/components/media/audio-player/index.ts +1 -1
- package/components/media/audio-player/use-audio-player.ts +312 -312
- package/components/media/index.ts +3 -3
- package/components/media/video-player/VideoPlayer.stories.tsx +98 -98
- package/components/media/video-player/VideoPlayer.test.tsx +73 -73
- package/components/media/video-player/VideoPlayer.tsx +310 -310
- package/components/media/video-player/index.ts +1 -1
- package/components/pages/forgot-password-page/ForgotPasswordPage.stories.tsx +24 -24
- package/components/pages/forgot-password-page/ForgotPasswordPage.tsx +188 -188
- package/components/pages/forgot-password-page/forgot-password-page.test.tsx +45 -45
- package/components/pages/forgot-password-page/index.ts +1 -1
- package/components/pages/home-content/HomeContent.stories.tsx +43 -43
- package/components/pages/home-content/HomeContent.tsx +120 -120
- package/components/pages/home-content/index.ts +1 -1
- package/components/pages/home-page/HomePage.stories.tsx +39 -39
- package/components/pages/home-page/HomePage.tsx +78 -74
- package/components/pages/home-page/home-page.test.tsx +53 -53
- package/components/pages/home-page/index.ts +1 -1
- package/components/pages/index.ts +8 -8
- package/components/pages/login-page/LoginPage.stories.tsx +39 -39
- package/components/pages/login-page/LoginPage.tsx +218 -216
- package/components/pages/login-page/index.ts +1 -1
- package/components/pages/login-page/login-page.test.tsx +63 -63
- package/components/pages/reset-password-page/ResetPasswordPage.stories.tsx +24 -24
- package/components/pages/reset-password-page/ResetPasswordPage.tsx +243 -239
- package/components/pages/reset-password-page/index.ts +1 -1
- package/components/pages/template-content/TemplateContent.stories.tsx +43 -43
- package/components/pages/template-content/TemplateContent.tsx +1354 -1235
- package/components/pages/template-content/index.ts +1 -1
- package/components/pages/template-page/TemplatePage.stories.tsx +39 -39
- package/components/pages/template-page/TemplatePage.tsx +62 -62
- package/components/pages/template-page/index.ts +1 -1
- package/components/pages/template-page/template-page.test.tsx +52 -52
- package/components/pages/verify-email-page/VerifyEmailPage.stories.tsx +41 -41
- package/components/pages/verify-email-page/VerifyEmailPage.tsx +206 -206
- package/components/pages/verify-email-page/index.ts +1 -1
- package/components/public-api-smoke.test.tsx +52 -52
- package/components/shared/CustomTooltipContent.tsx +48 -48
- package/components/shared/assistant-utils.test.ts +16 -16
- package/components/shared/assistant-utils.ts +225 -225
- package/components/shared/error-boundary.stories.tsx +114 -132
- package/components/shared/error-boundary.tsx +150 -154
- package/components/shared/error-fallbacks.tsx +222 -226
- package/components/shared/layout-constants.ts +8 -8
- package/components/shared/navigation.ts +35 -35
- package/components/shared/use-mobile.test.ts +16 -16
- package/components/shared/use-mobile.ts +36 -36
- package/components/shared/utils.test.ts +14 -14
- package/components/shared/utils.ts +6 -6
- package/components/ui/accordion/accordion.stories.tsx +105 -105
- package/components/ui/accordion/accordion.test.tsx +59 -59
- package/components/ui/accordion/accordion.tsx +77 -77
- package/components/ui/accordion/index.ts +1 -1
- package/components/ui/alert/alert.stories.tsx +86 -86
- package/components/ui/alert/alert.test.tsx +53 -53
- package/components/ui/alert/alert.tsx +93 -93
- package/components/ui/alert/index.ts +1 -1
- package/components/ui/alert-dialog/alert-dialog.stories.tsx +84 -84
- package/components/ui/alert-dialog/alert-dialog.test.tsx +70 -70
- package/components/ui/alert-dialog/alert-dialog.tsx +149 -149
- package/components/ui/alert-dialog/index.ts +1 -1
- package/components/ui/aspect-ratio/aspect-ratio.stories.tsx +46 -46
- package/components/ui/aspect-ratio/aspect-ratio.test.tsx +28 -28
- package/components/ui/aspect-ratio/aspect-ratio.tsx +20 -20
- package/components/ui/aspect-ratio/index.ts +1 -1
- package/components/ui/assistant-chart/AssistantChart.tsx +64 -64
- package/components/ui/assistant-chart/assistant-chart.stories.tsx +44 -44
- package/components/ui/assistant-chart/assistant-chart.test.tsx +46 -46
- package/components/ui/assistant-chart/index.ts +1 -1
- package/components/ui/avatar/avatar.stories.tsx +86 -86
- package/components/ui/avatar/avatar.test.tsx +55 -55
- package/components/ui/avatar/avatar.tsx +71 -71
- package/components/ui/avatar/index.ts +1 -1
- package/components/ui/badge/badge.stories.tsx +72 -72
- package/components/ui/badge/badge.test.tsx +40 -40
- package/components/ui/badge/badge.tsx +58 -58
- package/components/ui/badge/index.ts +1 -1
- package/components/ui/breadcrumb/breadcrumb.stories.tsx +123 -123
- package/components/ui/breadcrumb/breadcrumb.test.tsx +70 -70
- package/components/ui/breadcrumb/breadcrumb.tsx +114 -114
- package/components/ui/breadcrumb/index.ts +1 -1
- package/components/ui/button/button.stories.tsx +183 -183
- package/components/ui/button/button.test.tsx +64 -64
- package/components/ui/button/button.tsx +98 -98
- package/components/ui/button/index.ts +1 -1
- package/components/ui/calendar/calendar.stories.tsx +108 -108
- package/components/ui/calendar/calendar.test.tsx +53 -53
- package/components/ui/calendar/calendar.tsx +230 -230
- package/components/ui/calendar/index.ts +1 -1
- package/components/ui/card/card.stories.tsx +301 -301
- package/components/ui/card/card.test.tsx +55 -55
- package/components/ui/card/card.tsx +83 -83
- package/components/ui/card/index.ts +1 -1
- package/components/ui/carousel/carousel.stories.tsx +80 -80
- package/components/ui/carousel/carousel.test.tsx +75 -75
- package/components/ui/carousel/carousel.tsx +242 -242
- package/components/ui/carousel/index.ts +1 -1
- package/components/ui/chart/chart.stories.tsx +1328 -1328
- package/components/ui/chart/chart.test.tsx +178 -178
- package/components/ui/chart/chart.tsx +2232 -2232
- package/components/ui/chart/index.ts +1 -1
- package/components/ui/checkbox/checkbox.stories.tsx +109 -109
- package/components/ui/checkbox/checkbox.test.tsx +49 -49
- package/components/ui/checkbox/checkbox.tsx +68 -68
- package/components/ui/checkbox/index.ts +1 -1
- package/components/ui/collapsible/collapsible.stories.tsx +45 -45
- package/components/ui/collapsible/collapsible.test.tsx +51 -51
- package/components/ui/collapsible/collapsible.tsx +32 -32
- package/components/ui/collapsible/index.ts +1 -1
- package/components/ui/command/command.stories.tsx +134 -134
- package/components/ui/command/command.test.tsx +48 -48
- package/components/ui/command/command.tsx +163 -163
- package/components/ui/command/index.ts +1 -1
- package/components/ui/context-menu/context-menu.stories.tsx +76 -76
- package/components/ui/context-menu/context-menu.test.tsx +61 -61
- package/components/ui/context-menu/context-menu.tsx +236 -236
- package/components/ui/context-menu/index.ts +1 -1
- package/components/ui/dialog/dialog.stories.tsx +174 -174
- package/components/ui/dialog/dialog.test.tsx +78 -78
- package/components/ui/dialog/dialog.tsx +189 -189
- package/components/ui/dialog/index.ts +1 -1
- package/components/ui/drawer/drawer.stories.tsx +71 -71
- package/components/ui/drawer/drawer.test.tsx +67 -67
- package/components/ui/drawer/drawer.tsx +146 -146
- package/components/ui/drawer/index.ts +1 -1
- package/components/ui/dropdown-menu/dropdown-menu.stories.tsx +156 -156
- package/components/ui/dropdown-menu/dropdown-menu.test.tsx +62 -62
- package/components/ui/dropdown-menu/dropdown-menu.tsx +240 -240
- package/components/ui/dropdown-menu/index.ts +1 -1
- package/components/ui/empty/empty.stories.tsx +85 -85
- package/components/ui/empty/empty.test.tsx +31 -31
- package/components/ui/empty/empty.tsx +88 -88
- package/components/ui/empty/index.ts +1 -1
- package/components/ui/file-upload/file-upload.stories.tsx +144 -144
- package/components/ui/file-upload/file-upload.test.tsx +65 -65
- package/components/ui/file-upload/file-upload.tsx +142 -142
- package/components/ui/file-upload/index.ts +2 -2
- package/components/ui/file-upload/use-file-upload.ts +177 -177
- package/components/ui/form/form.stories.tsx +85 -85
- package/components/ui/form/form.test.tsx +75 -75
- package/components/ui/form/form.tsx +163 -163
- package/components/ui/form/index.ts +1 -1
- package/components/ui/google-maps-loader/google-maps-loader.test.tsx +35 -35
- package/components/ui/google-maps-loader/google-maps-loader.tsx +465 -465
- package/components/ui/google-maps-loader/index.ts +1 -1
- package/components/ui/hover-card/hover-card.stories.tsx +61 -61
- package/components/ui/hover-card/hover-card.test.tsx +48 -48
- package/components/ui/hover-card/hover-card.tsx +50 -50
- package/components/ui/hover-card/index.ts +1 -1
- package/components/ui/index.ts +400 -400
- package/components/ui/input/index.ts +1 -1
- package/components/ui/input/input.stories.tsx +153 -153
- package/components/ui/input/input.test.tsx +47 -47
- package/components/ui/input/input.tsx +57 -57
- package/components/ui/input-otp/index.ts +1 -1
- package/components/ui/input-otp/input-otp.stories.tsx +120 -120
- package/components/ui/input-otp/input-otp.test.tsx +74 -74
- package/components/ui/input-otp/input-otp.tsx +101 -101
- package/components/ui/label/index.ts +1 -1
- package/components/ui/label/label.stories.tsx +74 -74
- package/components/ui/label/label.test.tsx +45 -45
- package/components/ui/label/label.tsx +53 -53
- package/components/ui/map/index.ts +1 -1
- package/components/ui/map/map.stories.tsx +86 -86
- package/components/ui/map/map.test.tsx +82 -82
- package/components/ui/map/map.tsx +506 -506
- package/components/ui/map/mock.test.tsx +13 -13
- package/components/ui/map-config/index.ts +1 -1
- package/components/ui/map-config/map-config.ts +18 -18
- package/components/ui/map-layers/index.ts +1 -1
- package/components/ui/map-layers/map-layers.test.tsx +48 -48
- package/components/ui/map-layers/map-layers.tsx +126 -126
- package/components/ui/map.exports/index.ts +1 -1
- package/components/ui/map.exports/map.exports.ts +31 -31
- package/components/ui/menubar/index.ts +1 -1
- package/components/ui/menubar/menubar.stories.tsx +130 -130
- package/components/ui/menubar/menubar.test.tsx +53 -53
- package/components/ui/menubar/menubar.tsx +265 -265
- package/components/ui/navigation-menu/index.ts +1 -1
- package/components/ui/navigation-menu/navigation-menu.stories.tsx +126 -126
- package/components/ui/navigation-menu/navigation-menu.test.tsx +47 -47
- package/components/ui/navigation-menu/navigation-menu.tsx +165 -165
- package/components/ui/notification-badge/index.ts +1 -1
- package/components/ui/notification-badge/notification-badge.stories.tsx +66 -66
- package/components/ui/notification-badge/notification-badge.test.tsx +61 -61
- package/components/ui/notification-badge/notification-badge.tsx +91 -91
- package/components/ui/page-header/index.ts +1 -1
- package/components/ui/page-header/page-header.stories.tsx +69 -69
- package/components/ui/page-header/page-header.test.tsx +37 -37
- package/components/ui/page-header/page-header.tsx +124 -124
- package/components/ui/pagination/index.ts +3 -3
- package/components/ui/pagination/pagination.stories.tsx +210 -210
- package/components/ui/pagination/pagination.test.tsx +63 -63
- package/components/ui/pagination/pagination.tsx +140 -140
- package/components/ui/pagination/use-pagination.ts +173 -173
- package/components/ui/popover/index.ts +1 -1
- package/components/ui/popover/popover.stories.tsx +73 -73
- package/components/ui/popover/popover.test.tsx +48 -48
- package/components/ui/popover/popover.tsx +54 -54
- package/components/ui/progress/index.ts +1 -1
- package/components/ui/progress/progress.stories.tsx +55 -55
- package/components/ui/progress/progress.test.tsx +23 -23
- package/components/ui/progress/progress.tsx +68 -68
- package/components/ui/radio-group/index.ts +1 -1
- package/components/ui/radio-group/radio-group.stories.tsx +114 -114
- package/components/ui/radio-group/radio-group.test.tsx +78 -78
- package/components/ui/radio-group/radio-group.tsx +93 -93
- package/components/ui/rating/index.ts +1 -1
- package/components/ui/rating/rating.stories.tsx +50 -50
- package/components/ui/rating/rating.test.tsx +48 -48
- package/components/ui/rating/rating.tsx +145 -145
- package/components/ui/resizable/index.ts +1 -1
- package/components/ui/resizable/resizable.stories.tsx +88 -88
- package/components/ui/resizable/resizable.test.tsx +61 -61
- package/components/ui/resizable/resizable.tsx +452 -452
- package/components/ui/rich-text-editor/index.ts +7 -7
- package/components/ui/rich-text-editor/rich-text-editor.stories.tsx +290 -290
- package/components/ui/rich-text-editor/rich-text-editor.test.tsx +86 -86
- package/components/ui/rich-text-editor/rich-text-editor.tsx +634 -634
- package/components/ui/rich-text-editor/use-rich-text-editor.ts +453 -453
- package/components/ui/route-map/index.ts +1 -1
- package/components/ui/route-map/route-map.stories.tsx +48 -48
- package/components/ui/route-map/route-map.test.tsx +108 -108
- package/components/ui/route-map/route-map.tsx +349 -349
- package/components/ui/scroll-area/index.ts +1 -1
- package/components/ui/scroll-area/scroll-area.stories.tsx +31 -31
- package/components/ui/scroll-area/scroll-area.test.tsx +27 -27
- package/components/ui/scroll-area/scroll-area.tsx +70 -70
- package/components/ui/search/index.ts +1 -1
- package/components/ui/search/search.stories.tsx +107 -107
- package/components/ui/search/search.test.tsx +67 -67
- package/components/ui/search/search.tsx +141 -141
- package/components/ui/select/index.ts +1 -1
- package/components/ui/select/select.stories.tsx +163 -163
- package/components/ui/select/select.test.tsx +99 -99
- package/components/ui/select/select.tsx +195 -195
- package/components/ui/separator/index.ts +1 -1
- package/components/ui/separator/separator.stories.tsx +55 -55
- package/components/ui/separator/separator.test.tsx +23 -23
- package/components/ui/separator/separator.tsx +39 -39
- package/components/ui/sheet/index.ts +1 -1
- package/components/ui/sheet/sheet.stories.tsx +93 -93
- package/components/ui/sheet/sheet.test.tsx +62 -62
- package/components/ui/sheet/sheet.tsx +149 -149
- package/components/ui/simple-map/index.ts +1 -1
- package/components/ui/simple-map/simple-map.stories.tsx +44 -44
- package/components/ui/simple-map/simple-map.test.tsx +36 -36
- package/components/ui/simple-map/simple-map.tsx +92 -92
- package/components/ui/skeleton/index.ts +1 -1
- package/components/ui/skeleton/skeleton.stories.tsx +36 -36
- package/components/ui/skeleton/skeleton.test.tsx +19 -19
- package/components/ui/skeleton/skeleton.tsx +25 -25
- package/components/ui/slider/index.ts +1 -1
- package/components/ui/slider/slider.stories.tsx +44 -44
- package/components/ui/slider/slider.test.tsx +25 -25
- package/components/ui/slider/slider.tsx +66 -66
- package/components/ui/sonner/index.ts +1 -1
- package/components/ui/sonner/sonner.stories.tsx +41 -41
- package/components/ui/sonner/sonner.test.tsx +24 -24
- package/components/ui/sonner/sonner.tsx +74 -74
- package/components/ui/stats-card/index.ts +2 -2
- package/components/ui/stats-card/stats-card-skeleton.tsx +1 -3
- package/components/ui/stats-card/stats-card.stories.tsx +99 -99
- package/components/ui/stats-card/stats-card.test.tsx +34 -34
- package/components/ui/stats-card/stats-card.tsx +93 -93
- package/components/ui/stepper/index.ts +3 -3
- package/components/ui/stepper/stepper.stories.tsx +171 -171
- package/components/ui/stepper/stepper.test.tsx +47 -47
- package/components/ui/stepper/stepper.tsx +190 -190
- package/components/ui/stepper/use-stepper.ts +139 -139
- package/components/ui/switch/index.ts +1 -1
- package/components/ui/switch/switch.stories.tsx +93 -93
- package/components/ui/switch/switch.test.tsx +44 -44
- package/components/ui/switch/switch.tsx +70 -70
- package/components/ui/table/index.ts +1 -1
- package/components/ui/table/table.stories.tsx +114 -114
- package/components/ui/table/table.test.tsx +43 -43
- package/components/ui/table/table.tsx +104 -104
- package/components/ui/tabs/index.ts +1 -1
- package/components/ui/tabs/tabs.stories.tsx +140 -140
- package/components/ui/tabs/tabs.test.tsx +50 -50
- package/components/ui/tabs/tabs.tsx +66 -66
- package/components/ui/textarea/index.ts +1 -1
- package/components/ui/textarea/textarea.stories.tsx +69 -69
- package/components/ui/textarea/textarea.test.tsx +41 -41
- package/components/ui/textarea/textarea.tsx +61 -61
- package/components/ui/timeline/index.ts +1 -1
- package/components/ui/timeline/timeline.stories.tsx +97 -97
- package/components/ui/timeline/timeline.test.tsx +53 -53
- package/components/ui/timeline/timeline.tsx +124 -124
- package/components/ui/toggle/index.ts +1 -1
- package/components/ui/toggle/toggle.stories.tsx +56 -56
- package/components/ui/toggle/toggle.test.tsx +32 -32
- package/components/ui/toggle/toggle.tsx +55 -55
- package/components/ui/toggle-group/index.ts +1 -1
- package/components/ui/toggle-group/toggle-group.stories.tsx +66 -66
- package/components/ui/toggle-group/toggle-group.test.tsx +47 -47
- package/components/ui/toggle-group/toggle-group.tsx +79 -79
- package/components/ui/tooltip/index.ts +1 -1
- package/components/ui/tooltip/tooltip.stories.tsx +83 -83
- package/components/ui/tooltip/tooltip.test.tsx +39 -39
- package/components/ui/tooltip/tooltip.tsx +69 -69
- package/components/ui/tree-view/index.ts +4 -4
- package/components/ui/tree-view/tree-view.stories.tsx +154 -154
- package/components/ui/tree-view/tree-view.test.tsx +58 -58
- package/components/ui/tree-view/tree-view.tsx +171 -171
- package/components/ui/tree-view/use-tree-view.ts +237 -237
- package/components.json +892 -892
- package/contexts/ApiKeyContext.test.tsx +26 -26
- package/contexts/ApiKeyContext.tsx +196 -196
- package/contexts/AssistenteContext.test.tsx +17 -17
- package/contexts/AssistenteContext.tsx +113 -113
- package/contexts/AuthContext.tsx +121 -118
- package/contexts/BrandColorsContext.test.tsx +21 -21
- package/contexts/BrandColorsContext.tsx +251 -251
- package/contexts/LanguageContext.tsx +1 -2
- package/contexts/LayoutContext.test.tsx +29 -29
- package/contexts/LayoutContext.tsx +140 -140
- package/contexts/ThemeContext.test.tsx +38 -38
- package/contexts/ThemeContext.tsx +111 -111
- package/contexts/index.ts +8 -8
- package/contexts/theme-data.ts +340 -340
- package/dist/AssistantChart-COGiOV-g.cjs +3541 -0
- package/dist/AssistantChart-CWX1OWNM.js +3373 -0
- package/dist/AudioPlayer-9psiEucT.cjs +1282 -0
- package/dist/AudioPlayer-Dp2bD1Gk.js +1278 -0
- package/dist/BrandColorsContext-DZT7JjeD.js +659 -0
- package/dist/BrandColorsContext-awnBCmC4.cjs +666 -0
- package/dist/CodeBlock-DYkTfR0f.js +221 -0
- package/dist/CodeBlock-EOvp9cVu.cjs +223 -0
- package/dist/CustomTooltipContent-BhdIeBEg.cjs +54 -0
- package/dist/CustomTooltipContent-CNbVB2NS.js +33 -0
- package/dist/FeatureCard-BZ4CYxFf.cjs +497 -0
- package/dist/FeatureCard-DNycVGwT.js +485 -0
- package/dist/FeatureCardSkeleton-DZqc96mt.js +27 -0
- package/dist/FeatureCardSkeleton-pTa0YNKP.cjs +29 -0
- package/dist/LayoutContext-BEq_-n98.cjs +96 -0
- package/dist/LayoutContext-DNl1xSoX.js +92 -0
- package/dist/ThemeContext-CMD3z2Dz.cjs +1930 -0
- package/dist/ThemeContext-x_F2zsnv.js +1923 -0
- package/dist/VerifyEmailPage-BJjAMUTW.js +3223 -0
- package/dist/VerifyEmailPage-Bv8Ah_TK.cjs +3235 -0
- package/dist/VerifyEmailPage-CkBYfsNy.cjs +3232 -0
- package/dist/VerifyEmailPage-Cyl55sJb.js +3226 -0
- package/dist/VerifyEmailPage-X14vhdyl.js +3296 -0
- package/dist/VerifyEmailPage-u_Dn7t1U.cjs +3305 -0
- package/dist/XerticaOrbe-Uk2JML1-.cjs +1927 -0
- package/dist/XerticaOrbe-jA5T2iOk.js +1925 -0
- package/dist/XerticaProvider-BErr83Bg.js +42 -0
- package/dist/XerticaProvider-CwOkHxiT.cjs +44 -0
- package/dist/XerticaProvider-DUOJg9iX.js +49 -0
- package/dist/XerticaProvider-Dl_b72_l.cjs +51 -0
- package/dist/XerticaXLogo-BX3ueACh.js +255 -0
- package/dist/XerticaXLogo-mqjoBiLI.js +252 -0
- package/dist/XerticaXLogo-qBPhwK3g.cjs +260 -0
- package/dist/XerticaXLogo-uQgwns_E.cjs +257 -0
- package/dist/alert-dialog-DhwPioBa.cjs +885 -0
- package/dist/alert-dialog-DqlRW_An.js +831 -0
- package/dist/assistant.cjs.js +8 -4
- package/dist/assistant.es.js +5 -11
- package/dist/avatar-3kO2Anrp.js +54 -0
- package/dist/avatar-BCM7YQRC.cjs +77 -0
- package/dist/blocks.cjs.js +9 -4
- package/dist/blocks.es.js +2 -16
- package/dist/brand.cjs.js +10 -5
- package/dist/brand.es.js +3 -11
- package/dist/breadcrumb-BKtHF4gk.cjs +98 -0
- package/dist/breadcrumb-ifNsA7Zl.js +90 -0
- package/dist/button-0BlA47It.cjs +85 -0
- package/dist/button-DZHzN1Gd.js +62 -0
- package/dist/cli.js +471 -93
- package/dist/components/brand/theme-toggle/ThemeToggle.d.ts +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/dropdown-menu-BMcykFDf.cjs +225 -0
- package/dist/dropdown-menu-Dn_eV2Xb.js +190 -0
- package/dist/google-maps-loader-BCe58h9D.js +308 -0
- package/dist/google-maps-loader-casMyxlo.cjs +316 -0
- package/dist/hooks.cjs.js +12 -8
- package/dist/hooks.es.js +10 -27
- package/dist/index-9GWd0qxq.cjs +12 -0
- package/dist/index-BabBx2pa.js +6 -0
- package/dist/index.cjs.js +37 -32
- package/dist/index.es.js +30 -363
- package/dist/input-C_UiS2Py.cjs +152 -0
- package/dist/input-cc-PTD4R.js +123 -0
- package/dist/layout.cjs.js +10 -6
- package/dist/layout.es.js +7 -9
- package/dist/media.cjs.js +8 -3
- package/dist/media.es.js +1 -6
- package/dist/pages.cjs.js +8 -3
- package/dist/pages.es.js +1 -11
- package/dist/progress-C7Lti5wo.js +80 -0
- package/dist/progress-Cqwxbqs1.cjs +103 -0
- package/dist/rich-text-editor-DqLICivI.js +2832 -0
- package/dist/rich-text-editor-DxO1Hz3a.cjs +2903 -0
- package/dist/select-CH6v_KcQ.cjs +161 -0
- package/dist/select-D-xvCZK2.js +130 -0
- package/dist/sidebar-3XyzjVBw.js +792 -0
- package/dist/sidebar-B4ZWaMrE.js +792 -0
- package/dist/sidebar-BS1p2V7t.cjs +795 -0
- package/dist/sidebar-DyYvgyBj.cjs +795 -0
- package/dist/skeleton-DjiHerJn.cjs +87 -0
- package/dist/skeleton-DtR5tkYe.js +78 -0
- package/dist/slider-B00b9SVK.cjs +78 -0
- package/dist/slider-DQCNUUMj.js +56 -0
- package/dist/sonner-B-jWlik1.cjs +68 -0
- package/dist/sonner-C9tiqj4f.js +47 -0
- package/dist/tooltip-D8n9UYoU.cjs +72 -0
- package/dist/tooltip-RtbSmPYJ.js +48 -0
- package/dist/ui.cjs.js +23 -18
- package/dist/ui.es.js +16 -303
- package/dist/use-audio-player-B78fd2ct.js +188 -0
- package/dist/use-audio-player-DGvhPrgR.cjs +190 -0
- package/dist/use-mobile-BdXTRb0Z.cjs +51 -0
- package/dist/use-mobile-Ce2cBAQe.js +29 -0
- package/dist/xertica-assistant-B1NaSFFj.js +2173 -0
- package/dist/xertica-assistant-B687qEPU.js +2165 -0
- package/dist/xertica-assistant-CIaUlbIt.cjs +2180 -0
- package/dist/xertica-assistant-sOHwTgIP.cjs +2172 -0
- package/dist/xertica-ui.css +1 -1
- package/docs/ai-usage.md +195 -195
- package/docs/architecture-improvements.md +456 -456
- package/docs/architecture.md +312 -306
- package/docs/components/accordion.md +109 -109
- package/docs/components/alert-dialog.md +127 -127
- package/docs/components/alert.md +106 -106
- package/docs/components/aspect-ratio.md +58 -58
- package/docs/components/assistant-chart.md +47 -47
- package/docs/components/assistant.md +428 -426
- package/docs/components/audio-player.md +167 -167
- package/docs/components/avatar.md +101 -101
- package/docs/components/badge.md +84 -84
- package/docs/components/branding.md +252 -252
- package/docs/components/breadcrumb.md +104 -104
- package/docs/components/button.md +156 -156
- package/docs/components/calendar.md +141 -141
- package/docs/components/card-patterns.md +447 -445
- package/docs/components/card.md +245 -245
- package/docs/components/carousel.md +100 -100
- package/docs/components/chart.md +638 -638
- package/docs/components/checkbox.md +88 -88
- package/docs/components/code-block.md +105 -105
- package/docs/components/collapsible.md +86 -86
- package/docs/components/command.md +113 -113
- package/docs/components/context-menu.md +81 -81
- package/docs/components/dialog.md +198 -198
- package/docs/components/drawer.md +105 -105
- package/docs/components/dropdown-menu.md +127 -127
- package/docs/components/empty.md +127 -127
- package/docs/components/error-boundary.md +201 -191
- package/docs/components/file-upload.md +189 -189
- package/docs/components/floating-media-wrapper.md +63 -63
- package/docs/components/form.md +177 -177
- package/docs/components/formatted-document.md +105 -105
- package/docs/components/google-maps-loader.md +44 -44
- package/docs/components/header.md +177 -177
- package/docs/components/hooks.md +432 -430
- package/docs/components/hover-card.md +86 -86
- package/docs/components/image-with-fallback.md +107 -107
- package/docs/components/input-otp.md +95 -95
- package/docs/components/input.md +130 -130
- package/docs/components/label.md +69 -69
- package/docs/components/language-selector.md +20 -16
- package/docs/components/map-layers.md +138 -138
- package/docs/components/map.md +84 -84
- package/docs/components/markdown-message.md +47 -47
- package/docs/components/menubar.md +89 -89
- package/docs/components/modern-chat-input.md +164 -164
- package/docs/components/navigation-menu.md +83 -83
- package/docs/components/notification-badge.md +78 -78
- package/docs/components/page-header.md +93 -93
- package/docs/components/pages.md +323 -309
- package/docs/components/pagination.md +334 -334
- package/docs/components/popover.md +116 -116
- package/docs/components/progress.md +103 -103
- package/docs/components/radio-group.md +133 -133
- package/docs/components/rating.md +77 -77
- package/docs/components/resizable.md +84 -84
- package/docs/components/rich-text-editor.md +255 -255
- package/docs/components/route-map.md +124 -124
- package/docs/components/scroll-area.md +58 -58
- package/docs/components/search.md +87 -87
- package/docs/components/select.md +144 -144
- package/docs/components/separator.md +58 -58
- package/docs/components/sheet.md +122 -122
- package/docs/components/sidebar.md +314 -314
- package/docs/components/simple-map.md +51 -51
- package/docs/components/skeleton.md +99 -99
- package/docs/components/slider.md +84 -84
- package/docs/components/sonner.md +115 -115
- package/docs/components/stats-card.md +120 -120
- package/docs/components/stepper.md +268 -268
- package/docs/components/switch.md +106 -106
- package/docs/components/table.md +138 -138
- package/docs/components/tabs.md +117 -117
- package/docs/components/textarea.md +86 -86
- package/docs/components/theme-toggle.md +73 -73
- package/docs/components/timeline.md +121 -121
- package/docs/components/toggle-group.md +68 -68
- package/docs/components/toggle.md +62 -62
- package/docs/components/tooltip.md +116 -116
- package/docs/components/tree-view.md +238 -238
- package/docs/components/use-mobile.md +96 -96
- package/docs/components/video-player.md +68 -68
- package/docs/components/xertica-logo.md +36 -36
- package/docs/components/xertica-orbe.md +35 -35
- package/docs/components/xertica-provider.md +65 -65
- package/docs/components/xertica-xlogo.md +35 -35
- package/docs/decision-tree.md +293 -293
- package/docs/doc-audit.md +244 -243
- package/docs/form-sizing.md +162 -162
- package/docs/getting-started.md +616 -591
- package/docs/guidelines.md +330 -328
- package/docs/i18n.md +61 -57
- package/docs/installation.md +268 -267
- package/docs/layout.md +143 -143
- package/docs/llms.md +295 -295
- package/docs/patterns/analytics.md +194 -194
- package/docs/patterns/crud.md +149 -149
- package/docs/patterns/dashboard.md +138 -138
- package/docs/patterns/detail-page.md +296 -296
- package/docs/patterns/form.md +241 -241
- package/docs/patterns/login.md +156 -156
- package/docs/patterns/settings.md +368 -368
- package/docs/patterns/wizard.md +213 -213
- package/docs/state-management.md +289 -289
- package/guidelines/Guidelines.md +409 -406
- package/hooks/useTheme.test.tsx +16 -16
- package/hooks/useTheme.ts +4 -4
- package/imports/Podcast.tsx +540 -540
- package/imports/XerticaAi.tsx +46 -46
- package/imports/XerticaX.tsx +15 -15
- package/imports/svg-aueiaqngck.ts +20 -20
- package/imports/svg-v9krss1ozd.ts +23 -23
- package/imports/svg-vhrdofe3qe.ts +6 -6
- package/llms-compact.txt +2 -1
- package/llms.txt +2 -1
- package/mcp/resources.json +22 -22
- package/mcp/tools.json +35 -35
- package/package.json +219 -213
- package/scripts/ai-validator.ts +91 -91
- package/scripts/cleanup-case-dupes.ts +62 -62
- package/scripts/generate-ai-manifests.ts +107 -107
- package/styles/globals.css +13 -13
- package/styles/xertica/app-overrides/chat.css +61 -61
- package/styles/xertica/app-overrides/scrollbar.css +33 -33
- package/styles/xertica/base.css +90 -71
- package/styles/xertica/integrations/google-maps.css +76 -76
- package/styles/xertica/integrations/sonner.css +73 -73
- package/styles/xertica/theme-map.css +102 -99
- package/styles/xertica/tokens.css +240 -236
- package/templates/CLAUDE.md +16 -1
- package/templates/eslint.config.js +26 -26
- package/templates/guidelines/Guidelines.md +577 -553
- package/templates/package.json +69 -69
- package/templates/postcss.config.js +6 -6
- package/templates/src/app/App.tsx +46 -46
- package/templates/src/app/components/AppLayout.tsx +55 -55
- package/templates/src/app/components/AuthGuard.tsx +131 -82
- package/templates/src/app/context/AuthContext.tsx +108 -108
- package/templates/src/features/assistant/index.ts +5 -5
- package/templates/src/features/auth/index.ts +4 -4
- package/templates/src/features/auth/ui/AuthPageShell.tsx +32 -32
- package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +70 -72
- package/templates/src/features/auth/ui/LoginContent.tsx +92 -92
- package/templates/src/features/auth/ui/ResetPasswordContent.tsx +6 -2
- package/templates/src/features/auth/ui/SocialLoginButtons.tsx +78 -78
- package/templates/src/features/auth/ui/VerifyEmailContent.tsx +2 -6
- package/templates/src/features/home/data/mock.ts +41 -35
- package/templates/src/features/home/index.ts +11 -11
- package/templates/src/features/home/store/dashboardStore.ts +25 -25
- package/templates/src/features/home/ui/HomeContent.tsx +117 -119
- package/templates/src/features/template/index.ts +5 -5
- package/templates/src/features/template/ui/CrudTemplate.tsx +1 -4
- package/templates/src/features/template/ui/LoginTemplate.tsx +1 -1
- package/templates/src/features/template/ui/TemplateContent.tsx +29 -21
- package/templates/src/locales/en/pages/templates.json +17 -17
- package/templates/src/locales/es/pages/templates.json +17 -17
- package/templates/src/locales/pt-BR/pages/templates.json +17 -17
- package/templates/src/main.tsx +11 -11
- package/templates/src/pages/AssistantPage.tsx +26 -20
- package/templates/src/pages/ForgotPasswordPage.tsx +6 -6
- package/templates/src/pages/HomePage.tsx +53 -49
- package/templates/src/pages/LoginPage.tsx +10 -10
- package/templates/src/pages/ResetPasswordPage.tsx +6 -6
- package/templates/src/pages/TemplatePage.tsx +28 -28
- package/templates/src/pages/VerifyEmailPage.tsx +6 -6
- package/templates/src/shared/config/navigation.ts +19 -19
- package/templates/src/shared/error-boundary.tsx +150 -154
- package/templates/src/shared/error-fallbacks.tsx +222 -226
- package/templates/src/shared/lib/auth.ts +20 -20
- package/templates/src/shared/types/auth.ts +3 -3
- package/templates/src/styles/index.css +95 -95
- package/templates/src/styles/xertica/tokens.css +240 -236
- package/templates/tsconfig.json +25 -25
- package/templates/tsconfig.node.json +12 -12
- package/templates/vite-env.d.ts +1 -1
- package/templates/vite.config.js +20 -20
- package/templates/vite.config.ts +54 -51
- package/utils/color-utils.ts +72 -72
- package/utils/demo-responses.test.ts +10 -10
- package/utils/demo-responses.ts +151 -151
- package/utils/gemini.test.ts +25 -25
- package/utils/gemini.ts +155 -155
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
2
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
3
|
-
import { CodeBlock } from './CodeBlock';
|
|
4
|
-
import React from 'react';
|
|
5
|
-
|
|
6
|
-
describe('CodeBlock', () => {
|
|
7
|
-
const mockWriteText = vi.fn().mockResolvedValue(undefined);
|
|
8
|
-
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
vi.clearAllMocks();
|
|
11
|
-
// Mock clipboard API safely
|
|
12
|
-
vi.stubGlobal('navigator', {
|
|
13
|
-
clipboard: {
|
|
14
|
-
writeText: mockWriteText,
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('renders code correctly', () => {
|
|
20
|
-
const code = 'const x = 1;';
|
|
21
|
-
const { container } = render(<CodeBlock code={code} language="typescript" />);
|
|
22
|
-
// Simple check: is the text present in the container?
|
|
23
|
-
expect(container.textContent).toContain(code);
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('shows filename in header', () => {
|
|
27
|
-
render(<CodeBlock code="code" filename="test.ts" />);
|
|
28
|
-
expect(screen.getByText('test.ts')).toBeInTheDocument();
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('copies code to clipboard when button is clicked', async () => {
|
|
32
|
-
const code = 'copy me';
|
|
33
|
-
render(<CodeBlock code={code} />);
|
|
34
|
-
|
|
35
|
-
const copyButton = screen.getByLabelText('Copiar código');
|
|
36
|
-
fireEvent.click(copyButton);
|
|
37
|
-
|
|
38
|
-
expect(mockWriteText).toHaveBeenCalledWith(code);
|
|
39
|
-
|
|
40
|
-
await waitFor(() => {
|
|
41
|
-
expect(screen.getByLabelText('Copiado')).toBeInTheDocument();
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
});
|
|
1
|
+
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
2
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
3
|
+
import { CodeBlock } from './CodeBlock';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
|
|
6
|
+
describe('CodeBlock', () => {
|
|
7
|
+
const mockWriteText = vi.fn().mockResolvedValue(undefined);
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
vi.clearAllMocks();
|
|
11
|
+
// Mock clipboard API safely
|
|
12
|
+
vi.stubGlobal('navigator', {
|
|
13
|
+
clipboard: {
|
|
14
|
+
writeText: mockWriteText,
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('renders code correctly', () => {
|
|
20
|
+
const code = 'const x = 1;';
|
|
21
|
+
const { container } = render(<CodeBlock code={code} language="typescript" />);
|
|
22
|
+
// Simple check: is the text present in the container?
|
|
23
|
+
expect(container.textContent).toContain(code);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('shows filename in header', () => {
|
|
27
|
+
render(<CodeBlock code="code" filename="test.ts" />);
|
|
28
|
+
expect(screen.getByText('test.ts')).toBeInTheDocument();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('copies code to clipboard when button is clicked', async () => {
|
|
32
|
+
const code = 'copy me';
|
|
33
|
+
render(<CodeBlock code={code} />);
|
|
34
|
+
|
|
35
|
+
const copyButton = screen.getByLabelText('Copiar código');
|
|
36
|
+
fireEvent.click(copyButton);
|
|
37
|
+
|
|
38
|
+
expect(mockWriteText).toHaveBeenCalledWith(code);
|
|
39
|
+
|
|
40
|
+
await waitFor(() => {
|
|
41
|
+
expect(screen.getByLabelText('Copiado')).toBeInTheDocument();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './CodeBlock';
|
|
1
|
+
export * from './CodeBlock';
|
|
@@ -1,147 +1,147 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import { useTranslation } from 'react-i18next';
|
|
3
|
-
import { Button } from '../../ui/button';
|
|
4
|
-
import { ChevronDown, ChevronUp } from 'lucide-react';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Props for the FormattedDocument component.
|
|
8
|
-
*/
|
|
9
|
-
interface FormattedDocumentProps {
|
|
10
|
-
/** The raw markdown string to be converted and displayed */
|
|
11
|
-
content: string;
|
|
12
|
-
/** Maximum number of characters to show in the collapsed preview state */
|
|
13
|
-
maxPreviewLength?: number;
|
|
14
|
-
/** Additional CSS classes for the container */
|
|
15
|
-
className?: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Simple Markdown-to-HTML formatter with collapsible preview.
|
|
20
|
-
*
|
|
21
|
-
* @description
|
|
22
|
-
* Converts basic markdown syntax (headers, bold, lists, checkboxes) into styled
|
|
23
|
-
* Tailwind HTML elements. Includes a "See more/less" toggle for long documents.
|
|
24
|
-
*
|
|
25
|
-
* @ai-rules
|
|
26
|
-
* 1. Use this component to display AI-generated text or documentation strings.
|
|
27
|
-
* 2. It supports standard markdown symbols: #, ##, ###, **, *, -, [ ], [x].
|
|
28
|
-
* 3. `maxPreviewLength` defaults to 500 characters.
|
|
29
|
-
*/
|
|
30
|
-
export function FormattedDocument({
|
|
31
|
-
content,
|
|
32
|
-
maxPreviewLength = 500,
|
|
33
|
-
className = '',
|
|
34
|
-
}: FormattedDocumentProps) {
|
|
35
|
-
const [isExpanded, setIsExpanded] = useState(false);
|
|
36
|
-
const { t } = useTranslation();
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Converts simple Markdown strings to HTML using regex patterns.
|
|
40
|
-
*/
|
|
41
|
-
const convertMarkdownToHtml = (markdown: string): string => {
|
|
42
|
-
let html = markdown;
|
|
43
|
-
|
|
44
|
-
// Headers (with improved styling, reduced spacing)
|
|
45
|
-
html = html.replace(
|
|
46
|
-
/^### (.*$)/gim,
|
|
47
|
-
'<h3 class="text-base font-medium mt-2 mb-1 text-foreground">$1</h3>'
|
|
48
|
-
);
|
|
49
|
-
html = html.replace(
|
|
50
|
-
/^## (.*$)/gim,
|
|
51
|
-
'<h2 class="text-lg font-medium mt-2 mb-1 text-foreground">$1</h2>'
|
|
52
|
-
);
|
|
53
|
-
html = html.replace(
|
|
54
|
-
/^# (.*$)/gim,
|
|
55
|
-
'<h1 class="text-xl font-medium mt-3 mb-2 text-foreground">$1</h1>'
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
// Bold
|
|
59
|
-
html = html.replace(
|
|
60
|
-
/\*\*(.*?)\*\*/g,
|
|
61
|
-
'<strong class="font-medium text-foreground">$1</strong>'
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
// Italic
|
|
65
|
-
html = html.replace(/\*(.*?)\*/g, '<em class="italic">$1</em>');
|
|
66
|
-
|
|
67
|
-
// Checkboxes (Process before lists to avoid collisions)
|
|
68
|
-
html = html.replace(
|
|
69
|
-
/^[-*+] \[ \] (.*$)/gim,
|
|
70
|
-
'<div class="flex items-center gap-2 ml-4 my-0.5"><input type="checkbox" disabled class="rounded w-3.5 h-3.5 accent-primary" aria-label="$1" /> <span class="text-sm">$1</span></div>'
|
|
71
|
-
);
|
|
72
|
-
html = html.replace(
|
|
73
|
-
/^[-*+] \[x\] (.*$)/gim,
|
|
74
|
-
'<div class="flex items-center gap-2 ml-4 my-0.5"><input type="checkbox" checked disabled class="rounded w-3.5 h-3.5 accent-primary" aria-label="$1" /> <span class="text-sm">$1</span></div>'
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
// Lists (Bullet and Numbered) - Wrap blocks of items in ul/ol
|
|
78
|
-
html = html.replace(/((?:^[-*+] .*$(?:\n|$))+)/gim, match => {
|
|
79
|
-
const items = match
|
|
80
|
-
.trim()
|
|
81
|
-
.split('\n')
|
|
82
|
-
.map(item => `<li class="ml-6 my-0.5 list-disc">${item.replace(/^[-*+] /i, '')}</li>`)
|
|
83
|
-
.join('');
|
|
84
|
-
return `<ul class="list-disc my-2">${items}</ul>`;
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
html = html.replace(/((?:^\d+\. .*$(?:\n|$))+)/gim, match => {
|
|
88
|
-
const items = match
|
|
89
|
-
.trim()
|
|
90
|
-
.split('\n')
|
|
91
|
-
.map(item => `<li class="ml-6 my-0.5 list-decimal">${item.replace(/^\d+\. /i, '')}</li>`)
|
|
92
|
-
.join('');
|
|
93
|
-
return `<ol class="list-decimal my-2">${items}</ol>`;
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
// Horizontal rule
|
|
97
|
-
html = html.replace(/^---$/gim, '<hr class="my-2 border-border" />');
|
|
98
|
-
|
|
99
|
-
// Line breaks - treat single \n as space, \n\n as paragraph break
|
|
100
|
-
html = html.replace(/\n\n+/g, '</p><p class="my-0.5">');
|
|
101
|
-
html = html.replace(/\n/g, ' ');
|
|
102
|
-
|
|
103
|
-
// Wrap in paragraph
|
|
104
|
-
html = '<p class="my-0.5">' + html + '</p>';
|
|
105
|
-
|
|
106
|
-
return html;
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const htmlContent = convertMarkdownToHtml(content);
|
|
110
|
-
const isLong = content.length > maxPreviewLength;
|
|
111
|
-
|
|
112
|
-
// If not long or if expanded, show everything
|
|
113
|
-
const displayContent =
|
|
114
|
-
!isLong || isExpanded
|
|
115
|
-
? htmlContent
|
|
116
|
-
: convertMarkdownToHtml(content.substring(0, maxPreviewLength) + '...');
|
|
117
|
-
|
|
118
|
-
return (
|
|
119
|
-
<div className={className}>
|
|
120
|
-
<div
|
|
121
|
-
className="max-w-none text-sm text-foreground leading-relaxed break-words overflow-hidden"
|
|
122
|
-
dangerouslySetInnerHTML={{ __html: displayContent }}
|
|
123
|
-
/>
|
|
124
|
-
|
|
125
|
-
{isLong && (
|
|
126
|
-
<Button
|
|
127
|
-
variant="ghost"
|
|
128
|
-
size="sm"
|
|
129
|
-
onClick={() => setIsExpanded(!isExpanded)}
|
|
130
|
-
className="mt-2 w-full text-xs hover:bg-accent text-muted-foreground"
|
|
131
|
-
>
|
|
132
|
-
{isExpanded ? (
|
|
133
|
-
<>
|
|
134
|
-
<ChevronUp className="w-3 h-3 mr-1" />
|
|
135
|
-
{t('common.seeLess')}
|
|
136
|
-
</>
|
|
137
|
-
) : (
|
|
138
|
-
<>
|
|
139
|
-
<ChevronDown className="w-3 h-3 mr-1" />
|
|
140
|
-
{t('common.seeMore')}
|
|
141
|
-
</>
|
|
142
|
-
)}
|
|
143
|
-
</Button>
|
|
144
|
-
)}
|
|
145
|
-
</div>
|
|
146
|
-
);
|
|
147
|
-
}
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { Button } from '../../ui/button';
|
|
4
|
+
import { ChevronDown, ChevronUp } from 'lucide-react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Props for the FormattedDocument component.
|
|
8
|
+
*/
|
|
9
|
+
interface FormattedDocumentProps {
|
|
10
|
+
/** The raw markdown string to be converted and displayed */
|
|
11
|
+
content: string;
|
|
12
|
+
/** Maximum number of characters to show in the collapsed preview state */
|
|
13
|
+
maxPreviewLength?: number;
|
|
14
|
+
/** Additional CSS classes for the container */
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Simple Markdown-to-HTML formatter with collapsible preview.
|
|
20
|
+
*
|
|
21
|
+
* @description
|
|
22
|
+
* Converts basic markdown syntax (headers, bold, lists, checkboxes) into styled
|
|
23
|
+
* Tailwind HTML elements. Includes a "See more/less" toggle for long documents.
|
|
24
|
+
*
|
|
25
|
+
* @ai-rules
|
|
26
|
+
* 1. Use this component to display AI-generated text or documentation strings.
|
|
27
|
+
* 2. It supports standard markdown symbols: #, ##, ###, **, *, -, [ ], [x].
|
|
28
|
+
* 3. `maxPreviewLength` defaults to 500 characters.
|
|
29
|
+
*/
|
|
30
|
+
export function FormattedDocument({
|
|
31
|
+
content,
|
|
32
|
+
maxPreviewLength = 500,
|
|
33
|
+
className = '',
|
|
34
|
+
}: FormattedDocumentProps) {
|
|
35
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
36
|
+
const { t } = useTranslation();
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Converts simple Markdown strings to HTML using regex patterns.
|
|
40
|
+
*/
|
|
41
|
+
const convertMarkdownToHtml = (markdown: string): string => {
|
|
42
|
+
let html = markdown;
|
|
43
|
+
|
|
44
|
+
// Headers (with improved styling, reduced spacing)
|
|
45
|
+
html = html.replace(
|
|
46
|
+
/^### (.*$)/gim,
|
|
47
|
+
'<h3 class="text-base font-medium mt-2 mb-1 text-foreground">$1</h3>'
|
|
48
|
+
);
|
|
49
|
+
html = html.replace(
|
|
50
|
+
/^## (.*$)/gim,
|
|
51
|
+
'<h2 class="text-lg font-medium mt-2 mb-1 text-foreground">$1</h2>'
|
|
52
|
+
);
|
|
53
|
+
html = html.replace(
|
|
54
|
+
/^# (.*$)/gim,
|
|
55
|
+
'<h1 class="text-xl font-medium mt-3 mb-2 text-foreground">$1</h1>'
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
// Bold
|
|
59
|
+
html = html.replace(
|
|
60
|
+
/\*\*(.*?)\*\*/g,
|
|
61
|
+
'<strong class="font-medium text-foreground">$1</strong>'
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
// Italic
|
|
65
|
+
html = html.replace(/\*(.*?)\*/g, '<em class="italic">$1</em>');
|
|
66
|
+
|
|
67
|
+
// Checkboxes (Process before lists to avoid collisions)
|
|
68
|
+
html = html.replace(
|
|
69
|
+
/^[-*+] \[ \] (.*$)/gim,
|
|
70
|
+
'<div class="flex items-center gap-2 ml-4 my-0.5"><input type="checkbox" disabled class="rounded w-3.5 h-3.5 accent-primary" aria-label="$1" /> <span class="text-sm">$1</span></div>'
|
|
71
|
+
);
|
|
72
|
+
html = html.replace(
|
|
73
|
+
/^[-*+] \[x\] (.*$)/gim,
|
|
74
|
+
'<div class="flex items-center gap-2 ml-4 my-0.5"><input type="checkbox" checked disabled class="rounded w-3.5 h-3.5 accent-primary" aria-label="$1" /> <span class="text-sm">$1</span></div>'
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// Lists (Bullet and Numbered) - Wrap blocks of items in ul/ol
|
|
78
|
+
html = html.replace(/((?:^[-*+] .*$(?:\n|$))+)/gim, match => {
|
|
79
|
+
const items = match
|
|
80
|
+
.trim()
|
|
81
|
+
.split('\n')
|
|
82
|
+
.map(item => `<li class="ml-6 my-0.5 list-disc">${item.replace(/^[-*+] /i, '')}</li>`)
|
|
83
|
+
.join('');
|
|
84
|
+
return `<ul class="list-disc my-2">${items}</ul>`;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
html = html.replace(/((?:^\d+\. .*$(?:\n|$))+)/gim, match => {
|
|
88
|
+
const items = match
|
|
89
|
+
.trim()
|
|
90
|
+
.split('\n')
|
|
91
|
+
.map(item => `<li class="ml-6 my-0.5 list-decimal">${item.replace(/^\d+\. /i, '')}</li>`)
|
|
92
|
+
.join('');
|
|
93
|
+
return `<ol class="list-decimal my-2">${items}</ol>`;
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Horizontal rule
|
|
97
|
+
html = html.replace(/^---$/gim, '<hr class="my-2 border-border" />');
|
|
98
|
+
|
|
99
|
+
// Line breaks - treat single \n as space, \n\n as paragraph break
|
|
100
|
+
html = html.replace(/\n\n+/g, '</p><p class="my-0.5">');
|
|
101
|
+
html = html.replace(/\n/g, ' ');
|
|
102
|
+
|
|
103
|
+
// Wrap in paragraph
|
|
104
|
+
html = '<p class="my-0.5">' + html + '</p>';
|
|
105
|
+
|
|
106
|
+
return html;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const htmlContent = convertMarkdownToHtml(content);
|
|
110
|
+
const isLong = content.length > maxPreviewLength;
|
|
111
|
+
|
|
112
|
+
// If not long or if expanded, show everything
|
|
113
|
+
const displayContent =
|
|
114
|
+
!isLong || isExpanded
|
|
115
|
+
? htmlContent
|
|
116
|
+
: convertMarkdownToHtml(content.substring(0, maxPreviewLength) + '...');
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<div className={className}>
|
|
120
|
+
<div
|
|
121
|
+
className="max-w-none text-sm text-foreground leading-relaxed break-words overflow-hidden"
|
|
122
|
+
dangerouslySetInnerHTML={{ __html: displayContent }}
|
|
123
|
+
/>
|
|
124
|
+
|
|
125
|
+
{isLong && (
|
|
126
|
+
<Button
|
|
127
|
+
variant="ghost"
|
|
128
|
+
size="sm"
|
|
129
|
+
onClick={() => setIsExpanded(!isExpanded)}
|
|
130
|
+
className="mt-2 w-full text-xs hover:bg-accent text-muted-foreground"
|
|
131
|
+
>
|
|
132
|
+
{isExpanded ? (
|
|
133
|
+
<>
|
|
134
|
+
<ChevronUp className="w-3 h-3 mr-1" />
|
|
135
|
+
{t('common.seeLess')}
|
|
136
|
+
</>
|
|
137
|
+
) : (
|
|
138
|
+
<>
|
|
139
|
+
<ChevronDown className="w-3 h-3 mr-1" />
|
|
140
|
+
{t('common.seeMore')}
|
|
141
|
+
</>
|
|
142
|
+
)}
|
|
143
|
+
</Button>
|
|
144
|
+
)}
|
|
145
|
+
</div>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import { FormattedDocument } from './FormattedDocument';
|
|
3
|
-
import React from 'react';
|
|
4
|
-
|
|
5
|
-
const meta: Meta<typeof FormattedDocument> = {
|
|
6
|
-
title: 'Assistant/FormattedDocument',
|
|
7
|
-
component: FormattedDocument,
|
|
8
|
-
argTypes: {
|
|
9
|
-
maxPreviewLength: { control: 'number' },
|
|
10
|
-
},
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export default meta;
|
|
14
|
-
type Story = StoryObj<typeof FormattedDocument>;
|
|
15
|
-
|
|
16
|
-
const longContent = `# Strategic Project Proposal
|
|
17
|
-
## Overview
|
|
18
|
-
This proposal describes the implementation of a generative artificial intelligence layer across the entire customer journey.
|
|
19
|
-
|
|
20
|
-
### Key Objectives
|
|
21
|
-
- Reduce service latency by up to 40%
|
|
22
|
-
- Increase qualified lead conversion rate
|
|
23
|
-
- Automate weekly management reports
|
|
24
|
-
|
|
25
|
-
### Roadmap
|
|
26
|
-
1. **Week 1-2:** Discovery and Data Mapping
|
|
27
|
-
2. **Week 3-4:** Infrastructure and Agent Setup
|
|
28
|
-
3. **Week 5-8:** Pilot Implementation and Feedback Loop
|
|
29
|
-
|
|
30
|
-
## Technical Details
|
|
31
|
-
The architecture is based on RAG (Retrieval Augmented Generation) using high-performance vector databases. Agents are orchestrated in real-time to ensure accurate and contextual responses.
|
|
32
|
-
|
|
33
|
-
- [x] Persona definition
|
|
34
|
-
- [x] Guardrails configuration
|
|
35
|
-
- [ ] CRM integration
|
|
36
|
-
- [ ] Global deployment
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
**Note:** This is a preliminary version for board review.`;
|
|
40
|
-
|
|
41
|
-
export const Default: Story = {
|
|
42
|
-
args: {
|
|
43
|
-
content: longContent,
|
|
44
|
-
maxPreviewLength: 200,
|
|
45
|
-
},
|
|
46
|
-
render: args => (
|
|
47
|
-
<div className="w-full max-w-xl p-6 border rounded-xl bg-card">
|
|
48
|
-
<FormattedDocument {...args} />
|
|
49
|
-
</div>
|
|
50
|
-
),
|
|
51
|
-
};
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { FormattedDocument } from './FormattedDocument';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof FormattedDocument> = {
|
|
6
|
+
title: 'Assistant/FormattedDocument',
|
|
7
|
+
component: FormattedDocument,
|
|
8
|
+
argTypes: {
|
|
9
|
+
maxPreviewLength: { control: 'number' },
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default meta;
|
|
14
|
+
type Story = StoryObj<typeof FormattedDocument>;
|
|
15
|
+
|
|
16
|
+
const longContent = `# Strategic Project Proposal
|
|
17
|
+
## Overview
|
|
18
|
+
This proposal describes the implementation of a generative artificial intelligence layer across the entire customer journey.
|
|
19
|
+
|
|
20
|
+
### Key Objectives
|
|
21
|
+
- Reduce service latency by up to 40%
|
|
22
|
+
- Increase qualified lead conversion rate
|
|
23
|
+
- Automate weekly management reports
|
|
24
|
+
|
|
25
|
+
### Roadmap
|
|
26
|
+
1. **Week 1-2:** Discovery and Data Mapping
|
|
27
|
+
2. **Week 3-4:** Infrastructure and Agent Setup
|
|
28
|
+
3. **Week 5-8:** Pilot Implementation and Feedback Loop
|
|
29
|
+
|
|
30
|
+
## Technical Details
|
|
31
|
+
The architecture is based on RAG (Retrieval Augmented Generation) using high-performance vector databases. Agents are orchestrated in real-time to ensure accurate and contextual responses.
|
|
32
|
+
|
|
33
|
+
- [x] Persona definition
|
|
34
|
+
- [x] Guardrails configuration
|
|
35
|
+
- [ ] CRM integration
|
|
36
|
+
- [ ] Global deployment
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
**Note:** This is a preliminary version for board review.`;
|
|
40
|
+
|
|
41
|
+
export const Default: Story = {
|
|
42
|
+
args: {
|
|
43
|
+
content: longContent,
|
|
44
|
+
maxPreviewLength: 200,
|
|
45
|
+
},
|
|
46
|
+
render: args => (
|
|
47
|
+
<div className="w-full max-w-xl p-6 border rounded-xl bg-card">
|
|
48
|
+
<FormattedDocument {...args} />
|
|
49
|
+
</div>
|
|
50
|
+
),
|
|
51
|
+
};
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
import { render, screen, fireEvent } from '@testing-library/react';
|
|
2
|
-
import { describe, it, expect } from 'vitest';
|
|
3
|
-
import { FormattedDocument } from './FormattedDocument';
|
|
4
|
-
import React from 'react';
|
|
5
|
-
|
|
6
|
-
describe('FormattedDocument', () => {
|
|
7
|
-
it('renders markdown correctly', () => {
|
|
8
|
-
render(<FormattedDocument content="# Hello" />);
|
|
9
|
-
expect(screen.getByText('Hello')).toBeInTheDocument();
|
|
10
|
-
expect(document.querySelector('h1')).toBeInTheDocument();
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it('truncates content when it exceeds maxPreviewLength', () => {
|
|
14
|
-
const longContent = 'A'.repeat(100);
|
|
15
|
-
render(<FormattedDocument content={longContent} maxPreviewLength={50} />);
|
|
16
|
-
|
|
17
|
-
// Check if it's truncated (contains ellipsis)
|
|
18
|
-
expect(screen.getByText(/A{50}\.\.\./)).toBeInTheDocument();
|
|
19
|
-
expect(screen.getByText('See more')).toBeInTheDocument();
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it('expands content when See more is clicked', () => {
|
|
23
|
-
const longContent = 'A'.repeat(100);
|
|
24
|
-
render(<FormattedDocument content={longContent} maxPreviewLength={50} />);
|
|
25
|
-
|
|
26
|
-
fireEvent.click(screen.getByText('See more'));
|
|
27
|
-
|
|
28
|
-
expect(screen.getByText('A'.repeat(100))).toBeInTheDocument();
|
|
29
|
-
expect(screen.getByText('See less')).toBeInTheDocument();
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('renders checkboxes correctly', () => {
|
|
33
|
-
// Using separate lines and making sure they match the regex start-of-line
|
|
34
|
-
const content = '- [ ] Unchecked\n- [x] Checked';
|
|
35
|
-
const { container } = render(<FormattedDocument content={content} />);
|
|
36
|
-
|
|
37
|
-
const checkboxes = container.querySelectorAll('input[type="checkbox"]');
|
|
38
|
-
// If it only finds 1, maybe the regex is not picking up the second one because of how \n is handled.
|
|
39
|
-
// Let's just check for at least one and then debug if needed.
|
|
40
|
-
expect(checkboxes.length).toBeGreaterThanOrEqual(1);
|
|
41
|
-
});
|
|
42
|
-
});
|
|
1
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
2
|
+
import { describe, it, expect } from 'vitest';
|
|
3
|
+
import { FormattedDocument } from './FormattedDocument';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
|
|
6
|
+
describe('FormattedDocument', () => {
|
|
7
|
+
it('renders markdown correctly', () => {
|
|
8
|
+
render(<FormattedDocument content="# Hello" />);
|
|
9
|
+
expect(screen.getByText('Hello')).toBeInTheDocument();
|
|
10
|
+
expect(document.querySelector('h1')).toBeInTheDocument();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('truncates content when it exceeds maxPreviewLength', () => {
|
|
14
|
+
const longContent = 'A'.repeat(100);
|
|
15
|
+
render(<FormattedDocument content={longContent} maxPreviewLength={50} />);
|
|
16
|
+
|
|
17
|
+
// Check if it's truncated (contains ellipsis)
|
|
18
|
+
expect(screen.getByText(/A{50}\.\.\./)).toBeInTheDocument();
|
|
19
|
+
expect(screen.getByText('See more')).toBeInTheDocument();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('expands content when See more is clicked', () => {
|
|
23
|
+
const longContent = 'A'.repeat(100);
|
|
24
|
+
render(<FormattedDocument content={longContent} maxPreviewLength={50} />);
|
|
25
|
+
|
|
26
|
+
fireEvent.click(screen.getByText('See more'));
|
|
27
|
+
|
|
28
|
+
expect(screen.getByText('A'.repeat(100))).toBeInTheDocument();
|
|
29
|
+
expect(screen.getByText('See less')).toBeInTheDocument();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('renders checkboxes correctly', () => {
|
|
33
|
+
// Using separate lines and making sure they match the regex start-of-line
|
|
34
|
+
const content = '- [ ] Unchecked\n- [x] Checked';
|
|
35
|
+
const { container } = render(<FormattedDocument content={content} />);
|
|
36
|
+
|
|
37
|
+
const checkboxes = container.querySelectorAll('input[type="checkbox"]');
|
|
38
|
+
// If it only finds 1, maybe the regex is not picking up the second one because of how \n is handled.
|
|
39
|
+
// Let's just check for at least one and then debug if needed.
|
|
40
|
+
expect(checkboxes.length).toBeGreaterThanOrEqual(1);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './FormattedDocument';
|
|
1
|
+
export * from './FormattedDocument';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export * from './xertica-assistant';
|
|
2
|
-
export { CodeBlock } from './code-block';
|
|
3
|
-
export { MarkdownMessage } from './markdown-message';
|
|
4
|
-
export { ModernChatInput } from './modern-chat-input';
|
|
5
|
-
export { FormattedDocument } from './formatted-document';
|
|
6
|
-
export { generateDemoResponse } from '../../utils/demo-responses';
|
|
1
|
+
export * from './xertica-assistant';
|
|
2
|
+
export { CodeBlock } from './code-block';
|
|
3
|
+
export { MarkdownMessage } from './markdown-message';
|
|
4
|
+
export { ModernChatInput } from './modern-chat-input';
|
|
5
|
+
export { FormattedDocument } from './formatted-document';
|
|
6
|
+
export { generateDemoResponse } from '../../utils/demo-responses';
|