@devxcrew/react-ui 0.0.0-stage → 0.1.7
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/README.md +85 -2
- package/package.json +105 -4
- package/src/blocks/agent-chat-workspace/agent-chat-workspace.tsx +162 -0
- package/src/blocks/agent-chat-workspace/index.ts +2 -0
- package/src/blocks/agent-provider-settings/agent-provider-settings.tsx +183 -0
- package/src/blocks/agent-provider-settings/index.ts +2 -0
- package/src/blocks/agent-task-workspace/agent-task-workspace.tsx +48 -0
- package/src/blocks/agent-task-workspace/index.ts +2 -0
- package/src/blocks/analysis-context/analysis-context.tsx +6 -0
- package/src/blocks/analysis-context/index.ts +1 -0
- package/src/blocks/app-header/app-header.tsx +159 -0
- package/src/blocks/app-header/index.ts +2 -0
- package/src/blocks/archived-chat-workspace/archived-chat-workspace.tsx +29 -0
- package/src/blocks/archived-chat-workspace/index.ts +2 -0
- package/src/blocks/auth/README.md +32 -0
- package/src/blocks/auth/admin-login-page.tsx +15 -0
- package/src/blocks/auth/admin-password-forgot-page.tsx +5 -0
- package/src/blocks/auth/auth-page-layout.tsx +90 -0
- package/src/blocks/auth/client-login-page.tsx +20 -0
- package/src/blocks/auth/client-password-forgot-page.tsx +5 -0
- package/src/blocks/auth/identity-management-desk.tsx +530 -0
- package/src/blocks/auth/index.ts +12 -0
- package/src/blocks/auth/login-page.tsx +206 -0
- package/src/blocks/auth/password-forgot-page.tsx +60 -0
- package/src/blocks/auth/portal-pages.tsx +32 -0
- package/src/blocks/auth/privileged-desk.tsx +55 -0
- package/src/blocks/auth/register-page.tsx +117 -0
- package/src/blocks/auth/session-boundary.tsx +296 -0
- package/src/blocks/auth/super-admin-login-page.tsx +15 -0
- package/src/blocks/auth/super-admin-password-forgot-page.tsx +5 -0
- package/src/blocks/blog/blog-card.tsx +156 -0
- package/src/blocks/blog/blog-reader.tsx +175 -0
- package/src/blocks/blog/blog-types.ts +47 -0
- package/src/blocks/blog/index.ts +3 -0
- package/src/blocks/chat-composer/chat-composer.tsx +140 -0
- package/src/blocks/chat-composer/index.ts +1 -0
- package/src/blocks/chat-history/chat-history.tsx +59 -0
- package/src/blocks/chat-history/index.ts +1 -0
- package/src/blocks/chat-response-progress/chat-response-progress.tsx +34 -0
- package/src/blocks/chat-response-progress/index.ts +2 -0
- package/src/blocks/chat-runtime-controls/chat-runtime-controls.tsx +56 -0
- package/src/blocks/chat-runtime-controls/index.ts +2 -0
- package/src/blocks/chat-runtime-trace/chat-runtime-trace.tsx +71 -0
- package/src/blocks/chat-runtime-trace/index.ts +2 -0
- package/src/blocks/codex-connection-settings/codex-connection-settings.tsx +42 -0
- package/src/blocks/codex-connection-settings/index.ts +1 -0
- package/src/blocks/dropzone/dropzone-file-item.tsx +113 -0
- package/src/blocks/dropzone/dropzone-types.ts +32 -0
- package/src/blocks/dropzone/dropzone.tsx +216 -0
- package/src/blocks/dropzone/index.ts +3 -0
- package/src/blocks/ecommerce/cart/cart-drawer.tsx +228 -0
- package/src/blocks/ecommerce/cart/cart-types.ts +27 -0
- package/src/blocks/ecommerce/cart/index.ts +2 -0
- package/src/blocks/ecommerce/categories/categories-types.ts +23 -0
- package/src/blocks/ecommerce/categories/category-showcase.tsx +125 -0
- package/src/blocks/ecommerce/categories/index.ts +2 -0
- package/src/blocks/ecommerce/checkout/checkout-types.ts +48 -0
- package/src/blocks/ecommerce/checkout/checkout-wizard.tsx +468 -0
- package/src/blocks/ecommerce/checkout/index.ts +2 -0
- package/src/blocks/ecommerce/comparison/comparison-types.ts +28 -0
- package/src/blocks/ecommerce/comparison/index.ts +2 -0
- package/src/blocks/ecommerce/comparison/product-comparison.tsx +174 -0
- package/src/blocks/ecommerce/coupon-wallet/coupon-wallet-types.ts +21 -0
- package/src/blocks/ecommerce/coupon-wallet/coupon-wallet.tsx +154 -0
- package/src/blocks/ecommerce/coupon-wallet/index.ts +2 -0
- package/src/blocks/ecommerce/delivery-tracker/delivery-tracker-types.ts +20 -0
- package/src/blocks/ecommerce/delivery-tracker/delivery-tracker.tsx +169 -0
- package/src/blocks/ecommerce/delivery-tracker/index.ts +2 -0
- package/src/blocks/ecommerce/index.ts +12 -0
- package/src/blocks/ecommerce/payment-methods/index.ts +2 -0
- package/src/blocks/ecommerce/payment-methods/payment-method-selector.tsx +224 -0
- package/src/blocks/ecommerce/payment-methods/payment-methods-types.ts +21 -0
- package/src/blocks/ecommerce/price-history/index.ts +2 -0
- package/src/blocks/ecommerce/price-history/price-history-chart.tsx +217 -0
- package/src/blocks/ecommerce/price-history/price-history-types.ts +16 -0
- package/src/blocks/ecommerce/reviews/index.ts +2 -0
- package/src/blocks/ecommerce/reviews/reviews-section.tsx +309 -0
- package/src/blocks/ecommerce/reviews/reviews-types.ts +26 -0
- package/src/blocks/ecommerce/wishlist/index.ts +2 -0
- package/src/blocks/ecommerce/wishlist/wishlist-grid.tsx +149 -0
- package/src/blocks/ecommerce/wishlist/wishlist-types.ts +19 -0
- package/src/blocks/execution-status/README.md +25 -0
- package/src/blocks/execution-status/execution-status.tsx +135 -0
- package/src/blocks/execution-status/index.ts +2 -0
- package/src/blocks/file-tree/file-icons.tsx +84 -0
- package/src/blocks/file-tree/file-tree-node.tsx +158 -0
- package/src/blocks/file-tree/file-tree-types.ts +33 -0
- package/src/blocks/file-tree/file-tree.tsx +163 -0
- package/src/blocks/file-tree/index.ts +5 -0
- package/src/blocks/filter-builder/filter-builder.tsx +169 -0
- package/src/blocks/filter-builder/filter-row.tsx +164 -0
- package/src/blocks/filter-builder/filter-types.ts +61 -0
- package/src/blocks/filter-builder/index.ts +12 -0
- package/src/blocks/footer/footer-types.ts +35 -0
- package/src/blocks/footer/index.ts +2 -0
- package/src/blocks/footer/site-footer.tsx +212 -0
- package/src/blocks/form/form-block.tsx +113 -0
- package/src/blocks/form/form-lookup-field.tsx +60 -0
- package/src/blocks/form/index.ts +4 -0
- package/src/blocks/handover-stack/handover-stack.tsx +41 -0
- package/src/blocks/handover-stack/index.ts +1 -0
- package/src/blocks/idea-handover/idea-handover-readiness.ts +41 -0
- package/src/blocks/idea-handover/idea-handover-workspace.tsx +150 -0
- package/src/blocks/idea-handover/index.ts +4 -0
- package/src/blocks/kanban/index.ts +11 -0
- package/src/blocks/kanban/kanban-board.tsx +146 -0
- package/src/blocks/kanban/kanban-card.tsx +149 -0
- package/src/blocks/kanban/kanban-column.tsx +102 -0
- package/src/blocks/kanban/kanban-types.ts +38 -0
- package/src/blocks/loader/global-loader.tsx +90 -0
- package/src/blocks/loader/index.ts +1 -0
- package/src/blocks/mascot/README.md +21 -0
- package/src/blocks/mascot/index.ts +2 -0
- package/src/blocks/mascot/mascot.tsx +202 -0
- package/src/blocks/master-list/README.md +21 -0
- package/src/blocks/master-list/index.ts +12 -0
- package/src/blocks/master-list/master-form.tsx +157 -0
- package/src/blocks/master-list/master-list-desk.tsx +370 -0
- package/src/blocks/master-list/master-list.tsx +189 -0
- package/src/blocks/master-list/types.ts +18 -0
- package/src/blocks/mermaid-preview/index.ts +1 -0
- package/src/blocks/mermaid-preview/mermaid-preview.tsx +164 -0
- package/src/blocks/notifications/README.md +7 -0
- package/src/blocks/notifications/index.ts +1 -0
- package/src/blocks/notifications/notification-center-page.tsx +73 -0
- package/src/blocks/pricing/index.ts +7 -0
- package/src/blocks/pricing/pricing-table.tsx +173 -0
- package/src/blocks/pricing/pricing-types.ts +34 -0
- package/src/blocks/product-card/index.ts +2 -0
- package/src/blocks/product-card/product-card-types.ts +35 -0
- package/src/blocks/product-card/product-card.tsx +183 -0
- package/src/blocks/table/data-table-block.tsx +313 -0
- package/src/blocks/table/data-table-filter-menu.tsx +48 -0
- package/src/blocks/table/data-table-icon-menu-trigger.tsx +44 -0
- package/src/blocks/table/data-table-menu-content.tsx +32 -0
- package/src/blocks/table/data-table-pagination.tsx +149 -0
- package/src/blocks/table/data-table-row-actions.tsx +53 -0
- package/src/blocks/table/data-table-status.tsx +42 -0
- package/src/blocks/table/data-table-toolbar.tsx +124 -0
- package/src/blocks/table/data-table-totals.tsx +31 -0
- package/src/blocks/table/index.ts +13 -0
- package/src/blocks/workspace/index.ts +19 -0
- package/src/blocks/workspace/workspace-action-card.tsx +73 -0
- package/src/blocks/workspace/workspace-application-header.tsx +67 -0
- package/src/blocks/workspace/workspace-entity-card.tsx +48 -0
- package/src/blocks/workspace/workspace-health-summary.tsx +15 -0
- package/src/blocks/workspace/workspace-metric-card.tsx +97 -0
- package/src/blocks/workspace/workspace-page-header.tsx +43 -0
- package/src/blocks/workspace/workspace-publish-status.tsx +15 -0
- package/src/blocks/workspace/workspace-route-checklist.tsx +28 -0
- package/src/blocks/workspace/workspace-runtime-status.tsx +48 -0
- package/src/blocks/workspace/workspace-section-card.tsx +42 -0
- package/src/components/accordion.tsx +65 -0
- package/src/components/alert-dialog.tsx +160 -0
- package/src/components/alert.tsx +68 -0
- package/src/components/aspect-ratio.tsx +22 -0
- package/src/components/attachment.tsx +195 -0
- package/src/components/avatar.tsx +90 -0
- package/src/components/badge.tsx +55 -0
- package/src/components/breadcrumb.tsx +100 -0
- package/src/components/bubble.tsx +123 -0
- package/src/components/button-group.tsx +79 -0
- package/src/components/button.tsx +71 -0
- package/src/components/calendar.tsx +185 -0
- package/src/components/card.tsx +100 -0
- package/src/components/carousel.tsx +229 -0
- package/src/components/chart.tsx +338 -0
- package/src/components/checkbox.tsx +27 -0
- package/src/components/collapsible.tsx +15 -0
- package/src/components/combobox.tsx +269 -0
- package/src/components/command.tsx +181 -0
- package/src/components/compact-model-switcher.tsx +128 -0
- package/src/components/context-menu.tsx +244 -0
- package/src/components/dialog.tsx +138 -0
- package/src/components/direction.tsx +1 -0
- package/src/components/drawer.tsx +208 -0
- package/src/components/dropdown-menu.tsx +257 -0
- package/src/components/empty.tsx +93 -0
- package/src/components/field.tsx +232 -0
- package/src/components/hover-card.tsx +45 -0
- package/src/components/input-group.tsx +146 -0
- package/src/components/input-otp.tsx +83 -0
- package/src/components/input.tsx +19 -0
- package/src/components/item.tsx +188 -0
- package/src/components/kbd.tsx +26 -0
- package/src/components/label.tsx +17 -0
- package/src/components/markdown-content.tsx +113 -0
- package/src/components/marker.tsx +67 -0
- package/src/components/menubar.tsx +267 -0
- package/src/components/message-scroller.tsx +91 -0
- package/src/components/message.tsx +84 -0
- package/src/components/native-select.tsx +54 -0
- package/src/components/navigation-menu.tsx +160 -0
- package/src/components/pagination.tsx +118 -0
- package/src/components/popover.tsx +74 -0
- package/src/components/progress.tsx +82 -0
- package/src/components/questionnaire.tsx +150 -0
- package/src/components/radio-group.tsx +35 -0
- package/src/components/resizable.tsx +41 -0
- package/src/components/rich-text-editor.tsx +604 -0
- package/src/components/scroll-area.tsx +47 -0
- package/src/components/select.tsx +189 -0
- package/src/components/separator.tsx +18 -0
- package/src/components/sheet.tsx +125 -0
- package/src/components/sidebar.tsx +693 -0
- package/src/components/skeleton.tsx +13 -0
- package/src/components/slider.tsx +51 -0
- package/src/components/sonner.tsx +45 -0
- package/src/components/sparkline.tsx +231 -0
- package/src/components/spinner.tsx +20 -0
- package/src/components/status-badge.tsx +114 -0
- package/src/components/switch.tsx +31 -0
- package/src/components/table.tsx +91 -0
- package/src/components/tabs.tsx +72 -0
- package/src/components/textarea.tsx +17 -0
- package/src/components/toast.tsx +222 -0
- package/src/components/toggle-group.tsx +85 -0
- package/src/components/toggle.tsx +42 -0
- package/src/components/tooltip.tsx +53 -0
- package/src/design-system/README.md +55 -0
- package/src/design-system/action-intents.ts +21 -0
- package/src/design-system/agent-manifest.ts +83 -0
- package/src/design-system/block-registry.ts +272 -0
- package/src/design-system/component-registry.ts +142 -0
- package/src/design-system/contracts.ts +69 -0
- package/src/design-system/defaults.ts +3 -0
- package/src/design-system/index.ts +29 -0
- package/src/design-system/mcp-server.ts +156 -0
- package/src/design-system/page-registry.ts +74 -0
- package/src/design-system/selection.ts +67 -0
- package/src/design-system/template-registry.ts +33 -0
- package/src/features/interface-topology/index.ts +14 -0
- package/src/features/interface-topology/interface-topology.types.ts +40 -0
- package/src/features/interface-topology/topology-control.tsx +18 -0
- package/src/features/interface-topology/topology-inspector.tsx +228 -0
- package/src/features/interface-topology/topology-marker.tsx +47 -0
- package/src/features/interface-topology/topology-region.tsx +44 -0
- package/src/features/interface-topology/use-interface-topology.ts +178 -0
- package/src/hooks/use-mobile.ts +19 -0
- package/src/hooks/use-scroll-follow.ts +22 -0
- package/src/index.ts +11 -0
- package/src/layouts/README.md +65 -0
- package/src/layouts/agent-workspace/agent-activity-rail.tsx +101 -0
- package/src/layouts/agent-workspace/agent-workspace.tsx +27 -0
- package/src/layouts/agent-workspace/agent-workspace.types.ts +28 -0
- package/src/layouts/agent-workspace/index.ts +7 -0
- package/src/layouts/blog-header/blog-header-types.ts +25 -0
- package/src/layouts/blog-header/blog-header.tsx +172 -0
- package/src/layouts/blog-header/index.ts +2 -0
- package/src/layouts/documentation-workspace/README.md +8 -0
- package/src/layouts/documentation-workspace/documentation-workspace.tsx +34 -0
- package/src/layouts/documentation-workspace/index.ts +1 -0
- package/src/layouts/ecommerce-header/ecommerce-actions.tsx +89 -0
- package/src/layouts/ecommerce-header/ecommerce-announcement.tsx +43 -0
- package/src/layouts/ecommerce-header/ecommerce-drawer.tsx +97 -0
- package/src/layouts/ecommerce-header/ecommerce-header-types.ts +59 -0
- package/src/layouts/ecommerce-header/ecommerce-header.tsx +47 -0
- package/src/layouts/ecommerce-header/ecommerce-navigation.tsx +98 -0
- package/src/layouts/ecommerce-header/ecommerce-search.tsx +86 -0
- package/src/layouts/ecommerce-header/index.ts +2 -0
- package/src/layouts/main-workspace/index.ts +28 -0
- package/src/layouts/mdi/index.ts +1 -0
- package/src/layouts/mdi/mdi.tsx +20 -0
- package/src/layouts/mdi-main/index.ts +27 -0
- package/src/layouts/mdi-main/mdi-app-catalog.generated.ts +159 -0
- package/src/layouts/mdi-main/mdi-app-catalog.ts +76 -0
- package/src/layouts/mdi-main/mdi-app-switcher.tsx +107 -0
- package/src/layouts/mdi-main/mdi-feature-settings.tsx +135 -0
- package/src/layouts/mdi-main/mdi-global-search.tsx +192 -0
- package/src/layouts/mdi-main/mdi-main.tsx +241 -0
- package/src/layouts/mdi-main/mdi-notifications-menu.tsx +197 -0
- package/src/layouts/mdi-main/mdi-profile-menu.tsx +79 -0
- package/src/layouts/mdi-main/mdi-sidebar-navigation.tsx +226 -0
- package/src/layouts/mdi-main/mdi-sidebar.tsx +110 -0
- package/src/layouts/mdi-main/mdi-status-bar.tsx +26 -0
- package/src/layouts/mdi-main/mdi-top-menu-control.ts +4 -0
- package/src/layouts/mdi-main/mdi-top-menu.tsx +117 -0
- package/src/layouts/mdi-main/mdi-topology.tsx +297 -0
- package/src/layouts/mdi-main/mdi-tweak-panel.tsx +104 -0
- package/src/layouts/mdi-main/mdi-types.ts +131 -0
- package/src/layouts/mdi-main/use-mdi-features.ts +36 -0
- package/src/layouts/mdi-main/use-mdi-sidebar-state.ts +59 -0
- package/src/layouts/site-header/announcement-bar.tsx +55 -0
- package/src/layouts/site-header/category-strip.tsx +41 -0
- package/src/layouts/site-header/index.ts +16 -0
- package/src/layouts/site-header/main-navbar.tsx +179 -0
- package/src/layouts/site-header/mobile-drawer.tsx +140 -0
- package/src/layouts/site-header/site-header-types.ts +63 -0
- package/src/layouts/site-header/site-header.tsx +58 -0
- package/src/lib/random-id.ts +19 -0
- package/src/lib/utils.ts +6 -0
- package/src/providers/pdf-provider.ts +137 -0
- package/src/styles/globals.css +374 -0
- package/src/templates/README.md +12 -0
- package/src/templates/dashboard-01/components/app-sidebar.tsx +177 -0
- package/src/templates/dashboard-01/components/chart-area-interactive.tsx +276 -0
- package/src/templates/dashboard-01/components/data-table-cell-viewer.tsx +213 -0
- package/src/templates/dashboard-01/components/data-table.tsx +577 -0
- package/src/templates/dashboard-01/components/nav-documents.tsx +79 -0
- package/src/templates/dashboard-01/components/nav-main.tsx +55 -0
- package/src/templates/dashboard-01/components/nav-secondary.tsx +39 -0
- package/src/templates/dashboard-01/components/nav-user.tsx +97 -0
- package/src/templates/dashboard-01/components/section-cards.tsx +99 -0
- package/src/templates/dashboard-01/components/site-header.tsx +14 -0
- package/src/templates/dashboard-01/data.json +614 -0
- package/src/templates/dashboard-01/index.ts +7 -0
- package/src/templates/documentation-sidebar/app-sidebar.tsx +95 -0
- package/src/templates/documentation-sidebar/index.ts +2 -0
- package/src/templates/sidebar-07/components/app-sidebar.tsx +175 -0
- package/src/templates/sidebar-07/components/nav-main.tsx +64 -0
- package/src/templates/sidebar-07/components/nav-projects.tsx +79 -0
- package/src/templates/sidebar-07/components/nav-user.tsx +105 -0
- package/src/templates/sidebar-07/components/team-switcher.tsx +94 -0
- package/src/templates/sidebar-07/index.ts +1 -0
- package/src/templates/ui-page/index.ts +7 -0
- package/src/templates/ui-page/ui-browser-frame.tsx +27 -0
- package/src/templates/ui-page/ui-template-code.tsx +48 -0
- package/src/templates/ui-page/ui-template-header.tsx +87 -0
- package/src/templates/ui-page/ui-template-navigation.tsx +60 -0
- package/src/templates/ui-page/ui-template-page.tsx +97 -0
- package/src/theme/index.ts +12 -0
- package/src/theme/theme-config.ts +30 -0
- package/src/theme/theme-provider.tsx +142 -0
- package/src/theme/theme-selector.tsx +75 -0
- package/src/tokens/index.ts +15 -0
- package/src/vite-env.d.ts +3 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import { Toast as ToastPrimitive } from '@base-ui/react/toast'
|
|
5
|
+
import { cn } from '../lib/utils'
|
|
6
|
+
|
|
7
|
+
import { Button } from '@devxcrew/react-ui/components/button'
|
|
8
|
+
import {
|
|
9
|
+
XIcon,
|
|
10
|
+
CircleCheckIcon,
|
|
11
|
+
InfoIcon,
|
|
12
|
+
TriangleAlertIcon,
|
|
13
|
+
OctagonXIcon,
|
|
14
|
+
Loader2Icon,
|
|
15
|
+
} from 'lucide-react'
|
|
16
|
+
|
|
17
|
+
const toast = ToastPrimitive.createToastManager()
|
|
18
|
+
|
|
19
|
+
function ToastProvider({ ...props }: ToastPrimitive.Provider.Props) {
|
|
20
|
+
return <ToastPrimitive.Provider {...props} />
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function ToastPortal({ ...props }: ToastPrimitive.Portal.Props) {
|
|
24
|
+
return <ToastPrimitive.Portal data-slot="toast-portal" {...props} />
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function ToastViewport({ className, ...props }: ToastPrimitive.Viewport.Props) {
|
|
28
|
+
return (
|
|
29
|
+
<ToastPrimitive.Viewport
|
|
30
|
+
data-slot="toast-viewport"
|
|
31
|
+
className={cn(
|
|
32
|
+
'pointer-events-none fixed inset-x-4 bottom-4 z-50 mx-auto w-auto max-w-sm outline-none sm:right-4 sm:left-auto sm:mx-0 sm:w-full',
|
|
33
|
+
className,
|
|
34
|
+
)}
|
|
35
|
+
{...props}
|
|
36
|
+
/>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function Toast({ className, ...props }: ToastPrimitive.Root.Props) {
|
|
41
|
+
return (
|
|
42
|
+
<ToastPrimitive.Root
|
|
43
|
+
data-slot="toast"
|
|
44
|
+
className={cn(
|
|
45
|
+
'group/toast pointer-events-auto absolute right-0 bottom-0 z-[calc(1000-var(--toast-index))] w-full origin-bottom rounded-2xl border bg-popover text-popover-foreground shadow-lg will-change-transform outline-none select-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50',
|
|
46
|
+
'[--gap:0.75rem] [--height:var(--toast-frontmost-height,var(--toast-height))] [--offset-y:calc(var(--toast-offset-y)*-1+calc(var(--toast-index)*var(--gap)*-1)+var(--toast-swipe-movement-y))] [--peek:0.75rem] [--scale:calc(max(0,1-(var(--toast-index)*0.1)))] [--shrink:calc(1-var(--scale))]',
|
|
47
|
+
'h-(--height) [transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)-(var(--toast-index)*var(--peek))-(var(--shrink)*var(--height))))_scale(var(--scale))] [transition:transform_500ms_cubic-bezier(0.22,1,0.36,1),opacity_500ms,height_150ms]',
|
|
48
|
+
"after:absolute after:top-full after:left-0 after:h-[calc(var(--gap)+1px)] after:w-full after:content-['']",
|
|
49
|
+
'data-expanded:h-(--toast-height) data-expanded:[transform:translateX(var(--toast-swipe-movement-x))_translateY(var(--offset-y))]',
|
|
50
|
+
'data-limited:opacity-0 data-starting-style:[transform:translateY(150%)]',
|
|
51
|
+
'[&[data-ending-style]:not([data-limited]):not([data-swipe-direction])]:[transform:translateY(150%)]',
|
|
52
|
+
'data-ending-style:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))]',
|
|
53
|
+
'data-ending-style:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))]',
|
|
54
|
+
'data-ending-style:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))]',
|
|
55
|
+
'data-ending-style:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]',
|
|
56
|
+
'data-expanded:data-ending-style:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))]',
|
|
57
|
+
'data-expanded:data-ending-style:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))]',
|
|
58
|
+
'data-expanded:data-ending-style:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))]',
|
|
59
|
+
'data-expanded:data-ending-style:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]',
|
|
60
|
+
className,
|
|
61
|
+
)}
|
|
62
|
+
{...props}
|
|
63
|
+
/>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function ToastContent({ className, ...props }: ToastPrimitive.Content.Props) {
|
|
68
|
+
return (
|
|
69
|
+
<ToastPrimitive.Content
|
|
70
|
+
data-slot="toast-content"
|
|
71
|
+
className={cn(
|
|
72
|
+
'flex h-full items-center gap-3 overflow-hidden p-4 transition-opacity duration-250 ease-[cubic-bezier(0.22,1,0.36,1)] data-behind:opacity-0 data-expanded:opacity-100',
|
|
73
|
+
className,
|
|
74
|
+
)}
|
|
75
|
+
{...props}
|
|
76
|
+
/>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function ToastTitle({ className, ...props }: ToastPrimitive.Title.Props) {
|
|
81
|
+
return (
|
|
82
|
+
<ToastPrimitive.Title
|
|
83
|
+
data-slot="toast-title"
|
|
84
|
+
className={cn('text-sm font-medium', className)}
|
|
85
|
+
{...props}
|
|
86
|
+
/>
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function ToastDescription({ className, ...props }: ToastPrimitive.Description.Props) {
|
|
91
|
+
return (
|
|
92
|
+
<ToastPrimitive.Description
|
|
93
|
+
data-slot="toast-description"
|
|
94
|
+
className={cn('text-sm text-muted-foreground', className)}
|
|
95
|
+
{...props}
|
|
96
|
+
/>
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function ToastAction({
|
|
101
|
+
className,
|
|
102
|
+
render = <Button variant="outline" size="sm" />,
|
|
103
|
+
...props
|
|
104
|
+
}: ToastPrimitive.Action.Props) {
|
|
105
|
+
return (
|
|
106
|
+
<ToastPrimitive.Action
|
|
107
|
+
data-slot="toast-action"
|
|
108
|
+
render={render}
|
|
109
|
+
className={cn('shrink-0', className)}
|
|
110
|
+
{...props}
|
|
111
|
+
/>
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function ToastClose({
|
|
116
|
+
className,
|
|
117
|
+
children,
|
|
118
|
+
render = <Button variant="ghost" size="icon-sm" />,
|
|
119
|
+
...props
|
|
120
|
+
}: ToastPrimitive.Close.Props) {
|
|
121
|
+
return (
|
|
122
|
+
<ToastPrimitive.Close
|
|
123
|
+
data-slot="toast-close"
|
|
124
|
+
aria-label="Close toast"
|
|
125
|
+
render={render}
|
|
126
|
+
className={cn(
|
|
127
|
+
"relative shrink-0 text-muted-foreground after:absolute after:-inset-2 after:content-[''] hover:text-foreground",
|
|
128
|
+
className,
|
|
129
|
+
)}
|
|
130
|
+
{...props}
|
|
131
|
+
>
|
|
132
|
+
{children ?? <XIcon aria-hidden="true" />}
|
|
133
|
+
</ToastPrimitive.Close>
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function ToastIcon({ type }: { type: string | undefined }) {
|
|
138
|
+
let icon: React.ReactNode = null
|
|
139
|
+
|
|
140
|
+
if (type === 'success') {
|
|
141
|
+
icon = <CircleCheckIcon aria-hidden="true" />
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (type === 'info') {
|
|
145
|
+
icon = <InfoIcon aria-hidden="true" />
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (type === 'warning') {
|
|
149
|
+
icon = <TriangleAlertIcon aria-hidden="true" />
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (type === 'error') {
|
|
153
|
+
icon = <OctagonXIcon className="text-destructive" aria-hidden="true" />
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (type === 'loading') {
|
|
157
|
+
icon = <Loader2Icon className="animate-spin" aria-hidden="true" />
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (!icon) {
|
|
161
|
+
return null
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return (
|
|
165
|
+
<span
|
|
166
|
+
data-slot="toast-icon"
|
|
167
|
+
className="shrink-0 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4"
|
|
168
|
+
>
|
|
169
|
+
{icon}
|
|
170
|
+
</span>
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function ToastList() {
|
|
175
|
+
const { toasts } = ToastPrimitive.useToastManager()
|
|
176
|
+
|
|
177
|
+
return toasts.map((toastItem) => (
|
|
178
|
+
<Toast key={toastItem.id} toast={toastItem}>
|
|
179
|
+
<ToastContent>
|
|
180
|
+
<ToastIcon type={toastItem.type} />
|
|
181
|
+
<div className="flex min-w-0 flex-1 flex-col gap-1">
|
|
182
|
+
<ToastTitle />
|
|
183
|
+
<ToastDescription />
|
|
184
|
+
</div>
|
|
185
|
+
<ToastAction />
|
|
186
|
+
<ToastClose />
|
|
187
|
+
</ToastContent>
|
|
188
|
+
</Toast>
|
|
189
|
+
))
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function Toaster({ children, toastManager = toast, ...props }: ToastPrimitive.Provider.Props) {
|
|
193
|
+
return (
|
|
194
|
+
<ToastProvider toastManager={toastManager} {...props}>
|
|
195
|
+
{children}
|
|
196
|
+
<ToastPortal>
|
|
197
|
+
<ToastViewport>
|
|
198
|
+
<ToastList />
|
|
199
|
+
</ToastViewport>
|
|
200
|
+
</ToastPortal>
|
|
201
|
+
</ToastProvider>
|
|
202
|
+
)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const createToastManager = ToastPrimitive.createToastManager
|
|
206
|
+
const useToastManager = ToastPrimitive.useToastManager
|
|
207
|
+
|
|
208
|
+
export {
|
|
209
|
+
Toaster,
|
|
210
|
+
Toast,
|
|
211
|
+
ToastAction,
|
|
212
|
+
ToastClose,
|
|
213
|
+
ToastContent,
|
|
214
|
+
ToastDescription,
|
|
215
|
+
ToastPortal,
|
|
216
|
+
ToastProvider,
|
|
217
|
+
ToastTitle,
|
|
218
|
+
ToastViewport,
|
|
219
|
+
createToastManager,
|
|
220
|
+
toast,
|
|
221
|
+
useToastManager,
|
|
222
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import { Toggle as TogglePrimitive } from '@base-ui/react/toggle'
|
|
3
|
+
import { ToggleGroup as ToggleGroupPrimitive } from '@base-ui/react/toggle-group'
|
|
4
|
+
import { type VariantProps } from 'class-variance-authority'
|
|
5
|
+
import { cn } from '../lib/utils'
|
|
6
|
+
|
|
7
|
+
import { toggleVariants } from '@devxcrew/react-ui/components/toggle'
|
|
8
|
+
|
|
9
|
+
const ToggleGroupContext = React.createContext<
|
|
10
|
+
VariantProps<typeof toggleVariants> & {
|
|
11
|
+
spacing?: number
|
|
12
|
+
orientation?: 'horizontal' | 'vertical'
|
|
13
|
+
}
|
|
14
|
+
>({
|
|
15
|
+
size: 'default',
|
|
16
|
+
variant: 'default',
|
|
17
|
+
spacing: 2,
|
|
18
|
+
orientation: 'horizontal',
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
function ToggleGroup({
|
|
22
|
+
className,
|
|
23
|
+
variant,
|
|
24
|
+
size,
|
|
25
|
+
spacing = 2,
|
|
26
|
+
orientation = 'horizontal',
|
|
27
|
+
children,
|
|
28
|
+
...props
|
|
29
|
+
}: ToggleGroupPrimitive.Props &
|
|
30
|
+
VariantProps<typeof toggleVariants> & {
|
|
31
|
+
spacing?: number
|
|
32
|
+
orientation?: 'horizontal' | 'vertical'
|
|
33
|
+
}) {
|
|
34
|
+
return (
|
|
35
|
+
<ToggleGroupPrimitive
|
|
36
|
+
data-slot="toggle-group"
|
|
37
|
+
data-variant={variant}
|
|
38
|
+
data-size={size}
|
|
39
|
+
data-spacing={spacing}
|
|
40
|
+
data-orientation={orientation}
|
|
41
|
+
style={{ '--gap': spacing } as React.CSSProperties}
|
|
42
|
+
className={cn(
|
|
43
|
+
'group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-lg data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-vertical:flex-col data-vertical:items-stretch',
|
|
44
|
+
className,
|
|
45
|
+
)}
|
|
46
|
+
{...props}
|
|
47
|
+
>
|
|
48
|
+
<ToggleGroupContext.Provider value={{ variant, size, spacing, orientation }}>
|
|
49
|
+
{children}
|
|
50
|
+
</ToggleGroupContext.Provider>
|
|
51
|
+
</ToggleGroupPrimitive>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function ToggleGroupItem({
|
|
56
|
+
className,
|
|
57
|
+
children,
|
|
58
|
+
variant = 'default',
|
|
59
|
+
size = 'default',
|
|
60
|
+
...props
|
|
61
|
+
}: TogglePrimitive.Props & VariantProps<typeof toggleVariants>) {
|
|
62
|
+
const context = React.useContext(ToggleGroupContext)
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<TogglePrimitive
|
|
66
|
+
data-slot="toggle-group-item"
|
|
67
|
+
data-variant={context.variant || variant}
|
|
68
|
+
data-size={context.size || size}
|
|
69
|
+
data-spacing={context.spacing}
|
|
70
|
+
className={cn(
|
|
71
|
+
'shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-1.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-1.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-lg group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-lg group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-lg group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-lg group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t',
|
|
72
|
+
toggleVariants({
|
|
73
|
+
variant: context.variant || variant,
|
|
74
|
+
size: context.size || size,
|
|
75
|
+
}),
|
|
76
|
+
className,
|
|
77
|
+
)}
|
|
78
|
+
{...props}
|
|
79
|
+
>
|
|
80
|
+
{children}
|
|
81
|
+
</TogglePrimitive>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export { ToggleGroup, ToggleGroupItem }
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Toggle as TogglePrimitive } from '@base-ui/react/toggle'
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority'
|
|
3
|
+
import { cn } from '../lib/utils'
|
|
4
|
+
|
|
5
|
+
const toggleVariants = cva(
|
|
6
|
+
"group/toggle inline-flex items-center justify-center gap-1 rounded-lg text-sm font-medium whitespace-nowrap transition-all outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-pressed:bg-muted data-[state=on]:bg-muted dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
7
|
+
{
|
|
8
|
+
variants: {
|
|
9
|
+
variant: {
|
|
10
|
+
default: 'bg-transparent',
|
|
11
|
+
outline: 'border border-input bg-transparent hover:bg-muted',
|
|
12
|
+
},
|
|
13
|
+
size: {
|
|
14
|
+
default:
|
|
15
|
+
'h-8 min-w-8 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2',
|
|
16
|
+
sm: "h-7 min-w-7 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
|
|
17
|
+
lg: 'h-9 min-w-9 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
defaultVariants: {
|
|
21
|
+
variant: 'default',
|
|
22
|
+
size: 'default',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
function Toggle({
|
|
28
|
+
className,
|
|
29
|
+
variant = 'default',
|
|
30
|
+
size = 'default',
|
|
31
|
+
...props
|
|
32
|
+
}: TogglePrimitive.Props & VariantProps<typeof toggleVariants>) {
|
|
33
|
+
return (
|
|
34
|
+
<TogglePrimitive
|
|
35
|
+
data-slot="toggle"
|
|
36
|
+
className={cn(toggleVariants({ variant, size, className }))}
|
|
37
|
+
{...props}
|
|
38
|
+
/>
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { Toggle, toggleVariants }
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { Tooltip as TooltipPrimitive } from '@base-ui/react/tooltip'
|
|
4
|
+
import { cn } from '../lib/utils'
|
|
5
|
+
|
|
6
|
+
function TooltipProvider({ delay = 0, ...props }: TooltipPrimitive.Provider.Props) {
|
|
7
|
+
return <TooltipPrimitive.Provider data-slot="tooltip-provider" delay={delay} {...props} />
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function Tooltip({ ...props }: TooltipPrimitive.Root.Props) {
|
|
11
|
+
return <TooltipPrimitive.Root data-slot="tooltip" {...props} />
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {
|
|
15
|
+
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function TooltipContent({
|
|
19
|
+
className,
|
|
20
|
+
side = 'top',
|
|
21
|
+
sideOffset = 4,
|
|
22
|
+
align = 'center',
|
|
23
|
+
alignOffset = 0,
|
|
24
|
+
children,
|
|
25
|
+
...props
|
|
26
|
+
}: TooltipPrimitive.Popup.Props &
|
|
27
|
+
Pick<TooltipPrimitive.Positioner.Props, 'align' | 'alignOffset' | 'side' | 'sideOffset'>) {
|
|
28
|
+
return (
|
|
29
|
+
<TooltipPrimitive.Portal>
|
|
30
|
+
<TooltipPrimitive.Positioner
|
|
31
|
+
align={align}
|
|
32
|
+
alignOffset={alignOffset}
|
|
33
|
+
side={side}
|
|
34
|
+
sideOffset={sideOffset}
|
|
35
|
+
className="isolate z-50"
|
|
36
|
+
>
|
|
37
|
+
<TooltipPrimitive.Popup
|
|
38
|
+
data-slot="tooltip-content"
|
|
39
|
+
className={cn(
|
|
40
|
+
'z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pr-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',
|
|
41
|
+
className,
|
|
42
|
+
)}
|
|
43
|
+
{...props}
|
|
44
|
+
>
|
|
45
|
+
{children}
|
|
46
|
+
<TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5" />
|
|
47
|
+
</TooltipPrimitive.Popup>
|
|
48
|
+
</TooltipPrimitive.Positioner>
|
|
49
|
+
</TooltipPrimitive.Portal>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# CODEXSUN UI Design System Contract
|
|
2
|
+
|
|
3
|
+
This document defines the package-owned design-system contract that agents and applications use to
|
|
4
|
+
discover, select, and compose shared UI.
|
|
5
|
+
|
|
6
|
+
## Source of truth
|
|
7
|
+
|
|
8
|
+
`@devxcrew/react-ui/design-system` is the source of truth. The block, component, page, and template
|
|
9
|
+
registries define the available assets, their variants, and their public import paths. Do not copy
|
|
10
|
+
registry entries into an application or into UIUX.
|
|
11
|
+
|
|
12
|
+
`designSystemManifest` is the normalized agent-facing view. It includes an asset kind, stable id,
|
|
13
|
+
description, default variant, variant descriptions, source import, and ownership boundary.
|
|
14
|
+
`validateDesignSystemManifest()` must remain green when a registry changes.
|
|
15
|
+
|
|
16
|
+
## Ownership boundary
|
|
17
|
+
|
|
18
|
+
The package owns visual structure, semantic styling, accessibility defaults, and typed UI callbacks.
|
|
19
|
+
An application owns business data, field definitions and validation, routes and permissions,
|
|
20
|
+
persistence, and workflows. A block is a reusable rendering contract; it is not a business feature
|
|
21
|
+
or a data provider.
|
|
22
|
+
|
|
23
|
+
## MCP discovery
|
|
24
|
+
|
|
25
|
+
Run `npm run ui:mcp` to start the stdio MCP surface. The server exposes:
|
|
26
|
+
|
|
27
|
+
- `ui.list_assets` to search the normalized manifest.
|
|
28
|
+
- `ui.get_asset` to inspect one asset and its ownership contract.
|
|
29
|
+
- `ui.resolve_variant` to resolve a requested or default variant.
|
|
30
|
+
- `ui.validate_selection` to reject unknown assets and variants before code generation.
|
|
31
|
+
- `ui://manifest` as a read-only manifest resource.
|
|
32
|
+
|
|
33
|
+
Agents should discover an asset, resolve its variant, and then generate application composition
|
|
34
|
+
around the public import. They must not infer business behavior from a visual specimen.
|
|
35
|
+
|
|
36
|
+
## Selection contract
|
|
37
|
+
|
|
38
|
+
`createDesignSystemSelection()` resolves blocks, components, pages, and templates together. A
|
|
39
|
+
requested id or variant that is not in its registry is rejected. Templates are included so a page
|
|
40
|
+
can change from v1 to v3 without changing its application-owned data flow.
|
|
41
|
+
|
|
42
|
+
## UIUX boundary
|
|
43
|
+
|
|
44
|
+
UIUX is a visual gallery only. It renders package assets and examples for inspection, documentation,
|
|
45
|
+
and variant comparison. It must not become a feature owner, add durable data, or define an alternate
|
|
46
|
+
design-system registry. If an asset is registered in the package, UIUX should provide a reachable
|
|
47
|
+
visual route or a contract preview.
|
|
48
|
+
|
|
49
|
+
## Agent composition workflow
|
|
50
|
+
|
|
51
|
+
1. Discover the asset through MCP or `@devxcrew/react-ui/design-system`.
|
|
52
|
+
2. Resolve the requested variant and inspect its public source path.
|
|
53
|
+
3. Keep business data, routes, permissions, persistence, and workflows in the consuming application.
|
|
54
|
+
4. Pass typed data and callbacks into the package-owned UI.
|
|
55
|
+
5. Verify the manifest and the consuming application build/typecheck.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { buttonDefaultVariant } from './defaults'
|
|
2
|
+
|
|
3
|
+
export const actionVariantByIntent = {
|
|
4
|
+
alternative: 'secondary',
|
|
5
|
+
caution: 'warning',
|
|
6
|
+
destructive: 'destructive',
|
|
7
|
+
information: 'info',
|
|
8
|
+
navigation: 'link',
|
|
9
|
+
neutral: 'neutral',
|
|
10
|
+
positive: 'success',
|
|
11
|
+
primary: buttonDefaultVariant,
|
|
12
|
+
quiet: 'ghost',
|
|
13
|
+
surface: 'outline',
|
|
14
|
+
} as const
|
|
15
|
+
|
|
16
|
+
export type ActionIntent = keyof typeof actionVariantByIntent
|
|
17
|
+
export type ActionVariant = (typeof actionVariantByIntent)[ActionIntent]
|
|
18
|
+
|
|
19
|
+
export function resolveActionVariant(intent: ActionIntent): ActionVariant {
|
|
20
|
+
return actionVariantByIntent[intent]
|
|
21
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { designSystemBlocks } from "./block-registry";
|
|
2
|
+
import { designSystemComponents } from "./component-registry";
|
|
3
|
+
import { designSystemPages } from "./page-registry";
|
|
4
|
+
import { designSystemTemplates } from "./template-registry";
|
|
5
|
+
import type {
|
|
6
|
+
DesignSystemAssetKind,
|
|
7
|
+
DesignSystemAssetManifest,
|
|
8
|
+
DesignSystemOwnership,
|
|
9
|
+
DesignSystemVariantDefinition,
|
|
10
|
+
} from "./contracts";
|
|
11
|
+
|
|
12
|
+
const packageOwnership = Object.freeze([
|
|
13
|
+
"visual structure",
|
|
14
|
+
"semantic styling",
|
|
15
|
+
"accessibility defaults",
|
|
16
|
+
"typed UI callbacks",
|
|
17
|
+
]);
|
|
18
|
+
const applicationOwnership = Object.freeze([
|
|
19
|
+
"business data",
|
|
20
|
+
"fields and validation",
|
|
21
|
+
"routes and permissions",
|
|
22
|
+
"persistence and workflows",
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
export const designSystemManifest: readonly DesignSystemAssetManifest[] = Object.freeze([
|
|
26
|
+
...designSystemBlocks.map((definition) => createManifestEntry("block", definition)),
|
|
27
|
+
...designSystemComponents.map((definition) =>
|
|
28
|
+
createManifestEntry("component", {
|
|
29
|
+
...definition,
|
|
30
|
+
description: `Reusable ${definition.name} UI primitive.`,
|
|
31
|
+
}),
|
|
32
|
+
),
|
|
33
|
+
...designSystemPages.map((definition) => createManifestEntry("page", definition)),
|
|
34
|
+
...designSystemTemplates.map((definition) => createManifestEntry("template", definition)),
|
|
35
|
+
]);
|
|
36
|
+
|
|
37
|
+
export function getDesignSystemAsset(assetId: string, kind?: DesignSystemAssetKind) {
|
|
38
|
+
return designSystemManifest.find((asset) => asset.id === assetId && (!kind || asset.kind === kind));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function validateDesignSystemManifest(manifest: readonly DesignSystemAssetManifest[] = designSystemManifest) {
|
|
42
|
+
const seen = new Set<string>();
|
|
43
|
+
const errors: string[] = [];
|
|
44
|
+
|
|
45
|
+
for (const asset of manifest) {
|
|
46
|
+
const key = `${asset.kind}:${asset.id}`;
|
|
47
|
+
if (seen.has(key)) errors.push(`Duplicate asset: ${key}`);
|
|
48
|
+
seen.add(key);
|
|
49
|
+
if (!asset.variants.some(({ id }) => id === asset.defaultVariantId)) {
|
|
50
|
+
errors.push(`Missing default variant: ${key}:${asset.defaultVariantId}`);
|
|
51
|
+
}
|
|
52
|
+
if (!asset.source.startsWith("@devxcrew/react-ui/")) errors.push(`Invalid package source: ${key}`);
|
|
53
|
+
if (!asset.ownership.packageOwns.length || !asset.ownership.applicationOwns.length) {
|
|
54
|
+
errors.push(`Incomplete ownership contract: ${key}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return Object.freeze({ valid: errors.length === 0, errors });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function createManifestEntry(
|
|
62
|
+
kind: DesignSystemAssetKind,
|
|
63
|
+
definition: {
|
|
64
|
+
defaultVariantId: string;
|
|
65
|
+
description: string;
|
|
66
|
+
id: string;
|
|
67
|
+
name: string;
|
|
68
|
+
source: string;
|
|
69
|
+
variants: readonly DesignSystemVariantDefinition[];
|
|
70
|
+
},
|
|
71
|
+
): DesignSystemAssetManifest {
|
|
72
|
+
const ownership: DesignSystemOwnership = { applicationOwns: applicationOwnership, packageOwns: packageOwnership };
|
|
73
|
+
return Object.freeze({
|
|
74
|
+
defaultVariantId: definition.defaultVariantId,
|
|
75
|
+
description: definition.description,
|
|
76
|
+
id: definition.id,
|
|
77
|
+
kind,
|
|
78
|
+
name: definition.name,
|
|
79
|
+
ownership,
|
|
80
|
+
source: definition.source,
|
|
81
|
+
variants: definition.variants,
|
|
82
|
+
});
|
|
83
|
+
}
|