@otfdashkit/ui 0.1.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/LICENSE +21 -0
- package/dist/index.js +14886 -0
- package/dist/index.mjs +14389 -0
- package/package.json +124 -0
- package/src/advanced/BulkActions/BulkActions.stories.tsx +14 -0
- package/src/advanced/BulkActions/BulkActions.test.tsx +9 -0
- package/src/advanced/BulkActions/BulkActions.tsx +46 -0
- package/src/advanced/BulkActions/index.ts +2 -0
- package/src/advanced/CommandBar/CommandBar.stories.tsx +14 -0
- package/src/advanced/CommandBar/CommandBar.test.tsx +9 -0
- package/src/advanced/CommandBar/CommandBar.tsx +115 -0
- package/src/advanced/CommandBar/index.ts +2 -0
- package/src/advanced/Filters/Filters.stories.tsx +14 -0
- package/src/advanced/Filters/Filters.test.tsx +9 -0
- package/src/advanced/Filters/Filters.tsx +103 -0
- package/src/advanced/Filters/index.ts +2 -0
- package/src/advanced/Kanban/Kanban.stories.tsx +14 -0
- package/src/advanced/Kanban/Kanban.test.tsx +9 -0
- package/src/advanced/Kanban/Kanban.tsx +95 -0
- package/src/advanced/Kanban/index.ts +2 -0
- package/src/advanced/ToggleButton/ToggleButton.stories.tsx +14 -0
- package/src/advanced/ToggleButton/ToggleButton.test.tsx +9 -0
- package/src/advanced/ToggleButton/ToggleButton.tsx +78 -0
- package/src/advanced/ToggleButton/index.ts +2 -0
- package/src/advanced/bulk-actions.tsx +46 -0
- package/src/advanced/command-bar.tsx +115 -0
- package/src/advanced/filters.tsx +103 -0
- package/src/advanced/gantt.tsx +824 -0
- package/src/advanced/kanban.tsx +95 -0
- package/src/advanced/rich-editor.tsx +700 -0
- package/src/advanced/toggle-button.tsx +78 -0
- package/src/advanced/utils/cn.ts +1 -0
- package/src/app-shell/AppShell.tsx +24 -0
- package/src/app-shell/BillingStatus.tsx +63 -0
- package/src/app-shell/Sidebar.tsx +172 -0
- package/src/app-shell/SidebarResizer.tsx +109 -0
- package/src/app-shell/SortableNav.tsx +122 -0
- package/src/app-shell/UserMenu.tsx +135 -0
- package/src/app-shell/WorkspacesMenu.tsx +114 -0
- package/src/app-shell/index.ts +18 -0
- package/src/backgrounds/AnimatedGradient.tsx +151 -0
- package/src/backgrounds/DottedBackground.tsx +64 -0
- package/src/backgrounds/GradientBackground.tsx +113 -0
- package/src/backgrounds/HeroShaderA.tsx +255 -0
- package/src/backgrounds/NoiseBackground.tsx +51 -0
- package/src/backgrounds/index.ts +5 -0
- package/src/blocks/ChatDetail/ChatDetail.stories.tsx +14 -0
- package/src/blocks/ChatDetail/ChatDetail.test.tsx +9 -0
- package/src/blocks/ChatDetail/ChatDetail.tsx +73 -0
- package/src/blocks/ChatDetail/index.ts +2 -0
- package/src/blocks/FeedbackModal/FeedbackModal.stories.tsx +14 -0
- package/src/blocks/FeedbackModal/FeedbackModal.test.tsx +9 -0
- package/src/blocks/FeedbackModal/FeedbackModal.tsx +68 -0
- package/src/blocks/FeedbackModal/index.ts +2 -0
- package/src/blocks/FileCards/FileCards.stories.tsx +14 -0
- package/src/blocks/FileCards/FileCards.test.tsx +9 -0
- package/src/blocks/FileCards/FileCards.tsx +56 -0
- package/src/blocks/FileCards/index.ts +2 -0
- package/src/blocks/FilesList/FilesList.stories.tsx +14 -0
- package/src/blocks/FilesList/FilesList.test.tsx +9 -0
- package/src/blocks/FilesList/FilesList.tsx +72 -0
- package/src/blocks/FilesList/index.ts +2 -0
- package/src/blocks/FloatingActionButton/FloatingActionButton.stories.tsx +223 -0
- package/src/blocks/FloatingActionButton/FloatingActionButton.test.tsx +47 -0
- package/src/blocks/FloatingActionButton/FloatingActionButton.tsx +253 -0
- package/src/blocks/FloatingActionButton/index.ts +1 -0
- package/src/blocks/IntegrationCard/IntegrationCard.stories.tsx +14 -0
- package/src/blocks/IntegrationCard/IntegrationCard.test.tsx +9 -0
- package/src/blocks/IntegrationCard/IntegrationCard.tsx +50 -0
- package/src/blocks/IntegrationCard/index.ts +2 -0
- package/src/blocks/InviteModal/InviteModal.stories.tsx +14 -0
- package/src/blocks/InviteModal/InviteModal.test.tsx +9 -0
- package/src/blocks/InviteModal/InviteModal.tsx +69 -0
- package/src/blocks/InviteModal/index.ts +2 -0
- package/src/blocks/ManageTagsModal/ManageTagsModal.stories.tsx +14 -0
- package/src/blocks/ManageTagsModal/ManageTagsModal.test.tsx +9 -0
- package/src/blocks/ManageTagsModal/ManageTagsModal.tsx +63 -0
- package/src/blocks/ManageTagsModal/index.ts +2 -0
- package/src/blocks/MessagesCard/MessagesCard.stories.tsx +14 -0
- package/src/blocks/MessagesCard/MessagesCard.test.tsx +9 -0
- package/src/blocks/MessagesCard/MessagesCard.tsx +59 -0
- package/src/blocks/MessagesCard/index.ts +2 -0
- package/src/blocks/MetricCard/MetricCard.stories.tsx +14 -0
- package/src/blocks/MetricCard/MetricCard.test.tsx +9 -0
- package/src/blocks/MetricCard/MetricCard.tsx +79 -0
- package/src/blocks/MetricCard/index.ts +2 -0
- package/src/blocks/NotificationSettings/NotificationSettings.stories.tsx +14 -0
- package/src/blocks/NotificationSettings/NotificationSettings.test.tsx +9 -0
- package/src/blocks/NotificationSettings/NotificationSettings.tsx +61 -0
- package/src/blocks/NotificationSettings/index.ts +2 -0
- package/src/blocks/OrganizationMenu/OrganizationMenu.stories.tsx +14 -0
- package/src/blocks/OrganizationMenu/OrganizationMenu.test.tsx +9 -0
- package/src/blocks/OrganizationMenu/OrganizationMenu.tsx +66 -0
- package/src/blocks/OrganizationMenu/index.ts +2 -0
- package/src/blocks/RolesMenu/RolesMenu.stories.tsx +14 -0
- package/src/blocks/RolesMenu/RolesMenu.test.tsx +9 -0
- package/src/blocks/RolesMenu/RolesMenu.tsx +61 -0
- package/src/blocks/RolesMenu/index.ts +2 -0
- package/src/blocks/SelectUsersModal/SelectUsersModal.stories.tsx +14 -0
- package/src/blocks/SelectUsersModal/SelectUsersModal.test.tsx +9 -0
- package/src/blocks/SelectUsersModal/SelectUsersModal.tsx +64 -0
- package/src/blocks/SelectUsersModal/index.ts +2 -0
- package/src/blocks/SidebarLayoutDashboard/SidebarLayoutDashboard.stories.tsx +14 -0
- package/src/blocks/SidebarLayoutDashboard/SidebarLayoutDashboard.test.tsx +9 -0
- package/src/blocks/SidebarLayoutDashboard/SidebarLayoutDashboard.tsx +97 -0
- package/src/blocks/SidebarLayoutDashboard/index.ts +2 -0
- package/src/blocks/SidebarLayoutGroups/SidebarLayoutGroups.stories.tsx +14 -0
- package/src/blocks/SidebarLayoutGroups/SidebarLayoutGroups.test.tsx +9 -0
- package/src/blocks/SidebarLayoutGroups/SidebarLayoutGroups.tsx +79 -0
- package/src/blocks/SidebarLayoutGroups/index.ts +2 -0
- package/src/blocks/SidebarLayoutMinimal/SidebarLayoutMinimal.stories.tsx +14 -0
- package/src/blocks/SidebarLayoutMinimal/SidebarLayoutMinimal.test.tsx +9 -0
- package/src/blocks/SidebarLayoutMinimal/SidebarLayoutMinimal.tsx +73 -0
- package/src/blocks/SidebarLayoutMinimal/index.ts +2 -0
- package/src/blocks/SidebarLayoutSearch/SidebarLayoutSearch.stories.tsx +14 -0
- package/src/blocks/SidebarLayoutSearch/SidebarLayoutSearch.test.tsx +9 -0
- package/src/blocks/SidebarLayoutSearch/SidebarLayoutSearch.tsx +79 -0
- package/src/blocks/SidebarLayoutSearch/index.ts +2 -0
- package/src/blocks/SidebarLayoutUser/SidebarLayoutUser.stories.tsx +14 -0
- package/src/blocks/SidebarLayoutUser/SidebarLayoutUser.test.tsx +9 -0
- package/src/blocks/SidebarLayoutUser/SidebarLayoutUser.tsx +82 -0
- package/src/blocks/SidebarLayoutUser/index.ts +2 -0
- package/src/blocks/SortableTaskList/SortableTaskList.stories.tsx +14 -0
- package/src/blocks/SortableTaskList/SortableTaskList.test.tsx +9 -0
- package/src/blocks/SortableTaskList/SortableTaskList.tsx +70 -0
- package/src/blocks/SortableTaskList/index.ts +2 -0
- package/src/blocks/StackedLayoutBranded/StackedLayoutBranded.stories.tsx +14 -0
- package/src/blocks/StackedLayoutBranded/StackedLayoutBranded.test.tsx +9 -0
- package/src/blocks/StackedLayoutBranded/StackedLayoutBranded.tsx +64 -0
- package/src/blocks/StackedLayoutBranded/index.ts +2 -0
- package/src/blocks/StackedLayoutTabs/StackedLayoutTabs.stories.tsx +14 -0
- package/src/blocks/StackedLayoutTabs/StackedLayoutTabs.test.tsx +9 -0
- package/src/blocks/StackedLayoutTabs/StackedLayoutTabs.tsx +80 -0
- package/src/blocks/StackedLayoutTabs/index.ts +2 -0
- package/src/blocks/TaskCard/TaskCard.stories.tsx +14 -0
- package/src/blocks/TaskCard/TaskCard.test.tsx +9 -0
- package/src/blocks/TaskCard/TaskCard.tsx +88 -0
- package/src/blocks/TaskCard/index.ts +2 -0
- package/src/blocks/UserMenu/UserMenu.stories.tsx +14 -0
- package/src/blocks/UserMenu/UserMenu.test.tsx +9 -0
- package/src/blocks/UserMenu/UserMenu.tsx +62 -0
- package/src/blocks/UserMenu/index.ts +2 -0
- package/src/blocks/WorkspaceMembers/WorkspaceMembers.stories.tsx +14 -0
- package/src/blocks/WorkspaceMembers/WorkspaceMembers.test.tsx +9 -0
- package/src/blocks/WorkspaceMembers/WorkspaceMembers.tsx +61 -0
- package/src/blocks/WorkspaceMembers/index.ts +2 -0
- package/src/blocks/activity-heatmap.tsx +122 -0
- package/src/blocks/bar-list.tsx +75 -0
- package/src/blocks/chat-detail.tsx +73 -0
- package/src/blocks/feedback-modal.tsx +68 -0
- package/src/blocks/file-cards.tsx +56 -0
- package/src/blocks/files-list.tsx +72 -0
- package/src/blocks/integration-card.tsx +50 -0
- package/src/blocks/invite-modal.tsx +69 -0
- package/src/blocks/manage-tags-modal.tsx +63 -0
- package/src/blocks/messages-card.tsx +59 -0
- package/src/blocks/metric-card.tsx +79 -0
- package/src/blocks/notification-settings.tsx +61 -0
- package/src/blocks/organization-menu.tsx +85 -0
- package/src/blocks/roles-menu.tsx +61 -0
- package/src/blocks/select-users-modal.tsx +64 -0
- package/src/blocks/sidebar-layout-dashboard.tsx +97 -0
- package/src/blocks/sidebar-layout-groups.tsx +79 -0
- package/src/blocks/sidebar-layout-minimal.tsx +73 -0
- package/src/blocks/sidebar-layout-search.tsx +79 -0
- package/src/blocks/sidebar-layout-user.tsx +82 -0
- package/src/blocks/sortable-task-list.tsx +70 -0
- package/src/blocks/stacked-layout-branded.tsx +64 -0
- package/src/blocks/stacked-layout-tabs.tsx +80 -0
- package/src/blocks/task-card.tsx +88 -0
- package/src/blocks/user-menu.tsx +62 -0
- package/src/blocks/utils/cn.ts +1 -0
- package/src/blocks/workspace-members.tsx +61 -0
- package/src/charts/area-chart.tsx +83 -0
- package/src/charts/bar-chart.tsx +146 -0
- package/src/charts/heatmap.tsx +185 -0
- package/src/charts/line-chart.tsx +89 -0
- package/src/charts/sparkline.tsx +62 -0
- package/src/charts/utils/cn.ts +1 -0
- package/src/components/Banner/Banner.stories.tsx +14 -0
- package/src/components/Banner/Banner.test.tsx +9 -0
- package/src/components/Banner/Banner.tsx +203 -0
- package/src/components/Banner/index.ts +2 -0
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +14 -0
- package/src/components/Breadcrumb/Breadcrumb.test.tsx +9 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +58 -0
- package/src/components/Breadcrumb/index.ts +2 -0
- package/src/components/CommandItem/CommandItem.stories.tsx +14 -0
- package/src/components/CommandItem/CommandItem.test.tsx +9 -0
- package/src/components/CommandItem/CommandItem.tsx +36 -0
- package/src/components/CommandItem/index.ts +2 -0
- package/src/components/DataGrid/DataGrid.stories.tsx +14 -0
- package/src/components/DataGrid/DataGrid.test.tsx +9 -0
- package/src/components/DataGrid/DataGrid.tsx +125 -0
- package/src/components/DataGrid/index.ts +2 -0
- package/src/components/DataTable/DataTable.stories.tsx +14 -0
- package/src/components/DataTable/DataTable.test.tsx +9 -0
- package/src/components/DataTable/DataTable.tsx +139 -0
- package/src/components/DataTable/index.ts +2 -0
- package/src/components/EmptyState/EmptyState.stories.tsx +14 -0
- package/src/components/EmptyState/EmptyState.test.tsx +9 -0
- package/src/components/EmptyState/EmptyState.tsx +106 -0
- package/src/components/EmptyState/index.ts +2 -0
- package/src/components/Hotkeys/Hotkeys.stories.tsx +14 -0
- package/src/components/Hotkeys/Hotkeys.test.tsx +9 -0
- package/src/components/Hotkeys/Hotkeys.tsx +31 -0
- package/src/components/Hotkeys/index.ts +2 -0
- package/src/components/IconBadge/IconBadge.stories.tsx +14 -0
- package/src/components/IconBadge/IconBadge.test.tsx +9 -0
- package/src/components/IconBadge/IconBadge.tsx +35 -0
- package/src/components/IconBadge/index.ts +2 -0
- package/src/components/LoadingOverlay/LoadingOverlay.stories.tsx +14 -0
- package/src/components/LoadingOverlay/LoadingOverlay.test.tsx +9 -0
- package/src/components/LoadingOverlay/LoadingOverlay.tsx +38 -0
- package/src/components/LoadingOverlay/index.ts +2 -0
- package/src/components/Persona/Persona.stories.tsx +14 -0
- package/src/components/Persona/Persona.test.tsx +9 -0
- package/src/components/Persona/Persona.tsx +38 -0
- package/src/components/Persona/index.ts +2 -0
- package/src/components/PropertyList/PropertyList.stories.tsx +14 -0
- package/src/components/PropertyList/PropertyList.test.tsx +9 -0
- package/src/components/PropertyList/PropertyList.tsx +29 -0
- package/src/components/PropertyList/index.ts +2 -0
- package/src/components/Stat/Stat.stories.tsx +14 -0
- package/src/components/Stat/Stat.test.tsx +9 -0
- package/src/components/Stat/Stat.tsx +51 -0
- package/src/components/Stat/index.ts +2 -0
- package/src/components/Stepper/Stepper.stories.tsx +14 -0
- package/src/components/Stepper/Stepper.test.tsx +9 -0
- package/src/components/Stepper/Stepper.tsx +58 -0
- package/src/components/Stepper/index.ts +2 -0
- package/src/components/StructuredList/StructuredList.stories.tsx +14 -0
- package/src/components/StructuredList/StructuredList.test.tsx +9 -0
- package/src/components/StructuredList/StructuredList.tsx +51 -0
- package/src/components/StructuredList/index.ts +2 -0
- package/src/components/Timeline/Timeline.stories.tsx +14 -0
- package/src/components/Timeline/Timeline.test.tsx +9 -0
- package/src/components/Timeline/Timeline.tsx +69 -0
- package/src/components/Timeline/index.ts +2 -0
- package/src/components/Toaster/Toaster.stories.tsx +14 -0
- package/src/components/Toaster/Toaster.test.tsx +9 -0
- package/src/components/Toaster/Toaster.tsx +42 -0
- package/src/components/Toaster/index.ts +2 -0
- package/src/components/banner.tsx +203 -0
- package/src/components/breadcrumb.tsx +58 -0
- package/src/components/command-item.tsx +36 -0
- package/src/components/data-grid.tsx +125 -0
- package/src/components/data-table.tsx +139 -0
- package/src/components/empty-state.tsx +31 -0
- package/src/components/hotkeys.tsx +31 -0
- package/src/components/icon-badge.tsx +35 -0
- package/src/components/loading-overlay.tsx +38 -0
- package/src/components/persona.tsx +38 -0
- package/src/components/property-list.tsx +29 -0
- package/src/components/stat.tsx +51 -0
- package/src/components/stepper.tsx +69 -0
- package/src/components/structured-list.tsx +51 -0
- package/src/components/timeline.tsx +69 -0
- package/src/components/toaster.tsx +42 -0
- package/src/components/utils/cn.ts +1 -0
- package/src/data/ActionBar.tsx +115 -0
- package/src/data/DataGrid.tsx +453 -0
- package/src/data/DataList.tsx +79 -0
- package/src/data/EventCalendar.tsx +794 -0
- package/src/data/Filters.tsx +271 -0
- package/src/data/GridList.tsx +67 -0
- package/src/data/ImageCrop.tsx +198 -0
- package/src/data/SortableList.tsx +258 -0
- package/src/data/Tree.tsx +510 -0
- package/src/data/VideoPlayer.tsx +564 -0
- package/src/data/index.ts +6 -0
- package/src/engagement/Beacon/Beacon.stories.tsx +14 -0
- package/src/engagement/Beacon/Beacon.test.tsx +9 -0
- package/src/engagement/Beacon/Beacon.tsx +50 -0
- package/src/engagement/Beacon/index.ts +2 -0
- package/src/engagement/Tour/Tour.stories.tsx +14 -0
- package/src/engagement/Tour/Tour.test.tsx +9 -0
- package/src/engagement/Tour/Tour.tsx +106 -0
- package/src/engagement/Tour/index.ts +2 -0
- package/src/engagement/beacon.tsx +50 -0
- package/src/engagement/checklist.tsx +259 -0
- package/src/engagement/intro-disclosure.tsx +210 -0
- package/src/engagement/tour.tsx +106 -0
- package/src/engagement/utils/cn.ts +1 -0
- package/src/feedback/Toaster.tsx +141 -0
- package/src/feedback/index.ts +2 -0
- package/src/feedback/toast-emitter.ts +74 -0
- package/src/forms/ArrayField/ArrayField.stories.tsx +14 -0
- package/src/forms/ArrayField/ArrayField.test.tsx +9 -0
- package/src/forms/ArrayField/ArrayField.tsx +61 -0
- package/src/forms/ArrayField/index.ts +2 -0
- package/src/forms/AutoForm/AutoForm.stories.tsx +14 -0
- package/src/forms/AutoForm/AutoForm.test.tsx +9 -0
- package/src/forms/AutoForm/AutoForm.tsx +133 -0
- package/src/forms/AutoForm/index.ts +2 -0
- package/src/forms/DatePicker/DatePicker.stories.tsx +14 -0
- package/src/forms/DatePicker/DatePicker.test.tsx +9 -0
- package/src/forms/DatePicker/DatePicker.tsx +109 -0
- package/src/forms/DatePicker/index.ts +2 -0
- package/src/forms/Field/Field.stories.tsx +14 -0
- package/src/forms/Field/Field.test.tsx +9 -0
- package/src/forms/Field/Field.tsx +62 -0
- package/src/forms/Field/index.ts +2 -0
- package/src/forms/FileUpload/FileUpload.stories.tsx +14 -0
- package/src/forms/FileUpload/FileUpload.test.tsx +9 -0
- package/src/forms/FileUpload/FileUpload.tsx +101 -0
- package/src/forms/FileUpload/index.ts +2 -0
- package/src/forms/Form/Form.stories.tsx +14 -0
- package/src/forms/Form/Form.test.tsx +9 -0
- package/src/forms/Form/Form.tsx +57 -0
- package/src/forms/Form/index.ts +2 -0
- package/src/forms/ObjectField/ObjectField.stories.tsx +14 -0
- package/src/forms/ObjectField/ObjectField.test.tsx +9 -0
- package/src/forms/ObjectField/ObjectField.tsx +53 -0
- package/src/forms/ObjectField/index.ts +2 -0
- package/src/forms/PasswordInput/PasswordInput.stories.tsx +14 -0
- package/src/forms/PasswordInput/PasswordInput.test.tsx +9 -0
- package/src/forms/PasswordInput/PasswordInput.tsx +54 -0
- package/src/forms/PasswordInput/index.ts +2 -0
- package/src/forms/SearchInput/SearchInput.stories.tsx +14 -0
- package/src/forms/SearchInput/SearchInput.test.tsx +9 -0
- package/src/forms/SearchInput/SearchInput.tsx +64 -0
- package/src/forms/SearchInput/index.ts +2 -0
- package/src/forms/StepForm/StepForm.stories.tsx +14 -0
- package/src/forms/StepForm/StepForm.test.tsx +9 -0
- package/src/forms/StepForm/StepForm.tsx +113 -0
- package/src/forms/StepForm/index.ts +2 -0
- package/src/forms/array-field.tsx +61 -0
- package/src/forms/auto-form.tsx +133 -0
- package/src/forms/color-picker.tsx +258 -0
- package/src/forms/combobox.tsx +106 -0
- package/src/forms/date-picker.tsx +109 -0
- package/src/forms/field.tsx +62 -0
- package/src/forms/file-upload.tsx +101 -0
- package/src/forms/form.tsx +57 -0
- package/src/forms/object-field.tsx +53 -0
- package/src/forms/password-input.tsx +54 -0
- package/src/forms/search-input.tsx +64 -0
- package/src/forms/step-form.tsx +113 -0
- package/src/forms/tags.tsx +270 -0
- package/src/forms/utils/cn.ts +1 -0
- package/src/headers/ScrollHeader.tsx +110 -0
- package/src/headers/index.ts +1 -0
- package/src/index.ts +171 -0
- package/src/layout/PageContainer.tsx +40 -0
- package/src/layout/PageLayout.tsx +55 -0
- package/src/layout/index.ts +2 -0
- package/src/layouts/AppShell/AppShell.stories.tsx +14 -0
- package/src/layouts/AppShell/AppShell.test.tsx +9 -0
- package/src/layouts/AppShell/AppShell.tsx +129 -0
- package/src/layouts/AppShell/index.ts +2 -0
- package/src/layouts/Container/Container.stories.tsx +14 -0
- package/src/layouts/Container/Container.test.tsx +9 -0
- package/src/layouts/Container/Container.tsx +33 -0
- package/src/layouts/Container/index.ts +2 -0
- package/src/layouts/Navbar/Navbar.stories.tsx +14 -0
- package/src/layouts/Navbar/Navbar.test.tsx +9 -0
- package/src/layouts/Navbar/Navbar.tsx +60 -0
- package/src/layouts/Navbar/index.ts +2 -0
- package/src/layouts/Page/Page.stories.tsx +14 -0
- package/src/layouts/Page/Page.test.tsx +9 -0
- package/src/layouts/Page/Page.tsx +61 -0
- package/src/layouts/Page/index.ts +2 -0
- package/src/layouts/ResizeBox/ResizeBox.stories.tsx +14 -0
- package/src/layouts/ResizeBox/ResizeBox.test.tsx +9 -0
- package/src/layouts/ResizeBox/ResizeBox.tsx +45 -0
- package/src/layouts/ResizeBox/index.ts +2 -0
- package/src/layouts/Sidebar/Sidebar.stories.tsx +14 -0
- package/src/layouts/Sidebar/Sidebar.test.tsx +9 -0
- package/src/layouts/Sidebar/Sidebar.tsx +99 -0
- package/src/layouts/Sidebar/index.ts +2 -0
- package/src/layouts/SplitPage/SplitPage.stories.tsx +14 -0
- package/src/layouts/SplitPage/SplitPage.test.tsx +9 -0
- package/src/layouts/SplitPage/SplitPage.tsx +32 -0
- package/src/layouts/SplitPage/index.ts +2 -0
- package/src/layouts/Stack/Stack.stories.tsx +14 -0
- package/src/layouts/Stack/Stack.test.tsx +9 -0
- package/src/layouts/Stack/Stack.tsx +56 -0
- package/src/layouts/Stack/index.ts +2 -0
- package/src/layouts/app-shell.tsx +129 -0
- package/src/layouts/container.tsx +33 -0
- package/src/layouts/navbar.tsx +60 -0
- package/src/layouts/page.tsx +61 -0
- package/src/layouts/resize-box.tsx +45 -0
- package/src/layouts/sidebar.tsx +99 -0
- package/src/layouts/split-page.tsx +32 -0
- package/src/layouts/stack.tsx +56 -0
- package/src/layouts/utils/cn.ts +1 -0
- package/src/motion/FadeIn.tsx +33 -0
- package/src/motion/Morph.tsx +17 -0
- package/src/motion/Parallax.tsx +37 -0
- package/src/motion/Reveal.tsx +32 -0
- package/src/motion/Ripple.tsx +78 -0
- package/src/motion/ScaleIn.tsx +33 -0
- package/src/motion/SlideIn.tsx +42 -0
- package/src/motion/Stagger.tsx +48 -0
- package/src/motion/Transition.tsx +13 -0
- package/src/motion/index.ts +13 -0
- package/src/motion/presets.ts +33 -0
- package/src/motion/useLayoutId.ts +6 -0
- package/src/nav/CommandPalette.tsx +197 -0
- package/src/nav/HotkeysProvider.tsx +223 -0
- package/src/nav/index.ts +2 -0
- package/src/primitives/Accordion/Accordion.stories.tsx +14 -0
- package/src/primitives/Accordion/Accordion.test.tsx +9 -0
- package/src/primitives/Accordion/Accordion.tsx +56 -0
- package/src/primitives/Accordion/index.ts +2 -0
- package/src/primitives/Alert/Alert.stories.tsx +14 -0
- package/src/primitives/Alert/Alert.test.tsx +9 -0
- package/src/primitives/Alert/Alert.tsx +60 -0
- package/src/primitives/Alert/index.ts +2 -0
- package/src/primitives/AlertDialog/AlertDialog.stories.tsx +14 -0
- package/src/primitives/AlertDialog/AlertDialog.test.tsx +9 -0
- package/src/primitives/AlertDialog/AlertDialog.tsx +140 -0
- package/src/primitives/AlertDialog/index.ts +2 -0
- package/src/primitives/AspectRatio/AspectRatio.stories.tsx +14 -0
- package/src/primitives/AspectRatio/AspectRatio.test.tsx +9 -0
- package/src/primitives/AspectRatio/AspectRatio.tsx +6 -0
- package/src/primitives/AspectRatio/index.ts +2 -0
- package/src/primitives/Avatar/Avatar.stories.tsx +14 -0
- package/src/primitives/Avatar/Avatar.test.tsx +9 -0
- package/src/primitives/Avatar/Avatar.tsx +35 -0
- package/src/primitives/Avatar/index.ts +2 -0
- package/src/primitives/Badge/Badge.stories.tsx +14 -0
- package/src/primitives/Badge/Badge.test.tsx +9 -0
- package/src/primitives/Badge/Badge.tsx +28 -0
- package/src/primitives/Badge/index.ts +2 -0
- package/src/primitives/Button/Button.stories.tsx +14 -0
- package/src/primitives/Button/Button.test.tsx +9 -0
- package/src/primitives/Button/Button.tsx +113 -0
- package/src/primitives/Button/index.ts +2 -0
- package/src/primitives/Calendar/Calendar.stories.tsx +14 -0
- package/src/primitives/Calendar/Calendar.test.tsx +9 -0
- package/src/primitives/Calendar/Calendar.tsx +214 -0
- package/src/primitives/Calendar/index.ts +2 -0
- package/src/primitives/Card/Card.stories.tsx +14 -0
- package/src/primitives/Card/Card.test.tsx +9 -0
- package/src/primitives/Card/Card.tsx +48 -0
- package/src/primitives/Card/TextureCard.tsx +93 -0
- package/src/primitives/Card/index.ts +3 -0
- package/src/primitives/Carousel/Carousel.stories.tsx +14 -0
- package/src/primitives/Carousel/Carousel.test.tsx +9 -0
- package/src/primitives/Carousel/Carousel.tsx +261 -0
- package/src/primitives/Carousel/index.ts +2 -0
- package/src/primitives/Chart/Chart.stories.tsx +14 -0
- package/src/primitives/Chart/Chart.test.tsx +9 -0
- package/src/primitives/Chart/Chart.tsx +368 -0
- package/src/primitives/Chart/index.ts +2 -0
- package/src/primitives/Checkbox/Checkbox.stories.tsx +14 -0
- package/src/primitives/Checkbox/Checkbox.test.tsx +9 -0
- package/src/primitives/Checkbox/Checkbox.tsx +27 -0
- package/src/primitives/Checkbox/index.ts +2 -0
- package/src/primitives/Collapsible/Collapsible.stories.tsx +14 -0
- package/src/primitives/Collapsible/Collapsible.test.tsx +9 -0
- package/src/primitives/Collapsible/Collapsible.tsx +12 -0
- package/src/primitives/Collapsible/index.ts +2 -0
- package/src/primitives/Command/Command.stories.tsx +14 -0
- package/src/primitives/Command/Command.test.tsx +9 -0
- package/src/primitives/Command/Command.tsx +154 -0
- package/src/primitives/Command/index.ts +2 -0
- package/src/primitives/ContextMenu/ContextMenu.stories.tsx +14 -0
- package/src/primitives/ContextMenu/ContextMenu.test.tsx +9 -0
- package/src/primitives/ContextMenu/ContextMenu.tsx +101 -0
- package/src/primitives/ContextMenu/index.ts +2 -0
- package/src/primitives/Dialog/Dialog.stories.tsx +14 -0
- package/src/primitives/Dialog/Dialog.test.tsx +9 -0
- package/src/primitives/Dialog/Dialog.tsx +88 -0
- package/src/primitives/Dialog/DialogProvider.tsx +130 -0
- package/src/primitives/Dialog/index.ts +3 -0
- package/src/primitives/Drawer/Drawer.stories.tsx +14 -0
- package/src/primitives/Drawer/Drawer.test.tsx +9 -0
- package/src/primitives/Drawer/Drawer.tsx +123 -0
- package/src/primitives/Drawer/index.ts +2 -0
- package/src/primitives/DropdownMenu/DropdownMenu.stories.tsx +14 -0
- package/src/primitives/DropdownMenu/DropdownMenu.test.tsx +9 -0
- package/src/primitives/DropdownMenu/DropdownMenu.tsx +111 -0
- package/src/primitives/DropdownMenu/index.ts +2 -0
- package/src/primitives/Form/Form.stories.tsx +14 -0
- package/src/primitives/Form/Form.test.tsx +9 -0
- package/src/primitives/Form/Form.tsx +179 -0
- package/src/primitives/Form/index.ts +2 -0
- package/src/primitives/HoverCard/HoverCard.stories.tsx +14 -0
- package/src/primitives/HoverCard/HoverCard.test.tsx +9 -0
- package/src/primitives/HoverCard/HoverCard.tsx +31 -0
- package/src/primitives/HoverCard/index.ts +2 -0
- package/src/primitives/Input/Input.stories.tsx +14 -0
- package/src/primitives/Input/Input.test.tsx +9 -0
- package/src/primitives/Input/Input.tsx +110 -0
- package/src/primitives/Input/index.ts +2 -0
- package/src/primitives/InputOtp/InputOtp.stories.tsx +14 -0
- package/src/primitives/InputOtp/InputOtp.test.tsx +9 -0
- package/src/primitives/InputOtp/InputOtp.tsx +70 -0
- package/src/primitives/InputOtp/index.ts +2 -0
- package/src/primitives/Label/Label.stories.tsx +14 -0
- package/src/primitives/Label/Label.test.tsx +9 -0
- package/src/primitives/Label/Label.tsx +27 -0
- package/src/primitives/Label/index.ts +2 -0
- package/src/primitives/Menubar/Menubar.stories.tsx +14 -0
- package/src/primitives/Menubar/Menubar.test.tsx +9 -0
- package/src/primitives/Menubar/Menubar.tsx +255 -0
- package/src/primitives/Menubar/index.ts +2 -0
- package/src/primitives/NavigationMenu/NavigationMenu.stories.tsx +14 -0
- package/src/primitives/NavigationMenu/NavigationMenu.test.tsx +9 -0
- package/src/primitives/NavigationMenu/NavigationMenu.tsx +129 -0
- package/src/primitives/NavigationMenu/index.ts +2 -0
- package/src/primitives/Pagination/Pagination.stories.tsx +14 -0
- package/src/primitives/Pagination/Pagination.test.tsx +9 -0
- package/src/primitives/Pagination/Pagination.tsx +118 -0
- package/src/primitives/Pagination/index.ts +2 -0
- package/src/primitives/Popover/Popover.stories.tsx +14 -0
- package/src/primitives/Popover/Popover.test.tsx +9 -0
- package/src/primitives/Popover/Popover.tsx +30 -0
- package/src/primitives/Popover/index.ts +2 -0
- package/src/primitives/Progress/Progress.stories.tsx +14 -0
- package/src/primitives/Progress/Progress.test.tsx +9 -0
- package/src/primitives/Progress/Progress.tsx +20 -0
- package/src/primitives/Progress/index.ts +2 -0
- package/src/primitives/Radio/Radio.stories.tsx +14 -0
- package/src/primitives/Radio/Radio.test.tsx +9 -0
- package/src/primitives/Radio/Radio.tsx +33 -0
- package/src/primitives/Radio/index.ts +2 -0
- package/src/primitives/Resizable/Resizable.stories.tsx +14 -0
- package/src/primitives/Resizable/Resizable.test.tsx +9 -0
- package/src/primitives/Resizable/Resizable.tsx +44 -0
- package/src/primitives/Resizable/index.ts +2 -0
- package/src/primitives/ScrollArea/ScrollArea.stories.tsx +14 -0
- package/src/primitives/ScrollArea/ScrollArea.test.tsx +9 -0
- package/src/primitives/ScrollArea/ScrollArea.tsx +49 -0
- package/src/primitives/ScrollArea/index.ts +2 -0
- package/src/primitives/Select/Select.stories.tsx +14 -0
- package/src/primitives/Select/Select.test.tsx +9 -0
- package/src/primitives/Select/Select.tsx +140 -0
- package/src/primitives/Select/index.ts +2 -0
- package/src/primitives/Separator/Separator.stories.tsx +14 -0
- package/src/primitives/Separator/Separator.test.tsx +9 -0
- package/src/primitives/Separator/Separator.tsx +21 -0
- package/src/primitives/Separator/index.ts +2 -0
- package/src/primitives/Sheet/Sheet.stories.tsx +14 -0
- package/src/primitives/Sheet/Sheet.test.tsx +9 -0
- package/src/primitives/Sheet/Sheet.tsx +88 -0
- package/src/primitives/Sheet/index.ts +2 -0
- package/src/primitives/Skeleton/Skeleton.stories.tsx +14 -0
- package/src/primitives/Skeleton/Skeleton.test.tsx +9 -0
- package/src/primitives/Skeleton/Skeleton.tsx +71 -0
- package/src/primitives/Skeleton/index.ts +2 -0
- package/src/primitives/Slider/Slider.stories.tsx +14 -0
- package/src/primitives/Slider/Slider.test.tsx +9 -0
- package/src/primitives/Slider/Slider.tsx +20 -0
- package/src/primitives/Slider/index.ts +2 -0
- package/src/primitives/Sonner/Sonner.stories.tsx +14 -0
- package/src/primitives/Sonner/Sonner.test.tsx +9 -0
- package/src/primitives/Sonner/Sonner.tsx +30 -0
- package/src/primitives/Sonner/index.ts +2 -0
- package/src/primitives/Spinner/Spinner.stories.tsx +14 -0
- package/src/primitives/Spinner/Spinner.test.tsx +9 -0
- package/src/primitives/Spinner/Spinner.tsx +17 -0
- package/src/primitives/Spinner/index.ts +2 -0
- package/src/primitives/Switch/Switch.stories.tsx +14 -0
- package/src/primitives/Switch/Switch.test.tsx +9 -0
- package/src/primitives/Switch/Switch.tsx +31 -0
- package/src/primitives/Switch/index.ts +2 -0
- package/src/primitives/Table/Table.stories.tsx +14 -0
- package/src/primitives/Table/Table.test.tsx +9 -0
- package/src/primitives/Table/Table.tsx +121 -0
- package/src/primitives/Table/index.ts +2 -0
- package/src/primitives/Tabs/Tabs.stories.tsx +14 -0
- package/src/primitives/Tabs/Tabs.test.tsx +9 -0
- package/src/primitives/Tabs/Tabs.tsx +53 -0
- package/src/primitives/Tabs/index.ts +2 -0
- package/src/primitives/Textarea/Textarea.stories.tsx +14 -0
- package/src/primitives/Textarea/Textarea.test.tsx +9 -0
- package/src/primitives/Textarea/Textarea.tsx +22 -0
- package/src/primitives/Textarea/index.ts +2 -0
- package/src/primitives/Toggle/Toggle.stories.tsx +14 -0
- package/src/primitives/Toggle/Toggle.test.tsx +9 -0
- package/src/primitives/Toggle/Toggle.tsx +44 -0
- package/src/primitives/Toggle/index.ts +2 -0
- package/src/primitives/ToggleGroup/ToggleGroup.stories.tsx +14 -0
- package/src/primitives/ToggleGroup/ToggleGroup.test.tsx +9 -0
- package/src/primitives/ToggleGroup/ToggleGroup.tsx +62 -0
- package/src/primitives/ToggleGroup/index.ts +2 -0
- package/src/primitives/Tooltip/Tooltip.stories.tsx +14 -0
- package/src/primitives/Tooltip/Tooltip.test.tsx +9 -0
- package/src/primitives/Tooltip/Tooltip.tsx +29 -0
- package/src/primitives/Tooltip/index.ts +2 -0
- package/src/primitives/accordion.tsx +56 -0
- package/src/primitives/alert-dialog.tsx +140 -0
- package/src/primitives/alert.tsx +60 -0
- package/src/primitives/aspect-ratio.tsx +6 -0
- package/src/primitives/avatar.tsx +100 -0
- package/src/primitives/badge.tsx +28 -0
- package/src/primitives/button.tsx +43 -0
- package/src/primitives/calendar.tsx +214 -0
- package/src/primitives/card.tsx +48 -0
- package/src/primitives/carousel.tsx +261 -0
- package/src/primitives/chart.tsx +368 -0
- package/src/primitives/checkbox.tsx +26 -0
- package/src/primitives/code-block.tsx +173 -0
- package/src/primitives/collapsible.tsx +12 -0
- package/src/primitives/command.tsx +154 -0
- package/src/primitives/comparison.tsx +184 -0
- package/src/primitives/context-menu.tsx +101 -0
- package/src/primitives/dialog.tsx +88 -0
- package/src/primitives/drawer.tsx +117 -0
- package/src/primitives/dropdown-menu.tsx +111 -0
- package/src/primitives/form.tsx +179 -0
- package/src/primitives/hover-card.tsx +30 -0
- package/src/primitives/input-otp.tsx +70 -0
- package/src/primitives/input.tsx +23 -0
- package/src/primitives/label.tsx +27 -0
- package/src/primitives/logo-carousel.tsx +110 -0
- package/src/primitives/marquee.tsx +84 -0
- package/src/primitives/menubar.tsx +255 -0
- package/src/primitives/navigation-menu.tsx +129 -0
- package/src/primitives/pagination.tsx +118 -0
- package/src/primitives/popover.tsx +29 -0
- package/src/primitives/progress.tsx +20 -0
- package/src/primitives/qr-code.tsx +89 -0
- package/src/primitives/radio.tsx +33 -0
- package/src/primitives/rating.tsx +157 -0
- package/src/primitives/resizable.tsx +43 -0
- package/src/primitives/scroll-area.tsx +49 -0
- package/src/primitives/select.tsx +137 -0
- package/src/primitives/separator.tsx +21 -0
- package/src/primitives/sheet.tsx +87 -0
- package/src/primitives/skeleton.tsx +11 -0
- package/src/primitives/slider.tsx +20 -0
- package/src/primitives/sonner.tsx +27 -0
- package/src/primitives/spinner.tsx +17 -0
- package/src/primitives/switch.tsx +30 -0
- package/src/primitives/table.tsx +121 -0
- package/src/primitives/tabs.tsx +53 -0
- package/src/primitives/textarea.tsx +22 -0
- package/src/primitives/texture-card.tsx +52 -0
- package/src/primitives/toggle-group.tsx +62 -0
- package/src/primitives/toggle.tsx +44 -0
- package/src/primitives/tooltip.tsx +28 -0
- package/src/primitives/utils/cn.ts +1 -0
- package/src/provider/otf-ui-provider.tsx +66 -0
- package/src/styles.css +6 -0
- package/src/text/AnimatedNumber.tsx +157 -0
- package/src/text/Body.tsx +47 -0
- package/src/text/Caption.tsx +32 -0
- package/src/text/Code.tsx +43 -0
- package/src/text/GradientHeading.tsx +90 -0
- package/src/text/Heading.tsx +44 -0
- package/src/text/TextReveal.tsx +96 -0
- package/src/text/Typewriter.tsx +107 -0
- package/src/text/index.ts +8 -0
- package/src/theme/ColorSchemeSelect.tsx +74 -0
- package/src/theme/ThemeSwitch.tsx +116 -0
- package/src/theme/index.ts +2 -0
- package/src/themes/base.css +25 -0
- package/src/themes/glass.css +142 -0
- package/src/themes/linear.css +123 -0
- package/src/themes/midnight.css +131 -0
- package/src/themes/minimal.css +121 -0
- package/src/utils/cn.ts +6 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { ChevronLeft, ChevronRight } from 'lucide-react'
|
|
3
|
+
import { cn } from '../utils/cn'
|
|
4
|
+
|
|
5
|
+
const SidebarCtx = React.createContext<{ collapsed: boolean }>({ collapsed: false })
|
|
6
|
+
const useSidebarCtx = () => React.useContext(SidebarCtx)
|
|
7
|
+
|
|
8
|
+
const makeSlot = (name: string, cls: string) => {
|
|
9
|
+
const C = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
10
|
+
({ className, ...p }, ref) => <div ref={ref} className={cn(cls, className)} {...p} />
|
|
11
|
+
)
|
|
12
|
+
C.displayName = name
|
|
13
|
+
return C
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface SidebarProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
17
|
+
collapsed?: boolean
|
|
18
|
+
onCollapse?: () => void
|
|
19
|
+
width?: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const Sidebar = React.forwardRef<HTMLDivElement, SidebarProps>(
|
|
23
|
+
({ className, collapsed = false, onCollapse, width = '240px', style, children, ...props }, ref) => (
|
|
24
|
+
<SidebarCtx.Provider value={{ collapsed }}>
|
|
25
|
+
<div
|
|
26
|
+
ref={ref}
|
|
27
|
+
className={cn('flex flex-col h-full bg-[hsl(var(--card))] border-r border-[hsl(var(--border))] transition-all duration-200 overflow-hidden', className)}
|
|
28
|
+
style={{ width: collapsed ? '48px' : width, ...style }}
|
|
29
|
+
{...props}
|
|
30
|
+
>
|
|
31
|
+
<div className="flex-1 overflow-y-auto overflow-x-hidden">{children}</div>
|
|
32
|
+
{onCollapse && (
|
|
33
|
+
<button
|
|
34
|
+
onClick={onCollapse}
|
|
35
|
+
className="flex items-center justify-center h-10 w-full border-t border-[hsl(var(--border))] hover:bg-[hsl(var(--accent))] text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] transition-colors shrink-0"
|
|
36
|
+
>
|
|
37
|
+
{collapsed ? <ChevronRight className="h-4 w-4" /> : <ChevronLeft className="h-4 w-4" />}
|
|
38
|
+
</button>
|
|
39
|
+
)}
|
|
40
|
+
</div>
|
|
41
|
+
</SidebarCtx.Provider>
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
Sidebar.displayName = 'Sidebar'
|
|
45
|
+
|
|
46
|
+
export const SidebarHeader = makeSlot('SidebarHeader', 'px-3 py-4 border-b border-[hsl(var(--border))] shrink-0')
|
|
47
|
+
export const SidebarContent = makeSlot('SidebarContent', 'flex-1 overflow-y-auto py-2')
|
|
48
|
+
export const SidebarFooter = makeSlot('SidebarFooter', 'px-3 py-3 border-t border-[hsl(var(--border))] shrink-0')
|
|
49
|
+
export const SidebarGroup = makeSlot('SidebarGroup', 'mb-2')
|
|
50
|
+
export const SidebarSeparator = makeSlot('SidebarSeparator', 'h-px bg-[hsl(var(--border))] mx-3 my-2')
|
|
51
|
+
|
|
52
|
+
export const SidebarGroupLabel = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
53
|
+
({ className, ...props }, ref) => {
|
|
54
|
+
const { collapsed } = useSidebarCtx()
|
|
55
|
+
return (
|
|
56
|
+
<div
|
|
57
|
+
ref={ref}
|
|
58
|
+
className={cn('px-3 py-1 text-xs font-semibold text-[hsl(var(--muted-foreground))] uppercase tracking-wider', collapsed && 'sr-only', className)}
|
|
59
|
+
{...props}
|
|
60
|
+
/>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
SidebarGroupLabel.displayName = 'SidebarGroupLabel'
|
|
65
|
+
|
|
66
|
+
export interface SidebarItemProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onClick'> {
|
|
67
|
+
icon?: React.ReactNode
|
|
68
|
+
label: string
|
|
69
|
+
active?: boolean
|
|
70
|
+
href?: string
|
|
71
|
+
badge?: string | number
|
|
72
|
+
onClick?: React.MouseEventHandler<HTMLElement>
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export const SidebarItem = React.forwardRef<HTMLDivElement, SidebarItemProps>(
|
|
76
|
+
({ className, icon, label, active, href, badge, onClick, ...props }, ref) => {
|
|
77
|
+
const { collapsed } = useSidebarCtx()
|
|
78
|
+
const cls = cn(
|
|
79
|
+
'flex items-center gap-2.5 px-3 py-2 rounded-md cursor-pointer transition-colors mx-1 text-sm',
|
|
80
|
+
active
|
|
81
|
+
? 'bg-[hsl(var(--accent))] text-[hsl(var(--foreground))] font-medium'
|
|
82
|
+
: 'text-[hsl(var(--muted-foreground))] hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]',
|
|
83
|
+
collapsed && 'justify-center px-0 mx-2',
|
|
84
|
+
className
|
|
85
|
+
)
|
|
86
|
+
const inner = (
|
|
87
|
+
<>
|
|
88
|
+
{icon && <span className="shrink-0 flex items-center justify-center w-4 h-4">{icon}</span>}
|
|
89
|
+
{!collapsed && <span className="flex-1 min-w-0 truncate">{label}</span>}
|
|
90
|
+
{!collapsed && badge !== undefined && (
|
|
91
|
+
<span className="text-[10px] px-1.5 py-0.5 rounded-full bg-[hsl(var(--primary))] bg-opacity-10 text-[hsl(var(--primary))] shrink-0 font-medium">{badge}</span>
|
|
92
|
+
)}
|
|
93
|
+
</>
|
|
94
|
+
)
|
|
95
|
+
if (href) return <a href={href} className={cls} onClick={onClick}>{inner}</a>
|
|
96
|
+
return <div ref={ref} role="button" tabIndex={0} className={cls} onClick={onClick} {...props}>{inner}</div>
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
SidebarItem.displayName = 'SidebarItem'
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { SplitPage } from './SplitPage'
|
|
3
|
+
|
|
4
|
+
// TODO: add all variants
|
|
5
|
+
const meta: Meta<typeof SplitPage> = {
|
|
6
|
+
title: 'Layouts/SplitPage',
|
|
7
|
+
component: SplitPage,
|
|
8
|
+
tags: ['autodocs'],
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default meta
|
|
12
|
+
type Story = StoryObj<typeof SplitPage>
|
|
13
|
+
|
|
14
|
+
export const Default: Story = {}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { render } from '@testing-library/react'
|
|
2
|
+
import { SplitPage } from './SplitPage'
|
|
3
|
+
|
|
4
|
+
// TODO: add full a11y + variant tests
|
|
5
|
+
describe('SplitPage', () => {
|
|
6
|
+
it('renders without throwing', () => {
|
|
7
|
+
expect(() => render(<SplitPage />)).not.toThrow()
|
|
8
|
+
})
|
|
9
|
+
})
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '../utils/cn'
|
|
3
|
+
|
|
4
|
+
export const SplitPage = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
5
|
+
({ className, ...props }, ref) => (
|
|
6
|
+
<div ref={ref} className={cn('flex h-full w-full overflow-hidden', className)} {...props} />
|
|
7
|
+
)
|
|
8
|
+
)
|
|
9
|
+
SplitPage.displayName = 'SplitPage'
|
|
10
|
+
|
|
11
|
+
export interface SplitPageListProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
12
|
+
width?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const SplitPageList = React.forwardRef<HTMLDivElement, SplitPageListProps>(
|
|
16
|
+
({ className, width = '320px', style, ...props }, ref) => (
|
|
17
|
+
<div
|
|
18
|
+
ref={ref}
|
|
19
|
+
className={cn('shrink-0 h-full overflow-auto border-r border-[hsl(var(--border))]', className)}
|
|
20
|
+
style={{ width, ...style }}
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
)
|
|
24
|
+
)
|
|
25
|
+
SplitPageList.displayName = 'SplitPageList'
|
|
26
|
+
|
|
27
|
+
export const SplitPageDetail = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
28
|
+
({ className, ...props }, ref) => (
|
|
29
|
+
<div ref={ref} className={cn('flex-1 min-w-0 h-full overflow-auto', className)} {...props} />
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
SplitPageDetail.displayName = 'SplitPageDetail'
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { Stack } from './Stack'
|
|
3
|
+
|
|
4
|
+
// TODO: add all variants
|
|
5
|
+
const meta: Meta<typeof Stack> = {
|
|
6
|
+
title: 'Layouts/Stack',
|
|
7
|
+
component: Stack,
|
|
8
|
+
tags: ['autodocs'],
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default meta
|
|
12
|
+
type Story = StoryObj<typeof Stack>
|
|
13
|
+
|
|
14
|
+
export const Default: Story = {}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '../utils/cn'
|
|
3
|
+
|
|
4
|
+
type Direction = 'row' | 'col' | 'row-reverse' | 'col-reverse'
|
|
5
|
+
type Align = 'start' | 'center' | 'end' | 'stretch' | 'baseline'
|
|
6
|
+
type Justify = 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly'
|
|
7
|
+
|
|
8
|
+
const dirMap: Record<Direction, string> = {
|
|
9
|
+
row: 'flex-row', col: 'flex-col',
|
|
10
|
+
'row-reverse': 'flex-row-reverse', 'col-reverse': 'flex-col-reverse',
|
|
11
|
+
}
|
|
12
|
+
const alignMap: Record<Align, string> = {
|
|
13
|
+
start: 'items-start', center: 'items-center', end: 'items-end',
|
|
14
|
+
stretch: 'items-stretch', baseline: 'items-baseline',
|
|
15
|
+
}
|
|
16
|
+
const justifyMap: Record<Justify, string> = {
|
|
17
|
+
start: 'justify-start', center: 'justify-center', end: 'justify-end',
|
|
18
|
+
between: 'justify-between', around: 'justify-around', evenly: 'justify-evenly',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface StackProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
22
|
+
gap?: number
|
|
23
|
+
direction?: Direction
|
|
24
|
+
align?: Align
|
|
25
|
+
justify?: Justify
|
|
26
|
+
wrap?: boolean
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const Stack = React.forwardRef<HTMLDivElement, StackProps>(
|
|
30
|
+
({ className, gap, direction = 'col', align, justify, wrap, style, ...props }, ref) => (
|
|
31
|
+
<div
|
|
32
|
+
ref={ref}
|
|
33
|
+
className={cn(
|
|
34
|
+
'flex',
|
|
35
|
+
dirMap[direction],
|
|
36
|
+
align && alignMap[align],
|
|
37
|
+
justify && justifyMap[justify],
|
|
38
|
+
wrap && 'flex-wrap',
|
|
39
|
+
className
|
|
40
|
+
)}
|
|
41
|
+
style={{ ...(gap !== undefined ? { gap: `${gap * 4}px` } : {}), ...style }}
|
|
42
|
+
{...props}
|
|
43
|
+
/>
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
Stack.displayName = 'Stack'
|
|
47
|
+
|
|
48
|
+
export const HStack = React.forwardRef<HTMLDivElement, Omit<StackProps, 'direction'>>(
|
|
49
|
+
(props, ref) => <Stack ref={ref} direction="row" {...props} />
|
|
50
|
+
)
|
|
51
|
+
HStack.displayName = 'HStack'
|
|
52
|
+
|
|
53
|
+
export const VStack = React.forwardRef<HTMLDivElement, Omit<StackProps, 'direction'>>(
|
|
54
|
+
(props, ref) => <Stack ref={ref} direction="col" {...props} />
|
|
55
|
+
)
|
|
56
|
+
VStack.displayName = 'VStack'
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { Menu, X } from 'lucide-react'
|
|
5
|
+
import { cn } from '../utils/cn'
|
|
6
|
+
|
|
7
|
+
interface AppShellCtxValue {
|
|
8
|
+
collapsed: boolean
|
|
9
|
+
setCollapsed: (v: boolean) => void
|
|
10
|
+
mobileOpen: boolean
|
|
11
|
+
setMobileOpen: (v: boolean) => void
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const AppShellCtx = React.createContext<AppShellCtxValue>({
|
|
15
|
+
collapsed: false,
|
|
16
|
+
setCollapsed: () => {},
|
|
17
|
+
mobileOpen: false,
|
|
18
|
+
setMobileOpen: () => {},
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
export const useAppShell = () => React.useContext(AppShellCtx)
|
|
22
|
+
|
|
23
|
+
export interface AppShellProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
24
|
+
defaultCollapsed?: boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const AppShell = React.forwardRef<HTMLDivElement, AppShellProps>(
|
|
28
|
+
({ className, defaultCollapsed = false, children, ...props }, ref) => {
|
|
29
|
+
const [collapsed, setCollapsed] = React.useState(defaultCollapsed)
|
|
30
|
+
const [mobileOpen, setMobileOpen] = React.useState(false)
|
|
31
|
+
|
|
32
|
+
// Close mobile sidebar on nav link clicks inside the shell
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
const handleClick = (e: MouseEvent) => {
|
|
35
|
+
const target = e.target as HTMLElement
|
|
36
|
+
if (target.closest('a[href]') || target.closest('[data-mobile-close]')) {
|
|
37
|
+
setMobileOpen(false)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
document.addEventListener('click', handleClick)
|
|
41
|
+
return () => document.removeEventListener('click', handleClick)
|
|
42
|
+
}, [])
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<AppShellCtx.Provider value={{ collapsed, setCollapsed, mobileOpen, setMobileOpen }}>
|
|
46
|
+
<div
|
|
47
|
+
ref={ref}
|
|
48
|
+
className={cn('flex h-screen w-full overflow-hidden bg-background', className)}
|
|
49
|
+
{...props}
|
|
50
|
+
>
|
|
51
|
+
{/* Mobile backdrop — rendered inside AppShell so it doesn't break SSR */}
|
|
52
|
+
{mobileOpen && (
|
|
53
|
+
<div
|
|
54
|
+
className="fixed inset-0 z-40 bg-black/50 md:hidden"
|
|
55
|
+
onClick={() => setMobileOpen(false)}
|
|
56
|
+
/>
|
|
57
|
+
)}
|
|
58
|
+
{children}
|
|
59
|
+
</div>
|
|
60
|
+
</AppShellCtx.Provider>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
AppShell.displayName = 'AppShell'
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Sidebar wrapper.
|
|
68
|
+
* On MOBILE → hidden (display: none) by default; shown as a fixed overlay when mobileOpen=true.
|
|
69
|
+
* On DESKTOP → always visible as a normal flex child.
|
|
70
|
+
*
|
|
71
|
+
* ALWAYS wrap <Sidebar> in <AppShellSidebar> — never put <Sidebar> directly in <AppShell>.
|
|
72
|
+
* Without this wrapper the sidebar is visible on all screen sizes.
|
|
73
|
+
*/
|
|
74
|
+
export const AppShellSidebar = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
75
|
+
({ className, ...props }, ref) => {
|
|
76
|
+
const { mobileOpen } = useAppShell()
|
|
77
|
+
return (
|
|
78
|
+
<div
|
|
79
|
+
ref={ref}
|
|
80
|
+
className={cn(
|
|
81
|
+
'shrink-0 h-full',
|
|
82
|
+
// Mobile: hidden by default; shows as fixed overlay when open
|
|
83
|
+
mobileOpen
|
|
84
|
+
? 'fixed inset-y-0 left-0 z-50 flex'
|
|
85
|
+
: 'hidden md:flex',
|
|
86
|
+
// Desktop: always visible as a normal relative element
|
|
87
|
+
'md:relative',
|
|
88
|
+
className
|
|
89
|
+
)}
|
|
90
|
+
{...props}
|
|
91
|
+
/>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
AppShellSidebar.displayName = 'AppShellSidebar'
|
|
96
|
+
|
|
97
|
+
export const AppShellMain = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
98
|
+
({ className, ...props }, ref) => (
|
|
99
|
+
<div ref={ref} className={cn('flex-1 min-w-0 flex flex-col overflow-auto', className)} {...props} />
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
AppShellMain.displayName = 'AppShellMain'
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Hamburger/close button — place in your mobile header bar (md:hidden).
|
|
106
|
+
* Toggles the sidebar overlay on mobile.
|
|
107
|
+
*/
|
|
108
|
+
export const MobileSidebarTrigger = React.forwardRef<HTMLButtonElement, React.ButtonHTMLAttributes<HTMLButtonElement>>(
|
|
109
|
+
({ className, ...props }, ref) => {
|
|
110
|
+
const { mobileOpen, setMobileOpen } = useAppShell()
|
|
111
|
+
return (
|
|
112
|
+
<button
|
|
113
|
+
ref={ref}
|
|
114
|
+
onClick={() => setMobileOpen(!mobileOpen)}
|
|
115
|
+
aria-label={mobileOpen ? 'Close menu' : 'Open menu'}
|
|
116
|
+
className={cn(
|
|
117
|
+
'md:hidden inline-flex items-center justify-center rounded-md p-2',
|
|
118
|
+
'text-muted-foreground hover:bg-accent hover:text-accent-foreground',
|
|
119
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
|
120
|
+
className
|
|
121
|
+
)}
|
|
122
|
+
{...props}
|
|
123
|
+
>
|
|
124
|
+
{mobileOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
|
|
125
|
+
</button>
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
)
|
|
129
|
+
MobileSidebarTrigger.displayName = 'MobileSidebarTrigger'
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '../utils/cn'
|
|
3
|
+
|
|
4
|
+
type ContainerSize = 'sm' | 'md' | 'lg' | 'xl' | 'full'
|
|
5
|
+
|
|
6
|
+
const sizeMap: Record<ContainerSize, string> = {
|
|
7
|
+
sm: 'max-w-screen-sm',
|
|
8
|
+
md: 'max-w-screen-md',
|
|
9
|
+
lg: 'max-w-screen-lg',
|
|
10
|
+
xl: 'max-w-screen-xl',
|
|
11
|
+
full: 'max-w-full',
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ContainerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
15
|
+
size?: ContainerSize
|
|
16
|
+
noPadding?: boolean
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const Container = React.forwardRef<HTMLDivElement, ContainerProps>(
|
|
20
|
+
({ className, size = 'lg', noPadding = false, ...props }, ref) => (
|
|
21
|
+
<div
|
|
22
|
+
ref={ref}
|
|
23
|
+
className={cn(
|
|
24
|
+
'mx-auto w-full',
|
|
25
|
+
sizeMap[size],
|
|
26
|
+
!noPadding && 'px-4 sm:px-6 lg:px-8',
|
|
27
|
+
className
|
|
28
|
+
)}
|
|
29
|
+
{...props}
|
|
30
|
+
/>
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
Container.displayName = 'Container'
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '../utils/cn'
|
|
3
|
+
|
|
4
|
+
export interface NavbarProps extends React.HTMLAttributes<HTMLElement> {
|
|
5
|
+
sticky?: boolean
|
|
6
|
+
border?: boolean
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const Navbar = React.forwardRef<HTMLElement, NavbarProps>(
|
|
10
|
+
({ className, sticky = false, border = true, ...props }, ref) => (
|
|
11
|
+
<nav
|
|
12
|
+
ref={ref}
|
|
13
|
+
className={cn(
|
|
14
|
+
'z-40 w-full h-14 flex items-center bg-[hsl(var(--background))]',
|
|
15
|
+
sticky && 'sticky top-0',
|
|
16
|
+
border && 'border-b border-[hsl(var(--border))]',
|
|
17
|
+
className
|
|
18
|
+
)}
|
|
19
|
+
{...props}
|
|
20
|
+
/>
|
|
21
|
+
)
|
|
22
|
+
)
|
|
23
|
+
Navbar.displayName = 'Navbar'
|
|
24
|
+
|
|
25
|
+
export const NavbarBrand = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
26
|
+
({ className, ...props }, ref) => (
|
|
27
|
+
<div ref={ref} className={cn('flex items-center gap-2 px-4 shrink-0', className)} {...props} />
|
|
28
|
+
)
|
|
29
|
+
)
|
|
30
|
+
NavbarBrand.displayName = 'NavbarBrand'
|
|
31
|
+
|
|
32
|
+
type Align = 'start' | 'center' | 'end'
|
|
33
|
+
|
|
34
|
+
const alignMap: Record<Align, string> = {
|
|
35
|
+
start: 'justify-start',
|
|
36
|
+
center: 'justify-center flex-1',
|
|
37
|
+
end: 'justify-end ml-auto',
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface NavbarContentProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
41
|
+
align?: Align
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const NavbarContent = React.forwardRef<HTMLDivElement, NavbarContentProps>(
|
|
45
|
+
({ className, align = 'start', ...props }, ref) => (
|
|
46
|
+
<div
|
|
47
|
+
ref={ref}
|
|
48
|
+
className={cn('flex items-center gap-1 px-2', alignMap[align], className)}
|
|
49
|
+
{...props}
|
|
50
|
+
/>
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
NavbarContent.displayName = 'NavbarContent'
|
|
54
|
+
|
|
55
|
+
export const NavbarItem = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
56
|
+
({ className, ...props }, ref) => (
|
|
57
|
+
<div ref={ref} className={cn('flex items-center', className)} {...props} />
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
NavbarItem.displayName = 'NavbarItem'
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '../utils/cn'
|
|
3
|
+
|
|
4
|
+
export interface PageProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
maxWidth?: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const Page = React.forwardRef<HTMLDivElement, PageProps>(
|
|
9
|
+
({ className, maxWidth, style, ...props }, ref) => (
|
|
10
|
+
<div
|
|
11
|
+
ref={ref}
|
|
12
|
+
className={cn('flex flex-col min-h-full w-full', className)}
|
|
13
|
+
style={{ maxWidth, ...style }}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
)
|
|
17
|
+
)
|
|
18
|
+
Page.displayName = 'Page'
|
|
19
|
+
|
|
20
|
+
export const PageHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
21
|
+
({ className, ...props }, ref) => (
|
|
22
|
+
<div
|
|
23
|
+
ref={ref}
|
|
24
|
+
className={cn('flex items-start justify-between gap-4 px-6 py-4 border-b border-[hsl(var(--border))]', className)}
|
|
25
|
+
{...props}
|
|
26
|
+
/>
|
|
27
|
+
)
|
|
28
|
+
)
|
|
29
|
+
PageHeader.displayName = 'PageHeader'
|
|
30
|
+
|
|
31
|
+
export const PageTitle = React.forwardRef<HTMLHeadingElement, React.HTMLAttributes<HTMLHeadingElement>>(
|
|
32
|
+
({ className, ...props }, ref) => (
|
|
33
|
+
<h1
|
|
34
|
+
ref={ref}
|
|
35
|
+
className={cn('text-2xl font-semibold tracking-tight text-[hsl(var(--foreground))]', className)}
|
|
36
|
+
{...props}
|
|
37
|
+
/>
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
PageTitle.displayName = 'PageTitle'
|
|
41
|
+
|
|
42
|
+
export const PageDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
|
|
43
|
+
({ className, ...props }, ref) => (
|
|
44
|
+
<p ref={ref} className={cn('text-sm text-[hsl(var(--muted-foreground))] mt-1', className)} {...props} />
|
|
45
|
+
)
|
|
46
|
+
)
|
|
47
|
+
PageDescription.displayName = 'PageDescription'
|
|
48
|
+
|
|
49
|
+
export const PageActions = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
50
|
+
({ className, ...props }, ref) => (
|
|
51
|
+
<div ref={ref} className={cn('flex items-center gap-2 shrink-0', className)} {...props} />
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
PageActions.displayName = 'PageActions'
|
|
55
|
+
|
|
56
|
+
export const PageBody = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
57
|
+
({ className, ...props }, ref) => (
|
|
58
|
+
<div ref={ref} className={cn('flex-1 p-6 flex flex-col gap-6', className)} {...props} />
|
|
59
|
+
)
|
|
60
|
+
)
|
|
61
|
+
PageBody.displayName = 'PageBody'
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '../utils/cn'
|
|
3
|
+
|
|
4
|
+
export interface ResizeBoxProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
resize?: 'horizontal' | 'vertical' | 'both' | 'none'
|
|
6
|
+
minWidth?: number
|
|
7
|
+
minHeight?: number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const ResizeBox = React.forwardRef<HTMLDivElement, ResizeBoxProps>(
|
|
11
|
+
({ className, resize = 'both', minWidth = 100, minHeight = 100, style, ...props }, ref) => (
|
|
12
|
+
<div
|
|
13
|
+
ref={ref}
|
|
14
|
+
className={cn('overflow-auto relative', className)}
|
|
15
|
+
style={{ resize, minWidth, minHeight, ...style }}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
)
|
|
19
|
+
)
|
|
20
|
+
ResizeBox.displayName = 'ResizeBox'
|
|
21
|
+
|
|
22
|
+
const HandleIcon = () => (
|
|
23
|
+
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" aria-hidden>
|
|
24
|
+
<path d="M8 2L2 8" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
|
|
25
|
+
<path d="M8 5L5 8" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
|
|
26
|
+
<path d="M8 8L8 8" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
|
|
27
|
+
</svg>
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
export const ResizeHandle = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
31
|
+
({ className, ...props }, ref) => (
|
|
32
|
+
<div
|
|
33
|
+
ref={ref}
|
|
34
|
+
className={cn(
|
|
35
|
+
'absolute bottom-0 right-0 w-5 h-5 flex items-center justify-center',
|
|
36
|
+
'cursor-se-resize text-[hsl(var(--muted-foreground))] opacity-50 hover:opacity-100 transition-opacity',
|
|
37
|
+
className
|
|
38
|
+
)}
|
|
39
|
+
{...props}
|
|
40
|
+
>
|
|
41
|
+
<HandleIcon />
|
|
42
|
+
</div>
|
|
43
|
+
)
|
|
44
|
+
)
|
|
45
|
+
ResizeHandle.displayName = 'ResizeHandle'
|